Repository navigation
.NET: fall back when a restored agent mode is no longer configured - #9873
NingLin Liu (ninglinLiu) wants to merge 14 commits into
Conversation
GetModeAsync / ProvideAIContextAsync / mode_get now reset to the configured default when session state holds a mode that was removed, matching Python get_agent_mode. Fixes microsoft#9829
There was a problem hiding this comment.
🟡 Changes recommended
Restoring the fallback mode leaves a pending notification marker intact, causing a spurious draft-to-draft mode-change notification on the next invocation; the marker must be cleared and the restore-and-invoke case tested.
1 open issue
What changed in this PR
This PR addresses #9829 by making .NET AgentModeProvider fall back to the configured default when a restored session references a removed mode, matching Python behavior.
Changes:
- Validate restored modes in
GetModeAsync, AI context generation, andmode_get. - Persist the fallback mode in session state.
- Add a regression test for restoring a session after its mode is removed.
| File | Description |
|---|---|
dotnet/tests/Microsoft.Agents.AI.UnitTests/Harness/AgentMode/AgentModeProviderTests.cs |
Tests fallback after restoring an obsolete mode. |
dotnet/src/Microsoft.Agents.AI/Harness/AgentMode/AgentModeProvider.cs |
Centralizes restored-mode validation and persists corrections. |
Review effort: Balanced
| string mode = await v2.GetModeAsync(restored); | ||
|
|
||
| // Assert | ||
| Assert.Equal("draft", mode); | ||
| Assert.Equal("draft", await v2.GetModeAsync(restored)); |
There was a problem hiding this comment.
Why call GetModeAsync twice and check it's output twice?
There was a problem hiding this comment.
Good catch — the second GetModeAsync is intentional: the first call is what performs the fallback and persists draft into session state, and the second call asserts that the rewritten mode sticks (so a later restore/read does not re-trigger fallback or flip back to the removed "review" id). Happy to collapse it to a single read + a StateBag assertion if you prefer that shape.
|
this fixed my repro |

Motivation & Context
AgentModeProvidervalidates the default mode and everySetModeAsync/mode_setcall against the configured modes, but a mode restored from persisted session state is not validated. After an app removes or renames a mode, sessions saved before that change keep the old mode:GetModeAsyncreturns it, instructions mention it, andSetModeAsyncwould reject setting it again.Description & Review Guide
GetModeAsync,ProvideAIContextAsync, andmode_getnow run restored modes throughEnsureConfiguredMode, which falls back to the configured default and persists the correction — matching Pythonget_agent_mode.Related Issue
Fixes #9829
AI Assistance
AI assistance details: Assisted with implementation and the restore regression test; I reviewed the change against Python
get_agent_modeand the issue repro, and accept responsibility for the change.Contribution Checklist
breaking changelabel (or add "[BREAKING]" to the title prefix, before or after any language prefix) — a workflow keeps the label and title prefix in sync automatically.