fix(a2a_executor): remove shadowing local Part import that broke streaming
Python scoping rule: any name assigned anywhere in a function body is local for the entire body. The outbound-files block at ~L442 had `from a2a.types import ... Part ...`, which made `Part` a local name throughout the execute() function. The astream_events loop at L358 — which runs BEFORE that import — then raised: UnboundLocalError: cannot access local variable 'Part' where it is not associated with a value Every streaming A2A reply died with "Agent error: cannot access local variable 'Part' where it is not associated with a value" instead of the actual agent text. 5 tests caught it: - test_streaming_plain_string_content - test_streaming_anthropic_content_blocks - test_non_stream_events_ignored - test_core_execute_on_chat_model_end_captures_last_ai_message - test_core_execute_pii_redaction_when_pii_found Fix: drop `Part` from the function-scope import (it is already imported at module level on line 42) and leave a comment pinning the rationale so a future refactor doesn't re-introduce the shadow. All 43 test_a2a_executor tests pass locally. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
425df5e5a9
commit
a34121d451
@ -439,7 +439,14 @@ class LangGraphA2AExecutor(AgentExecutor):
|
||||
# deepagents, future ReAct variants) inherits it.
|
||||
_outbound = collect_outbound_files(final_text)
|
||||
if _outbound:
|
||||
from a2a.types import FilePart, FileWithUri, Message, Part, Role, TextPart
|
||||
# NOTE: do NOT re-import `Part` here. It is already imported
|
||||
# at module scope (line 42). A function-scope `from a2a.types
|
||||
# import ... Part ...` would mark `Part` as a local name
|
||||
# throughout this function under Python's scoping rules,
|
||||
# making the earlier `Part(text=text)` call (line ~358, inside
|
||||
# the astream_events loop) raise UnboundLocalError because
|
||||
# the local binding is not yet in scope at that point.
|
||||
from a2a.types import FilePart, FileWithUri, Message, Role, TextPart
|
||||
_parts: list[Part] = [Part(root=TextPart(text=final_text))] if final_text else []
|
||||
for f in _outbound:
|
||||
_parts.append(Part(root=FilePart(file=FileWithUri(
|
||||
|
||||
Loading…
Reference in New Issue
Block a user