Skip to content

[BREAKING] Python: Refactor SharedState to State with sync methods and superstep caching#3667

Open
moonbox3 wants to merge 3 commits intomicrosoft:mainfrom
moonbox3:workflows-state-update
Open

[BREAKING] Python: Refactor SharedState to State with sync methods and superstep caching#3667
moonbox3 wants to merge 3 commits intomicrosoft:mainfrom
moonbox3:workflows-state-update

Conversation

@moonbox3
Copy link
Contributor

@moonbox3 moonbox3 commented Feb 4, 2026

Motivation and Context

Refactors the workflow state management system with breaking changes:

  • Rename SharedState -> State class and _shared_state.py -> _state.py
  • Convert all async methods to sync (Python dicts are thread-safe; async was unnecessary overhead)
  • Implement superstep caching: writes go to pending cache, committed at superstep boundary via commit(), which is now consistent with the .NET behavior.
  • Add get(key, default=None) API that returns default instead of raising KeyError
  • Add has(key) method for existence checks
  • Rename WorkflowCheckpoint.shared_stateWorkflowCheckpoint.state
  • Remove State from public exports (internal implementation detail)

Breaking Changes

Before After
SharedState State
ctx.shared_state ctx.state
await ctx.get_shared_state(key) ctx.get_state(key, default=None)
await ctx.set_shared_state(key, value) ctx.set_state(key, value)
checkpoint.shared_state checkpoint.state

Description

Contribution Checklist

  • The code builds clean without any errors or warnings
  • The PR follows the Contribution Guidelines
  • All unit tests pass, and I have added new tests where possible
  • Is this a breaking change? If yes, add "[BREAKING]" prefix to the title of the PR.

@moonbox3 moonbox3 self-assigned this Feb 4, 2026
Copilot AI review requested due to automatic review settings February 4, 2026 06:33
@moonbox3 moonbox3 added python workflows Related to Workflows in agent-framework breaking change Introduces changes that are not backward compatible and may require updates to dependent code. labels Feb 4, 2026
@github-actions github-actions bot changed the title [BREAKING] Python: Refactor SharedState to State with sync methods and superstep caching Python: [BREAKING] Python: Refactor SharedState to State with sync methods and superstep caching Feb 4, 2026
@markwallace-microsoft markwallace-microsoft added the documentation Improvements or additions to documentation label Feb 4, 2026
@markwallace-microsoft
Copy link
Member

markwallace-microsoft commented Feb 4, 2026

Python Test Coverage

Python Test Coverage Report •
FileStmtsMissCoverMissing
packages/core/agent_framework/_workflows
   _agent_executor.py1712386%95, 117, 151, 167–168, 219–220, 222–223, 255–257, 265–267, 277–279, 281, 285, 289, 293–294
   _checkpoint.py121298%182–183
   _checkpoint_summary.py27485%36–39
   _const.py60100% 
   _edge_runner.py1621391%53, 58, 71, 138–139, 143, 150, 206, 211, 355–356, 360, 401
   _executor.py1731094%212, 334, 336, 345, 365, 368, 475, 480, 490, 649
   _runner.py2113284%124–125, 168–171, 175, 216–218, 243–244, 246, 281–283, 307–311, 315, 350, 354, 356, 362, 370–373, 386, 422
   _runner_context.py168696%84, 87, 383, 403, 491, 495
   _state.py430100% 
   _workflow.py2491793%89, 259–261, 263–264, 282, 310, 412, 689, 723, 728, 731, 750–752, 817
   _workflow_context.py1742187%63–64, 72, 76, 90, 166, 191, 309, 428, 471, 473–474, 476–477, 486–488, 490–492, 494
   _workflow_executor.py1734375%96, 445, 456, 468–471, 474–476, 479–480, 482, 485–487, 490–494, 498–499, 508, 513, 547, 573–578, 581, 584, 592, 597, 608, 618, 622, 628, 632, 642, 646
