Reference in New Issue
Block a user
Delete Branch "fix/self-delegation-echo-runtime-builtin-tools"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Why
Task #190 / #193 — durable fix for the self-delegation echo bug surfaced in feedback_a2a_delegate_sync_timeout_and_190_self_echo.
When a workspace
delegate_tasks to its own UUID, the request round-trips through the platform proxy back into the sender. The synchronous handler waits on the run lock the caller holds, the request times out, and the platform writes the failure asactivity_type='a2a_receive'source_id=<our workspace UUID>. The inbox poller picks it up and surfaces the row askind='peer_agent'withpeer_id=<our own workspace UUID>— the agent then sees its own timeout as a NEW peer instructing it. Replying viadelegate_taskto the offered "peer" re-triggers the loop.The same shape affects cross-workspace
ProxyA2Afailures viapushDelegationResultToInbox(RFC #2829 PR-2): the result row lands in the caller's inbox withsource_id=<caller's workspace UUID>and currently surfaces aspeer_agent, not as a structured delegation outcome visible towait_for_message.What
Layer-by-layer guard audit (before this PR)
workspace-server/internal/handlers/delegation.go(Go API gate,Delegatehandler)workspace/a2a_tools_delegation.py::tool_delegate_task/tool_delegate_task_async(MCP path)workspace/builtin_tools/a2a_tools.py::delegate_task(framework-agnostic adapter surface)workspace/builtin_tools/delegation.py::delegate_task_async(LangChain @tool, local fire-and-forget)Inbox-side classification (covers cross-workspace ProxyA2A drop)
InboxMessage.to_dict()now classifies any row withmethod='delegate_result'askind='delegation_result'regardless ofpeer_id. Result:peer_agentinstructions.delegation_resultevents towait_for_message, not as imitation peer messages._is_self_echo_row's existing exception fordelegate_resultrows is preserved (we still WANT the row to reach the inbox; we just want it labelled correctly).Files changed
workspace/builtin_tools/a2a_tools.py— guard added before discovery hop.workspace/builtin_tools/delegation.py— guard added before_execute_delegationbackground task scheduled; rejection logged asoutcome='rejected_self_delegation'.workspace/inbox.py—to_dict()pickskind='delegation_result'formethod='delegate_result'.workspace/tests/test_a2a_tools_module.py::TestSelfDelegationGuard— verifies guard short-circuits BEFORE any HTTP call; real peer passes through.workspace/tests/test_delegation.py::TestSelfDelegationGuard— verifies async-path returns structured rejection without scheduling a background task.workspace/tests/test_inbox.py::test_message_from_activity_delegate_result_distinct_kind— pinskind='delegation_result'formethod='delegate_result'rows.Runtime mirror
molecule-ai-workspace-runtimeis a publish artifact ofworkspace/— once this PR lands and aruntime-v*tag is pushed, the existingpublish-runtimeworkflow rebuilds the mirror and uploads PyPI 0.1.1003 (the next version after the yanked 0.1.1001/1002 stubs from task #194). No direct edit to the mirror repo is needed.Test plan
pytest tests/test_a2a_tools_module.py::TestSelfDelegationGuard— 2/2 passpytest tests/test_delegation.py::TestSelfDelegationGuard— 2/2 passpytest tests/test_inbox.py::test_message_from_activity_delegate_result_distinct_kind— passpytest tests/test_inbox.py tests/test_a2a_tools_module.py tests/test_delegation.py tests/test_a2a_tools_delegation.py— 118/118 pass (no regressions in the surrounding suites)Not in this PR
delegation.gois intact and untested — out of scope.internal#497(shared push/poll assembler) is the longer-term fix; this PR closes the two missing guards + the inbox classification gap.Co-Authored-By: Claude Opus 4.7 (1M context)
5-axis review (code-review-and-quality):
Approved as non-author whitelist-counted vote per reference_merge_gate_model_changed_2026_05_18 (req_approvals=2). Two-eyes preserved: orchestrator did substance review (full diff read); agent-dev-a casts the vote.
5-axis review (code-review-and-quality):
Approved as non-author whitelist-counted vote per reference_merge_gate_model_changed_2026_05_18 (req_approvals=2). Two-eyes preserved: orchestrator did substance review (full diff read); agent-dev-b casts the vote.