Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/AgentNet.Tests/PollyInProcessTests.fs
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,7 @@ let ``Policy forwards CancellationToken through TypedAgent to ChatAgent``() =
// Arrange: A ChatAgent whose Chat function observes the cancellation token
let mutable tokenWasCancelled = false

let config = { Name = Some "TestAgent"; Instructions = "test"; Tools = [] }
let config = { Name = Some "TestAgent"; Instructions = "test"; Tools = []; ChatOptions = None }

let chatFn msg ct = task {
try
Expand Down
40 changes: 39 additions & 1 deletion src/AgentNet/AgentFramework.fs
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,39 @@ module MAF =
// The explicit annotation ensures correct overload resolution
AIFunctionFactory.Create(method = tool.MethodInfo, target = null, options = options)

/// Wraps an IChatClient to merge default ChatOptions into every call.
/// Defaults are the base; per-call options override where present.
let private withDefaultOptions (defaults: ChatOptions) (inner: IChatClient) =
let mergeOptions (callOptions: ChatOptions) =
let merged = defaults.Clone()
if callOptions <> null then
if callOptions.Temperature.HasValue then merged.Temperature <- callOptions.Temperature
if callOptions.TopP.HasValue then merged.TopP <- callOptions.TopP
if callOptions.TopK.HasValue then merged.TopK <- callOptions.TopK
if callOptions.MaxOutputTokens.HasValue then merged.MaxOutputTokens <- callOptions.MaxOutputTokens
if callOptions.FrequencyPenalty.HasValue then merged.FrequencyPenalty <- callOptions.FrequencyPenalty
if callOptions.PresencePenalty.HasValue then merged.PresencePenalty <- callOptions.PresencePenalty
if callOptions.Seed.HasValue then merged.Seed <- callOptions.Seed
if callOptions.ModelId <> null then merged.ModelId <- callOptions.ModelId
if callOptions.ResponseFormat <> null then merged.ResponseFormat <- callOptions.ResponseFormat
if callOptions.StopSequences <> null && callOptions.StopSequences.Count > 0 then
merged.StopSequences <- ResizeArray(callOptions.StopSequences)
for tool in callOptions.Tools do merged.Tools.Add(tool)
if callOptions.AdditionalProperties <> null then
if merged.AdditionalProperties = null then
merged.AdditionalProperties <- AdditionalPropertiesDictionary()
for kvp in callOptions.AdditionalProperties do
merged.AdditionalProperties.[kvp.Key] <- kvp.Value
merged
{ new IChatClient with
member _.GetResponseAsync(messages, options, ct) =
inner.GetResponseAsync(messages, mergeOptions options, ct)
member _.GetStreamingResponseAsync(messages, options, ct) =
inner.GetStreamingResponseAsync(messages, mergeOptions options, ct)
member _.GetService(serviceType, serviceKey) =
inner.GetService(serviceType, serviceKey)
member _.Dispose() = () }

/// Creates a ChatClientAgent from an AgentNet ChatAgent config
let createAgent (chatClient: IChatClient) (config: ChatAgentConfig) : AIAgent =
// Convert tools to AIFunctions and cast to AITool
Expand All @@ -34,9 +67,14 @@ module MAF =
|> ResizeArray
:> IList<AITool>

let client =
match config.ChatOptions with
| Some opts -> withDefaultOptions opts chatClient
| None -> chatClient

// Create the agent using the constructor with named parameters
ChatClientAgent(
chatClient,
client,
name = (config.Name |> Option.defaultValue "Agent"),
instructions = config.Instructions,
tools = tools) :> AIAgent
Expand Down
8 changes: 7 additions & 1 deletion src/AgentNet/ChatAgent.fs
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,14 @@ namespace AgentNet
open System.Collections.Generic
open System.Threading
open System.Threading.Tasks
open Microsoft.Extensions.AI

/// Configuration for a chat agent
type ChatAgentConfig = {
Name: string option
Instructions: string
Tools: ToolDef list
ChatOptions: ChatOptions option
}

/// Role of a participant in a chat conversation
Expand Down Expand Up @@ -75,7 +77,7 @@ type ChatAgent with

/// Creates an agent config with the given instructions
static member create (instructions: string) : ChatAgentConfig =
{ Name = None; Instructions = instructions; Tools = [] }
{ Name = None; Instructions = instructions; Tools = []; ChatOptions = None }

/// Sets the agent's name
static member withName (name: string) (config: ChatAgentConfig) : ChatAgentConfig =
Expand All @@ -88,3 +90,7 @@ type ChatAgent with
/// Adds a list of tools to the agent
static member withTools (tools: ToolDef list) (config: ChatAgentConfig) : ChatAgentConfig =
{ config with Tools = config.Tools @ tools }

/// Sets ChatOptions (temperature, top-p, model, etc.) for the agent
static member withChatOptions (options: ChatOptions) (config: ChatAgentConfig) : ChatAgentConfig =
{ config with ChatOptions = Some options }