TOTAL16332198187% 

Python Unit Test Overview

Tests Skipped Failures Errors Time
3845 221 💤 0 ❌ 0 🔥 1m 9s ⏱️

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR implements a breaking refactoring of workflow state management, renaming SharedState to State, converting all async methods to sync, and implementing superstep caching semantics to align with .NET behavior.

Changes:

  • Renamed SharedState class to State and file _shared_state.py to _state.py
  • Converted all state methods from async to sync (removing asyncio.Lock)
  • Implemented superstep caching: writes go to pending buffer, committed at boundaries via commit()
  • Added get(key, default=None) API and has(key) method
  • Renamed WorkflowCheckpoint.shared_stateWorkflowCheckpoint.state
  • Updated all references across codebase (workflow context, runner, executors, tests, samples)

Reviewed changes

Copilot reviewed 47 out of 47 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
_state.py New State class with sync methods and superstep caching implementation
_workflow.py Updated to use State with commit() call after kwargs initialization
_runner.py Integrated commit() at superstep boundaries
_workflow_context.py Changed to sync get_state/set_state methods
_checkpoint.py Renamed shared_state field to state
__init__.py Updated exports (but State still exported - should be removed)
Test files Updated all test mocks and assertions to use State
Sample files Updated comments and documentation references
Frontend Updated TypeScript interfaces and references

@moonbox3 moonbox3 changed the title Python: [BREAKING] Python: Refactor SharedState to State with sync methods and superstep caching [BREAKING] Python: Refactor SharedState to State with sync methods and superstep caching Feb 4, 2026
@moonbox3 moonbox3 moved this to In Review in Agent Framework Feb 4, 2026
new_email = Email(email_id=str(uuid4()), email_content=email_text)
await ctx.set_shared_state(f"{EMAIL_STATE_PREFIX}{new_email.email_id}", new_email)
await ctx.set_shared_state(CURRENT_EMAIL_ID_KEY, new_email.email_id)
ctx.set_state(f"{EMAIL_STATE_PREFIX}{new_email.email_id}", new_email)
Copy link
Member

Choose a reason for hiding this comment

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

is this prefix needed to demonstrate the concept?

messages: Messages exchanged between executors
shared_state: Complete shared state including user data and executor states.
Executor states are stored under the reserved key '_executor_state'.
state: Complete workflow state including user data and executor states.
Copy link
Member

Choose a reason for hiding this comment

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

maybe clarify that this is committed state only

The value will be visible to subsequent `get()` calls but won't be
committed to the actual state until `commit()` is called.
"""
self._pending[key] = value
Copy link
Member

Choose a reason for hiding this comment

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

should we deal with two pending updates for the same key? maybe from two different executors?

The complete AgentResponse, or None if waiting for user input.
"""
run_kwargs: dict[str, Any] = await ctx.get_shared_state(WORKFLOW_RUN_KWARGS_KEY)
run_kwargs: dict[str, Any] = ctx.get_state(WORKFLOW_RUN_KWARGS_KEY) or {}
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
run_kwargs: dict[str, Any] = ctx.get_state(WORKFLOW_RUN_KWARGS_KEY) or {}
run_kwargs: dict[str, Any] = ctx.get_state(WORKFLOW_RUN_KWARGS_KEY, {})

@@ -459,41 +459,37 @@ def get_yielded_outputs(self) -> list[Any]:

@deprecated(
Copy link
Contributor

Choose a reason for hiding this comment

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

Should we remove these deprecated methods?

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

Labels

breaking change Introduces changes that are not backward compatible and may require updates to dependent code. documentation Improvements or additions to documentation python workflows Related to Workflows in agent-framework

Projects

Status: In Review

Development

Successfully merging this pull request may close these issues.

Python: Clean up public API surface and kwargs propagation Python: Refactor State class - rename, simplify, and implement superstep caching

5 participants