Skip to content

Python: Resolve workflow request info from pending state - #7500

Open
moonbox3 wants to merge 1 commit into
microsoft:mainfrom
moonbox3:harden-workflow-request-info-resolving
Open

Python: Resolve workflow request info from pending state#7500
moonbox3 wants to merge 1 commit into
microsoft:mainfrom
moonbox3:harden-workflow-request-info-resolving

Conversation

@moonbox3

@moonbox3 moonbox3 commented Aug 4, 2026

Copy link
Copy Markdown
Contributor

Motivation & Context

Keep workflow request-info resolution consistent with retained pending state while preserving existing transport and type compatibility.

Description & Review Guide

  • What are the major changes? Add pending-request lookup and agent resolution interfaces, retain legacy parsing through explicit type mappings, migrate first-party callers, and document the state model.
  • What is the impact of these changes? Existing wire and response flows remain compatible, including restored workflows and supported generic annotations.
  • What do you want reviewers to focus on? Correlation semantics and compatibility behavior for legacy and custom type resolution.

Related Issue

None.

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 is linked to an issue and there is no other open PR for this issue (see Related Issue above).
  • 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.

Copilot AI lite review requested due to automatic review settings August 4, 2026 04:35
@moonbox3
moonbox3 temporarily deployed to github-app-auth August 4, 2026 04:35 — with GitHub Actions Inactive
@moonbox3
moonbox3 temporarily deployed to github-app-auth August 4, 2026 04:35 — with GitHub Actions Inactive
@moonbox3
moonbox3 temporarily deployed to github-app-auth August 4, 2026 04:35 — with GitHub Actions Inactive
@agent-framework-automation agent-framework-automation Bot added documentation Usage: [Issues, PRs], Target: documentation in the code base and learn docs python Usage: [Issues, PRs], Target: Python labels Aug 4, 2026
@github-actions

github-actions Bot commented Aug 4, 2026

Copy link
Copy Markdown
Contributor

Python Test Coverage

Python Test Coverage Report •
FileStmtsMissCoverMissing
packages/core/agent_framework/_workflows
   _agent.py3803191%92, 96, 167–168, 394, 407, 474, 485, 487, 543, 609, 679, 757, 787, 815, 863, 872, 933, 940, 946–947, 958, 990, 997, 1018, 1027, 1031, 1033–1035, 1042
   _events.py1581292%91–92, 240, 244, 246, 278, 360, 375, 390, 405, 418, 458
   _typing_utils.py2594483%24, 39–40, 56, 103–104, 130, 132, 307, 331, 376–381, 435, 460, 515, 517–518, 527, 529, 536, 538, 558, 560, 562, 567–574, 577–578, 580–584, 586
   _workflow.py3682493%61, 63, 68, 92, 97, 158, 194, 434–436, 438–439, 463, 497, 625, 664, 955, 976, 1024, 1036, 1042, 1073–1075
TOTAL44637411690% 

Python Unit Test Overview

Tests Skipped Failures Errors Time
9182 34 💤 0 ❌ 0 🔥 2m 22s ⏱️

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.

Pull request overview

Introduces an authoritative, pending-state-based resolver for Python workflow request_info handling (including workflow-as-agent HITL), avoiding reliance on copied transport payloads for request data and Python type resolution while keeping the current wire shape compatible during a deprecation window.

Changes:

  • Add Workflow.get_pending_request_info(request_id) and WorkflowAgent.resolve_request_info(content) to resolve pending request-info data from workflow-held state with strict correlation validation.
  • Replace import-based type resolution with a safer compatibility mechanism (serialize_type registry + deserialize_type allowlist/registry/builtins), and deprecate legacy dict parsers with warnings.
  • Update first-party samples/docs and expand unit test coverage for tampering, correlation semantics, checkpoint rehydration, and generic response-type compatibility.

Reviewed changes

