Thanks to visit codestin.com
Credit goes to github.com

Skip to content

LCORE-2914: refactor A2A executor to use pydantic-ai agents#2092

Open
are-ces wants to merge 1 commit into
lightspeed-core:mainfrom
are-ces:lcore-2914-a2a-client-support
Open

LCORE-2914: refactor A2A executor to use pydantic-ai agents#2092
are-ces wants to merge 1 commit into
lightspeed-core:mainfrom
are-ces:lcore-2914-a2a-client-support

Conversation

@are-ces

@are-ces are-ces commented Jul 8, 2026

Copy link
Copy Markdown
Contributor

Description

Prerequisite for A2A client support (LCORE-2914). The A2A server endpoint currently bypasses pydantic-ai entirely — it calls client.responses.create() directly against Llama Stack. This PR refactors A2AAgentExecutor to use build_agent() + agent.run_stream_events(), aligning it with the query and streaming query endpoints.

This enables pydantic-ai skills and capabilities in A2A-served requests, which is required before external agent delegation tools can be registered as pydantic-ai capabilities in a follow-up PR.

Changes

  • Replace raw client.responses.create() with build_agent() + agent.run_stream_events() in A2AAgentExecutor._process_task_streaming()
  • Rewrite _convert_stream_to_events() to consume pydantic-ai AgentStreamEvent / AgentRunResultEvent instead of OpenAIResponseObjectStream chunks
  • Add _build_a2a_parts_from_agent_result() to convert agent results to A2A Parts (replaces _convert_responses_content_to_a2a_parts())
  • Add _dispatch_agent_event() to map pydantic-ai events to A2A TaskStatusUpdateEvent
  • Catch AgentRunError using map_agent_inference_error() from existing utils

Type of change

  • Refactor
  • New feature
  • Bug fix
  • CVE fix
  • Optimization
  • Documentation Update
  • Configuration Update
  • Bump-up service version
  • Bump-up dependent library
  • Bump-up library or tool used for development (does not change the final image)
  • CI configuration change
  • Konflux configuration change
  • Unit tests improvement
  • Integration tests improvement
  • End to end tests improvement
  • Benchmarks improvement

Tools used to create PR

  • Assisted-by: Claude Opus 4.6
  • Generated by: Claude Opus 4.6

Related Tickets & Documents

Checklist before requesting a review

  • I have performed a self-review of my code.
  • PR has passed all pre-merge test jobs.
  • If it is a core feature, I have added thorough tests.

Testing

  • uv run make verify — all linters pass
  • uv run make test-unit — 2973 tests pass, 0 failures
  • Existing A2A tests updated to mock build_agent() instead of client.responses.create()
  • New TestDispatchAgentEvent and TestBuildA2APartsFromAgentResult test classes cover the pydantic-ai event mapping

Summary by CodeRabbit

  • New Features

    • Improved task progress updates during agent runs, including clearer working-status updates as text streams and tools are invoked.
    • Final results are now assembled from the agent’s completed output for more consistent task artifacts (including conversation metadata).
  • Bug Fixes

    • Better handling of agent preparation and run failures, including more resilient error mapping for stream/agent run issues.
    • Improved support for compacted conversation turns to preserve context more reliably.
  • Tests

    • Updated and expanded unit coverage for agent-run streaming, event dispatching, and final-result assembly behavior.

@coderabbitai

coderabbitai Bot commented Jul 8, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Walkthrough

The A2A executor now streams from a Pydantic-AI agent, converts agent events into A2A task status and artifact updates, and uses agent results to build final parts. Error handling now includes AgentRunError, and the unit tests were updated for the new streaming and event-mapping flow.

Changes

A2A agent streaming migration

