JKToolKit.CodexSDK.AgentFramework
0.0.168
See the version list below for details.
dotnet add package JKToolKit.CodexSDK.AgentFramework --version 0.0.168
NuGet\Install-Package JKToolKit.CodexSDK.AgentFramework -Version 0.0.168
<PackageReference Include="JKToolKit.CodexSDK.AgentFramework" Version="0.0.168" />
<PackageVersion Include="JKToolKit.CodexSDK.AgentFramework" Version="0.0.168" />
<PackageReference Include="JKToolKit.CodexSDK.AgentFramework" />
paket add JKToolKit.CodexSDK.AgentFramework --version 0.0.168
#r "nuget: JKToolKit.CodexSDK.AgentFramework, 0.0.168"
#:package JKToolKit.CodexSDK.AgentFramework@0.0.168
#addin nuget:?package=JKToolKit.CodexSDK.AgentFramework&version=0.0.168
#tool nuget:?package=JKToolKit.CodexSDK.AgentFramework&version=0.0.168
Microsoft Agent Framework Adapter
JKToolKit.CodexSDK.AgentFramework makes Codex usable from Microsoft Agent Framework and adapts Agent Framework function tools to Codex app-server dynamic tools.
Use it when you want a Codex-backed AIAgent, or when you already have Agent Framework tools represented as Microsoft.Extensions.AI.AIFunction instances and want Codex app-server to call them through its item/tool/call flow.
NuGet package: JKToolKit.CodexSDK.AgentFramework
Microsoft docs: Agent Framework and function tools.
Install
Install the adapter package into the project that owns your Agent Framework tools:
dotnet add package JKToolKit.CodexSDK.AgentFramework
The adapter package depends on JKToolKit.CodexSDK, Microsoft.Agents.AI, Microsoft.Extensions.AI, and Microsoft.Extensions.AI.Abstractions.
Usage
Create a Codex-backed Agent Framework agent:
using System.Text.Json;
using JKToolKit.CodexSDK.AgentFramework.Agents;
using JKToolKit.CodexSDK.Models;
using Microsoft.Agents.AI;
using Microsoft.Extensions.AI;
AIFunction getWeather = AIFunctionFactory.Create(
(Func<string, string>)(location => $"Weather in {location}: cloudy."),
name: "get_weather",
description: "Gets the weather for a location.");
AIAgent agent = new CodexAgentClient()
.AsAIAgent(
model: "gpt-5.5",
instructions: "You are a helpful assistant.",
tools: [getWeather]);
Console.WriteLine(await agent.RunAsync("What is the weather like in Amsterdam?"));
Use sessions for multi-turn conversations:
AgentSession session = await agent.CreateSessionAsync();
Console.WriteLine(await agent.RunAsync("My name is Alice.", session));
Console.WriteLine(await agent.RunAsync("What is my name?", session));
JsonElement serialized = await agent.SerializeSessionAsync(session);
AgentSession resumed = await agent.DeserializeSessionAsync(serialized);
Stream responses:
await foreach (AgentResponseUpdate update in agent.RunStreamingAsync("Order a pizza."))
{
Console.Write(update.Text);
}
Configure Codex-specific run options:
var runOptions = new CodexAgentRunOptions
{
Cwd = Environment.CurrentDirectory,
ApprovalPolicy = CodexApprovalPolicy.Never,
Sandbox = CodexSandboxMode.ReadOnly
};
Console.WriteLine(await agent.RunAsync("Inspect the current project.", options: runOptions));
Use Agent Framework ChatClientAgentRunOptions when you also want Agent Framework chat options, structured output, reasoning options, or function invocation middleware:
using JKToolKit.CodexSDK.AgentFramework.Agents;
using JKToolKit.CodexSDK.Models;
using Microsoft.Agents.AI;
using Microsoft.Extensions.AI;
var runOptions = new ChatClientAgentRunOptions(new ChatOptions
{
ModelId = "gpt-5.5",
ResponseFormat = ChatResponseFormat.ForJsonSchema<PizzaOrder>(),
Reasoning = new ReasoningOptions
{
Effort = ReasoningEffort.High,
Output = ReasoningOutput.Summary
},
Tools = [getWeather]
}).ConfigureCodex(codex =>
{
codex.Cwd = Environment.CurrentDirectory;
codex.ApprovalPolicy = CodexApprovalPolicy.Never;
});
AgentResponse<PizzaOrder> response =
await agent.RunAsync<PizzaOrder>("Return a small pizza order as JSON.", options: runOptions);
Attach Agent Framework function invocation middleware the same way you would for other AIAgent implementations:
AIAgent middlewareAgent = agent
.AsBuilder()
.Use(async (innerAgent, context, next, cancellationToken) =>
{
context.Arguments["requestSource"] = "codex";
return await next(context, cancellationToken);
})
.Build();
Console.WriteLine(await middlewareAgent.RunAsync(
"What is the weather like in Amsterdam?",
options: new ChatClientAgentRunOptions().ConfigureCodex(codex =>
{
codex.Cwd = Environment.CurrentDirectory;
})));
Provide services for AIFunctionFactory functions that take an IServiceProvider parameter:
AIAgent agent = new CodexAgentClient().AsAIAgent(new CodexAIAgentOptions
{
Instructions = "You are a helpful assistant.",
Tools = [AIFunctionFactory.Create(ReadFromServices)],
FunctionInvocationServices = serviceProvider
});
Handle ApprovalRequiredAIFunction calls with a Codex-side approval callback:
using JKToolKit.CodexSDK.AgentFramework.Tools;
AIFunction deleteFile = new ApprovalRequiredAIFunction(
AIFunctionFactory.Create(DeleteFile, name: "delete_file"));
AIAgent agent = new CodexAgentClient().AsAIAgent(new CodexAIAgentOptions
{
Tools = [deleteFile],
ToolApprovalHandler = (request, cancellationToken) =>
{
return ValueTask.FromResult(
request.ToolName == "delete_file"
? AgentFrameworkToolApprovalResponse.Reject("File deletion is disabled.")
: AgentFrameworkToolApprovalResponse.Approve());
}
});
The lower-level adapter remains available when you want to manually wire Codex app-server:
using JKToolKit.CodexSDK;
using JKToolKit.CodexSDK.AgentFramework.Tools;
using JKToolKit.CodexSDK.AppServer;
using JKToolKit.CodexSDK.Models;
using Microsoft.Extensions.AI;
AIFunction getWeather = AIFunctionFactory.Create(
(Func<string, string>)(location => $"Weather in {location}: cloudy."),
name: "get_weather",
description: "Gets the weather for a location.");
var agentFrameworkTools = AgentFrameworkCodexToolAdapter.Create([getWeather]);
await using var sdk = CodexSdk.Create(builder =>
{
builder.ConfigureAppServer(o =>
{
o.ExperimentalApi = true;
o.ApprovalHandler = agentFrameworkTools.ApprovalHandler;
});
});
await using var codex = await sdk.AppServer.StartAsync();
var thread = await codex.StartThreadAsync(new ThreadStartOptions
{
Cwd = Environment.CurrentDirectory,
Sandbox = CodexSandboxMode.ReadOnly,
ApprovalPolicy = CodexApprovalPolicy.Never,
DynamicTools = agentFrameworkTools.DynamicTools
});
await using var turn = await codex.StartTurnAsync(thread.Id, new TurnStartOptions
{
Input = [TurnInputItem.Text("Use the weather tool for Vienna.")]
});
Run the end-to-end pizza demo:
dotnet run --project src/JKToolKit.CodexSDK.Demo -- agent-framework-function-calling --repo "<repo-path>"
The demo inherits the default model from your Codex configuration. To force a model, pass --model <MODEL>, for example:
dotnet run --project src/JKToolKit.CodexSDK.Demo -- agent-framework-function-calling --model gpt-5.5
Notes
CodexAgentClient().AsAIAgent(...)returns a normal Agent FrameworkAIAgent, so Agent Framework middleware, workflows,RunAsync<T>,RunStreamingAsync, andAIAgent.AsAIFunction(...)can be used on top of it.CodexAgentSessionstores the backing Codex thread id and the Agent Framework session state bag. Serialize and deserialize the session through the Agent Framework APIs to resume the same Codex thread later.- Codex dynamic tools are currently behind the app-server experimental API capability. The native
AIAgentsurface enables it automatically when tools are present. - Tool names are the
AIFunction.Namevalues supplied by Agent Framework. - Agent Framework tools must currently be
AIFunctioninstances. Hosted Agent Framework tools such as provider-native code interpreter, file search, or web search are not translated to Codex dynamic tools. - Per-run tools can be used when creating a new Codex thread. Once a
CodexAgentSessionhas a thread id, create a new session to use a different tool set. - Function invocation middleware is supported for default tools and
ChatClientAgentRunOptionstools throughChatClientFactory. When combining it with Codex-specific settings, attach those settings withConfigureCodex(...); Agent Framework's function middleware only accepts no options, baseAgentRunOptions, orChatClientAgentRunOptions. ApprovalRequiredAIFunctionis supported throughtoolApprovalHandler. Codex dynamic tool calls are synchronous, so the adapter does not use Agent FrameworkFunctionApprovalRequestContent/FunctionApprovalResponseContentround trips. Without an approval handler, approval-required functions are rejected before invocation.
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net10.0 is compatible. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
-
net10.0
- JKToolKit.CodexSDK (>= 0.0.168)
- Microsoft.Agents.AI (>= 1.3.0)
- Microsoft.Extensions.AI (>= 10.5.0)
- Microsoft.Extensions.AI.Abstractions (>= 10.5.0)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.