Python: [BREAKING] Require building functional workflow instances - #7521
Conversation
Use a versioned opaque single-use token on WorkflowRunResult, validate it before request correlation, consume it immediately before replayed user code, and rotate it on each pause. Carry the same explicit authority through streaming and non-streaming FunctionalWorkflowAgent responses. Files changed: functional workflow/runtime result APIs, functional HITL regression tests, core agent guidance, and the functional HITL sample. Next iteration: enforce pending-state overlap and token-authorized abandonment, then document and test checkpoint authorization boundaries. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Reject fresh messages and checkpoint restores while an in-memory continuation is pending. Add token-authorized abandonment on FunctionalWorkflow and FunctionalWorkflowAgent, and clear retained replay state atomically when authority is consumed while preserving the active message for token rotation and checkpoints. Files changed: functional workflow runtime and agent adapter, functional lifecycle regression tests, and core workflow guidance. Next iteration: preserve and document authorized checkpoint continuation boundaries. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Treat checkpoint restore as a host- and storage-authorized path independent of process-local continuation tokens, and issue fresh authority whenever restored execution pauses again. Cover default and per-run storage, deterministic and custom request IDs, token rotation, and checkpoint-plus-response restore. Files changed: functional workflow and checkpoint interface guidance, functional checkpoint lifecycle tests, the functional HITL sample, and core workflow guidance. Next iteration: run the final repository-wide Python validation gates. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Run the complete Python workspace checks, aggregate coverage suite, repository hooks, and core package build from the final combined worktree. Keep the validation iteration code-neutral because all gates pass without corrective changes. Files changed: none; this commit records the final validation gate. Blockers: none. Next iteration: no remaining AFK tasks. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Publish retained continuation state only after checkpoint persistence succeeds, and cover reuse after a transient save failure. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: a8f47743-1cdc-4924-8e1b-667d0d790b78
Python Test Coverage Report •
Python Unit Test Overview
|
||||||||||||||||||||||||||||||
There was a problem hiding this comment.
Pull request overview
This PR updates the Python functional workflow “HITL” (human-in-the-loop) continuation model so that response-only resumes require an explicit, single-use continuation token, aligning behavior across pause, retry, and checkpoint-restore flows.
Changes:
- Introduces and plumbs an opaque
continuation_tokenthrough functional workflow results and the functional workflow agent surface to authorize response-only in-memory resumes. - Tightens functional workflow state transitions by rejecting fresh input / checkpoint-restore while an in-memory continuation is pending, and adds explicit
abandon_continuation(...)support. - Updates docs, samples, and test coverage to reflect the new continuation-token behavior (including streaming final responses carrying the token).
Reviewed changes
Copilot reviewed 6 out of 6 changed files in this pull request and generated no comments.
Show a summary per file
| File | Description |
|---|---|
| python/samples/03-workflows/functional/hitl_review.py | Updates the HITL sample to resume using the returned continuation token. |
| python/packages/core/tests/workflow/test_functional_workflow.py | Adds/updates unit tests covering token-required resume, rejection paths, abandon behavior, and streaming token propagation. |
| python/packages/core/AGENTS.md | Documents the new functional workflow continuation token semantics and constraints. |
| python/packages/core/agent_framework/_workflows/_workflow.py | Extends WorkflowRunResult to carry an optional continuation_token. |
| python/packages/core/agent_framework/_workflows/_functional.py | Implements functional continuation authority (issue/validate/consume), state clearing, abandon support, and agent propagation. |
| python/packages/core/agent_framework/_workflows/_checkpoint.py | Clarifies that checkpoint IDs are locators, not authorization credentials. |
There was a problem hiding this comment.
Automated Code Review
Reviewers: 2 | Confidence: 86%
✓ Correctness
Found one cancellation-path correctness issue that can permanently lock the workflow after consuming its continuation token.
✓ Test Coverage
No actionable test-coverage gaps identified in the provided diff.
Automated review by moonbox3's agents
Add owner recovery for lost tokens, harden malformed token validation, preserve consistent failure surfaces, and keep agent pending state aligned with resumable workflow state. Document process-local single-use continuation semantics and extend regression coverage across direct, streaming, checkpoint, and agent paths. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: a8f47743-1cdc-4924-8e1b-667d0d790b78
Release the workflow run guard when cancellation interrupts resumed user code while keeping the single-use continuation token consumed. Replace sample assertions with explicit runtime checks and add cancellation regression coverage. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: a8f47743-1cdc-4924-8e1b-667d0d790b78
Remove continuation-token handling and align functional workflows with the graph workflow ownership model: one stateful instance per logical caller or session. Add create_instance() for independent callers, document the ownership contract, and cover pending-state isolation between instances. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: a8f47743-1cdc-4924-8e1b-667d0d790b78
|
/review |
There was a problem hiding this comment.
MAF Automated Review — Iteration 1
Result: Findings reported
Scope: full PR (8 commit(s)): fbb01312de87, ada453fec70b, a602ea9310fc, 7671ac79e38a, 90ab95c6ee76, 76d5f3b5e5cc, b128713b4ad4, 9082f1788ad0
Model: gpt-5.6-sol
Overview
The PR clearly establishes per-instance ownership for response-only replay state, adds a focused cloning helper, and tests that one clone cannot consume another clone's in-memory continuation. The constructor's fresh mutable fields and pending-request validation provide strong isolation for that path. However, cloned workflows retain the same checkpoint storage, whose contract permits restoration across instances, so the new guidance overstates isolation for mutually untrusted callers when checkpointing is enabled.
Reviewed the supplied pull-request change set across correctness, security/reliability, architecture, and failure behavior.
1 verified finding remained after source verification (1 medium) across 1 file. Details are attached to the affected lines below.
Affected areas: python/packages/core/agent_framework/_workflows/_functional.py
Do not inherit checkpoint storage when creating an independent workflow instance. Allow hosts to provide an explicitly caller-scoped storage adapter and document that shared checkpoint access requires host authorization and tenant isolation. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: a8f47743-1cdc-4924-8e1b-667d0d790b78
Make @workflow return a stateless FunctionalWorkflowDefinition and require build() before run() or as_agent(). This aligns functional workflows with the graph definition/build lifecycle and prevents module-level decorated definitions from retaining caller state. Move checkpoint configuration to build(), export the definition type, migrate samples, and cover isolated built instances. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: a8f47743-1cdc-4924-8e1b-667d0d790b78
|
/review |
There was a problem hiding this comment.
MAF Automated Review — Iteration 2
Result: No findings
Scope: 2 net-new commit(s): 98f2bb8423e9, 5a7508ea2bed
Model: gpt-5.6-sol
Overview
The PR cleanly separates stateless functional workflow definitions from stateful per-caller runtime instances and moves checkpoint storage selection to build(). Tests establish independent pending continuations, explicit checkpoint storage, concurrency rejection, and runtime reuse after ordinary completion. No residual Critical, High, or Medium defect was established in the incremental review range.
Reviewed the supplied incremental change set across correctness, security/reliability, architecture, and failure behavior.
No publishable findings remained after source verification for this scope.
Motivation & Context
Align functional workflows with the established definition/build lifecycle used by graph workflows.
Description & Review Guide
@workflownow returns a stateless definition, and callers usebuild()to create a stateful workflow instance before running it or adapting it as an agent.build().Related Issue
Internal tracking.
Contribution Checklist
breaking changelabel (or add "[BREAKING]" in the title prefix, before or after a language prefix) — a workflow keeps the label and title prefix in sync automatically.