Links: Architecture: docs/Architecture/Overview.md Modules: ClaudeChatClient.cs, ClaudeServiceCollectionExtensions.cs ADRs: 003-microsoft-extensions-ai-integration.md
Enable ManagedCode.ClaudeCodeSharpSDK 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 (ClaudeChatClient) adaptingClaudeClient/ClaudeThread- Input mapping:
ChatMessage[]-> single Claude prompt string - Output mapping:
RunResult->ChatResponsewith assistant text andUsageDetails - Streaming:
ThreadEvent->ChatResponseUpdatemapping - DI registration via
AddClaudeChatClient()/AddKeyedClaudeChatClient() - Claude-specific options via
ChatOptions.AdditionalPropertieswithclaude:*prefix
IEmbeddingGenerator(Claude Code CLI is not an embedding service)IImageGenerator(Claude Code CLI is not an image generator)- Consumer-side
AIToolregistration (Claude manages tools internally) - Image/file prompt attachments in the current print-mode adapter
ChatOptions.ModelIdmaps toThreadOptions.Model.ChatOptions.ConversationIdtriggers thread resume viaResumeThread(id).- Multiple
ChatMessageentries are concatenated into a single prompt while preserving original message chronology (Claude Code CLI is single-prompt-per-turn). DataContentis rejected withNotSupportedExceptionbecause current Claude print-mode support is text-only in this SDK.ChatOptions.Toolsis ignored.GetService<ChatClientMetadata>()currently returns provider name"ClaudeCodeCLI".- Streaming events map assistant-message and usage events, not token-level deltas.
- Turn failures (
TurnFailedEvent) propagate asInvalidOperationException. ChatOptions.AdditionalPropertiescurrently supportsclaude:working_directory,claude:permission_mode,claude:allowed_tools,claude:disallowed_tools,claude:system_prompt,claude:append_system_prompt, andclaude:max_budget_usd.
-
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, and thread ID asConversationId
- Actor: consumer code using
-
Streaming
- Trigger:
client.GetStreamingResponseAsync(messages) - Steps: map messages -> create thread ->
RunStreamedAsync-> stream events asChatResponseUpdate - 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 an existing Claude conversation
- Trigger:
ClaudeCodeSharpSDK.Extensions.AI/ClaudeCodeSharpSDK.Extensions.AI.csprojManagedCode.ClaudeCodeSharpSDK.Extensions.AIpackageIChatClientadapter (ClaudeChatClient) and DI extensions
ClaudeCodeSharpSDK.Tests/MEAI- mapper and DI coverage for the adapter inside the shared TUnit test project
- Adapter entry points:
ClaudeChatClient,ClaudeChatClientOptions,ClaudeServiceCollectionExtensions - Mapping layer:
ChatMessageMapper,ChatOptionsMapper,ChatResponseMapper,StreamingEventMapper - Docs: ADR
003and this feature specification
using Microsoft.Extensions.AI;
using ManagedCode.ClaudeCodeSharpSDK.Extensions.AI;
IChatClient client = new ClaudeChatClient();using Microsoft.Extensions.AI;
using Microsoft.Extensions.DependencyInjection;
using ManagedCode.ClaudeCodeSharpSDK.Extensions.AI.Extensions;
var services = new ServiceCollection();
services.AddClaudeChatClient();
using var provider = services.BuildServiceProvider();
var chatClient = provider.GetRequiredService<IChatClient>();using Microsoft.Extensions.AI;
using Microsoft.Extensions.DependencyInjection;
using ManagedCode.ClaudeCodeSharpSDK.Extensions.AI.Extensions;
var services = new ServiceCollection();
services.AddKeyedClaudeChatClient("claude-main");
using var provider = services.BuildServiceProvider();
var keyedClient = provider.GetRequiredKeyedService<IChatClient>("claude-main");flowchart LR
Input["IEnumerable<ChatMessage>"]
MsgMapper["ChatMessageMapper"]
OptMapper["ChatOptionsMapper"]
Thread["ClaudeThread.RunAsync"]
RespMapper["ChatResponseMapper"]
Output["ChatResponse"]
Input --> MsgMapper
MsgMapper --> Thread
OptMapper --> Thread
Thread --> RespMapper
RespMapper --> Output
- build:
dotnet build ManagedCode.ClaudeCodeSharpSDK.slnx -c Release -warnaserror - test:
dotnet test --solution ManagedCode.ClaudeCodeSharpSDK.slnx -c Release - format:
dotnet format ManagedCode.ClaudeCodeSharpSDK.slnx
- Mapper tests: ClaudeCodeSharpSDK.Tests/MEAI
- DI tests: ClaudeServiceCollectionExtensionsTests.cs
ClaudeChatClientimplementsIChatClientwith mapper coverage for the currently supported text-first adapter surface.- DI extensions register the client correctly.
- All mapper and DI tests pass.
- ADR and feature docs stay aligned with the adapter surface.