Skip to content

Add IHostedConversationClient abstraction for hosted conversation lifecycle management#7393

Draft
rogerbarreto wants to merge 3 commits intodotnet:mainfrom
rogerbarreto:proposal-hostedconversationclient
Draft

Add IHostedConversationClient abstraction for hosted conversation lifecycle management#7393
rogerbarreto wants to merge 3 commits intodotnet:mainfrom
rogerbarreto:proposal-hostedconversationclient

Conversation

@rogerbarreto
Copy link
Contributor

@rogerbarreto rogerbarreto commented Mar 13, 2026

Add IHostedConversationClient abstraction for hosted conversation lifecycle management

Summary

Adds a new IHostedConversationClient interface to Microsoft.Extensions.AI for managing server-side hosted conversations (create, get, delete, add messages, list messages). This is complementary to IChatClient — the ConversationId returned by this client feeds into ChatOptions.ConversationId for inference.

Includes the full middleware stack (logging, OpenTelemetry, ConfigureOptions, builder, DI registration), an OpenAI implementation wrapping ConversationClient, and a UseHostedConversations() ChatClient builder extension that enables chatClient.GetService<IHostedConversationClient>().

Components

Microsoft.Extensions.AI.Abstractions (6 files):

  • IHostedConversationClient — 5 CRUD operations (CreateAsync, GetAsync, DeleteAsync, AddMessagesAsync, GetMessagesAsync) + GetService
  • HostedConversation — Response type with ConversationId, CreatedAt, Metadata, RawRepresentation, AdditionalProperties
  • HostedConversationCreationOptions — Options with Metadata, Messages, RawRepresentationFactory, Clone()
  • HostedConversationClientMetadataProviderName, ProviderUri
  • DelegatingHostedConversationClient — Base class for middleware chains
  • HostedConversationClientExtensionsGetService<T> convenience

Microsoft.Extensions.AI (10 files):

  • HostedConversationClientBuilderUse()/Build() pipeline builder
  • LoggingHostedConversationClient — Debug/Trace level logging
  • OpenTelemetryHostedConversationClient — Activity spans + duration histogram
  • ConfigureOptionsHostedConversationClient — Options callback for CreateAsync
  • HostedConversationChatClientDelegatingChatClient bridge enabling chatClient.GetService<IHostedConversationClient>() via UseHostedConversations() builder extension
  • Builder extension methods + DI ServiceCollection registration

Microsoft.Extensions.AI.OpenAI (1 new file + 1 modified):

  • OpenAIHostedConversationClient — Wraps OpenAI.Conversations.ConversationClient with protocol-level JSON APIs
  • AsIHostedConversationClient() extension on ConversationClient

Tests (8 files, 63 tests):

  • Abstraction tests: property roundtrips, clone independence, delegation
  • Middleware tests: builder chain, logging, ConfigureOptions, ChatClient bridge
  • OpenAI tests: GetService, metadata, null guards

Documentation:

  • docs/HostedConversation-ProviderMapping.md — Provider mapping for OpenAI, Azure Foundry, AWS Bedrock, Google Gemini, Anthropic, Ollama with gap analysis

Usage Example

OpenAIClient openAIClient = new(apiKey);

// Build a chat client with conversation support wired in
IChatClient chatClient = openAIClient.GetChatClient("gpt-4o")
    .AsIChatClient()
    .AsBuilder()
    .UseHostedConversations(
        openAIClient.GetConversationClient().AsIHostedConversationClient())
    .UseLogging()
    .Build();

// Discover the conversation client via GetService
var conversationClient = chatClient.GetService<IHostedConversationClient>()!;
var conversation = await conversationClient.CreateAsync();

// Use the conversation for inference
var response = await chatClient.GetResponseAsync(messages, new ChatOptions
{
    ConversationId = conversation.ConversationId
});

Design Decisions

  • Reuses ChatMessage for conversation items — no new message type needed
  • [Experimental(MEAI001)] on all types — same diagnostic ID as other AI experiments
  • RawRepresentation / RawRepresentationFactory escape hatches for 99.9% provider coverage
  • UseHostedConversations() builder extension bridges IChatClientIHostedConversationClient discovery
  • Anthropic/Ollama: implementable via local adapter pattern (no native server-side conversation CRUD)
Microsoft Reviewers: Open in CodeFlow

…ecycle management

Adds a new IHostedConversationClient interface for managing server-side
conversations (create, get, delete, add messages, list messages), with
full middleware stack (logging, OpenTelemetry, ConfigureOptions, builder,
DI registration) and OpenAI implementation wrapping ConversationClient.

Key components:
- IHostedConversationClient interface with 5 CRUD operations + GetService
- HostedConversation, HostedConversationCreationOptions, metadata types
- DelegatingHostedConversationClient for middleware chains
- HostedConversationClientBuilder with Use()/Build() pipeline
- LoggingHostedConversationClient, OpenTelemetryHostedConversationClient,
  ConfigureOptionsHostedConversationClient middleware
- HostedConversationChatClient bridge enabling
  chatClient.GetService<IHostedConversationClient>() via
  UseHostedConversations() builder extension
- OpenAIHostedConversationClient wrapping OpenAI Conversations API
- RawRepresentation/RawRepresentationFactory escape hatches
- Provider mapping report documenting OpenAI, Azure, Bedrock, Gemini,
  Anthropic, and Ollama support with gap analysis
- 63 unit tests across abstractions, middleware, and OpenAI layers
@github-actions github-actions bot added the area-ai Microsoft.Extensions.AI libraries label Mar 13, 2026
- Refactor HostedConversationCreationOptions to HostedConversationClientOptions
  (single shared options type across all operations, matching IHostedFileClient
  pattern with Limit, RawRepresentationFactory, AdditionalProperties)
- Remove Metadata property from HostedConversation and options (use
  AdditionalProperties only, same as IHostedFileClient)
- Remove Messages from creation options (OpenAI-only feature; use
  RawRepresentationFactory or AddMessagesAsync instead)
- Rewrite OpenTelemetryHostedConversationClient to follow files.* pattern
  (conversations.* namespace with disclaimer, no gen_ai.* since no OTel
  semantic convention exists for conversation operations)
- Remove HostedConversationChatClient bridge and UseHostedConversations()
  builder extension per Stephen's feedback
- Update Azure Foundry section in provider mapping doc (v2 uses OpenAI
  directly, not deprecated Threads API per qubitron's feedback)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area-ai Microsoft.Extensions.AI libraries

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants