Skip to content

Preserve durable agent state schema 1.2 compatibility - #90

Closed
Tamir Dresher (tamirdresher) wants to merge 1 commit into
microsoft:mainfrom
tamirdresher:tamirdresher-microsoft-durable-state-schema-1-2
Closed

Preserve durable agent state schema 1.2 compatibility#90
Tamir Dresher (tamirdresher) wants to merge 1 commit into
microsoft:mainfrom
tamirdresher:tamirdresher-microsoft-durable-state-schema-1-2

Conversation

@tamirdresher

Copy link
Copy Markdown
Contributor

Summary

Adds the .NET durable agent state schema 1.2 compatibility foundation.

This PR focuses only on the persisted state model and serialization behavior. It does not add the .NET history provider, history ownership, retention, metrics, or samples.

Changes

  1. Adds stable message IDs and migration for older state without IDs.
  2. Preserves MessageId and AdditionalProperties.
  3. Adds strict schema version parsing and compatible version migration.
  4. Preserves future same-major versions and unknown JSON fields.
  5. Adds session, ingestedPositions, truncation, errorResponse, and compaction schema compatibility.
  6. Safely preserves unknown content without activating .NET runtime types.
  7. Adds a Python-shaped compatibility fixture and focused tests.

Relationship to PR #59

This is the .NET schema and serialization foundation corresponding to ADR-0032 and the Python work in #59.

This PR is based on main, not #59, and does not require the Python branch to compile. Both PRs modify schemas/durable-agent-entity-state.json, so whichever lands second will need to reconcile the shared schema artifact.

Validation

  1. Targeted state tests passed.
  2. Full DurableTask unit suite passed with 288 tests.
  3. Release package build passed.
  4. Schema and fixture validation passed.
  5. Format, analyzers, and diff checks passed.

Stack

This is PR 1 of the C# durable history stack.

The following PRs will add delivery and TTL hardening, history ownership and session persistence, retention and metrics, and samples.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

Copilot-Session: 532fe4f5-939b-4962-989d-a1883dccd283
Copilot AI lite review requested due to automatic review settings September 8, 2026 16:35

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot review overview

🟡 Changes recommended

There are approval-blocking issues: required CHANGELOG entry is missing and ChatMessage.AdditionalProperties serialization can throw and break persistence without safe fallback handling.

Once you've addressed the issues Copilot identified, you can request another Copilot review.

Review tier: Lite
Findings: 1 Medium severity · 1 Low severity

New issues introduced by this change (2)
Severity Finding
Medium severity dotnet/​src/​Microsoft.Agents.AI.DurableTask/​State/​DurableAgentStateMessage.cs — DurableAgentStateMessage.FromChatMessage serializes ChatMessage.AdditionalProperties via…
Low severity dotnet/​src/​Microsoft.Agents.AI.DurableTask/​State/​DurableAgentState.cs — This PR modifies code under dotnet/src, but there is no corresponding entry added to…
What changed in this PR

Establishes the .NET durable agent state schema 1.2 compatibility layer, focusing on persisted state model + JSON serialization behaviors needed for cross-runtime (notably Python) interoperability and forward-compatible round-tripping.

Changes:

  • Expands the shared JSON schema and fixtures to cover schema 1.2 additions (message IDs, extension metadata, session, ingested positions, truncation evidence, errorResponse/compaction entries).
  • Introduces strict numeric SemVer parsing/validation and a clone-for-write flow that promotes older compatible 1.x state to 1.2 while preserving future same-major versions.
  • Improves round-tripping behavior for unknown JSON fields and opaque/unknown content (including safe, non-type-activating preservation patterns) with targeted unit tests.
