Description
Hi everyone,
I'm trying to save conversation messages to a database using ChatHistoryProvider. However, InvokeContext.Session.StateBag seems to reset with every new message, creating a fresh session context each time. As a result, I can't track or associate incoming messages with their parent conversation.
Is DevUI designed to spawn a new session per message, or is there a specific way I should be passing/maintaining the conversation ID across requests?
Thanks for any insights!
The conversationId is red in image below because it has been recreated

Code Sample
using Microsoft.Agents.AI;
using Microsoft.Agents.AI.DevUI;
using Microsoft.Agents.AI.Hosting;
using Microsoft.Extensions.AI;
using OpenAI;
using OpenAI.Chat;
using System.ClientModel;
using TestChatHistoryProvider;
var builder = WebApplication.CreateBuilder(args);
// Add services to the container.
builder.Services.AddControllers();
// Learn more about configuring OpenAPI at https://aka.ms/aspnet/openapi
builder.Services.AddOpenApi();
var apiKey = builder.Configuration["ApiKey"]
?? throw new InvalidOperationException("Configuration value 'ApiKey' is missing.");
var openAIClient = new ChatClient(
model: "gpt-5-mini",
credential: new ApiKeyCredential(apiKey),
options: new OpenAIClientOptions()
{
Endpoint = new Uri("myendpoind")
}
).AsIChatClient();
var agentBuilder = builder.AddAIAgent("Alex", (sp, key) =>
{
return openAIClient.AsAIAgent(new ChatClientAgentOptions()
{
Name = "Alex",
ChatOptions = new ChatOptions()
{
Instructions = "You are a helpful assistant.",
},
ChatHistoryProvider = new CosmosChatHistoryProvider()
})
.AsBuilder()
.UseToolApproval(new ToolApprovalAgentOptions
{
AutoApprovalRules = [AgentSkillsProvider.AllToolsAutoApprovalRule],
})
.Build()
;
});
builder.Services.AddOpenAIResponses();
builder.Services.AddOpenAIConversations();
builder.AddDevUI();
var app = builder.Build();
// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
app.MapOpenApi();
}
app.MapOpenAIResponses();
app.MapOpenAIConversations();
app.MapDevUI();
app.UseHttpsRedirection();
app.UseAuthorization();
app.MapControllers();
app.Run();
using Microsoft.Agents.AI;
using Microsoft.Extensions.AI;
namespace TestChatHistoryProvider
{
public class DummyChatHistoryProvider : ChatHistoryProvider, IAsyncDisposable
{
private readonly ProviderSessionState<State> _sessionState;
public DummyChatHistoryProvider()
{
_sessionState = new ProviderSessionState<State>((_ => new State(Guid.NewGuid().ToString("N"))), this.GetType().Name);
}
protected override ValueTask<IEnumerable<ChatMessage>> ProvideChatHistoryAsync(InvokingContext context, CancellationToken cancellationToken = default)
{
//context.Session.StateBag here is recreated with new incoming messages
var state = _sessionState.GetOrInitializeState(context.Session);
return base.ProvideChatHistoryAsync(context, cancellationToken);
}
public ValueTask DisposeAsync()
{
return ValueTask.CompletedTask;
}
public sealed class State
{
public State(string conversationId)
{
this.ConversationId = conversationId ?? throw new ArgumentNullException(nameof(conversationId));
}
public string ConversationId { get; set; }
}
}
}
Error Messages / Stack Traces
Package Versions
<PackageReference Include="Microsoft.Agents.AI" Version="1.15.0" /> <PackageReference Include="Microsoft.Agents.AI.DevUI" Version="1.15.0-preview.260722.1" /> <PackageReference Include="Microsoft.Agents.AI.Hosting.OpenAI" Version="1.15.0-alpha.260722.1" /> <PackageReference Include="Microsoft.Agents.AI.OpenAI" Version="1.15.0" /> <PackageReference Include="Microsoft.AspNetCore.OpenApi" Version="10.0.10" />
.NET Version
.NET 10
Additional Context
No response
Description
Hi everyone,
I'm trying to save conversation messages to a database using ChatHistoryProvider. However, InvokeContext.Session.StateBag seems to reset with every new message, creating a fresh session context each time. As a result, I can't track or associate incoming messages with their parent conversation.
Is DevUI designed to spawn a new session per message, or is there a specific way I should be passing/maintaining the conversation ID across requests?
Thanks for any insights!
The conversationId is red in image below because it has been recreated

Code Sample
Error Messages / Stack Traces
Package Versions
.NET Version
.NET 10
Additional Context
No response