Links: Architecture: docs/Architecture/Overview.md Modules: CodexChatClient.cs ADRs: 003-microsoft-extensions-ai-integration.md
Enable CodexSharpSDK to participate as a first-class provider in the Microsoft.Extensions.AI ecosystem by implementing IChatClient, unlocking DI registration, middleware pipelines, and provider-agnostic consumer code.
IChatClientimplementation (CodexChatClient) adaptingCodexClient/CodexThread- Input mapping:
ChatMessage[]→ Codex prompt + images - Output mapping:
RunResult→ChatResponsewithUsageDetailsand rich content - Streaming:
ThreadEvent→ChatResponseUpdatemapping - Custom
AIContenttypes for Codex-specific items (commands, file changes, MCP, web search, collab) - DI registration via
AddCodexChatClient()/AddKeyedCodexChatClient() - Codex-specific options via
ChatOptions.AdditionalPropertieswithcodex:*prefix
IEmbeddingGenerator(Codex CLI is not an embedding service)IImageGenerator(Codex CLI is not an image generator)- Consumer-side
AIToolregistration (Codex manages tools internally) Temperature,TopP,TopKmapping (Codex usesModelReasoningEffort)
ChatOptions.ModelIdmaps toThreadOptions.Model.ChatOptions.ConversationIdtriggers thread resume viaResumeThread(id).- Multiple
ChatMessageentries are concatenated into a single prompt while preserving original message chronology (Codex CLI is single-prompt-per-turn). ChatOptions.Toolsis silently ignored; tool results surface as customAIContenttypes.GetService<ChatClientMetadata>()returns provider name"CodexCLI"with default model from options.- Streaming maps assistant item completion, usage, and safe native activity metadata at item-level, not token-level. Completed command, file-change, MCP, web-search, and collaboration items retain their existing typed MEAI content and add fixed
managedcode:activity/managedcode:activity_phasemetadata; intermediate events use metadata only. Typed payload fields remain available for SDK consumer compatibility; Prostir reads only the safe categories and does not display raw native fields.AgentMessageItemupdates are full snapshots in theThreadEventcontract, so the adapter waits for the authoritative completion snapshot and emits it once per item identity; the separate app-serveritem/agentMessage/deltanotification is not part of thiscodex exec --jsoncontract. - Turn failures (
TurnFailedEvent) propagate asInvalidOperationException.
-
Basic chat completion
- Actor: Consumer code using
IChatClient - Trigger:
client.GetResponseAsync([new ChatMessage(ChatRole.User, "prompt")]) - Steps: map messages → create thread → RunAsync → map result
- Result:
ChatResponsewith text, usage, thread ID as ConversationId
- Actor: Consumer code using
-
Streaming
- Trigger:
client.GetStreamingResponseAsync(messages) - Steps: map messages → create thread → RunStreamedAsync → stream events as ChatResponseUpdate
- Result:
IAsyncEnumerable<ChatResponseUpdate>with incremental content
- Trigger:
-
Multi-turn resume
- Trigger:
client.GetResponseAsync(messages, new ChatOptions { ConversationId = "thread-123" }) - Steps: resume thread with ID → RunAsync → map result
- Result: Continuation in existing Codex conversation
- Trigger:
CodexSharpSDK.Extensions.AI/CodexSharpSDK.Extensions.AI.csprojManagedCode.CodexSharpSDK.Extensions.AIpackageIChatClientadapter (CodexChatClient) and DI extensions
CodexSharpSDK.Extensions.AI.Tests/CodexSharpSDK.Extensions.AI.Tests.csproj- mapper/DI test coverage for M.E.AI integration
- Adapter entry points:
CodexChatClient,CodexChatClientOptions,CodexServiceCollectionExtensions - Mapping layer:
ChatMessageMapper,ChatOptionsMapper,ChatResponseMapper,StreamingEventMapper - Rich content models:
CommandExecutionContent,FileChangeContent,McpToolCallContent,WebSearchContent,CollabToolCallContent - Docs: ADR
003and this feature specification
using Microsoft.Extensions.AI;
using ManagedCode.CodexSharpSDK.Extensions.AI;
using ManagedCode.CodexSharpSDK.Models;
IChatClient client = new CodexChatClient(new CodexChatClientOptions
{
DefaultModel = CodexModels.Gpt54,
});using Microsoft.Extensions.AI;
using Microsoft.Extensions.DependencyInjection;
using ManagedCode.CodexSharpSDK.Extensions.AI.Extensions;
using ManagedCode.CodexSharpSDK.Models;
var services = new ServiceCollection();
services.AddCodexChatClient(options =>
{
options.DefaultModel = CodexModels.Gpt54;
});
using var provider = services.BuildServiceProvider();
var chatClient = provider.GetRequiredService<IChatClient>();using Microsoft.Extensions.AI;
using Microsoft.Extensions.DependencyInjection;
using ManagedCode.CodexSharpSDK.Extensions.AI.Extensions;
using ManagedCode.CodexSharpSDK.Models;
var services = new ServiceCollection();
services.AddKeyedCodexChatClient("codex-main", options =>
{
options.DefaultModel = CodexModels.Gpt54;
});
using var provider = services.BuildServiceProvider();
var keyedClient = provider.GetRequiredKeyedService<IChatClient>("codex-main");flowchart LR
Input["IEnumerable<ChatMessage>"]
MsgMapper["ChatMessageMapper"]
OptMapper["ChatOptionsMapper"]
Thread["CodexThread.RunAsync"]
RespMapper["ChatResponseMapper"]
Output["ChatResponse"]
Input --> MsgMapper
MsgMapper --> Thread
OptMapper --> Thread
Thread --> RespMapper
RespMapper --> Output
- build:
dotnet build ManagedCode.CodexSharpSDK.slnx -c Release -warnaserror - test:
dotnet test --solution ManagedCode.CodexSharpSDK.slnx -c Release - format:
dotnet format ManagedCode.CodexSharpSDK.slnx
- Mapper tests:
CodexSharpSDK.Extensions.AI.Tests/ChatMessageMapperTests.cs,ChatOptionsMapperTests.cs,ChatResponseMapperTests.cs,StreamingEventMapperTests.cs - DI tests:
CodexSharpSDK.Extensions.AI.Tests/CodexServiceCollectionExtensionsTests.cs
Native provider failures end the mapped stream only after the upstream CLI event iterator is disposed successfully. A resulting CliExecutionFailureException (an InvalidOperationException subtype) exposes the CLI exit code when present and sets RootProcessExitConfirmed only after root-process exit plus natural redirected-stream EOF; this does not attest to detached descendants or external effects. If iterator cleanup is uncertain, its ordinary cleanup exception takes precedence and no confirmed-failure marker is emitted.
CodexChatClientimplementsIChatClientwith full mapper coverage.- DI extensions register client correctly.
- All mapper and DI tests pass.
- ADR and feature docs created.
- Architecture overview updated.