test
Some checks failed
CodeQL / Analyze (csharp) (push) Has been cancelled
CodeQL / Analyze (python) (push) Has been cancelled
dotnet-build-and-test / paths-filter (push) Has been cancelled
dotnet-build-and-test / dotnet-build-and-test (Debug, windows-latest, net9.0) (push) Has been cancelled
dotnet-build-and-test / dotnet-build-and-test (Release, integration, true, ubuntu-latest, net10.0) (push) Has been cancelled
dotnet-build-and-test / dotnet-build-and-test (Release, integration, true, windows-latest, net472) (push) Has been cancelled
dotnet-build-and-test / dotnet-build-and-test (Release, ubuntu-latest, net8.0) (push) Has been cancelled
dotnet-build-and-test / dotnet-build-and-test-check (push) Has been cancelled
Python - Merge - Tests / paths-filter (push) Has been cancelled
Python - Merge - Tests / Python Tests - Core (integration, ubuntu-latest, 3.10) (push) Has been cancelled
Python - Merge - Tests / Python Tests - Azure AI (integration, ubuntu-latest, 3.10) (push) Has been cancelled
Python - Merge - Tests / python-integration-tests-check (push) Has been cancelled
Python - Lab Tests / paths-filter (push) Has been cancelled
Python - Lab Tests / Python Lab Tests (ubuntu-latest, 3.10) (push) Has been cancelled
Python - Lab Tests / Python Lab Tests (ubuntu-latest, 3.11) (push) Has been cancelled
Python - Lab Tests / Python Lab Tests (ubuntu-latest, 3.12) (push) Has been cancelled
Python - Lab Tests / Python Lab Tests (ubuntu-latest, 3.13) (push) Has been cancelled
Python - Lab Tests / Python Lab Tests (ubuntu-latest, 3.14) (push) Has been cancelled
Python - Lab Tests / Python Lab Tests (windows-latest, 3.10) (push) Has been cancelled
Python - Lab Tests / Python Lab Tests (windows-latest, 3.11) (push) Has been cancelled
Python - Lab Tests / Python Lab Tests (windows-latest, 3.12) (push) Has been cancelled
Python - Lab Tests / Python Lab Tests (windows-latest, 3.13) (push) Has been cancelled
Python - Lab Tests / Python Lab Tests (windows-latest, 3.14) (push) Has been cancelled
Check .md links / markdown-link-check (push) Has been cancelled
Some checks failed
CodeQL / Analyze (csharp) (push) Has been cancelled
CodeQL / Analyze (python) (push) Has been cancelled
dotnet-build-and-test / paths-filter (push) Has been cancelled
dotnet-build-and-test / dotnet-build-and-test (Debug, windows-latest, net9.0) (push) Has been cancelled
dotnet-build-and-test / dotnet-build-and-test (Release, integration, true, ubuntu-latest, net10.0) (push) Has been cancelled
dotnet-build-and-test / dotnet-build-and-test (Release, integration, true, windows-latest, net472) (push) Has been cancelled
dotnet-build-and-test / dotnet-build-and-test (Release, ubuntu-latest, net8.0) (push) Has been cancelled
dotnet-build-and-test / dotnet-build-and-test-check (push) Has been cancelled
Python - Merge - Tests / paths-filter (push) Has been cancelled
Python - Merge - Tests / Python Tests - Core (integration, ubuntu-latest, 3.10) (push) Has been cancelled
Python - Merge - Tests / Python Tests - Azure AI (integration, ubuntu-latest, 3.10) (push) Has been cancelled
Python - Merge - Tests / python-integration-tests-check (push) Has been cancelled
Python - Lab Tests / paths-filter (push) Has been cancelled
Python - Lab Tests / Python Lab Tests (ubuntu-latest, 3.10) (push) Has been cancelled
Python - Lab Tests / Python Lab Tests (ubuntu-latest, 3.11) (push) Has been cancelled
Python - Lab Tests / Python Lab Tests (ubuntu-latest, 3.12) (push) Has been cancelled
Python - Lab Tests / Python Lab Tests (ubuntu-latest, 3.13) (push) Has been cancelled
Python - Lab Tests / Python Lab Tests (ubuntu-latest, 3.14) (push) Has been cancelled
Python - Lab Tests / Python Lab Tests (windows-latest, 3.10) (push) Has been cancelled
Python - Lab Tests / Python Lab Tests (windows-latest, 3.11) (push) Has been cancelled
Python - Lab Tests / Python Lab Tests (windows-latest, 3.12) (push) Has been cancelled
Python - Lab Tests / Python Lab Tests (windows-latest, 3.13) (push) Has been cancelled
Python - Lab Tests / Python Lab Tests (windows-latest, 3.14) (push) Has been cancelled
Check .md links / markdown-link-check (push) Has been cancelled
This commit is contained in:
208
dotnet/samples/AGUIClientServer/README.md
Normal file
208
dotnet/samples/AGUIClientServer/README.md
Normal file
@@ -0,0 +1,208 @@
|
||||
# AG-UI Client and Server Sample
|
||||
|
||||
This sample demonstrates how to use the AG-UI (Agent UI) protocol to enable communication between a client application and a remote agent server. The AG-UI protocol provides a standardized way for clients to interact with AI agents.
|
||||
|
||||
## Overview
|
||||
|
||||
The demonstration has two components:
|
||||
|
||||
1. **AGUIServer** - An ASP.NET Core web server that hosts an AI agent and exposes it via the AG-UI protocol
|
||||
2. **AGUIClient** - A console application that connects to the AG-UI server and displays streaming updates
|
||||
|
||||
> **Warning**
|
||||
> The AG-UI protocol is still under development and changing.
|
||||
> We will try to keep these samples updated as the protocol evolves.
|
||||
|
||||
## Configuring Environment Variables
|
||||
|
||||
Configure the required Azure OpenAI environment variables:
|
||||
|
||||
```powershell
|
||||
$env:AZURE_OPENAI_ENDPOINT="<<your-model-endpoint>>"
|
||||
$env:AZURE_OPENAI_DEPLOYMENT_NAME="gpt-4.1-mini"
|
||||
```
|
||||
|
||||
> **Note:** This sample uses `DefaultAzureCredential` for authentication. Make sure you're authenticated with Azure (e.g., via `az login`, Visual Studio, or environment variables).
|
||||
|
||||
## Running the Sample
|
||||
|
||||
### Step 1: Start the AG-UI Server
|
||||
|
||||
```bash
|
||||
cd AGUIServer
|
||||
dotnet build
|
||||
dotnet run --urls "http://localhost:5100"
|
||||
```
|
||||
|
||||
The server will start and listen on `http://localhost:5100`.
|
||||
|
||||
### Step 2: Testing with the REST Client (Optional)
|
||||
|
||||
Before running the client, you can test the server using the included `.http` file:
|
||||
|
||||
1. Open [./AGUIServer/AGUIServer.http](./AGUIServer/AGUIServer.http) in Visual Studio or VS Code with the REST Client extension
|
||||
2. Send a test request to verify the server is working
|
||||
3. Observe the server-sent events stream in the response
|
||||
|
||||
Sample request:
|
||||
```http
|
||||
POST http://localhost:5100/
|
||||
Content-Type: application/json
|
||||
|
||||
{
|
||||
"threadId": "thread_123",
|
||||
"runId": "run_456",
|
||||
"messages": [
|
||||
{
|
||||
"role": "user",
|
||||
"content": "What is the capital of France?"
|
||||
}
|
||||
],
|
||||
"context": {}
|
||||
}
|
||||
```
|
||||
|
||||
### Step 3: Run the AG-UI Client
|
||||
|
||||
In a new terminal window:
|
||||
|
||||
```bash
|
||||
cd AGUIClient
|
||||
dotnet run
|
||||
```
|
||||
|
||||
Optionally, configure a different server URL:
|
||||
|
||||
```powershell
|
||||
$env:AGUI_SERVER_URL="http://localhost:5100"
|
||||
```
|
||||
|
||||
### Step 4: Interact with the Agent
|
||||
|
||||
1. The client will connect to the AG-UI server
|
||||
2. Enter your message at the prompt
|
||||
3. Observe the streaming updates with color-coded output:
|
||||
- **Yellow**: Run started notification showing thread and run IDs
|
||||
- **Cyan**: Agent's text response (streamed character by character)
|
||||
- **Green**: Run finished notification
|
||||
- **Red**: Error messages (if any occur)
|
||||
4. Type `:q` or `quit` to exit
|
||||
|
||||
## Sample Output
|
||||
|
||||
```
|
||||
AGUIClient> dotnet run
|
||||
info: AGUIClient[0]
|
||||
Connecting to AG-UI server at: http://localhost:5100
|
||||
|
||||
User (:q or quit to exit): What is the capital of France?
|
||||
|
||||
[Run Started - Thread: thread_abc123, Run: run_xyz789]
|
||||
The capital of France is Paris. It is known for its rich history, culture, and iconic landmarks such as the Eiffel Tower and the Louvre Museum.
|
||||
[Run Finished - Thread: thread_abc123, Run: run_xyz789]
|
||||
|
||||
User (:q or quit to exit): Tell me a fun fact about space
|
||||
|
||||
[Run Started - Thread: thread_abc123, Run: run_def456]
|
||||
Here's a fun fact: A day on Venus is longer than its year! Venus takes about 243 Earth days to rotate once on its axis, but only about 225 Earth days to orbit the Sun.
|
||||
[Run Finished - Thread: thread_abc123, Run: run_def456]
|
||||
|
||||
User (:q or quit to exit): :q
|
||||
```
|
||||
|
||||
## How It Works
|
||||
|
||||
### Server Side
|
||||
|
||||
The `AGUIServer` uses the `MapAGUI` extension method to expose an agent through the AG-UI protocol:
|
||||
|
||||
```csharp
|
||||
AIAgent agent = new OpenAIClient(apiKey)
|
||||
.GetChatClient(model)
|
||||
.AsAIAgent(
|
||||
instructions: "You are a helpful assistant.",
|
||||
name: "AGUIAssistant");
|
||||
|
||||
app.MapAGUI("/", agent);
|
||||
```
|
||||
|
||||
This automatically handles:
|
||||
- HTTP POST requests with message payloads
|
||||
- Converting agent responses to AG-UI event streams
|
||||
- Server-sent events (SSE) formatting
|
||||
- Thread and run management
|
||||
|
||||
### Client Side
|
||||
|
||||
The `AGUIClient` uses the `AGUIChatClient` to connect to the remote server:
|
||||
|
||||
```csharp
|
||||
using HttpClient httpClient = new();
|
||||
var chatClient = new AGUIChatClient(
|
||||
httpClient,
|
||||
endpoint: serverUrl,
|
||||
modelId: "agui-client",
|
||||
jsonSerializerOptions: null);
|
||||
|
||||
AIAgent agent = chatClient.AsAIAgent(
|
||||
instructions: null,
|
||||
name: "agui-client",
|
||||
description: "AG-UI Client Agent",
|
||||
tools: []);
|
||||
|
||||
bool isFirstUpdate = true;
|
||||
AgentResponseUpdate? currentUpdate = null;
|
||||
|
||||
await foreach (AgentResponseUpdate update in agent.RunStreamingAsync(messages, thread))
|
||||
{
|
||||
// First update indicates run started
|
||||
if (isFirstUpdate)
|
||||
{
|
||||
Console.WriteLine($"[Run Started - Thread: {update.ConversationId}, Run: {update.ResponseId}]");
|
||||
isFirstUpdate = false;
|
||||
}
|
||||
|
||||
currentUpdate = update;
|
||||
|
||||
foreach (AIContent content in update.Contents)
|
||||
{
|
||||
switch (content)
|
||||
{
|
||||
case TextContent textContent:
|
||||
// Display streaming text
|
||||
Console.Write(textContent.Text);
|
||||
break;
|
||||
case ErrorContent errorContent:
|
||||
// Display error notification
|
||||
Console.WriteLine($"[Error: {errorContent.Message}]");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Last update indicates run finished
|
||||
if (currentUpdate != null)
|
||||
{
|
||||
Console.WriteLine($"\n[Run Finished - Thread: {currentUpdate.ConversationId}, Run: {currentUpdate.ResponseId}]");
|
||||
}
|
||||
```
|
||||
|
||||
The `RunStreamingAsync` method:
|
||||
1. Sends messages to the server via HTTP POST
|
||||
2. Receives server-sent events (SSE) stream
|
||||
3. Parses events into `AgentResponseUpdate` objects
|
||||
4. Yields updates as they arrive for real-time display
|
||||
|
||||
## Key Concepts
|
||||
|
||||
- **Thread**: Represents a conversation context that persists across multiple runs (accessed via `ConversationId` property)
|
||||
- **Run**: A single execution of the agent for a given set of messages (identified by `ResponseId` property)
|
||||
- **AgentResponseUpdate**: Contains the response data with:
|
||||
- `ResponseId`: The unique run identifier
|
||||
- `ConversationId`: The thread/conversation identifier
|
||||
- `Contents`: Collection of content items (TextContent, ErrorContent, etc.)
|
||||
- **Run Lifecycle**:
|
||||
- The **first** `AgentResponseUpdate` in a run indicates the run has started
|
||||
- Subsequent updates contain streaming content as the agent processes
|
||||
- The **last** `AgentResponseUpdate` in a run indicates the run has finished
|
||||
- If an error occurs, the update will contain `ErrorContent`
|
||||
Reference in New Issue
Block a user