Skip to content

Python: validate functional workflow HITL response types - #8309

Open
CoralGarden52 wants to merge 2 commits into
microsoft:mainfrom
CoralGarden52:fix/functional-workflow-response-type-validation
Open

Python: validate functional workflow HITL response types#8309
CoralGarden52 wants to merge 2 commits into
microsoft:mainfrom
CoralGarden52:fix/functional-workflow-response-type-validation

Conversation

@CoralGarden52

@CoralGarden52 CoralGarden52 commented Sep 11, 2026

Copy link
Copy Markdown
Contributor

Motivation & Context

Functional workflows currently return the raw value supplied to run(responses=...) from RunContext.request_info, even when the request declares a different response_type. On clean upstream commit c47da07e22943d238a94f0a094180c1c2b13d2a7, a workflow declaring response_type=int accepted "not-an-int" and produced ['not-an-int:str'] instead of rejecting the response. The graph workflow path already validates and coerces responses, and the original functional workflow review in #4238 identified this mismatch. Issue #8308 tracks the bug.

The existing functional-workflow behavior for an explicit None response is preserved: it logs the established warning and returns None.

Description & Review Guide

  • What are the major changes?
    • Apply the shared workflow response coercion and runtime type validation when a functional workflow replays a response.
    • Convert string responses to Content for response_type=Content, matching the graph workflow path.
    • Preserve the existing warning-and-return behavior for None responses.
    • Add response-only resume regression coverage for incompatible responses, JSON-like values coerced to a declared type, and strings converted to Content.
  • What is the impact of these changes?
    • Invalid non-None HITL responses now fail at the response boundary instead of silently entering workflow code.
    • Compatible values continue through the existing shared coercion rules.
    • Before the fix, the minimal reproduction returned ['not-an-int:str']; after the fix it raises ValueError: Response type mismatch for request ID typed: expected <class 'int'>, got <class 'str'>.
    • Verification evidence: the full core unit suite passed with 5044 passed, 131 skipped, 2 xfailed; the focused functional workflow, graph workflow, and typing utility tests passed; Ruff format/lint passed; Pyright reported 0 errors, 0 warnings for both changed files.
  • What do you want reviewers to focus on?
    • Whether the functional workflow behavior now matches _workflow.py for coercion and runtime type checking.
    • Whether preserving the documented None behavior is the right compatibility boundary.
    • Whether the regression tests cover the public response-only resume path for rejection, coercion, and Content conversion.

Related Issue

Fixes #8308

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 balanced review requested due to automatic review settings September 11, 2026 15:43
@CoralGarden52
CoralGarden52 deployed to github-app-auth September 11, 2026 15:43 — with GitHub Actions Active
@CoralGarden52
CoralGarden52 deployed to github-app-auth September 11, 2026 15:43 — with GitHub Actions Active
@CoralGarden52
CoralGarden52 deployed to github-app-auth September 11, 2026 15:44 — with GitHub Actions Active
@agent-framework-automation agent-framework-automation Bot added the python Usage: [Issues, PRs], Target: Python label Sep 11, 2026
@CoralGarden52
CoralGarden52 deployed to github-app-auth September 11, 2026 15:44 — with GitHub Actions Active

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

Successful coercion and string-to-Content behavior lack functional workflow coverage.

Once you've addressed the issues Copilot identified, you can request another Copilot review.

Pull request overview

Aligns functional HITL response handling with graph workflows.

Changes:

  • Adds response coercion and runtime type validation.
  • Converts string responses to Content while preserving None.
  • Adds an incompatible-response regression test.
File summaries
File Description
_functional.py Validates and coerces replayed responses.
test_functional_workflow.py Tests type-mismatch rejection.
Review details
  • Files reviewed: 2/2 changed files
  • Comments generated: 1
  • Review effort level: Balanced

💡 Add a code-review agent skill for context-aware, tailored reviews. Learn more in the docs.

Comment on lines +250 to +252
if response_type is Content and isinstance(value, str):
value = Content.from_text(text=value)
value = try_coerce_to_type(value, response_type)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Added functional-workflow resume regression tests covering both successful branches: JSON-like dictionary responses are coerced into the declared dataclass type, and string responses are converted to Content. The existing mismatch-rejection and None compatibility tests remain covered, all relevant tests pass, and the changes are included in commit cd515ac59.

@CoralGarden52
CoralGarden52 deployed to github-app-auth September 11, 2026 15:51 — with GitHub Actions Active
@CoralGarden52
CoralGarden52 deployed to github-app-auth September 11, 2026 15:52 — with GitHub Actions Active
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]: Functional workflow accepts HITL responses that violate response_type

2 participants