Skip to content

Python: [Breaking] Additional bug fix for declarative workflows#6489

Open
peibekwe wants to merge 9 commits into
mainfrom
peibekwe/declarative-bugfix-python-new
Open

Python: [Breaking] Additional bug fix for declarative workflows#6489
peibekwe wants to merge 9 commits into
mainfrom
peibekwe/declarative-bugfix-python-new

Conversation

@peibekwe

@peibekwe peibekwe commented Jun 12, 2026

Copy link
Copy Markdown
Contributor

Description

Additional bug fix for declarative workflows

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.

@peibekwe peibekwe self-assigned this Jun 12, 2026
Copilot AI review requested due to automatic review settings June 12, 2026 00:10
@github-actions github-actions Bot changed the title Additional bug fix for declarative workflows Python: Additional bug fix for declarative workflows Jun 12, 2026
@github-actions

github-actions Bot commented Jun 12, 2026

Copy link
Copy Markdown
Contributor

Python Test Coverage

Python Test Coverage Report •
FileStmtsMissCoverMissing
packages/declarative/agent_framework_declarative/_workflows
   _executors_mcp.py2502291%100, 329, 332, 338, 341, 350, 360, 364, 379, 382, 395, 398, 409–411, 423–425, 462–463, 521, 549
   _executors_tools.py169199%203
TOTAL39099446488% 

Python Unit Test Overview

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

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

This PR adjusts the declarative workflow approval/yield-resume flow so that resumed tool invocations are bound to the framework-delivered original_request payload (the exact data that was approved), rather than relying on side-channel state stored under per-executor keys.

Changes:

  • Update InvokeFunctionToolExecutor and InvokeMcpToolActionExecutor to resume from original_request and to pass an explicit request_id into ctx.request_info(...) so the framework pending key matches the payload ID.
  • Remove internal “approval state” persistence/cleanup logic and update existing unit tests accordingly.
  • Add a dedicated regression test suite pinning the approval-binding contract (including concurrency/out-of-order resume scenarios) and surface MCP connection_name in approval request UX.

Reviewed changes

Copilot reviewed 7 out of 7 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
python/samples/03-workflows/declarative/invoke_mcp_tool/main.py Displays MCP connection_name in the approval prompt output.
python/packages/declarative/tests/test_invoke_mcp_tool_executor.py Updates MCP approval-flow tests to reflect payload-bound resume behavior.
python/packages/declarative/tests/test_function_tool_executor.py Removes state-key-based approval assertions; aligns tests with payload-bound resume.
python/packages/declarative/tests/test_declarative_approval_binding.py Adds regression tests for approval request/response binding and concurrency behavior.
python/packages/declarative/agent_framework_declarative/_workflows/_executors_tools.py Stops storing approval state; uses explicit request IDs and resumes from original_request.
python/packages/declarative/agent_framework_declarative/_workflows/_executors_mcp.py Stops storing approval state; adds connection_name to request payload and resumes from original_request.
python/packages/declarative/agent_framework_declarative/_workflows/init.py Removes exports related to prior approval-state persistence helpers.

@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: 3 | Confidence: 92%

✓ Correctness

Clean refactoring that removes side-channel approval state (ToolApprovalState, _MCPToolApprovalState) in favor of sourcing invocation parameters directly from the original_request payload delivered by the framework. The design eliminates potential 'approve X then call Y' attacks, supports checkpoint-restore without prior state, handles concurrent pending approvals correctly, and keeps secrets out of checkpoint state. The code is well-tested with comprehensive regression tests. No correctness issues found.

✓ Failure Modes

This PR cleanly removes stateful side-channel approval state (ToolApprovalState, _MCPToolApprovalState) in favor of using the original_request payload as the source of truth for resumed invocations. The request_info API accepts the request_id kwarg correctly, output configuration is safely re-derived from the immutable action definition, and headers are properly re-evaluated on resume. No concrete silent failure paths or operational failure modes were identified in the changed code.

✓ Design Approach

The approval-binding fix correctly pins MCP invocation inputs to the approved request, but the MCP resume path still re-derives result-routing behavior from mutable workflow state. That leaves a silent post-approval drift where an approved tool call can write/send its output to a different conversation or visibility path than the one in effect when approval was requested.


Automated review by peibekwe's agents

@peibekwe peibekwe changed the title Python: Additional bug fix for declarative workflows Python: [Breaking] Additional bug fix for declarative workflows Jun 12, 2026
@peibekwe peibekwe marked this pull request as ready for review June 12, 2026 05:11

@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: 90% | Result: All clear

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


Automated review by peibekwe's agents

Comment on lines +278 to +283
tool_name = original_request.tool_name
server_url = original_request.server_url
server_label = original_request.server_label
arguments = original_request.arguments
connection_name = getattr(original_request, "connection_name", None)
metadata: dict[str, Any] = getattr(original_request, "metadata", None) or {}

@eavanvalkenburg eavanvalkenburg Jun 12, 2026

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Nit: do we need to unpack all of these, most seem to be used only once

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

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants