For anything beyond a quick experiment, keep agent definitions out of Program.cs. A separate Agents folder keeps identity, instructions, model settings, and tool attachments easier to review.
using Runiq.Agents;using Runiq.Agents.Tools;using Runiq.WorkflowTravelPlanner.Tools;namespace Runiq.WorkflowTravelPlanner.Agents;public sealed class WeatherAgent : Agent{ private WeatherAgent(string? apiKey) : base( id: "weather-agent", name: "Weather Agent", instructions: """ You are the Weather Analyst in a deterministic travel planning workflow. Your responsibility: - Analyze weather and travel comfort only. - Always use WeatherTool when the request involves a city or trip plan. - After using WeatherTool, write a short natural-language contribution. Boundaries: - Do not create an itinerary. - Do not write the final travel plan. - Do not print raw JSON. """, model: "openai/gpt-5", apiKey: apiKey) { } public static Agent Create(string? apiKey) { return new WeatherAgent(apiKey) .AddTool<WeatherTool>(); }}
The constructor is private because application code should use WeatherAgent.Create(...). That factory returns the agent with its required tool attached.
The planner has a different responsibility and a different tool:
C#
using Runiq.Agents;using Runiq.Agents.Tools;using Runiq.WorkflowTravelPlanner.Tools;namespace Runiq.WorkflowTravelPlanner.Agents;public sealed class PlannerAgent : Agent{ private PlannerAgent(string? apiKey) : base( id: "planner-agent", name: "Planner Agent", instructions: """ You are the final Travel Planner in a deterministic travel planning workflow. Your responsibility: - Create the final user-facing itinerary. - Use the previous workflow step output as context. - Always use MealSuggestionTool before finalizing. - Produce a practical, clear, low-fatigue travel plan. Boundaries: - Do not print raw JSON. - Do not expose internal tool output directly. """, model: "openai/gpt-5", apiKey: apiKey) { } public static Agent Create(string? apiKey) { return new PlannerAgent(apiKey) .AddTool<MealSuggestionTool>(); }}
This is usually easier to maintain than one large "travel agent" with every responsibility and every tool attached.
Local providers such as ollama are represented in the current runtime defaults without an API key requirement:
C#
new Agent( id: "local-agent", name: "Local Agent", instructions: "Answer using the local model.", model: "ollama/llama3.2");
OpenAI, Groq, Mistral, DeepSeek, OpenRouter, Together, Fireworks, NVIDIA, and Azure OpenAI are registered as API-key providers in the current implementation.