mirror of
https://github.com/microsoft/agent-framework.git
synced 2026-06-16 21:04:09 +08:00
Merge branch 'feature/responses-hosting' of https://github.com/microsoft/agent-framework into hosted-agent-adapter
# Conflicts: # dotnet/nuget/nuget-package.props # dotnet/samples/04-hosting/FoundryHostedAgents/HostedAgentsV2/Hosted-ChatClientAgent/Program.cs # dotnet/samples/04-hosting/FoundryHostedAgents/HostedAgentsV2/Hosted-FoundryAgent/Program.cs # dotnet/samples/04-hosting/FoundryHostedAgents/HostedAgentsV2/Hosted-LocalTools/Program.cs # dotnet/samples/04-hosting/FoundryHostedAgents/HostedAgentsV2/Hosted-McpTools/Program.cs # dotnet/samples/04-hosting/FoundryHostedAgents/HostedAgentsV2/Hosted-Workflows/Program.cs # dotnet/samples/04-hosting/FoundryResponsesHosting/Program.cs # dotnet/tests/Microsoft.Agents.AI.Foundry.UnitTests/Hosting/AgentFrameworkResponseHandlerTests.cs # dotnet/tests/Microsoft.Agents.AI.Foundry.UnitTests/Hosting/InputConverterTests.cs # dotnet/tests/Microsoft.Agents.AI.Foundry.UnitTests/Hosting/OutputConverterTests.cs # dotnet/tests/Microsoft.Agents.AI.Foundry.UnitTests/Hosting/ServiceCollectionExtensionsTests.cs # dotnet/tests/Microsoft.Agents.AI.Foundry.UnitTests/Hosting/WorkflowIntegrationTests.cs
This commit is contained in:
+17
@@ -0,0 +1,17 @@
|
||||
# Use the official .NET 10.0 ASP.NET runtime as a parent image
|
||||
FROM mcr.microsoft.com/dotnet/aspnet:10.0 AS base
|
||||
WORKDIR /app
|
||||
|
||||
FROM mcr.microsoft.com/dotnet/sdk:10.0 AS build
|
||||
WORKDIR /src
|
||||
COPY . .
|
||||
RUN dotnet restore
|
||||
RUN dotnet publish -c Release -o /app/publish
|
||||
|
||||
# Final stage
|
||||
FROM base AS final
|
||||
WORKDIR /app
|
||||
COPY --from=build /app/publish .
|
||||
EXPOSE 8088
|
||||
ENV ASPNETCORE_URLS=http://+:8088
|
||||
ENTRYPOINT ["dotnet", "HostedInvocationsEchoAgent.dll"]
|
||||
+19
@@ -0,0 +1,19 @@
|
||||
# Dockerfile for contributors building from the agent-framework repository source.
|
||||
#
|
||||
# This project uses ProjectReference to the local Microsoft.Agents.AI.Abstractions source,
|
||||
# which means a standard multi-stage Docker build cannot resolve dependencies outside
|
||||
# this folder. Instead, pre-publish the app targeting the container runtime and copy
|
||||
# the output into the container:
|
||||
#
|
||||
# dotnet publish -c Debug -f net10.0 -r linux-musl-x64 --self-contained false -o out
|
||||
# docker build -f Dockerfile.contributor -t hosted-invocations-echo-agent .
|
||||
# docker run --rm -p 8088:8088 hosted-invocations-echo-agent
|
||||
#
|
||||
# For end-users consuming the NuGet package (not ProjectReference), use the standard
|
||||
# Dockerfile which performs a full dotnet restore + publish inside the container.
|
||||
FROM mcr.microsoft.com/dotnet/aspnet:10.0-alpine AS final
|
||||
WORKDIR /app
|
||||
COPY out/ .
|
||||
EXPOSE 8088
|
||||
ENV ASPNETCORE_URLS=http://+:8088
|
||||
ENTRYPOINT ["dotnet", "HostedInvocationsEchoAgent.dll"]
|
||||
+85
@@ -0,0 +1,85 @@
|
||||
// Copyright (c) Microsoft. All rights reserved.
|
||||
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Text.Json;
|
||||
using Microsoft.Extensions.AI;
|
||||
|
||||
namespace Microsoft.Agents.AI;
|
||||
|
||||
/// <summary>
|
||||
/// A minimal <see cref="AIAgent"/> that echoes the user's input text back as the response.
|
||||
/// No LLM or external service is required.
|
||||
/// </summary>
|
||||
public sealed class EchoAIAgent : AIAgent
|
||||
{
|
||||
/// <inheritdoc/>
|
||||
public override string Name => "echo-agent";
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override string Description => "An agent that echoes back the input message.";
|
||||
|
||||
/// <inheritdoc/>
|
||||
protected override Task<AgentResponse> RunCoreAsync(
|
||||
IEnumerable<ChatMessage> messages,
|
||||
AgentSession? session = null,
|
||||
AgentRunOptions? options = null,
|
||||
CancellationToken cancellationToken = default)
|
||||
{
|
||||
var inputText = GetInputText(messages);
|
||||
var response = new AgentResponse(new ChatMessage(ChatRole.Assistant, $"Echo: {inputText}"));
|
||||
return Task.FromResult(response);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
protected override async IAsyncEnumerable<AgentResponseUpdate> RunCoreStreamingAsync(
|
||||
IEnumerable<ChatMessage> messages,
|
||||
AgentSession? session = null,
|
||||
AgentRunOptions? options = null,
|
||||
[EnumeratorCancellation] CancellationToken cancellationToken = default)
|
||||
{
|
||||
var inputText = GetInputText(messages);
|
||||
yield return new AgentResponseUpdate
|
||||
{
|
||||
Role = ChatRole.Assistant,
|
||||
Contents = [new TextContent($"Echo: {inputText}")],
|
||||
};
|
||||
|
||||
await Task.CompletedTask;
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
protected override ValueTask<AgentSession> CreateSessionCoreAsync(CancellationToken cancellationToken = default)
|
||||
=> new(new EchoAgentSession());
|
||||
|
||||
/// <inheritdoc/>
|
||||
protected override ValueTask<JsonElement> SerializeSessionCoreAsync(
|
||||
AgentSession session,
|
||||
JsonSerializerOptions? jsonSerializerOptions = null,
|
||||
CancellationToken cancellationToken = default)
|
||||
=> new(JsonSerializer.SerializeToElement(new { }, jsonSerializerOptions));
|
||||
|
||||
/// <inheritdoc/>
|
||||
protected override ValueTask<AgentSession> DeserializeSessionCoreAsync(
|
||||
JsonElement serializedState,
|
||||
JsonSerializerOptions? jsonSerializerOptions = null,
|
||||
CancellationToken cancellationToken = default)
|
||||
=> new(new EchoAgentSession());
|
||||
|
||||
private static string GetInputText(IEnumerable<ChatMessage> messages)
|
||||
{
|
||||
foreach (var message in messages)
|
||||
{
|
||||
if (message.Role == ChatRole.User)
|
||||
{
|
||||
return message.Text ?? string.Empty;
|
||||
}
|
||||
}
|
||||
|
||||
return string.Empty;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Minimal session for the echo agent. No state is persisted.
|
||||
/// </summary>
|
||||
private sealed class EchoAgentSession : AgentSession;
|
||||
}
|
||||
+33
@@ -0,0 +1,33 @@
|
||||
// Copyright (c) Microsoft. All rights reserved.
|
||||
|
||||
using Azure.AI.AgentServer.Invocations;
|
||||
using Microsoft.Agents.AI;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
|
||||
namespace HostedInvocationsEchoAgent;
|
||||
|
||||
/// <summary>
|
||||
/// An <see cref="InvocationHandler"/> that reads the request body as plain text,
|
||||
/// passes it to the <see cref="EchoAIAgent"/>, and writes the response back.
|
||||
/// </summary>
|
||||
public sealed class EchoInvocationHandler(EchoAIAgent agent) : InvocationHandler
|
||||
{
|
||||
/// <inheritdoc/>
|
||||
public override async Task HandleAsync(
|
||||
HttpRequest request,
|
||||
HttpResponse response,
|
||||
InvocationContext context,
|
||||
CancellationToken cancellationToken)
|
||||
{
|
||||
// Read the raw text from the request body.
|
||||
using var reader = new StreamReader(request.Body);
|
||||
var input = await reader.ReadToEndAsync(cancellationToken);
|
||||
|
||||
// Run the echo agent with the input text.
|
||||
var agentResponse = await agent.RunAsync(input, cancellationToken: cancellationToken);
|
||||
|
||||
// Write the agent response text back to the HTTP response.
|
||||
response.ContentType = "text/plain";
|
||||
await response.WriteAsync(agentResponse.Text, cancellationToken);
|
||||
}
|
||||
}
|
||||
+29
@@ -0,0 +1,29 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk.Web">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFrameworks>net10.0</TargetFrameworks>
|
||||
<Nullable>enable</Nullable>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<CentralPackageTransitivePinningEnabled>false</CentralPackageTransitivePinningEnabled>
|
||||
<RootNamespace>HostedInvocationsEchoAgent</RootNamespace>
|
||||
<AssemblyName>HostedInvocationsEchoAgent</AssemblyName>
|
||||
<NoWarn>$(NoWarn);</NoWarn>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Azure.AI.AgentServer.Invocations" />
|
||||
</ItemGroup>
|
||||
|
||||
<!-- For contributors: uses ProjectReference to build against local source -->
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\..\..\..\src\Microsoft.Agents.AI.Abstractions\Microsoft.Agents.AI.Abstractions.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<!-- For end-users: uncomment the PackageReference below and remove the ProjectReference above
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.Agents.AI.Abstractions" Version="1.0.0" />
|
||||
<PackageReference Include="Azure.AI.AgentServer.Invocations" />
|
||||
</ItemGroup>
|
||||
-->
|
||||
|
||||
</Project>
|
||||
+24
@@ -0,0 +1,24 @@
|
||||
// Copyright (c) Microsoft. All rights reserved.
|
||||
|
||||
using Azure.AI.AgentServer.Invocations;
|
||||
using HostedInvocationsEchoAgent;
|
||||
using Microsoft.Agents.AI;
|
||||
|
||||
var builder = WebApplication.CreateBuilder(args);
|
||||
|
||||
// Register the echo agent as a singleton (no LLM needed).
|
||||
builder.Services.AddSingleton<EchoAIAgent>();
|
||||
|
||||
// Register the Invocations SDK services and wire the handler.
|
||||
builder.Services.AddInvocationsServer();
|
||||
builder.Services.AddScoped<InvocationHandler, EchoInvocationHandler>();
|
||||
|
||||
var app = builder.Build();
|
||||
|
||||
// Map the Invocations protocol endpoints:
|
||||
// POST /invocations — invoke the agent
|
||||
// GET /invocations/{id} — get result (not used by this sample)
|
||||
// POST /invocations/{id}/cancel — cancel (not used by this sample)
|
||||
app.MapInvocationsServer();
|
||||
|
||||
app.Run();
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"profiles": {
|
||||
"Hosted-Invocations-EchoAgent": {
|
||||
"commandName": "Project",
|
||||
"environmentVariables": {
|
||||
"ASPNETCORE_ENVIRONMENT": "Development"
|
||||
},
|
||||
"applicationUrl": "http://localhost:8088"
|
||||
}
|
||||
}
|
||||
}
|
||||
+66
@@ -0,0 +1,66 @@
|
||||
# Hosted-Invocations-EchoAgent
|
||||
|
||||
A minimal echo agent hosted as a Foundry Hosted Agent using the **Invocations protocol**. The agent reads the request body as plain text, passes it through a custom `EchoAIAgent`, and writes the echoed text back in the response. No LLM or Azure credentials are required.
|
||||
|
||||
## Prerequisites
|
||||
|
||||
- [.NET 10 SDK](https://dotnet.microsoft.com/download/dotnet/10.0)
|
||||
|
||||
## Running directly (contributors)
|
||||
|
||||
This project uses `ProjectReference` to build against the local Agent Framework source.
|
||||
|
||||
```bash
|
||||
cd dotnet/samples/04-hosting/FoundryHostedAgents/HostedAgentsV2/Hosted-Invocations-EchoAgent
|
||||
dotnet run
|
||||
```
|
||||
|
||||
The agent will start on `http://localhost:8088`.
|
||||
|
||||
### Test it
|
||||
|
||||
```bash
|
||||
curl -X POST http://localhost:8088/invocations \
|
||||
-H "Content-Type: text/plain" \
|
||||
-d "Hello, world!"
|
||||
```
|
||||
|
||||
Expected response:
|
||||
|
||||
```
|
||||
Echo: Hello, world!
|
||||
```
|
||||
|
||||
## Running with Docker
|
||||
|
||||
Since this project uses `ProjectReference`, the standard `Dockerfile` cannot resolve dependencies outside this folder. Use `Dockerfile.contributor` which takes a pre-published output.
|
||||
|
||||
### 1. Publish for the container runtime (Linux Alpine)
|
||||
|
||||
```bash
|
||||
dotnet publish -c Debug -f net10.0 -r linux-musl-x64 --self-contained false -o out
|
||||
```
|
||||
|
||||
### 2. Build the Docker image
|
||||
|
||||
```bash
|
||||
docker build -f Dockerfile.contributor -t hosted-invocations-echo-agent .
|
||||
```
|
||||
|
||||
### 3. Run the container
|
||||
|
||||
```bash
|
||||
docker run --rm -p 8088:8088 hosted-invocations-echo-agent
|
||||
```
|
||||
|
||||
### 4. Test it
|
||||
|
||||
```bash
|
||||
curl -X POST http://localhost:8088/invocations \
|
||||
-H "Content-Type: text/plain" \
|
||||
-d "Hello from Docker!"
|
||||
```
|
||||
|
||||
## NuGet package users
|
||||
|
||||
If you are consuming the Agent Framework as a NuGet package (not building from source), use the standard `Dockerfile` instead of `Dockerfile.contributor`. See the commented section in `Hosted-Invocations-EchoAgent.csproj` for the `PackageReference` alternative.
|
||||
+27
@@ -0,0 +1,27 @@
|
||||
# yaml-language-server: $schema=https://raw.githubusercontent.com/microsoft/AgentSchema/refs/heads/main/schemas/v1.0/AgentManifest.yaml
|
||||
name: hosted-invocations-echo-agent
|
||||
displayName: "Hosted Invocations Echo Agent"
|
||||
|
||||
description: >
|
||||
A minimal echo agent hosted as a Foundry Hosted Agent using the Invocations
|
||||
protocol. Reads the request body as plain text, echoes it back in the response.
|
||||
|
||||
metadata:
|
||||
tags:
|
||||
- AI Agent Hosting
|
||||
- Azure AI AgentServer
|
||||
- Invocations Protocol
|
||||
- Agent Framework
|
||||
|
||||
template:
|
||||
name: hosted-invocations-echo-agent
|
||||
kind: hosted
|
||||
protocols:
|
||||
- protocol: invocations
|
||||
version: 1.0.0
|
||||
resources:
|
||||
cpu: "0.25"
|
||||
memory: 0.5Gi
|
||||
parameters:
|
||||
properties: []
|
||||
resources: []
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
# yaml-language-server: $schema=https://raw.githubusercontent.com/microsoft/AgentSchema/refs/heads/main/schemas/v1.0/ContainerAgent.yaml
|
||||
kind: hosted
|
||||
name: hosted-invocations-echo-agent
|
||||
protocols:
|
||||
- protocol: invocations
|
||||
version: 1.0.0
|
||||
resources:
|
||||
cpu: "0.25"
|
||||
memory: 0.5Gi
|
||||
+129
@@ -0,0 +1,129 @@
|
||||
// Copyright (c) Microsoft. All rights reserved.
|
||||
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Text.Json;
|
||||
using Microsoft.Extensions.AI;
|
||||
|
||||
namespace Microsoft.Agents.AI;
|
||||
|
||||
/// <summary>
|
||||
/// An <see cref="AIAgent"/> that invokes a remote agent hosted with the Invocations protocol
|
||||
/// by sending plain-text HTTP POST requests to the <c>/invocations</c> endpoint.
|
||||
/// </summary>
|
||||
public sealed class InvocationsAIAgent : AIAgent
|
||||
{
|
||||
private readonly HttpClient _httpClient;
|
||||
private readonly Uri _invocationsUri;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="InvocationsAIAgent"/> class.
|
||||
/// </summary>
|
||||
/// <param name="agentEndpoint">
|
||||
/// The base URI of the hosted agent (e.g., <c>http://localhost:8089</c>).
|
||||
/// The <c>/invocations</c> path is appended automatically.
|
||||
/// </param>
|
||||
/// <param name="httpClient">Optional <see cref="HttpClient"/> to use. If <see langword="null"/>, a new instance is created.</param>
|
||||
/// <param name="name">Optional name for the agent.</param>
|
||||
/// <param name="description">Optional description for the agent.</param>
|
||||
public InvocationsAIAgent(
|
||||
Uri agentEndpoint,
|
||||
HttpClient? httpClient = null,
|
||||
string? name = null,
|
||||
string? description = null)
|
||||
{
|
||||
ArgumentNullException.ThrowIfNull(agentEndpoint);
|
||||
|
||||
this._httpClient = httpClient ?? new HttpClient();
|
||||
|
||||
// Ensure the base URI ends with a slash so that combining works correctly.
|
||||
var baseUri = agentEndpoint.AbsoluteUri.EndsWith('/')
|
||||
? agentEndpoint
|
||||
: new Uri(agentEndpoint.AbsoluteUri + "/");
|
||||
this._invocationsUri = new Uri(baseUri, "invocations");
|
||||
|
||||
this.Name = name ?? "invocations-agent";
|
||||
this.Description = description ?? "An agent that calls a remote Invocations protocol endpoint.";
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override string? Name { get; }
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override string? Description { get; }
|
||||
|
||||
/// <inheritdoc/>
|
||||
protected override async Task<AgentResponse> RunCoreAsync(
|
||||
IEnumerable<ChatMessage> messages,
|
||||
AgentSession? session = null,
|
||||
AgentRunOptions? options = null,
|
||||
CancellationToken cancellationToken = default)
|
||||
{
|
||||
var inputText = GetLastUserText(messages);
|
||||
var responseText = await SendInvocationAsync(inputText, cancellationToken).ConfigureAwait(false);
|
||||
return new AgentResponse(new ChatMessage(ChatRole.Assistant, responseText));
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
protected override async IAsyncEnumerable<AgentResponseUpdate> RunCoreStreamingAsync(
|
||||
IEnumerable<ChatMessage> messages,
|
||||
AgentSession? session = null,
|
||||
AgentRunOptions? options = null,
|
||||
[EnumeratorCancellation] CancellationToken cancellationToken = default)
|
||||
{
|
||||
// The Invocations protocol returns a complete response (no SSE streaming),
|
||||
// so we yield a single update with the full text.
|
||||
var inputText = GetLastUserText(messages);
|
||||
var responseText = await SendInvocationAsync(inputText, cancellationToken).ConfigureAwait(false);
|
||||
|
||||
yield return new AgentResponseUpdate
|
||||
{
|
||||
Role = ChatRole.Assistant,
|
||||
Contents = [new TextContent(responseText)],
|
||||
};
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
protected override ValueTask<AgentSession> CreateSessionCoreAsync(CancellationToken cancellationToken = default)
|
||||
=> new(new InvocationsAgentSession());
|
||||
|
||||
/// <inheritdoc/>
|
||||
protected override ValueTask<JsonElement> SerializeSessionCoreAsync(
|
||||
AgentSession session,
|
||||
JsonSerializerOptions? jsonSerializerOptions = null,
|
||||
CancellationToken cancellationToken = default)
|
||||
=> new(JsonSerializer.SerializeToElement(new { }, jsonSerializerOptions));
|
||||
|
||||
/// <inheritdoc/>
|
||||
protected override ValueTask<AgentSession> DeserializeSessionCoreAsync(
|
||||
JsonElement serializedState,
|
||||
JsonSerializerOptions? jsonSerializerOptions = null,
|
||||
CancellationToken cancellationToken = default)
|
||||
=> new(new InvocationsAgentSession());
|
||||
|
||||
private async Task<string> SendInvocationAsync(string input, CancellationToken cancellationToken)
|
||||
{
|
||||
using var content = new StringContent(input, System.Text.Encoding.UTF8, "text/plain");
|
||||
using var response = await this._httpClient.PostAsync(this._invocationsUri, content, cancellationToken).ConfigureAwait(false);
|
||||
response.EnsureSuccessStatusCode();
|
||||
return await response.Content.ReadAsStringAsync(cancellationToken).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
private static string GetLastUserText(IEnumerable<ChatMessage> messages)
|
||||
{
|
||||
string? lastUserText = null;
|
||||
foreach (var message in messages)
|
||||
{
|
||||
if (message.Role == ChatRole.User)
|
||||
{
|
||||
lastUserText = message.Text;
|
||||
}
|
||||
}
|
||||
|
||||
return lastUserText ?? string.Empty;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Minimal session for the invocations agent. No state is persisted.
|
||||
/// </summary>
|
||||
private sealed class InvocationsAgentSession : AgentSession;
|
||||
}
|
||||
+61
@@ -0,0 +1,61 @@
|
||||
// Copyright (c) Microsoft. All rights reserved.
|
||||
|
||||
using DotNetEnv;
|
||||
using Microsoft.Agents.AI;
|
||||
|
||||
// Load .env file if present (for local development)
|
||||
Env.TraversePath().Load();
|
||||
|
||||
Uri agentEndpoint = new(Environment.GetEnvironmentVariable("AGENT_ENDPOINT")
|
||||
?? "http://localhost:8088");
|
||||
|
||||
// Create an agent that calls the remote Invocations endpoint.
|
||||
InvocationsAIAgent agent = new(agentEndpoint);
|
||||
|
||||
// REPL
|
||||
Console.ForegroundColor = ConsoleColor.Cyan;
|
||||
Console.WriteLine($"""
|
||||
══════════════════════════════════════════════════════════
|
||||
Simple Invocations Agent Sample
|
||||
Connected to: {agentEndpoint}
|
||||
Type a message or 'quit' to exit
|
||||
══════════════════════════════════════════════════════════
|
||||
""");
|
||||
Console.ResetColor();
|
||||
Console.WriteLine();
|
||||
|
||||
while (true)
|
||||
{
|
||||
Console.ForegroundColor = ConsoleColor.Green;
|
||||
Console.Write("You> ");
|
||||
Console.ResetColor();
|
||||
|
||||
string? input = Console.ReadLine();
|
||||
|
||||
if (string.IsNullOrWhiteSpace(input)) { continue; }
|
||||
if (input.Equals("quit", StringComparison.OrdinalIgnoreCase)) { break; }
|
||||
|
||||
try
|
||||
{
|
||||
Console.ForegroundColor = ConsoleColor.Yellow;
|
||||
Console.Write("Agent> ");
|
||||
Console.ResetColor();
|
||||
|
||||
await foreach (var update in agent.RunStreamingAsync(input))
|
||||
{
|
||||
Console.Write(update);
|
||||
}
|
||||
|
||||
Console.WriteLine();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.ForegroundColor = ConsoleColor.Red;
|
||||
Console.WriteLine($"Error: {ex.Message}");
|
||||
Console.ResetColor();
|
||||
}
|
||||
|
||||
Console.WriteLine();
|
||||
}
|
||||
|
||||
Console.WriteLine("Goodbye!");
|
||||
+22
@@ -0,0 +1,22 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFrameworks>net10.0</TargetFrameworks>
|
||||
<Nullable>enable</Nullable>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<CentralPackageTransitivePinningEnabled>false</CentralPackageTransitivePinningEnabled>
|
||||
<RootNamespace>SimpleInvocationsAgentClient</RootNamespace>
|
||||
<AssemblyName>simple-invocations-agent-client</AssemblyName>
|
||||
<NoWarn>$(NoWarn);NU1903;NU1605</NoWarn>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="DotNetEnv" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\..\..\..\..\src\Microsoft.Agents.AI.Abstractions\Microsoft.Agents.AI.Abstractions.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
Reference in New Issue
Block a user