|
1 | 1 | #!/usr/bin/dotnet run |
2 | | -#:package Microsoft.Extensions.AI@9.9.1 |
3 | | -#:package Microsoft.Agents.AI.OpenAI@1.0.0-preview.251001.3 |
4 | | -#:package Microsoft.Agents.AI@1.0.0-preview.251001.3 |
5 | | -#:package DotNetEnv@3.1.1 |
6 | 2 |
|
7 | | -// 📚 Import Essential Namespaces for Agent Development |
8 | | -using System; |
9 | | -using System.ComponentModel; |
| 3 | +#:package Microsoft.Extensions.AI@10.* |
| 4 | +#:package Microsoft.Agents.AI.OpenAI@1.*-* |
| 5 | + |
10 | 6 | using System.ClientModel; |
11 | | -using Microsoft.Extensions.AI; |
| 7 | +using System.ComponentModel; |
| 8 | + |
12 | 9 | using Microsoft.Agents.AI; |
| 10 | +using Microsoft.Extensions.AI; |
| 11 | + |
13 | 12 | using OpenAI; |
14 | | -using DotNetEnv; |
15 | | - |
16 | | -// 🔧 Load Environment Configuration from .env File |
17 | | -// Load configuration from a .env file located 3 directories up from current location |
18 | | -// This loads: GITHUB_ENDPOINT, GITHUB_TOKEN, GITHUB_MODEL_ID |
19 | | -// Ensures secure handling of API credentials and configuration settings |
20 | | -Env.Load("../../../.env"); |
21 | | - |
22 | | -// 🎲 Tool Function: Random Destination Generator (.NET Implementation) |
23 | | -// This static method demonstrates how to create tools for agents in .NET |
24 | | -// The [Description] attribute helps the AI understand when and how to use this function |
25 | | -// This showcases the .NET approach to extending agent capabilities with custom tools |
| 13 | + |
| 14 | +// Tool Function: Random Destination Generator |
| 15 | +// This static method will be available to the agent as a callable tool |
| 16 | +// The [Description] attribute helps the AI understand when to use this function |
| 17 | +// This demonstrates how to create custom tools for AI agents |
26 | 18 | [Description("Provides a random vacation destination.")] |
27 | 19 | static string GetRandomDestination() |
28 | 20 | { |
29 | | - // Curated list of popular vacation destinations worldwide |
30 | | - // The agent will randomly select from these options when users need destination suggestions |
| 21 | + // List of popular vacation destinations around the world |
| 22 | + // The agent will randomly select from these options |
31 | 23 | var destinations = new List<string> |
32 | 24 | { |
33 | | - "Paris, France", // European cultural capital |
34 | | - "Tokyo, Japan", // Asian modern metropolis |
35 | | - "New York City, USA", // American urban experience |
36 | | - "Sydney, Australia", // Oceanic coastal beauty |
37 | | - "Rome, Italy", // Historical European city |
38 | | - "Barcelona, Spain", // Mediterranean cultural hub |
39 | | - "Cape Town, South Africa", // African scenic destination |
40 | | - "Rio de Janeiro, Brazil", // South American beach city |
41 | | - "Bangkok, Thailand", // Southeast Asian cultural center |
42 | | - "Vancouver, Canada" // North American natural beauty |
| 25 | + "Paris, France", |
| 26 | + "Tokyo, Japan", |
| 27 | + "New York City, USA", |
| 28 | + "Sydney, Australia", |
| 29 | + "Rome, Italy", |
| 30 | + "Barcelona, Spain", |
| 31 | + "Cape Town, South Africa", |
| 32 | + "Rio de Janeiro, Brazil", |
| 33 | + "Bangkok, Thailand", |
| 34 | + "Vancouver, Canada" |
43 | 35 | }; |
44 | 36 |
|
45 | | - // Generate random index using System.Random and return selected destination |
46 | | - // This demonstrates simple random selection in .NET |
| 37 | + // Generate random index and return selected destination |
| 38 | + // Uses System.Random for simple random selection |
47 | 39 | var random = new Random(); |
48 | 40 | int index = random.Next(destinations.Count); |
49 | 41 | return destinations[index]; |
50 | 42 | } |
51 | 43 |
|
52 | | -// 🔑 Extract and Validate Configuration from Environment Variables |
53 | | -// Retrieve GitHub Models API endpoint - throws exception if not configured |
54 | | -var github_endpoint = Environment.GetEnvironmentVariable("GITHUB_ENDPOINT") ?? throw new InvalidOperationException("GITHUB_ENDPOINT is not set."); |
55 | | -// Get the AI model ID - defaults to gpt-4o-mini if not specified |
56 | | -var github_model_id = Environment.GetEnvironmentVariable("GITHUB_MODEL_ID") ?? "gpt-4o-mini"; |
57 | | -// Retrieve GitHub authentication token - throws exception if missing |
58 | | -var github_token = Environment.GetEnvironmentVariable("GITHUB_TOKEN") ?? throw new InvalidOperationException("GITHUB_TOKEN is not set."); |
59 | | - |
60 | | -// ⚙️ Configure OpenAI Client Options for GitHub Models Integration |
61 | | -// Create configuration options to redirect OpenAI client calls to GitHub Models endpoint |
62 | | -// This enables using OpenAI-compatible APIs with GitHub's model inference service |
| 44 | +// Extract configuration from environment variables |
| 45 | +// Retrieve the GitHub Models API endpoint, defaults to https://models.github.ai/inference if not specified |
| 46 | +// Retrieve the model ID, defaults to openai/gpt-5-mini if not specified |
| 47 | +// Retrieve the GitHub token for authentication, throws exception if not specified |
| 48 | +var github_endpoint = Environment.GetEnvironmentVariable("GH_ENDPOINT") ?? "https://models.github.ai/inference"; |
| 49 | +var github_model_id = Environment.GetEnvironmentVariable("GH_MODEL_ID") ?? "openai/gpt-5-mini"; |
| 50 | +var github_token = Environment.GetEnvironmentVariable("GH_TOKEN") ?? throw new InvalidOperationException("GH_TOKEN is not set."); |
| 51 | + |
| 52 | +// Configure OpenAI Client Options |
| 53 | +// Create configuration options to point to GitHub Models endpoint |
| 54 | +// This redirects OpenAI client calls to GitHub's model inference service |
63 | 55 | var openAIOptions = new OpenAIClientOptions() |
64 | 56 | { |
65 | | - Endpoint = new Uri(github_endpoint) // Set custom endpoint for GitHub Models API |
| 57 | + Endpoint = new Uri(github_endpoint) |
66 | 58 | }; |
67 | 59 |
|
68 | | -// 🔌 Initialize OpenAI Client with GitHub Models Configuration |
69 | | -// Create OpenAI client instance using GitHub token for authentication |
| 60 | +// Initialize OpenAI Client with GitHub Models Configuration |
| 61 | +// Create OpenAI client using GitHub token for authentication |
70 | 62 | // Configure it to use GitHub Models endpoint instead of OpenAI directly |
71 | | -// This client will handle all communication with the AI model |
72 | 63 | var openAIClient = new OpenAIClient(new ApiKeyCredential(github_token), openAIOptions); |
73 | 64 |
|
74 | | -// 🤖 Define Agent Identity and Comprehensive Instructions |
| 65 | +// Define Agent Identity and Comprehensive Instructions |
75 | 66 | // Agent name for identification and logging purposes |
76 | | -const string AGENT_NAME = "TravelAgent"; |
| 67 | +var AGENT_NAME = "TravelAgent"; |
77 | 68 |
|
78 | 69 | // Detailed instructions that define the agent's personality, capabilities, and behavior |
79 | 70 | // This system prompt shapes how the agent responds and interacts with users |
80 | | -const string AGENT_INSTRUCTIONS = @"You are a helpful AI Agent that can help plan vacations for customers. |
| 71 | +var AGENT_INSTRUCTIONS = """ |
| 72 | +You are a helpful AI Agent that can help plan vacations for customers. |
81 | 73 |
|
82 | 74 | Important: When users specify a destination, always plan for that location. Only suggest random destinations when the user hasn't specified a preference. |
83 | 75 |
|
84 | 76 | When the conversation begins, introduce yourself with this message: |
85 | | -""Hello! I'm your TravelAgent assistant. I can help plan vacations and suggest interesting destinations for you. Here are some things you can ask me: |
| 77 | +"Hello! I'm your TravelAgent assistant. I can help plan vacations and suggest interesting destinations for you. Here are some things you can ask me: |
86 | 78 | 1. Plan a day trip to a specific location |
87 | 79 | 2. Suggest a random vacation destination |
88 | 80 | 3. Find destinations with specific features (beaches, mountains, historical sites, etc.) |
89 | 81 | 4. Plan an alternative trip if you don't like my first suggestion |
90 | 82 |
|
91 | | -What kind of trip would you like me to help you plan today?"" |
| 83 | +What kind of trip would you like me to help you plan today?" |
92 | 84 |
|
93 | | -Always prioritize user preferences. If they mention a specific destination like ""Bali"" or ""Paris,"" focus your planning on that location rather than suggesting alternatives. |
94 | | -"; |
| 85 | +Always prioritize user preferences. If they mention a specific destination like "Bali" or "Paris," focus your planning on that location rather than suggesting alternatives. |
| 86 | +"""; |
95 | 87 |
|
96 | | -// 🤖 Create AI Agent with Advanced Travel Planning Capabilities |
| 88 | +// Create AI Agent with Advanced Travel Planning Capabilities |
97 | 89 | // Initialize complete agent pipeline: OpenAI client → Chat client → AI agent |
98 | 90 | // Configure agent with name, detailed instructions, and available tools |
99 | 91 | // This demonstrates the .NET agent creation pattern with full configuration |
100 | | -AIAgent agent = new OpenAIClient(new ApiKeyCredential(github_token), openAIOptions) |
101 | | - .GetChatClient(github_model_id) // Get chat client for the specified AI model |
| 92 | +AIAgent agent = openAIClient |
| 93 | + .GetChatClient(github_model_id) |
102 | 94 | .CreateAIAgent( |
103 | | - name: AGENT_NAME, // Set agent identifier for logging and tracking |
104 | | - instructions: AGENT_INSTRUCTIONS, // Comprehensive behavior and personality instructions |
105 | | - tools: [AIFunctionFactory.Create((Func<string>)GetRandomDestination)] // Register tool functions |
| 95 | + name: AGENT_NAME, |
| 96 | + instructions: AGENT_INSTRUCTIONS, |
| 97 | + tools: [AIFunctionFactory.Create(GetRandomDestination)] |
106 | 98 | ); |
107 | 99 |
|
108 | | -// 🧵 Create New Conversation Thread for Context Management |
| 100 | +// Create New Conversation Thread for Context Management |
109 | 101 | // Initialize a new conversation thread to maintain context across multiple interactions |
110 | 102 | // Threads enable the agent to remember previous exchanges and maintain conversational state |
111 | 103 | // This is essential for multi-turn conversations and contextual understanding |
112 | 104 | AgentThread thread = agent.GetNewThread(); |
113 | 105 |
|
114 | | -// 🚀 Execute Agent: First Travel Planning Request |
| 106 | +// Execute Agent: First Travel Planning Request |
115 | 107 | // Run the agent with an initial request that will likely trigger the random destination tool |
116 | 108 | // The agent will analyze the request, use the GetRandomDestination tool, and create an itinerary |
117 | 109 | // Using the thread parameter maintains conversation context for subsequent interactions |
118 | | -Console.WriteLine(await agent.RunAsync("Plan me a day trip", thread)); |
| 110 | +await foreach (var update in agent.RunStreamingAsync("Plan me a day trip", thread)) |
| 111 | +{ |
| 112 | + await Task.Delay(10); |
| 113 | + Console.Write(update); |
| 114 | +} |
119 | 115 |
|
120 | | -// 🔄 Execute Agent: Follow-up Request with Context Awareness |
| 116 | +Console.WriteLine(); |
| 117 | + |
| 118 | +// Execute Agent: Follow-up Request with Context Awareness |
121 | 119 | // Demonstrate contextual conversation by referencing the previous response |
122 | 120 | // The agent remembers the previous destination suggestion and will provide an alternative |
123 | 121 | // This showcases the power of conversation threads and contextual understanding in .NET agents |
124 | | -Console.WriteLine(await agent.RunAsync("I don't like that destination. Plan me another vacation.", thread)); |
| 122 | +await foreach (var update in agent.RunStreamingAsync("I don't like that destination. Plan me another vacation.", thread)) |
| 123 | +{ |
| 124 | + await Task.Delay(10); |
| 125 | + Console.Write(update); |
| 126 | +} |
0 commit comments