Copilot reviewed 15 out of 15 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
python/samples/03-workflows/README.md Updates sample description to reflect authoritative pending request resolution for workflow-as-agent HITL.
python/samples/03-workflows/orchestrations/README.md Updates handoff workflow-as-agent sample description to reflect authoritative HITL request resolution.
python/samples/03-workflows/agents/workflow_as_agent_human_in_the_loop.py Migrates sample to agent.resolve_request_info(...) and uses authoritative request IDs for responses.
python/samples/03-workflows/agents/handoff_workflow_as_agent.py Migrates request extraction to agent.resolve_request_info(...) and adds runtime type validation.
python/packages/orchestrations/tests/test_handoff.py Adds coverage ensuring workflow-as-agent request-info remains usable with generic response type metadata.
python/packages/core/tests/workflow/test_workflow_agent.py Adds extensive resolve_request_info tests (correlation, tampering, replay/stale behavior, data non-trust).
python/packages/core/tests/workflow/test_typing_utils.py Adds tests for safer type serialization/deserialization, allowlists, ambiguity handling, and non-import behavior.
python/packages/core/tests/workflow/test_request_info_event_rehydrate.py Adds tests ensuring legacy reconstruction paths don’t import payload-selected modules and validates restored pending lookup.
python/packages/core/tests/workflow/test_request_info_and_response.py Adds tests for non-consuming pending lookup and consumption semantics after successful responses.
python/packages/core/AGENTS.md Documents the request-info trust boundary and preferred resolution APIs; notes legacy deprecations.
python/packages/core/agent_framework/_workflows/_workflow.py Adds get_pending_request_info public API backed by runner context pending state.
python/packages/core/agent_framework/_workflows/_typing_utils.py Reworks serialize_type/deserialize_type to avoid payload-driven imports and support explicit trusted mappings/registry.
python/packages/core/agent_framework/_workflows/_events.py Deprecates WorkflowEvent.from_dict, adds allowed_types, and routes through safer deserialize_type.
python/packages/core/agent_framework/_workflows/_agent.py Deprecates legacy request-info args parsing and adds resolve_request_info to validate and resolve authoritative pending events.
docs/decisions/0033-authoritative-workflow-request-info-resolution.md Adds ADR documenting the design decision, drivers, and migration plan.

Comment thread python/packages/core/agent_framework/_workflows/_agent.py

@github-actions github-actions Bot 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.

Automated Code Review

Reviewers: 5 | Confidence: 49%

✗ Correctness

Found one backward-compatibility bug: legacy typing-generic wire names are serialized but can no longer be deserialized.

✓ Security Reliability

I could not complete a verifiable review: every read tool call (view, grep, bash) in this session was blocked by the environment, so I was unable to open the changed production files (_typing_utils.py, _events.py, _agent.py, _workflow.py) or the surrounding runner-context/checkpoint code needed to confirm behavior. Reading the diff alone, the change is coherent with its stated rationale: deserialize_type no longer imports payload-selected modules and resolves only against builtins, a process-local weakref registry, and exact per-call allowed_types; Workflow.get_pending_request_info provides a non-consuming authoritative lookup; and WorkflowAgent.resolve_request_info strictly correlates call_id / arguments.request_id / request_event.request_id and compares only safely comparable metadata while ignoring copied request data. The main residual risk I would want a maintainer to consider is the deliberate loss of cross-process type resolution (a serialized name unknown to the current process now raises ValueError instead of importing), which the ADR explicitly acknowledges as a compatibility-window trade-off. I am reporting zero findings because I could not verify any concrete issue against source.

✓ Test Coverage

The generic compatibility test covers only serialization, missing a backward-compatibility regression in deserialization.

✓ Failure Modes

I could not perform this review. All read-only tool calls in this session (view, grep, bash) were rejected by the environment with 'unexpected user permission response', so I was unable to open python/packages/core/agent_framework/_workflows/_typing_utils.py, _agent.py, _workflow.py, _events.py, the checkpoint/serialization code paths, or the test files needed to verify any suspected failure mode. Per the evidence discipline requirements, I am omitting all findings rather than emitting unverified claims. Areas that a reviewer with working file access should verify: (1) deserialize_type no longer imports modules, so any cross-process consumer that previously relied on import-based resolution (e.g. checkpoint restore in a fresh process, distributed/devui hosts) must be confirmed to resolve types through serialize_type registration or an explicit allowed_types mapping, otherwise restore fails closed with 'Unknown serialized type'; (2) the process-global weakref registry in serialize_type and its Lock interacting with async event loops; (3) the warnings.catch_warnings() suppression inside RequestInfoFunctionArgs.from_dict, which mutates global warning filter state and is not thread-safe (note: the test asserting exactly one recorded warning appears to depend on this suppression, so any change there must keep that test passing).