Layer / File(s) Summary
Imports and helper support
src/app/endpoints/a2a.py, tests/unit/app/endpoints/test_a2a.py
Pydantic-AI event/result types and agent/error-mapping utilities replace Responses-stream-specific imports; the executor caches the latest run result, and new helpers build final parts and working-status text updates.
Agent stream conversion pipeline
src/app/endpoints/a2a.py, tests/unit/app/endpoints/test_a2a.py
_convert_stream_to_events now runs agent.run_stream_events(prompt), accumulates text deltas, maps tool-call events into working status updates, and emits the final artifact update; tests cover part building, conversation metadata, and _dispatch_agent_event mappings.
Task streaming error handling
src/app/endpoints/a2a.py, tests/unit/app/endpoints/test_a2a.py
_process_task_streaming catches AgentRunError during preparation and execution, maps failures through map_agent_inference_error, and tests cover agent-run failures plus compaction-related mock updates.

Estimated code review effort: 4 (Complex) | ~60 minutes

Suggested reviewers: jrobertboos, tisnik

🚥 Pre-merge checks | ✅ 6
✅ Passed checks (6 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly matches the main change: refactoring the A2A executor to use pydantic-ai agents.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Performance And Algorithmic Complexity ✅ Passed No meaningful perf regressions found: the new stream path stays linear per event, with no nested API fan-out, O(n^2) loops, or unbounded buffers.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
✨ Simplify code
  • Create PR with simplified code

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@are-ces

are-ces commented Jul 9, 2026

Copy link
Copy Markdown
Contributor Author

@coderabbitai full review

@coderabbitai

coderabbitai Bot commented Jul 9, 2026

Copy link
Copy Markdown
Contributor
✅ Action performed

Full review finished.

@coderabbitai coderabbitai 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.

Actionable comments posted: 4

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/app/endpoints/a2a.py`:
- Around line 119-121: The new helper signatures and docstrings in the A2A
endpoint module need to match repo conventions. Update the affected helpers such
as the ones around the text-to-parts conversion and related endpoint helpers to
use modern union syntax instead of Optional[...] (for example,
AgentRunResult[str] | None and similar) and replace any docstring section
headers from Args: to Parameters:. Keep the changes consistent across the
referenced helpers so the annotations and Google-style docstrings all follow the
same convention.
- Around line 546-578: The _dispatch_agent_event() method is mutating the
caller-owned text_parts list via append, which violates the no in-place
parameter modification guideline. Refactor _dispatch_agent_event() so it only
derives the event payload and does not update text_parts directly; instead,
return the text delta or updated text alongside the TaskStatusUpdateEvent and
let _convert_stream_to_events() handle accumulation. Keep the change localized
around _dispatch_agent_event(), PartStartEvent, and PartDeltaEvent handling.

In `@tests/unit/app/endpoints/test_a2a.py`:
- Around line 885-892: The stream mock setup in the test is attaching a final
result to mock_stream.result, but the production path reads the final output
from AgentRunResultEvent.result instead. Update the test around mock_run_result
and mock_stream to yield an AgentRunResultEvent through the async iterator so
the final artifact/result path is actually exercised, and remove the unused
mock_stream.result assignment.
- Around line 740-745: The test name and setup in
test_process_task_streaming_handles_agent_run_error do not match the injected
failure, since it currently triggers APIConnectionError instead of the
AgentRunError path. Update this test to either explicitly inject and assert the
AgentRunError mapping in _process_task_streaming, or rename the test to reflect
the APIConnectionError behavior; if needed, add a separate case so the
AgentRunError branch remains covered.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: 06d76901-367a-4e71-885f-702e1e288fd9

📥 Commits

Reviewing files that changed from the base of the PR and between 0fe1e95 and 50b2a99.

📒 Files selected for processing (2)
  • src/app/endpoints/a2a.py
  • tests/unit/app/endpoints/test_a2a.py
📜 Review details
⚠️ CI failures not shown inline (1)

GitHub Actions: Integration tests / 1_integration_tests (3.13).txt: LCORE-2914: refactor A2A executor to use pydantic-ai agents

Conclusion: failure

View job details

dict])
     v = handler(item, index)
 tests/integration/endpoints/test_responses_integration.py::test_streaming_blocked_returns_sse_and_persists_turn
   /home/runner/work/lightspeed-stack/lightspeed-stack/.venv/lib/python3.13/site-packages/pydantic/main.py:475: UserWarning: Pydantic serializer warnings:
     PydanticSerializationUnexpectedValue(Expected `OpenAIResponseToolMCP` - serialized value may not be as expected [field_name='tools', input_value={'type': 'mcp', 'server_l..., 'allowed_tools': None}, input_type=dict])
     PydanticSerializationUnexpectedValue(Expected `OpenAIResponseToolMCP` - serialized value may not be as expected [field_name='tools', input_value={'type': 'mcp', 'server_l..., 'allowed_tools': None}, input_type=dict])
     PydanticSerializationUnexpectedValue(Expected `OpenAIResponseToolMCP` - serialized value may not be as expected [field_name='tools', input_value={'type': 'mcp', 'server_l..., 'allowed_tools': None}, input_type=dict])
     return self.__pydantic_serializer__.to_python(
 -- Docs: https://docs.pytest.org/en/stable/how-to/capture-warnings.html
 ================================ tests coverage ================================
 _______________ coverage: platform linux, python 3.13.14-final-0 _______________
 Name                                                                       Stmts   Miss  Cover   Missing
 --------------------------------------------------------------------------------------------------------
 src/__init__.py                                                                0      0   100%
 src/a2a_storage/__init__.py                                                    6      0   100%
 src/a2a_storage/context_store.py                                              13      0   100%
 src/a2a_storage/in_memory_context_store.py                                    32     20    38%   25-28, 39-47, 56-58, 70-75, 85, 93
 src/a2a_storage/postgres_context_store.py                                     54     37    31%   47-51,...
🧰 Additional context used
📓 Path-based instructions (3)
tests/**/*.py

📄 CodeRabbit inference engine (AGENTS.md)

tests/**/*.py: Use pytest for all unit and integration tests; do not use unittest
Use pytest.mark.asyncio marker for async tests

Files:

  • tests/unit/app/endpoints/test_a2a.py
src/**/*.py

📄 CodeRabbit inference engine (AGENTS.md)

src/**/*.py: Use absolute imports for internal modules: from authentication import get_auth_dependency
Llama Stack imports: Use from llama_stack_client import AsyncLlamaStackClient
Check constants.py for shared constants before defining new ones
All modules must start with descriptive docstrings explaining purpose
Use logger = get_logger(__name__) from log.py for module logging
All functions must have complete type annotations for parameters and return types, use modern syntax (str | int), and include descriptive docstrings
Use snake_case with descriptive, action-oriented names for functions (get_, validate_, check_)
Avoid in-place parameter modification anti-patterns; return new data structures instead of modifying function parameters
Use async def for I/O operations and external API calls
Use standard log levels with clear purposes: debug() for diagnostic info, info() for program execution, warning() for unexpected events, error() for serious problems
All classes must have descriptive docstrings explaining purpose and use PascalCase with standard suffixes: Configuration, Error/Exception, Resolver, Interface
Abstract classes must use ABC with @abstractmethod decorators
Follow Google Python docstring conventions with required sections: Parameters, Returns, Raises, and Attributes for classes

Files:

  • src/app/endpoints/a2a.py
src/app/**/*.py

📄 CodeRabbit inference engine (AGENTS.md)

src/app/**/*.py: FastAPI dependencies: Import from fastapi module for APIRouter, HTTPException, Request, status, Depends
Use FastAPI HTTPException with appropriate status codes for API endpoints and handle APIConnectionError from Llama Stack

Files:

  • src/app/endpoints/a2a.py
🧠 Learnings (3)
📚 Learning: 2026-06-24T13:45:37.249Z
Learnt from: Jdubrick
Repo: lightspeed-core/lightspeed-stack PR: 1971
File: src/utils/markdown_repair.py:31-36
Timestamp: 2026-06-24T13:45:37.249Z
Learning: In the lightspeed-stack repository, docstrings must use the section header name "Parameters:" (not "Args:") for function arguments, even if the project references Google Python docstring conventions. Ensure docstrings follow the project’s established "Parameters:" header format for any documented function parameters.

Applied to files:

  • tests/unit/app/endpoints/test_a2a.py
  • src/app/endpoints/a2a.py
📚 Learning: 2026-04-06T20:18:07.852Z
Learnt from: major
Repo: lightspeed-core/lightspeed-stack PR: 1463
File: src/app/endpoints/rlsapi_v1.py:266-271
Timestamp: 2026-04-06T20:18:07.852Z
Learning: In the lightspeed-stack codebase, within `src/app/endpoints/` inference/MCP endpoints, treat `tools: Optional[list[Any]]` in MCP tool definitions as an intentional, consistent typing pattern (used across `query`, `responses`, `streaming_query`, `rlsapi_v1`). Do not raise or suggest this as a typing issue during code review; changing it in isolation could break endpoint typing consistency across the codebase.

Applied to files:

  • src/app/endpoints/a2a.py
📚 Learning: 2026-07-06T15:26:18.398Z
Learnt from: Jdubrick
Repo: lightspeed-core/lightspeed-stack PR: 2071
File: src/models/config.py:2416-2422
Timestamp: 2026-07-06T15:26:18.398Z
Learning: In this repo’s Python code under src/**, don’t treat differences in string concatenation style as a style inconsistency when Black has effectively forced (or made clearer) use of explicit `+` string concatenation in multi-line logger/string expressions. If adjacent-literal implicit concatenation is avoided/changed specifically to accommodate Black’s formatting in these call sites, accept the `+` usage and don’t recommend converting it solely for consistency with nearby blocks that use implicit concatenation.

Applied to files:

  • src/app/endpoints/a2a.py
🪛 ast-grep (0.44.1)
tests/unit/app/endpoints/test_a2a.py

[warning] 803-803: Do not make http calls without encryption
Context: "http://test-llama-stack/responses"
Note: [CWE-319] Cleartext Transmission of Sensitive Information.

(requests-http)

Comment thread src/app/endpoints/a2a.py Outdated
Comment thread src/app/endpoints/a2a.py
Comment thread tests/unit/app/endpoints/test_a2a.py Outdated
Comment thread tests/unit/app/endpoints/test_a2a.py Outdated
@are-ces are-ces force-pushed the lcore-2914-a2a-client-support branch from 50b2a99 to 31a6cad Compare July 9, 2026 07:56
Replace direct client.responses.create() calls with build_agent() +
agent.run_stream_events(), aligning the A2A server path with the
query and streaming query endpoints. This enables pydantic-ai skills
and capabilities in A2A-served requests.

Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
@are-ces are-ces force-pushed the lcore-2914-a2a-client-support branch from 31a6cad to 29bd62d Compare July 9, 2026 12:02

@coderabbitai coderabbitai 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.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/app/endpoints/a2a.py`:
- Around line 489-496: The unused executor state in _convert_stream_to_events()
should be removed: self._run_result is assigned when handling
AgentRunResultEvent but never read anywhere. Update the A2A executor flow by
deleting the self._run_result assignment and removing the attribute from the
class if it exists, keeping the run_result local to the streaming logic unless
another method truly needs it.
- Around line 130-131: The `a2a` endpoint is reading the wrong field from
`AgentRunResult`, so the final text assignment will break at runtime in the
pinned `pydantic-ai` version. Update the `run_result` handling in the endpoint
logic to use `run_result.output` instead of `run_result.response.text`, and make
sure the corresponding code in `src/utils/agents/streaming.py` uses the same
`AgentRunResult` output field for consistency.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: f47ca9b2-cc6d-449a-92ec-315cf42ae90a

📥 Commits

Reviewing files that changed from the base of the PR and between 50b2a99 and 29bd62d.

📒 Files selected for processing (2)
  • src/app/endpoints/a2a.py
  • tests/unit/app/endpoints/test_a2a.py
📜 Review details
⏰ Context from checks skipped due to timeout. (8)
  • GitHub Check: Konflux kflux-prd-rh02 / lightspeed-stack-0-7-on-pull-request
  • GitHub Check: E2E: server mode / ci / group 2
  • GitHub Check: E2E Tests for Lightspeed Evaluation job
  • GitHub Check: E2E: library mode / ci / group 2
  • GitHub Check: E2E: library mode / ci / group 1
  • GitHub Check: E2E: server mode / ci / group 1
  • GitHub Check: E2E: library mode / ci / group 3
  • GitHub Check: E2E: server mode / ci / group 3
🧰 Additional context used
📓 Path-based instructions (3)
src/**/*.py

📄 CodeRabbit inference engine (AGENTS.md)

src/**/*.py: Use absolute imports for internal modules: from authentication import get_auth_dependency
Llama Stack imports: Use from llama_stack_client import AsyncLlamaStackClient
Check constants.py for shared constants before defining new ones
All modules must start with descriptive docstrings explaining purpose
Use logger = get_logger(__name__) from log.py for module logging
All functions must have complete type annotations for parameters and return types, use modern syntax (str | int), and include descriptive docstrings
Use snake_case with descriptive, action-oriented names for functions (get_, validate_, check_)
Avoid in-place parameter modification anti-patterns; return new data structures instead of modifying function parameters
Use async def for I/O operations and external API calls
Use standard log levels with clear purposes: debug() for diagnostic info, info() for program execution, warning() for unexpected events, error() for serious problems
All classes must have descriptive docstrings explaining purpose and use PascalCase with standard suffixes: Configuration, Error/Exception, Resolver, Interface
Abstract classes must use ABC with @abstractmethod decorators
Follow Google Python docstring conventions with required sections: Parameters, Returns, Raises, and Attributes for classes

Files:

  • src/app/endpoints/a2a.py
src/app/**/*.py

📄 CodeRabbit inference engine (AGENTS.md)

src/app/**/*.py: FastAPI dependencies: Import from fastapi module for APIRouter, HTTPException, Request, status, Depends
Use FastAPI HTTPException with appropriate status codes for API endpoints and handle APIConnectionError from Llama Stack

Files:

  • src/app/endpoints/a2a.py
tests/**/*.py

📄 CodeRabbit inference engine (AGENTS.md)

tests/**/*.py: Use pytest for all unit and integration tests; do not use unittest
Use pytest.mark.asyncio marker for async tests

Files:

  • tests/unit/app/endpoints/test_a2a.py
🧠 Learnings (3)
📚 Learning: 2026-04-06T20:18:07.852Z
Learnt from: major
Repo: lightspeed-core/lightspeed-stack PR: 1463
File: src/app/endpoints/rlsapi_v1.py:266-271
Timestamp: 2026-04-06T20:18:07.852Z
Learning: In the lightspeed-stack codebase, within `src/app/endpoints/` inference/MCP endpoints, treat `tools: Optional[list[Any]]` in MCP tool definitions as an intentional, consistent typing pattern (used across `query`, `responses`, `streaming_query`, `rlsapi_v1`). Do not raise or suggest this as a typing issue during code review; changing it in isolation could break endpoint typing consistency across the codebase.

Applied to files:

  • src/app/endpoints/a2a.py
📚 Learning: 2026-06-24T13:45:37.249Z
Learnt from: Jdubrick
Repo: lightspeed-core/lightspeed-stack PR: 1971
File: src/utils/markdown_repair.py:31-36
Timestamp: 2026-06-24T13:45:37.249Z
Learning: In the lightspeed-stack repository, docstrings must use the section header name "Parameters:" (not "Args:") for function arguments, even if the project references Google Python docstring conventions. Ensure docstrings follow the project’s established "Parameters:" header format for any documented function parameters.

Applied to files:

  • src/app/endpoints/a2a.py
  • tests/unit/app/endpoints/test_a2a.py
📚 Learning: 2026-07-06T15:26:18.398Z
Learnt from: Jdubrick
Repo: lightspeed-core/lightspeed-stack PR: 2071
File: src/models/config.py:2416-2422
Timestamp: 2026-07-06T15:26:18.398Z
Learning: In this repo’s Python code under src/**, don’t treat differences in string concatenation style as a style inconsistency when Black has effectively forced (or made clearer) use of explicit `+` string concatenation in multi-line logger/string expressions. If adjacent-literal implicit concatenation is avoided/changed specifically to accommodate Black’s formatting in these call sites, accept the `+` usage and don’t recommend converting it solely for consistency with nearby blocks that use implicit concatenation.

Applied to files:

  • src/app/endpoints/a2a.py
🪛 ast-grep (0.44.1)
tests/unit/app/endpoints/test_a2a.py

[warning] 804-804: Do not make http calls without encryption
Context: "http://test-llama-stack/responses"
Note: [CWE-319] Cleartext Transmission of Sensitive Information.

(requests-http)

🔇 Additional comments (9)
src/app/endpoints/a2a.py (5)

538-548: 📐 Maintainability & Code Quality

_dispatch_agent_event() mutates the caller-owned text_parts list.

This was previously flagged: the method appends to the text_parts parameter, which violates the repo guideline against in-place parameter modification. Consider returning the delta alongside the event and accumulating in _convert_stream_to_events().

Source: Coding guidelines


34-49: LGTM!

Also applies to: 63-68


83-84: LGTM!


374-388: LGTM!

Also applies to: 423-447


586-615: LGTM!

tests/unit/app/endpoints/test_a2a.py (4)

26-43: LGTM!

Also applies to: 155-217


741-828: LGTM!

Also applies to: 830-904


906-985: LGTM!

Also applies to: 987-1020


1078-1179: LGTM!

Comment thread src/app/endpoints/a2a.py
Comment thread src/app/endpoints/a2a.py
Comment on lines +489 to +496
run_result: AgentRunResult[str] | None = None

async with agent.run_stream_events(prompt) as stream:
async for event in stream:
if isinstance(event, AgentRunResultEvent):
run_result = event.result
self._run_result = run_result
continue

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.

📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Check for any reader of self._run_result / executor reuse
rg -nP '_run_result' src tests
echo "--- how executor is instantiated (per-request vs shared) ---"
rg -nP -C3 'A2AAgentExecutor\(' src

Repository: lightspeed-core/lightspeed-stack

Length of output: 7522


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "--- surrounding A2AAgentExecutor state and usage ---"
sed -n '202,280p' src/app/endpoints/a2a.py

echo "--- _run_result references in the file ---"
rg -n '_run_result|run_result' src/app/endpoints/a2a.py

echo "--- where the A2A agent executor is created and how long it lives ---"
sed -n '740,790p' src/app/endpoints/a2a.py

echo "--- any other A2AAgentExecutor instantiation sites ---"
rg -n 'A2AAgentExecutor\(' src

Repository: lightspeed-core/lightspeed-stack

Length of output: 5677


Remove the unused executor state

self._run_result is assigned in _convert_stream_to_events() but never read. Drop the attribute and the assignment unless a later step needs per-run state.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/app/endpoints/a2a.py` around lines 489 - 496, The unused executor state
in _convert_stream_to_events() should be removed: self._run_result is assigned
when handling AgentRunResultEvent but never read anywhere. Update the A2A
executor flow by deleting the self._run_result assignment and removing the
attribute from the class if it exists, keeping the run_result local to the
streaming logic unless another method truly needs it.

@are-ces are-ces requested a review from asimurka July 9, 2026 12:16

@asimurka asimurka 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.

LGTM in overall, I pointed out some things worth checking

Comment thread src/app/endpoints/a2a.py
_TASK_STORE: Optional[TaskStore] = None
_CONTEXT_STORE: Optional[A2AContextStore] = None
_TASK_STORE: TaskStore | None = None
_CONTEXT_STORE: A2AContextStore | None = None

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.

nit: The original version with using Optional aligns with contribution guides (occurs also below sometimes)

Comment thread src/app/endpoints/a2a.py
state=TaskState.working,
message=new_agent_text_message(
f"MCP call: {item_id}",
f"MCP call: {event.part.tool_name}",

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.

There is an equivalent attribute event.part.tool_call_id

Comment thread src/app/endpoints/a2a.py
_ = artifact_id

if isinstance(event, PartStartEvent):
if isinstance(event.part, PydanticTextPart):

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.

This should be only TextPart there is doubled import at the top of this module.

Comment thread src/app/endpoints/a2a.py
item_id = getattr(chunk, "item_id", "")
yield TaskStatusUpdateEvent(
elif isinstance(event, PartEndEvent):
if isinstance(event.part, NativeToolCallPart):

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.

Just note: NativeToolCallPart can contain also file search, mcp tools list and web search (not only mcp call as in the original implementation)

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants