This sample demonstrates how to make a multi-turn chat session durable using DurableChatSessionClient.
Each call to ChatAsync issues a [WorkflowUpdate] against a long-lived Temporal workflow, so conversation
history survives worker restarts without any extra persistence code. Three demos run in sequence:
multi-turn context carry-over, tool calls, and history retrieval.
DurableChatSessionClient.ChatAsync— each message is a workflow update, not a bare HTTP call- Conversation ID maps 1:1 to a Temporal workflow ID — the same ID routes all turns to the same instance
GetHistoryAsyncretrieves the full message log, including tool call and tool result entriesDurableAIDataConverter.Instancepreserves MEAI's$typediscriminator across workflow history round-tripsUseFunctionInvocation()handles the LLM tool-call loop inside the activity — tool results are sent back to the model before the activity returns
- Context carry-over without resending history. The second question ("What is the population of that city?") is answerable because the workflow holds the prior exchange. The caller sends only the new message — the workflow supplies the full history to the LLM automatically.
DurableAIDataConverteris required. Without it,FunctionCallContent,FunctionResultContent, and otherAIContentsubtypes lose their$typediscriminator when serialized into workflow history, causing deserialization errors on replay.- Tool calls stay inside the activity.
UseFunctionInvocation()completes the full request-call-result loop as one Temporal activity. This is the right model when you want simplicity — see the DurableTools sample if you need per-tool retry policies. - Sessions have a TTL.
opts.SessionTimeToLivecontrols how long the workflow waits for a new turn before shutting down. Set it to match your expected idle window.
- .NET 10 SDK or later
- A local Temporal server:
temporal server start-dev - An OpenAI-compatible API key
dotnet user-secrets set "OPENAI_API_KEY" "sk-..." --project samples/MEAI/DurableChat
dotnet user-secrets set "OPENAI_API_BASE_URL" "https://api.openai.com/v1" --project samples/MEAI/DurableChatdotnet run --project samples/MEAI/DurableChat/DurableChat.csprojWorker started.
════════════════════════════════════════════════════════
Demo 1: Multi-Turn Conversation
════════════════════════════════════════════════════════
Conversation ID: multi-turn-<guid>
User : What is the capital of France?
Agent: The capital of France is Paris.
User : What is the population of that city?
Agent: Paris has a population of approximately 2.1 million ...
════════════════════════════════════════════════════════
(Demo 2 — tool call exchange — output omitted for brevity; shows the model invoking get_weather and returning a forecast.)
════════════════════════════════════════════════════════
Demo 3: History Query
════════════════════════════════════════════════════════
Persisted history:
[User ] Name three planets in our solar system.
[Agent] Mercury, Venus, and Earth are three planets ...
...
Total messages stored: 4
════════════════════════════════════════════════════════