Example: Weather Agent
This example builds a fully functional weather agent with a custom Python capability that calls a weather API. By the end, you’ll have an agent package you can test locally and publish to the marketplace.
Project structure
Section titled “Project structure”Directoryweather-agent/
- agent.yaml
- agent.md
Directorycapabilities/
Directoryweather/
- manifest.yaml
- prompt.md
- Dockerfile
- requirements.txt
- server.py
Step-by-step
Section titled “Step-by-step”-
agent.yaml
agent.yaml id: weather-agentname: Weather Agentmodel:temperature: 0.5routing: inlinecapabilities:- id: weatherinstall_steps:- id: api_keytype: inputlabel: OpenWeatherMap API Keydescription: Get a free key at openweathermap.org/apistore_as:scope: systemcapability_id: weathercredential_name: OPENWEATHER_API_KEY -
agent.md
agent.md You are Weather Agent, a helpful assistant that provides accurate,real-time weather information.## Instructions- Use the `weather_lookup` tool to answer any weather question.- Always ask for a location if the user doesn't provide one.- Report temperature, conditions, humidity, and wind speed.## Constraints- Only answer weather-related questions.- Never guess weather data — always use the tool. -
manifest.yaml
capabilities/weather/manifest.yaml id: weatherclass: toolimage: weather-cap:latesttools:- name: weather_lookupdescription: Get current weather conditions for a location.input_schema:type: objectproperties:location:type: stringdescription: City name or coordinatesunits:type: stringdescription: "metric or imperial"required: [location]recommended_policy: allownetwork:mode: allowlisthosts:- "api.openweathermap.org:443"credentials:- name: OPENWEATHER_API_KEYscope: systemrequired: truedescription: API key from openweathermap.orgresources:max_memory_mb: 128max_cpu_fraction: 0.5max_cpu_seconds: 30 -
server.py — the gRPC capability
capabilities/weather/server.py import grpc, json, requestsfrom concurrent import futuresimport capability_pb2 as pb2import capability_pb2_grpc as pb2_grpcBASE_URL = "https://api.openweathermap.org/data/2.5/weather"class WeatherService(pb2_grpc.CapabilityServicer):def Invoke(self, request, context):args = json.loads(request.args_json.decode())config = json.loads(request.config_json.decode())api_key = config["OPENWEATHER_API_KEY"]location = args.get("location", "")units = args.get("units", "metric")try:resp = requests.get(BASE_URL, params={"q": location, "units": units,"appid": api_key,}, timeout=5)resp.raise_for_status()data = resp.json()result = {"location": data["name"],"temperature": data["main"]["temp"],"conditions": data["weather"][0]["description"],"humidity": data["main"]["humidity"],"wind_speed": data["wind"]["speed"],}return pb2.InvokeResponse(result_json=json.dumps(result).encode())except Exception as e:return pb2.InvokeResponse(result_json=json.dumps({"error": str(e)}).encode())def serve():server = grpc.server(futures.ThreadPoolExecutor(max_workers=4))pb2_grpc.add_CapabilityServicer_to_server(WeatherService(), server)server.add_insecure_port("[::]:50051")server.start()server.wait_for_termination()if __name__ == "__main__":serve() -
Dockerfile
capabilities/weather/Dockerfile FROM python:3.12-slimWORKDIR /appCOPY requirements.txt .RUN pip install --no-cache-dir -r requirements.txtCOPY . .USER 1000EXPOSE 50051CMD ["python", "server.py"] -
Test it
Place the
weather-agent/directory inside your Seluagents/folder and restart Selu.Open
http://localhost:3000, select the Weather Agent, and ask: “What’s the weather in Tokyo?”
Next steps
Section titled “Next steps”Ready to publish? Check the Marketplace Guidelines.