mirror of
https://github.com/microsoft/agent-framework.git
synced 2026-06-16 21:04:09 +08:00
.NET: Updates to Foundry Agents Package (#2125)
* Remove the conversation creation always * Update unit tests + address IL + refactor * Apply suggestions from code review Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * Internalize unused methods --------- Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
This commit is contained in:
committed by
GitHub
Unverified
parent
ec86cb56b5
commit
9687e6e6a5
+2
-2
@@ -564,7 +564,7 @@ public static class AgentClientExtensions
|
||||
/// </summary>
|
||||
private static AgentVersion CreateAgentVersionWithProtocol(AgentClient agentClient, string agentName, AgentVersionCreationOptions creationOptions, CancellationToken cancellationToken)
|
||||
{
|
||||
using BinaryContent protocolRequest = BinaryContent.Create(ModelReaderWriter.Write(creationOptions));
|
||||
using BinaryContent protocolRequest = BinaryContent.Create(ModelReaderWriter.Write(creationOptions, ModelReaderWriterOptions.Json, AzureAIAgentsContext.Default));
|
||||
ClientResult protocolResponse = agentClient.CreateAgentVersion(agentName, protocolRequest, cancellationToken.ToRequestOptions(false));
|
||||
return ClientResult.FromValue((AgentVersion)protocolResponse, protocolResponse.GetRawResponse()).Value;
|
||||
}
|
||||
@@ -574,7 +574,7 @@ public static class AgentClientExtensions
|
||||
/// </summary>
|
||||
private static async Task<AgentVersion> CreateAgentVersionWithProtocolAsync(AgentClient agentClient, string agentName, AgentVersionCreationOptions creationOptions, CancellationToken cancellationToken)
|
||||
{
|
||||
using BinaryContent protocolRequest = BinaryContent.Create(ModelReaderWriter.Write(creationOptions));
|
||||
using BinaryContent protocolRequest = BinaryContent.Create(ModelReaderWriter.Write(creationOptions, ModelReaderWriterOptions.Json, AzureAIAgentsContext.Default));
|
||||
ClientResult protocolResponse = await agentClient.CreateAgentVersionAsync(agentName, protocolRequest, cancellationToken.ToRequestOptions(false)).ConfigureAwait(false);
|
||||
return ClientResult.FromValue((AgentVersion)protocolResponse, protocolResponse.GetRawResponse()).Value;
|
||||
}
|
||||
@@ -72,42 +72,41 @@ internal sealed class AzureAIAgentChatClient : DelegatingChatClient
|
||||
/// <inheritdoc/>
|
||||
public override async Task<ChatResponse> GetResponseAsync(IEnumerable<ChatMessage> messages, ChatOptions? options = null, CancellationToken cancellationToken = default)
|
||||
{
|
||||
var conversationId = await this.GetOrCreateConversationAsync(options, cancellationToken).ConfigureAwait(false);
|
||||
var conversationChatOptions = this.GetConversationEnabledChatOptions(options, conversationId);
|
||||
var agentOptions = this.GetAgentEnabledChatOptions(options);
|
||||
|
||||
return await base.GetResponseAsync(messages, conversationChatOptions, cancellationToken).ConfigureAwait(false);
|
||||
return await base.GetResponseAsync(messages, agentOptions, cancellationToken).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public async override IAsyncEnumerable<ChatResponseUpdate> GetStreamingResponseAsync(IEnumerable<ChatMessage> messages, ChatOptions? options = null, [EnumeratorCancellation] CancellationToken cancellationToken = default)
|
||||
{
|
||||
var conversation = await this.GetOrCreateConversationAsync(options, cancellationToken).ConfigureAwait(false);
|
||||
var conversationOptions = this.GetConversationEnabledChatOptions(options, conversation);
|
||||
var agentOptions = this.GetAgentEnabledChatOptions(options);
|
||||
|
||||
await foreach (var chunk in base.GetStreamingResponseAsync(messages, conversationOptions, cancellationToken).ConfigureAwait(false))
|
||||
await foreach (var chunk in base.GetStreamingResponseAsync(messages, agentOptions, cancellationToken).ConfigureAwait(false))
|
||||
{
|
||||
yield return chunk;
|
||||
}
|
||||
}
|
||||
|
||||
private async Task<string> GetOrCreateConversationAsync(ChatOptions? options, CancellationToken cancellationToken)
|
||||
=> string.IsNullOrWhiteSpace(options?.ConversationId)
|
||||
? (await this._agentClient.GetConversationClient().CreateConversationAsync(cancellationToken: cancellationToken).ConfigureAwait(false)).Value.Id
|
||||
: options.ConversationId;
|
||||
|
||||
private ChatOptions GetConversationEnabledChatOptions(ChatOptions? chatOptions, string conversationId)
|
||||
private ChatOptions GetAgentEnabledChatOptions(ChatOptions? options)
|
||||
{
|
||||
// Start with a clone of the base chat options defined for the agent, if any.
|
||||
ChatOptions conversationChatOptions = this._chatOptions?.Clone() ?? new();
|
||||
ChatOptions agentEnabledChatOptions = this._chatOptions?.Clone() ?? new();
|
||||
|
||||
// Ignore per-request all options that can't be overridden.
|
||||
conversationChatOptions.Instructions = null;
|
||||
conversationChatOptions.Tools = null;
|
||||
agentEnabledChatOptions.Instructions = null;
|
||||
agentEnabledChatOptions.Tools = null;
|
||||
agentEnabledChatOptions.Temperature = null;
|
||||
agentEnabledChatOptions.TopP = null;
|
||||
agentEnabledChatOptions.PresencePenalty = null;
|
||||
|
||||
// Use the conversation from the request, or the one defined at the client level.
|
||||
agentEnabledChatOptions.ConversationId = options?.ConversationId ?? this._chatOptions?.ConversationId;
|
||||
|
||||
// Preserve the original RawRepresentationFactory
|
||||
var originalFactory = chatOptions?.RawRepresentationFactory;
|
||||
var originalFactory = options?.RawRepresentationFactory;
|
||||
|
||||
conversationChatOptions.RawRepresentationFactory = (client) =>
|
||||
agentEnabledChatOptions.RawRepresentationFactory = (client) =>
|
||||
{
|
||||
if (originalFactory?.Invoke(this) is not ResponseCreationOptions responseCreationOptions)
|
||||
{
|
||||
@@ -115,12 +114,11 @@ internal sealed class AzureAIAgentChatClient : DelegatingChatClient
|
||||
}
|
||||
|
||||
SetAgentReference(responseCreationOptions, this._agentVersion);
|
||||
SetConversationReference(responseCreationOptions, conversationId);
|
||||
|
||||
return responseCreationOptions;
|
||||
};
|
||||
|
||||
return conversationChatOptions;
|
||||
return agentEnabledChatOptions;
|
||||
}
|
||||
|
||||
// Since the SetAdditionalProperty/SetAgentReference/SetConversationReference extensions in Azure.AI.Agents does not yet support the recent updates in OpenAI 2.6.0
|
||||
@@ -139,10 +137,5 @@ internal sealed class AzureAIAgentChatClient : DelegatingChatClient
|
||||
SetAdditionalProperty(responseCreationOptions, "agent", ModelReaderWriter.Write(agentReference, new ModelReaderWriterOptions("W"), AzureAIAgentsContext.Default));
|
||||
responseCreationOptions.Patch.Remove([.. "$."u8, .. Encoding.UTF8.GetBytes("model")]);
|
||||
}
|
||||
|
||||
private static void SetConversationReference(ResponseCreationOptions responseCreationOptions, string conversationId)
|
||||
{
|
||||
SetAdditionalProperty(responseCreationOptions, "conversation", BinaryData.FromString($"\"{conversationId}\""));
|
||||
}
|
||||
#pragma warning restore SCME0001 // Type is for evaluation purposes only and is subject to change or removal in future updates. Suppress this diagnostic to proceed.
|
||||
}
|
||||
|
||||
@@ -110,7 +110,7 @@ public abstract class StatefulExecutor<TState> : Executor
|
||||
{
|
||||
if (!skipCache && !context.ConcurrentRunsEnabled)
|
||||
{
|
||||
TState newState = await invocation(this._stateCache ?? (this._initialStateFactory()),
|
||||
TState newState = await invocation(this._stateCache ?? this._initialStateFactory(),
|
||||
context,
|
||||
cancellationToken).ConfigureAwait(false)
|
||||
?? this._initialStateFactory();
|
||||
|
||||
+26
-155
@@ -992,7 +992,7 @@ public sealed class AgentClientExtensionsTests
|
||||
Assert.Contains("required_tool", requestBody);
|
||||
}
|
||||
|
||||
return new HttpResponseMessage(HttpStatusCode.OK) { Content = new StringContent(AgentVersionTestJsonObject, Encoding.UTF8, "application/json") };
|
||||
return new HttpResponseMessage(HttpStatusCode.OK) { Content = new StringContent(TestDataUtil.GetAgentVersionResponseJson(), Encoding.UTF8, "application/json") };
|
||||
});
|
||||
|
||||
#pragma warning disable CA5399
|
||||
@@ -1034,7 +1034,7 @@ public sealed class AgentClientExtensionsTests
|
||||
Assert.Contains("required_tool", requestBody);
|
||||
}
|
||||
|
||||
return new HttpResponseMessage(HttpStatusCode.OK) { Content = new StringContent(AgentVersionTestJsonObject, Encoding.UTF8, "application/json") };
|
||||
return new HttpResponseMessage(HttpStatusCode.OK) { Content = new StringContent(TestDataUtil.GetAgentVersionResponseJson(), Encoding.UTF8, "application/json") };
|
||||
});
|
||||
|
||||
#pragma warning disable CA5399
|
||||
@@ -1788,7 +1788,7 @@ public sealed class AgentClientExtensionsTests
|
||||
mockAgentClient
|
||||
.Setup(x => x.GetAgent(It.IsAny<string>(), It.IsAny<RequestOptions>()))
|
||||
.Callback<string, RequestOptions>((name, options) => capturedRequestOptions = options)
|
||||
.Returns(ClientResult.FromResponse(new MockPipelineResponse(200, BinaryData.FromString(AgentTestJsonObject))));
|
||||
.Returns(ClientResult.FromResponse(new MockPipelineResponse(200, BinaryData.FromString(TestDataUtil.GetAgentResponseJson()))));
|
||||
|
||||
mockAgentClient.Setup(x => x.GetOpenAIClient(It.IsAny<OpenAIClientOptions?>()))
|
||||
.Returns(new OpenAIClient(new ApiKeyCredential("test-key")));
|
||||
@@ -1813,7 +1813,7 @@ public sealed class AgentClientExtensionsTests
|
||||
mockAgentClient
|
||||
.Setup(x => x.GetAgentAsync(It.IsAny<string>(), It.IsAny<RequestOptions>()))
|
||||
.Callback<string, RequestOptions>((name, options) => capturedRequestOptions = options)
|
||||
.Returns(Task.FromResult(ClientResult.FromResponse(new MockPipelineResponse(200, BinaryData.FromString(AgentTestJsonObject)))));
|
||||
.Returns(Task.FromResult(ClientResult.FromResponse(new MockPipelineResponse(200, BinaryData.FromString(TestDataUtil.GetAgentResponseJson())))));
|
||||
|
||||
mockAgentClient.Setup(x => x.GetOpenAIClient(It.IsAny<OpenAIClientOptions?>()))
|
||||
.Returns(new OpenAIClient(new ApiKeyCredential("test-key")));
|
||||
@@ -1838,7 +1838,7 @@ public sealed class AgentClientExtensionsTests
|
||||
mockAgentClient
|
||||
.Setup(x => x.CreateAgentVersion(It.IsAny<string>(), It.IsAny<BinaryContent>(), It.IsAny<RequestOptions>()))
|
||||
.Callback<string, BinaryContent, RequestOptions>((name, content, options) => capturedRequestOptions = options)
|
||||
.Returns(ClientResult.FromResponse(new MockPipelineResponse(200, BinaryData.FromString(AgentVersionTestJsonObject))));
|
||||
.Returns(ClientResult.FromResponse(new MockPipelineResponse(200, BinaryData.FromString(TestDataUtil.GetAgentVersionResponseJson()))));
|
||||
|
||||
mockAgentClient.Setup(x => x.GetOpenAIClient(It.IsAny<OpenAIClientOptions?>()))
|
||||
.Returns(new OpenAIClient(new ApiKeyCredential("test-key")));
|
||||
@@ -1865,7 +1865,7 @@ public sealed class AgentClientExtensionsTests
|
||||
mockAgentClient
|
||||
.Setup(x => x.CreateAgentVersionAsync(It.IsAny<string>(), It.IsAny<BinaryContent>(), It.IsAny<RequestOptions>()))
|
||||
.Callback<string, BinaryContent, RequestOptions>((name, content, options) => capturedRequestOptions = options)
|
||||
.Returns(Task.FromResult(ClientResult.FromResponse(new MockPipelineResponse(200, BinaryData.FromString(AgentVersionTestJsonObject)))));
|
||||
.Returns(Task.FromResult(ClientResult.FromResponse(new MockPipelineResponse(200, BinaryData.FromString(TestDataUtil.GetAgentVersionResponseJson())))));
|
||||
|
||||
mockAgentClient.Setup(x => x.GetOpenAIClient(It.IsAny<OpenAIClientOptions?>()))
|
||||
.Returns(new OpenAIClient(new ApiKeyCredential("test-key")));
|
||||
@@ -1891,7 +1891,7 @@ public sealed class AgentClientExtensionsTests
|
||||
Assert.Equal("POST", request.Method.Method);
|
||||
Assert.Contains("MEAI", request.Headers.UserAgent.ToString());
|
||||
|
||||
return new HttpResponseMessage(HttpStatusCode.OK) { Content = new StringContent(AgentTestJsonObject, Encoding.UTF8, "application/json") };
|
||||
return new HttpResponseMessage(HttpStatusCode.OK) { Content = new StringContent(TestDataUtil.GetAgentResponseJson(), Encoding.UTF8, "application/json") };
|
||||
});
|
||||
|
||||
#pragma warning disable CA5399
|
||||
@@ -1923,7 +1923,7 @@ public sealed class AgentClientExtensionsTests
|
||||
Assert.Equal("GET", request.Method.Method);
|
||||
Assert.Contains("MEAI", request.Headers.UserAgent.ToString());
|
||||
|
||||
return new HttpResponseMessage(HttpStatusCode.OK) { Content = new StringContent(AgentTestJsonObject, Encoding.UTF8, "application/json") };
|
||||
return new HttpResponseMessage(HttpStatusCode.OK) { Content = new StringContent(TestDataUtil.GetAgentResponseJson(), Encoding.UTF8, "application/json") };
|
||||
});
|
||||
|
||||
#pragma warning disable CA5399
|
||||
@@ -1959,50 +1959,9 @@ public sealed class AgentClientExtensionsTests
|
||||
/// </summary>
|
||||
private AgentRecord CreateTestAgentRecord()
|
||||
{
|
||||
return ModelReaderWriter.Read<AgentRecord>(BinaryData.FromString(AgentTestJsonObject))!;
|
||||
return ModelReaderWriter.Read<AgentRecord>(BinaryData.FromString(TestDataUtil.GetAgentResponseJson()))!;
|
||||
}
|
||||
|
||||
private const string AgentDefinitionPlaceholder = """
|
||||
{
|
||||
"kind": "prompt",
|
||||
"model": "gpt-5-mini",
|
||||
"instructions": "You are a storytelling agent. You craft engaging one-line stories based on user prompts and context.",
|
||||
"tools": []
|
||||
}
|
||||
""";
|
||||
|
||||
private const string AgentTestJsonObject = $$"""
|
||||
{
|
||||
"object": "agent",
|
||||
"id": "agent_abc123",
|
||||
"name": "agent_abc123",
|
||||
"versions": {
|
||||
"latest": {
|
||||
"metadata": {},
|
||||
"object": "agent.version",
|
||||
"id": "agent_abc123:1",
|
||||
"name": "agent_abc123",
|
||||
"version": "1",
|
||||
"description": "",
|
||||
"created_at": 1761771936,
|
||||
"definition": {{AgentDefinitionPlaceholder}}
|
||||
}
|
||||
}
|
||||
}
|
||||
""";
|
||||
|
||||
private const string AgentVersionTestJsonObject = $$"""
|
||||
{
|
||||
"object": "agent.version",
|
||||
"id": "agent_abc123:1",
|
||||
"name": "agent_abc123",
|
||||
"version": "1",
|
||||
"description": "",
|
||||
"created_at": 1761771936,
|
||||
"definition": {{AgentDefinitionPlaceholder}}
|
||||
}
|
||||
""";
|
||||
|
||||
private const string OpenAPISpec = """
|
||||
{
|
||||
"openapi": "3.0.3",
|
||||
@@ -2038,7 +1997,7 @@ public sealed class AgentClientExtensionsTests
|
||||
/// </summary>
|
||||
private AgentVersion CreateTestAgentVersion()
|
||||
{
|
||||
return ModelReaderWriter.Read<AgentVersion>(BinaryData.FromString(AgentVersionTestJsonObject))!;
|
||||
return ModelReaderWriter.Read<AgentVersion>(BinaryData.FromString(TestDataUtil.GetAgentVersionResponseJson()))!;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -2066,88 +2025,50 @@ public sealed class AgentClientExtensionsTests
|
||||
|
||||
public override ClientResult GetAgent(string agentName, RequestOptions options)
|
||||
{
|
||||
return ClientResult.FromValue(ModelReaderWriter.Read<AgentRecord>(BinaryData.FromString(this.ApplyResponseChanges(AgentTestJsonObject)))!, new MockPipelineResponse(200, BinaryData.FromString(this.ApplyResponseChanges(AgentTestJsonObject))));
|
||||
var responseJson = TestDataUtil.GetAgentResponseJson(this._agentName, this._agentDefinition, this._instructions, this._description);
|
||||
return ClientResult.FromValue(ModelReaderWriter.Read<AgentRecord>(BinaryData.FromString(responseJson))!, new MockPipelineResponse(200, BinaryData.FromString(responseJson)));
|
||||
}
|
||||
|
||||
public override ClientResult<AgentRecord> GetAgent(string agentName, CancellationToken cancellationToken = default)
|
||||
{
|
||||
return ClientResult.FromValue(ModelReaderWriter.Read<AgentRecord>(BinaryData.FromString(this.ApplyResponseChanges(AgentTestJsonObject)))!, new MockPipelineResponse(200));
|
||||
var responseJson = TestDataUtil.GetAgentResponseJson(this._agentName, this._agentDefinition, this._instructions, this._description);
|
||||
return ClientResult.FromValue(ModelReaderWriter.Read<AgentRecord>(BinaryData.FromString(responseJson))!, new MockPipelineResponse(200));
|
||||
}
|
||||
|
||||
public override Task<ClientResult> GetAgentAsync(string agentName, RequestOptions options)
|
||||
{
|
||||
return Task.FromResult<ClientResult>(ClientResult.FromValue(ModelReaderWriter.Read<AgentRecord>(BinaryData.FromString(this.ApplyResponseChanges(AgentTestJsonObject)))!, new MockPipelineResponse(200, BinaryData.FromString(this.ApplyResponseChanges(AgentTestJsonObject)))));
|
||||
var responseJson = TestDataUtil.GetAgentResponseJson(this._agentName, this._agentDefinition, this._instructions, this._description);
|
||||
return Task.FromResult<ClientResult>(ClientResult.FromValue(ModelReaderWriter.Read<AgentRecord>(BinaryData.FromString(responseJson))!, new MockPipelineResponse(200, BinaryData.FromString(responseJson))));
|
||||
}
|
||||
|
||||
public override Task<ClientResult<AgentRecord>> GetAgentAsync(string agentName, CancellationToken cancellationToken = default)
|
||||
{
|
||||
return Task.FromResult(ClientResult.FromValue(ModelReaderWriter.Read<AgentRecord>(BinaryData.FromString(this.ApplyResponseChanges(AgentTestJsonObject)))!, new MockPipelineResponse(200)));
|
||||
var responseJson = TestDataUtil.GetAgentResponseJson(this._agentName, this._agentDefinition, this._instructions, this._description);
|
||||
return Task.FromResult(ClientResult.FromValue(ModelReaderWriter.Read<AgentRecord>(BinaryData.FromString(responseJson))!, new MockPipelineResponse(200)));
|
||||
}
|
||||
|
||||
public override ClientResult CreateAgentVersion(string agentName, BinaryContent content, RequestOptions? options = null)
|
||||
{
|
||||
return ClientResult.FromValue(ModelReaderWriter.Read<AgentVersion>(BinaryData.FromString(this.ApplyResponseChanges(AgentVersionTestJsonObject)))!, new MockPipelineResponse(200, BinaryData.FromString(this.ApplyResponseChanges(AgentVersionTestJsonObject))));
|
||||
var responseJson = TestDataUtil.GetAgentVersionResponseJson(this._agentName, this._agentDefinition, this._instructions, this._description);
|
||||
return ClientResult.FromValue(ModelReaderWriter.Read<AgentVersion>(BinaryData.FromString(responseJson))!, new MockPipelineResponse(200, BinaryData.FromString(responseJson)));
|
||||
}
|
||||
|
||||
public override ClientResult<AgentVersion> CreateAgentVersion(string agentName, AgentVersionCreationOptions? options = null, CancellationToken cancellationToken = default)
|
||||
{
|
||||
return ClientResult.FromValue(ModelReaderWriter.Read<AgentVersion>(BinaryData.FromString(this.ApplyResponseChanges(AgentVersionTestJsonObject)))!, new MockPipelineResponse(200));
|
||||
var responseJson = TestDataUtil.GetAgentVersionResponseJson(this._agentName, this._agentDefinition, this._instructions, this._description);
|
||||
return ClientResult.FromValue(ModelReaderWriter.Read<AgentVersion>(BinaryData.FromString(responseJson))!, new MockPipelineResponse(200));
|
||||
}
|
||||
|
||||
public override Task<ClientResult> CreateAgentVersionAsync(string agentName, BinaryContent content, RequestOptions? options = null)
|
||||
{
|
||||
return Task.FromResult<ClientResult>(ClientResult.FromValue(ModelReaderWriter.Read<AgentVersion>(BinaryData.FromString(this.ApplyResponseChanges(AgentVersionTestJsonObject)))!, new MockPipelineResponse(200, BinaryData.FromString(this.ApplyResponseChanges(AgentVersionTestJsonObject)))));
|
||||
var responseJson = TestDataUtil.GetAgentVersionResponseJson(this._agentName, this._agentDefinition, this._instructions, this._description);
|
||||
return Task.FromResult<ClientResult>(ClientResult.FromValue(ModelReaderWriter.Read<AgentVersion>(BinaryData.FromString(responseJson))!, new MockPipelineResponse(200, BinaryData.FromString(responseJson))));
|
||||
}
|
||||
|
||||
public override Task<ClientResult<AgentVersion>> CreateAgentVersionAsync(string agentName, AgentVersionCreationOptions? options = null, CancellationToken cancellationToken = default)
|
||||
{
|
||||
return Task.FromResult(ClientResult.FromValue(ModelReaderWriter.Read<AgentVersion>(BinaryData.FromString(this.ApplyResponseChanges(AgentVersionTestJsonObject)))!, new MockPipelineResponse(200)));
|
||||
}
|
||||
|
||||
private static string TryApplyAgentDefinition(string json, AgentDefinition? definition)
|
||||
{
|
||||
if (definition is not null)
|
||||
{
|
||||
json = json.Replace(AgentDefinitionPlaceholder, ModelReaderWriter.Write(definition).ToString());
|
||||
}
|
||||
return json;
|
||||
}
|
||||
|
||||
private static string TryApplyAgentName(string json, string? agentName)
|
||||
{
|
||||
if (!string.IsNullOrEmpty(agentName))
|
||||
{
|
||||
return json.Replace("\"agent_abc123\"", $"\"{agentName}\"");
|
||||
}
|
||||
return json;
|
||||
}
|
||||
|
||||
private static string TryApplyInstructions(string json, string? instructions)
|
||||
{
|
||||
if (!string.IsNullOrEmpty(instructions))
|
||||
{
|
||||
return json.Replace("You are a storytelling agent. You craft engaging one-line stories based on user prompts and context.", instructions);
|
||||
}
|
||||
return json;
|
||||
}
|
||||
|
||||
private static string TryApplyDescription(string json, string? description)
|
||||
{
|
||||
if (!string.IsNullOrEmpty(description))
|
||||
{
|
||||
return json.Replace("\"description\": \"\"", $"\"description\": \"{description}\"");
|
||||
}
|
||||
return json;
|
||||
}
|
||||
|
||||
private string ApplyResponseChanges(string json)
|
||||
{
|
||||
var modifiedJson = TryApplyAgentName(json, this._agentName);
|
||||
modifiedJson = TryApplyAgentDefinition(modifiedJson, this._agentDefinition);
|
||||
modifiedJson = TryApplyInstructions(modifiedJson, this._instructions);
|
||||
modifiedJson = TryApplyDescription(modifiedJson, this._description);
|
||||
|
||||
return modifiedJson;
|
||||
var responseJson = TestDataUtil.GetAgentVersionResponseJson(this._agentName, this._agentDefinition, this._instructions, this._description);
|
||||
return Task.FromResult(ClientResult.FromValue(ModelReaderWriter.Read<AgentVersion>(BinaryData.FromString(responseJson))!, new MockPipelineResponse(200)));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2247,58 +2168,8 @@ public sealed class AgentClientExtensionsTests
|
||||
}
|
||||
}
|
||||
|
||||
private sealed class FakeAuthenticationTokenProvider : AuthenticationTokenProvider
|
||||
{
|
||||
public override GetTokenOptions? CreateTokenOptions(IReadOnlyDictionary<string, object> properties)
|
||||
{
|
||||
return new GetTokenOptions(new Dictionary<string, object>());
|
||||
}
|
||||
|
||||
public override AuthenticationToken GetToken(GetTokenOptions options, CancellationToken cancellationToken)
|
||||
{
|
||||
return new AuthenticationToken("token-value", "token-type", DateTimeOffset.UtcNow.AddHours(1));
|
||||
}
|
||||
|
||||
public override ValueTask<AuthenticationToken> GetTokenAsync(GetTokenOptions options, CancellationToken cancellationToken)
|
||||
{
|
||||
return new ValueTask<AuthenticationToken>(this.GetToken(options, cancellationToken));
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
private sealed class HttpHandlerAssert : HttpClientHandler
|
||||
{
|
||||
private readonly Func<HttpRequestMessage, HttpResponseMessage>? _assertion;
|
||||
private readonly Func<HttpRequestMessage, Task<HttpResponseMessage>>? _assertionAsync;
|
||||
|
||||
public HttpHandlerAssert(Func<HttpRequestMessage, HttpResponseMessage> assertion)
|
||||
{
|
||||
this._assertion = assertion;
|
||||
}
|
||||
public HttpHandlerAssert(Func<HttpRequestMessage, Task<HttpResponseMessage>> assertionAsync)
|
||||
{
|
||||
this._assertionAsync = assertionAsync;
|
||||
}
|
||||
|
||||
protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
|
||||
{
|
||||
if (this._assertionAsync is not null)
|
||||
{
|
||||
return await this._assertionAsync.Invoke(request);
|
||||
}
|
||||
|
||||
return this._assertion!.Invoke(request);
|
||||
}
|
||||
|
||||
#if NET
|
||||
protected override HttpResponseMessage Send(HttpRequestMessage request, CancellationToken cancellationToken)
|
||||
{
|
||||
return this._assertion!(request);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Helper method to access internal ChatOptions property via reflection.
|
||||
/// </summary>
|
||||
@@ -0,0 +1,212 @@
|
||||
// Copyright (c) Microsoft. All rights reserved.
|
||||
|
||||
using System;
|
||||
using System.ClientModel.Primitives;
|
||||
using System.Net;
|
||||
using System.Net.Http;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Azure.AI.Agents;
|
||||
|
||||
namespace Microsoft.Agents.AI.AzureAI.UnitTests;
|
||||
|
||||
public class AzureAIChatClientTests
|
||||
{
|
||||
/// <summary>
|
||||
/// Verify that when the ChatOptions has a "conv_" prefixed conversation ID, the chat client uses conversation in the http requests via the chat client
|
||||
/// </summary>
|
||||
[Fact]
|
||||
public async Task ChatClient_UsesDefaultConversationIdAsync()
|
||||
{
|
||||
// Arrange
|
||||
var requestTriggered = false;
|
||||
using var httpHandler = new HttpHandlerAssert(async (request) =>
|
||||
{
|
||||
if (request.RequestUri!.PathAndQuery.Contains("openai/responses"))
|
||||
{
|
||||
requestTriggered = true;
|
||||
|
||||
// Assert
|
||||
if (request.Content is not null)
|
||||
{
|
||||
var requestBody = await request.Content.ReadAsStringAsync().ConfigureAwait(false);
|
||||
Assert.Contains("conv_12345", requestBody);
|
||||
}
|
||||
|
||||
return new HttpResponseMessage(HttpStatusCode.OK) { Content = new StringContent(TestDataUtil.GetOpenAIDefaultResponseJson(), Encoding.UTF8, "application/json") };
|
||||
}
|
||||
|
||||
return new HttpResponseMessage(HttpStatusCode.OK) { Content = new StringContent(TestDataUtil.GetAgentResponseJson(), Encoding.UTF8, "application/json") };
|
||||
});
|
||||
|
||||
#pragma warning disable CA5399
|
||||
using var httpClient = new HttpClient(httpHandler);
|
||||
#pragma warning restore CA5399
|
||||
|
||||
var client = new AgentClient(new Uri("https://test.openai.azure.com/"), new FakeAuthenticationTokenProvider(), new() { Transport = new HttpClientPipelineTransport(httpClient) });
|
||||
|
||||
var agent = await client.GetAIAgentAsync(
|
||||
new ChatClientAgentOptions
|
||||
{
|
||||
Name = "test-agent",
|
||||
Instructions = "Test instructions",
|
||||
ChatOptions = new() { ConversationId = "conv_12345" }
|
||||
}, openAIClientOptions: new() { Transport = new HttpClientPipelineTransport(httpClient) });
|
||||
|
||||
// Act
|
||||
var thread = agent.GetNewThread();
|
||||
await agent.RunAsync("Hello", thread);
|
||||
|
||||
Assert.True(requestTriggered);
|
||||
var chatClientThread = Assert.IsType<ChatClientAgentThread>(thread);
|
||||
Assert.Equal("conv_12345", chatClientThread.ConversationId);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Verify that when the chat client doesn't have a default "conv_" conversation id, the chat client still uses the conversation ID in HTTP requests.
|
||||
/// </summary>
|
||||
[Fact]
|
||||
public async Task ChatClient_UsesPerRequestConversationId_WhenNoDefaultConversationIdIsProvidedAsync()
|
||||
{
|
||||
// Arrange
|
||||
var requestTriggered = false;
|
||||
using var httpHandler = new HttpHandlerAssert(async (request) =>
|
||||
{
|
||||
if (request.RequestUri!.PathAndQuery.Contains("openai/responses"))
|
||||
{
|
||||
requestTriggered = true;
|
||||
|
||||
// Assert
|
||||
if (request.Content is not null)
|
||||
{
|
||||
var requestBody = await request.Content.ReadAsStringAsync().ConfigureAwait(false);
|
||||
Assert.Contains("conv_12345", requestBody);
|
||||
}
|
||||
|
||||
return new HttpResponseMessage(HttpStatusCode.OK) { Content = new StringContent(TestDataUtil.GetOpenAIDefaultResponseJson(), Encoding.UTF8, "application/json") };
|
||||
}
|
||||
|
||||
return new HttpResponseMessage(HttpStatusCode.OK) { Content = new StringContent(TestDataUtil.GetAgentResponseJson(), Encoding.UTF8, "application/json") };
|
||||
});
|
||||
|
||||
#pragma warning disable CA5399
|
||||
using var httpClient = new HttpClient(httpHandler);
|
||||
#pragma warning restore CA5399
|
||||
|
||||
var client = new AgentClient(new Uri("https://test.openai.azure.com/"), new FakeAuthenticationTokenProvider(), new() { Transport = new HttpClientPipelineTransport(httpClient) });
|
||||
|
||||
var agent = await client.GetAIAgentAsync(
|
||||
new ChatClientAgentOptions
|
||||
{
|
||||
Name = "test-agent",
|
||||
Instructions = "Test instructions",
|
||||
}, openAIClientOptions: new() { Transport = new HttpClientPipelineTransport(httpClient) });
|
||||
|
||||
// Act
|
||||
var thread = agent.GetNewThread();
|
||||
await agent.RunAsync("Hello", thread, options: new ChatClientAgentRunOptions() { ChatOptions = new() { ConversationId = "conv_12345" } });
|
||||
|
||||
Assert.True(requestTriggered);
|
||||
var chatClientThread = Assert.IsType<ChatClientAgentThread>(thread);
|
||||
Assert.Equal("conv_12345", chatClientThread.ConversationId);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Verify that even when the chat client has a default conversation id, the chat client will prioritize the per-request conversation id provided in HTTP requests.
|
||||
/// </summary>
|
||||
[Fact]
|
||||
public async Task ChatClient_UsesPerRequestConversationId_EvenWhenDefaultConversationIdIsProvidedAsync()
|
||||
{
|
||||
// Arrange
|
||||
var requestTriggered = false;
|
||||
using var httpHandler = new HttpHandlerAssert(async (request) =>
|
||||
{
|
||||
if (request.RequestUri!.PathAndQuery.Contains("openai/responses"))
|
||||
{
|
||||
requestTriggered = true;
|
||||
|
||||
// Assert
|
||||
if (request.Content is not null)
|
||||
{
|
||||
var requestBody = await request.Content.ReadAsStringAsync().ConfigureAwait(false);
|
||||
Assert.Contains("conv_12345", requestBody);
|
||||
}
|
||||
|
||||
return new HttpResponseMessage(HttpStatusCode.OK) { Content = new StringContent(TestDataUtil.GetOpenAIDefaultResponseJson(), Encoding.UTF8, "application/json") };
|
||||
}
|
||||
|
||||
return new HttpResponseMessage(HttpStatusCode.OK) { Content = new StringContent(TestDataUtil.GetAgentResponseJson(), Encoding.UTF8, "application/json") };
|
||||
});
|
||||
|
||||
#pragma warning disable CA5399
|
||||
using var httpClient = new HttpClient(httpHandler);
|
||||
#pragma warning restore CA5399
|
||||
|
||||
var client = new AgentClient(new Uri("https://test.openai.azure.com/"), new FakeAuthenticationTokenProvider(), new() { Transport = new HttpClientPipelineTransport(httpClient) });
|
||||
|
||||
var agent = await client.GetAIAgentAsync(
|
||||
new ChatClientAgentOptions
|
||||
{
|
||||
Name = "test-agent",
|
||||
Instructions = "Test instructions",
|
||||
ChatOptions = new() { ConversationId = "conv_should_not_use_default" }
|
||||
}, openAIClientOptions: new() { Transport = new HttpClientPipelineTransport(httpClient) });
|
||||
|
||||
// Act
|
||||
var thread = agent.GetNewThread();
|
||||
await agent.RunAsync("Hello", thread, options: new ChatClientAgentRunOptions() { ChatOptions = new() { ConversationId = "conv_12345" } });
|
||||
|
||||
Assert.True(requestTriggered);
|
||||
var chatClientThread = Assert.IsType<ChatClientAgentThread>(thread);
|
||||
Assert.Equal("conv_12345", chatClientThread.ConversationId);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Verify that when the chat client is provided without a "conv_" prefixed conversation ID, the chat client uses the previous conversation ID in HTTP requests.
|
||||
/// </summary>
|
||||
[Fact]
|
||||
public async Task ChatClient_UsesPreviousResponseId_WhenConversationIsNotPrefixedAsConvAsync()
|
||||
{
|
||||
// Arrange
|
||||
var requestTriggered = false;
|
||||
using var httpHandler = new HttpHandlerAssert(async (request) =>
|
||||
{
|
||||
if (request.RequestUri!.PathAndQuery.Contains("openai/responses"))
|
||||
{
|
||||
requestTriggered = true;
|
||||
|
||||
// Assert
|
||||
if (request.Content is not null)
|
||||
{
|
||||
var requestBody = await request.Content.ReadAsStringAsync().ConfigureAwait(false);
|
||||
Assert.Contains("resp_0888a", requestBody);
|
||||
}
|
||||
|
||||
return new HttpResponseMessage(HttpStatusCode.OK) { Content = new StringContent(TestDataUtil.GetOpenAIDefaultResponseJson(), Encoding.UTF8, "application/json") };
|
||||
}
|
||||
|
||||
return new HttpResponseMessage(HttpStatusCode.OK) { Content = new StringContent(TestDataUtil.GetAgentResponseJson(), Encoding.UTF8, "application/json") };
|
||||
});
|
||||
|
||||
#pragma warning disable CA5399
|
||||
using var httpClient = new HttpClient(httpHandler);
|
||||
#pragma warning restore CA5399
|
||||
|
||||
var client = new AgentClient(new Uri("https://test.openai.azure.com/"), new FakeAuthenticationTokenProvider(), new() { Transport = new HttpClientPipelineTransport(httpClient) });
|
||||
|
||||
var agent = await client.GetAIAgentAsync(
|
||||
new ChatClientAgentOptions
|
||||
{
|
||||
Name = "test-agent",
|
||||
Instructions = "Test instructions",
|
||||
}, openAIClientOptions: new() { Transport = new HttpClientPipelineTransport(httpClient) });
|
||||
|
||||
// Act
|
||||
var thread = agent.GetNewThread();
|
||||
await agent.RunAsync("Hello", thread, options: new ChatClientAgentRunOptions() { ChatOptions = new() { ConversationId = "resp_0888a" } });
|
||||
|
||||
Assert.True(requestTriggered);
|
||||
var chatClientThread = Assert.IsType<ChatClientAgentThread>(thread);
|
||||
Assert.Equal("resp_0888a46cbf2b1ff3006914596e05d08195a77c3f5187b769a7", chatClientThread.ConversationId);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
// Copyright (c) Microsoft. All rights reserved.
|
||||
|
||||
using System;
|
||||
using System.ClientModel;
|
||||
using System.ClientModel.Primitives;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Microsoft.Agents.AI.AzureAI.UnitTests;
|
||||
|
||||
internal sealed class FakeAuthenticationTokenProvider : AuthenticationTokenProvider
|
||||
{
|
||||
public override GetTokenOptions? CreateTokenOptions(IReadOnlyDictionary<string, object> properties)
|
||||
{
|
||||
return new GetTokenOptions(new Dictionary<string, object>());
|
||||
}
|
||||
|
||||
public override AuthenticationToken GetToken(GetTokenOptions options, CancellationToken cancellationToken)
|
||||
{
|
||||
return new AuthenticationToken("token-value", "token-type", DateTimeOffset.UtcNow.AddHours(1));
|
||||
}
|
||||
|
||||
public override ValueTask<AuthenticationToken> GetTokenAsync(GetTokenOptions options, CancellationToken cancellationToken)
|
||||
{
|
||||
return new ValueTask<AuthenticationToken>(this.GetToken(options, cancellationToken));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
// Copyright (c) Microsoft. All rights reserved.
|
||||
|
||||
using System;
|
||||
using System.Net.Http;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Microsoft.Agents.AI.AzureAI.UnitTests;
|
||||
|
||||
internal sealed class HttpHandlerAssert : HttpClientHandler
|
||||
{
|
||||
private readonly Func<HttpRequestMessage, HttpResponseMessage>? _assertion;
|
||||
private readonly Func<HttpRequestMessage, Task<HttpResponseMessage>>? _assertionAsync;
|
||||
|
||||
public HttpHandlerAssert(Func<HttpRequestMessage, HttpResponseMessage> assertion)
|
||||
{
|
||||
this._assertion = assertion;
|
||||
}
|
||||
public HttpHandlerAssert(Func<HttpRequestMessage, Task<HttpResponseMessage>> assertionAsync)
|
||||
{
|
||||
this._assertionAsync = assertionAsync;
|
||||
}
|
||||
|
||||
protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
|
||||
{
|
||||
if (this._assertionAsync is not null)
|
||||
{
|
||||
return await this._assertionAsync.Invoke(request);
|
||||
}
|
||||
|
||||
return this._assertion!.Invoke(request);
|
||||
}
|
||||
|
||||
#if NET
|
||||
protected override HttpResponseMessage Send(HttpRequestMessage request, CancellationToken cancellationToken)
|
||||
{
|
||||
return this._assertion!(request);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
+12
@@ -8,4 +8,16 @@
|
||||
<ProjectReference Include="..\..\src\Microsoft.Agents.AI.AzureAI\Microsoft.Agents.AI.AzureAI.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<None Update="TestData\AgentResponse.json">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Update="TestData\AgentVersionResponse.json">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Update="TestData\OpenAIDefaultResponse.json">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</None>
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
{
|
||||
"object": "agent",
|
||||
"id": "agent_abc123",
|
||||
"name": "agent_abc123",
|
||||
"versions": {
|
||||
"latest": {
|
||||
"metadata": {},
|
||||
"object": "agent.version",
|
||||
"id": "agent_abc123:1",
|
||||
"name": "agent_abc123",
|
||||
"version": "1",
|
||||
"description": "",
|
||||
"created_at": 1761771936,
|
||||
"definition": "agent-definition-placeholder"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"object": "agent.version",
|
||||
"id": "agent_abc123:1",
|
||||
"name": "agent_abc123",
|
||||
"version": "1",
|
||||
"description": "",
|
||||
"created_at": 1761771936,
|
||||
"definition": "agent-definition-placeholder"
|
||||
}
|
||||
+68
@@ -0,0 +1,68 @@
|
||||
{
|
||||
"id": "resp_0888a46cbf2b1ff3006914596e05d08195a77c3f5187b769a7",
|
||||
"object": "response",
|
||||
"created_at": 1762941294,
|
||||
"status": "completed",
|
||||
"background": false,
|
||||
"billing": {
|
||||
"payer": "developer"
|
||||
},
|
||||
"error": null,
|
||||
"incomplete_details": null,
|
||||
"instructions": null,
|
||||
"max_output_tokens": null,
|
||||
"max_tool_calls": null,
|
||||
"model": "gpt-4o-mini-2024-07-18",
|
||||
"output": [
|
||||
{
|
||||
"id": "msg_0888a46cbf2b1ff3006914596f814481958e8cf500a6dabbec",
|
||||
"type": "message",
|
||||
"status": "completed",
|
||||
"content": [
|
||||
{
|
||||
"type": "output_text",
|
||||
"annotations": [],
|
||||
"logprobs": [],
|
||||
"text": "Hello! How can I assist you today?"
|
||||
}
|
||||
],
|
||||
"role": "assistant"
|
||||
}
|
||||
],
|
||||
"parallel_tool_calls": true,
|
||||
"previous_response_id": null,
|
||||
"prompt_cache_key": null,
|
||||
"prompt_cache_retention": null,
|
||||
"reasoning": {
|
||||
"effort": null,
|
||||
"summary": null
|
||||
},
|
||||
"safety_identifier": null,
|
||||
"service_tier": "default",
|
||||
"store": true,
|
||||
"temperature": 1.0,
|
||||
"text": {
|
||||
"format": {
|
||||
"type": "text"
|
||||
},
|
||||
"verbosity": "medium"
|
||||
},
|
||||
"tool_choice": "auto",
|
||||
"tools": [],
|
||||
"top_logprobs": 0,
|
||||
"top_p": 1.0,
|
||||
"truncation": "disabled",
|
||||
"usage": {
|
||||
"input_tokens": 9,
|
||||
"input_tokens_details": {
|
||||
"cached_tokens": 0
|
||||
},
|
||||
"output_tokens": 10,
|
||||
"output_tokens_details": {
|
||||
"reasoning_tokens": 0
|
||||
},
|
||||
"total_tokens": 19
|
||||
},
|
||||
"user": null,
|
||||
"metadata": {}
|
||||
}
|
||||
@@ -0,0 +1,101 @@
|
||||
// Copyright (c) Microsoft. All rights reserved.
|
||||
|
||||
using System.ClientModel.Primitives;
|
||||
using System.IO;
|
||||
using Azure.AI.Agents;
|
||||
|
||||
namespace Microsoft.Agents.AI.AzureAI.UnitTests;
|
||||
|
||||
/// <summary>
|
||||
/// Utility class for loading and processing test data files.
|
||||
/// </summary>
|
||||
internal static class TestDataUtil
|
||||
{
|
||||
private static readonly string s_agentResponseJson = File.ReadAllText("TestData/AgentResponse.json");
|
||||
private static readonly string s_agentVersionResponseJson = File.ReadAllText("TestData/AgentVersionResponse.json");
|
||||
private static readonly string s_openAIDefaultResponseJson = File.ReadAllText("TestData/OpenAIDefaultResponse.json");
|
||||
|
||||
private const string AgentDefinitionPlaceholder = "\"agent-definition-placeholder\"";
|
||||
|
||||
private const string DefaultAgentDefinition = """
|
||||
{
|
||||
"kind": "prompt",
|
||||
"model": "gpt-5-mini",
|
||||
"instructions": "You are a storytelling agent. You craft engaging one-line stories based on user prompts and context.",
|
||||
"tools": []
|
||||
}
|
||||
""";
|
||||
|
||||
/// <summary>
|
||||
/// Gets the agent response JSON with optional placeholder replacements applied.
|
||||
/// </summary>
|
||||
public static string GetAgentResponseJson(string? agentName = null, AgentDefinition? agentDefinition = null, string? instructions = null, string? description = null)
|
||||
{
|
||||
var json = s_agentResponseJson;
|
||||
json = ApplyAgentName(json, agentName);
|
||||
json = ApplyAgentDefinition(json, agentDefinition);
|
||||
json = ApplyInstructions(json, instructions);
|
||||
json = ApplyDescription(json, description);
|
||||
return json;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the agent version response JSON with optional placeholder replacements applied.
|
||||
/// </summary>
|
||||
public static string GetAgentVersionResponseJson(string? agentName = null, AgentDefinition? agentDefinition = null, string? instructions = null, string? description = null)
|
||||
{
|
||||
var json = s_agentVersionResponseJson;
|
||||
json = ApplyAgentName(json, agentName);
|
||||
json = ApplyAgentDefinition(json, agentDefinition);
|
||||
json = ApplyInstructions(json, instructions);
|
||||
json = ApplyDescription(json, description);
|
||||
return json;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the OpenAI default response JSON with optional placeholder replacements applied.
|
||||
/// </summary>
|
||||
public static string GetOpenAIDefaultResponseJson(string? agentName = null, AgentDefinition? agentDefinition = null, string? instructions = null, string? description = null)
|
||||
{
|
||||
var json = s_openAIDefaultResponseJson;
|
||||
json = ApplyAgentName(json, agentName);
|
||||
json = ApplyAgentDefinition(json, agentDefinition);
|
||||
json = ApplyInstructions(json, instructions);
|
||||
json = ApplyDescription(json, description);
|
||||
return json;
|
||||
}
|
||||
|
||||
private static string ApplyAgentName(string json, string? agentName)
|
||||
{
|
||||
if (!string.IsNullOrEmpty(agentName))
|
||||
{
|
||||
return json.Replace("\"agent_abc123\"", $"\"{agentName}\"");
|
||||
}
|
||||
return json;
|
||||
}
|
||||
|
||||
private static string ApplyAgentDefinition(string json, AgentDefinition? definition)
|
||||
{
|
||||
return (definition is not null)
|
||||
? json.Replace(AgentDefinitionPlaceholder, ModelReaderWriter.Write(definition).ToString())
|
||||
: json.Replace(AgentDefinitionPlaceholder, DefaultAgentDefinition);
|
||||
}
|
||||
|
||||
private static string ApplyInstructions(string json, string? instructions)
|
||||
{
|
||||
if (!string.IsNullOrEmpty(instructions))
|
||||
{
|
||||
return json.Replace("You are a storytelling agent. You craft engaging one-line stories based on user prompts and context.", instructions);
|
||||
}
|
||||
return json;
|
||||
}
|
||||
|
||||
private static string ApplyDescription(string json, string? description)
|
||||
{
|
||||
if (!string.IsNullOrEmpty(description))
|
||||
{
|
||||
return json.Replace("\"description\": \"\"", $"\"description\": \"{description}\"");
|
||||
}
|
||||
return json;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user