File Description
schemas/​fixtures/​python-durable-agent-state-1.2.json Adds a Python-shaped 1.2 fixture covering IDs, extension metadata, unknown content, and new data fields.
schemas/​durable-agent-entity-state.json Updates the shared schema for 1.2 fields and forward-compatible metadata/unknown-field behavior.
dotnet/​tests/​Microsoft.Agents.AI.DurableTask.UnitTests/​State/​DurableAgentStateTests.cs Adds tests for strict SemVer, clone promotion behavior, and unknown-field round-tripping.
dotnet/​tests/​Microsoft.Agents.AI.DurableTask.UnitTests/​State/​DurableAgentStateResponseTests.cs Updates expectations to preserve opaque/metadata-only messages and tests generated IDs.
dotnet/​tests/​Microsoft.Agents.AI.DurableTask.UnitTests/​State/​DurableAgentStateMessageTests.cs Adds tests for message IDs, additional properties, and deterministic identity synthesis.
dotnet/​tests/​Microsoft.Agents.AI.DurableTask.UnitTests/​State/​DurableAgentStateContentTests.cs Adds tests for usage extensionData projection, safe unknown-content handling, and envelope behavior.
dotnet/​tests/​Microsoft.Agents.AI.DurableTask.UnitTests/​Microsoft.Agents.AI.DurableTask.UnitTests.csproj Links the shared fixture into unit test outputs.
dotnet/​src/​Microsoft.Agents.AI.DurableTask/​State/​README.md Documents 1.2 schema/versioning and unknown-content preservation rules.
dotnet/​src/​Microsoft.Agents.AI.DurableTask/​State/​DurableAgentStateUsage.cs Splits declared extensionData from [JsonExtensionData] and projects numeric counts safely.
dotnet/​src/​Microsoft.Agents.AI.DurableTask/​State/​DurableAgentStateUnknownContent.cs Implements durable unknown-content envelope + safe metadata extraction/omission rules.
dotnet/​src/​Microsoft.Agents.AI.DurableTask/​State/​DurableAgentStateTruncation.cs Adds truncation evidence model for schema 1.2.
dotnet/​src/​Microsoft.Agents.AI.DurableTask/​State/​DurableAgentStateSchemaVersion.cs Adds strict numeric SemVer core parsing and supported-major validation.
dotnet/​src/​Microsoft.Agents.AI.DurableTask/​State/​DurableAgentStateResponse.cs Preserves opaque/metadata-only messages and generates deterministic message IDs.
dotnet/​src/​Microsoft.Agents.AI.DurableTask/​State/​DurableAgentStateRequest.cs Generates deterministic message IDs for requests and omits null optionals on write.
dotnet/​src/​Microsoft.Agents.AI.DurableTask/​State/​DurableAgentStateMessageIdentity.cs Adds deterministic message ID synthesis for older/migrated state.
dotnet/​src/​Microsoft.Agents.AI.DurableTask/​State/​DurableAgentStateMessage.cs Adds messageId + extensionData storage and converts AdditionalProperties.
dotnet/​src/​Microsoft.Agents.AI.DurableTask/​State/​DurableAgentStateJsonConverter.cs Enforces strict schemaVersion parsing and preserves root extension/unknown properties.
dotnet/​src/​Microsoft.Agents.AI.DurableTask/​State/​DurableAgentStateJsonContext.cs Registers new polymorphic entry types/truncation for source-gen serialization.
dotnet/​src/​Microsoft.Agents.AI.DurableTask/​State/​DurableAgentStateErrorResponse.cs Adds model type for cross-runtime errorResponse entries.
dotnet/​src/​Microsoft.Agents.AI.DurableTask/​State/​DurableAgentStateErrorContent.cs Preserves non-string error details as JSON and round-trips safely.
dotnet/​src/​Microsoft.Agents.AI.DurableTask/​State/​DurableAgentStateEntry.cs Adds entry-level extensionData + unknown properties and new derived entry kinds.
dotnet/​src/​Microsoft.Agents.AI.DurableTask/​State/​DurableAgentStateData.cs Adds session/ingestedPositions/truncation plus extensionData vs unknown separation.
dotnet/​src/​Microsoft.Agents.AI.DurableTask/​State/​DurableAgentStateContent.cs Passes logger through unknown-content conversion and renames extension-data capture.
dotnet/​src/​Microsoft.Agents.AI.DurableTask/​State/​DurableAgentStateCompaction.cs Adds model type for cross-runtime compaction entries.
dotnet/​src/​Microsoft.Agents.AI.DurableTask/​State/​DurableAgentState.cs Defaults new state to schema 1.2, adds clone-for-write promotion + migration hooks.
dotnet/​src/​Microsoft.Agents.AI.DurableTask/​Logs.cs Adds a warning log hook for safe unknown-content serialization fallbacks.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment on lines +73 to +79
Dictionary<string, JsonElement>? additionalProperties = message.AdditionalProperties?
.ToDictionary(
pair => pair.Key,
pair => JsonSerializer.SerializeToElement(
pair.Value,
DurableAgentJsonUtilities.DefaultOptions.GetTypeInfo(typeof(object))));

Comment on lines +14 to +16
internal const string CurrentSchemaVersion = "1.2.0";
private static readonly DurableAgentStateSchemaVersion s_currentSchemaVersion =
DurableAgentStateSchemaVersion.ParseSupported(CurrentSchemaVersion);
@tamirdresher

Copy link
Copy Markdown
Contributor Author

Superseded by #92 and #93. The shared schema contract is now reviewed separately in #92, and the .NET implementation is stacked above it in #93.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants