Skip to content

Python: Register declarative workflow types for checkpoint restore - #10076

Draft
Naveen Chatlapalli (1aifanatic) wants to merge 1 commit into
microsoft:mainfrom
1aifanatic:contrib/python-declarative-checkpoint-types
Draft

Naveen Chatlapalli (1aifanatic) wants to merge 1 commit into
microsoft:mainfrom
1aifanatic:contrib/python-declarative-checkpoint-types

Conversation

@1aifanatic

Copy link
Copy Markdown
Contributor

Motivation & Context

A declarative workflow that uses FileCheckpointStorage saves only its first checkpoint. Every later save logs Checkpoint deserialization blocked for type 'agent_framework_declarative._workflows._declarative_base:ActionComplete' and is skipped. The run continues, so nothing raises. But the checkpoint taken while the workflow waits for input is never stored, so a paused workflow can't be resumed from storage. Restoring the latest checkpoint returns the iteration-0 one, and the response then fails with Response provided for unknown request ID.

This is the same gap #8258 closed for orchestrations. The restricted unpickler trusts agent_framework. and agent_framework_orchestrations., but not this package, so users have had to list framework-internal module paths in allowed_checkpoint_types. Details and a repro are in #10074.

Description & Review Guide

  • What are the major changes?
    • agent_framework_declarative._workflows registers its checkpoint-crossing types with the public register_checkpoint_type on import, the same way agent_framework_orchestrations does. Each type is listed for a stated reason:
      • executor message envelopes: ActionTrigger, ActionComplete, ConditionResult, LoopIterationResult, LoopControl
      • request_info payloads and responses: ExternalInputRequest/Response, AgentExternalInputRequest/Response, ToolApprovalRequest/Response, MCPToolApprovalRequest
      • ExternalLoopState, which is kept in workflow state while an agent's external input loop is paused
    • The core prefix allowlist is unchanged.
    • The WorkflowFactory docstring's checkpointing example called FileCheckpointStorage(path=...), which raises TypeError. It now passes the path positionally.
  • What is the impact of these changes? Declarative workflows checkpoint and resume with FileCheckpointStorage (and other restricted-decoding storages) without a user-maintained allowlist. Existing allowlists keep working.
  • What do you want reviewers to focus on? Whether the registered set is complete. I listed every type the declarative executors pass to send_message, request_info or ctx.state.set. Types that only travel as core Message/Content values are already trusted.

Tests (packages/declarative/tests/test_checkpoint_types.py), all using a FileCheckpointStorage with no allowed_checkpoint_types:

  • A fully populated instance of each of the 13 types round-trips through save and load.
  • End to end: a workflow pauses on RequestExternalInput. The test checks that every checkpoint file on disk decodes, restores the latest checkpoint into a fresh workflow, answers the request, and checks the output ("Hello - approved").

All 14 fail on main and pass here. The full declarative suite passes (1682 tests), and pyright reports no errors. Separately, I ran a Question followed by an InvokeFunctionTool with requireApproval: true, restoring from storage at each pause. Both resumes work and the workflow completes.

Related Issue

Fixes #10074

AI Assistance

  • No material AI assistance was used.
  • This is an AI-assisted contribution. I reviewed, understood, and verified all submitted content and accept responsibility for it.

AI assistance details: Claude Code helped find the failure while running the docstring example, trace it to the unpickler allowlist, write the registration and tests, and draft this description.

Contribution Checklist

  • The code builds clean without any errors or warnings
  • All unit tests pass, and I have added new tests where possible
  • The PR follows the Contribution Guidelines
  • This PR links to an agreed issue with no competing open PR, or the Related Issue section documents a trivial-change or repository-automation exception.
  • This is not a breaking change. If it is a breaking change, add the breaking change label (or add "[BREAKING]" to the title prefix, before or after any language prefix) — a workflow keeps the label and title prefix in sync automatically.

🤖 Generated with Claude Code

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

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.

🟡 Changes recommended

The duplicate test module basename causes pytest collection to fail with an import-file-mismatch error when both suites are collected, so the module needs a unique name.

1 open issue
What changed in this PR

This PR addresses #10074 by registering declarative workflow types for restricted checkpoint decoding, following the orchestration approach in #8258 without widening the core allowlist.

Changes:

  • Registers 13 framework-owned message, request, response, and state types on import.
  • Adds file-backed round-trip tests and a paused-workflow restore/resume test.
  • Corrects the FileCheckpointStorage constructor call in the factory docstring.
File Description
python/​packages/​declarative/​tests/​test_checkpoint_types.py Adds checkpoint round-trip and pause/resume regression tests.
python/​packages/​declarative/​agent_framework_declarative/​_workflows/​_factory.py Fixes the checkpointing documentation example.
python/​packages/​declarative/​agent_framework_declarative/​_workflows/​__init__.py Registers declarative types for restricted checkpoint decoding.

Review effort: Balanced

@@ -0,0 +1,164 @@
# Copyright (c) Microsoft. All rights reserved.

"""Built-in declarative workflow types must survive a checkpoint round trip.

This branch was previously deployed

1 inactive deployment
github-app-auth — f9cbda2d Deployed Nov 4, 2026 by 1aifanatic via team_check #8665
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

python Usage: [Issues, PRs], Target: Python

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Python: [Bug]: Declarative workflows cannot save or resume checkpoints with FileCheckpointStorage

2 participants