✓ Design Approach

I was unable to perform the required verification pass: every file-read tool call in this session (view, grep, bash) failed with a permission error, so I could not open _typing_utils.py, _workflow.py, _agent.py, the checkpoint serialization paths, or any existing tests in the checkout. Reviewing the diff text alone, the design is coherent and internally consistent: pending workflow state becomes the single authority for request-info data and Python types, Workflow.get_pending_request_info is non-consuming and delegates to the runner context, WorkflowAgent.resolve_request_info validates only safely-comparable correlation and metadata fields while ignoring copied request data, and the legacy from_dict entry points are retained behind DeprecationWarnings with an allowed_types escape hatch so the wire shape is unchanged. The tests in the diff directly assert each of these properties (identity-preserving repeated lookup, consumption only on successful response, tamper rejection per field, no-import type resolution, restored-checkpoint lookup). The one area I would have wanted to check but could not is whether any cross-process checkpoint-restore path depends on deserialize_type resolving a type that was never passed through serialize_type in the loading process, since the registry is process-local; because I could not open the checkpoint code to confirm or refute that, I am omitting it as a finding rather than reporting it unverified. No findings are emitted.

Flagged Issues

  • python/packages/core/agent_framework/_workflows/_typing_utils.py:351 leaves legacy typing aliases such as typing.List unregistered and unresolvable during deserialization.

Automated review by moonbox3's agents

Comment thread python/packages/core/agent_framework/_workflows/_typing_utils.py Outdated
Comment thread python/packages/core/tests/workflow/test_typing_utils.py Outdated
@github-actions

github-actions Bot commented Aug 4, 2026

Copy link
Copy Markdown
Contributor

Flagged issue

python/packages/core/agent_framework/_workflows/_typing_utils.py:351 leaves legacy typing aliases such as typing.List unregistered and unresolvable during deserialization.


Source: automated DevFlow PR review

@moonbox3
moonbox3 temporarily deployed to github-app-auth August 4, 2026 04:44 — with GitHub Actions Inactive
@moonbox3
moonbox3 temporarily deployed to github-app-auth August 4, 2026 05:30 — with GitHub Actions Inactive
@moonbox3

moonbox3 commented Aug 4, 2026

Copy link
Copy Markdown
Contributor Author

Addressed the DevFlow compatibility finding in 55ba857: supported historical typing aliases now use a fixed trusted resolution map, and the tests cover the deserialization round trip.

@moonbox3
moonbox3 force-pushed the harden-workflow-request-info-resolving branch from 55ba857 to c40e830 Compare August 4, 2026 05:55
@moonbox3
moonbox3 temporarily deployed to github-app-auth August 4, 2026 05:55 — with GitHub Actions Inactive
@moonbox3
moonbox3 marked this pull request as ready for review August 4, 2026 06:19
@moonbox3
moonbox3 temporarily deployed to github-app-auth August 4, 2026 06:19 — with GitHub Actions Inactive

@github-actions github-actions Bot 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.

Automated Code Review

Reviewers: 5 | Confidence: 44% | Result: All clear

Reviewed: Correctness, Security Reliability, Test Coverage, Failure Modes, Design Approach


Automated review by moonbox3's agents

Add authoritative pending request lookup and workflow-agent resolution, retain legacy parsing through trusted compatibility mappings, and migrate first-party consumers while preserving the existing wire shape.

Co-authored-by: Copilot <[email protected]>

Copilot-Session: a53fe20b-c3f0-4583-badc-d5deac7c1049
@moonbox3
moonbox3 force-pushed the harden-workflow-request-info-resolving branch from c40e830 to 68ecde7 Compare August 4, 2026 08:20
@moonbox3
moonbox3 temporarily deployed to github-app-auth August 4, 2026 08:20 — with GitHub Actions Inactive
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentation Usage: [Issues, PRs], Target: documentation in the code base and learn docs python Usage: [Issues, PRs], Target: Python

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants