Skip to content

Conversation

eranco74
Copy link

@eranco74 eranco74 commented Oct 23, 2025

Link to Issue or Description of Change

The previous logic iterated through session events in reverse and then reversed the resulting list of parts. This caused incorrect ordering for multi-part messages generated by _present_other_agent_message.

Specifically, introductory text like "For context:" was appearing after the content it was meant to introduce.

This change simplifies the implementation by removing both reversals. It now processes events in chronological order, ensuring all message parts are appended in the correct sequence.

Please ensure you have read the contribution guide before creating a pull request.

Problem:
Incorrect ordering for multi-part messages generated by _present_other_agent_message.

Solution:
processes events in chronological order, ensuring all message parts are appended in the correct sequence.

Testing Plan

Please describe the tests that you ran to verify your changes. This is required
for all PRs that are not small documentation or typo fixes.

Unit Tests:

  • I have added or updated unit tests for my change.
  • All unit tests pass locally.

Manual End-to-End (E2E) Tests:

Please provide instructions on how to manually test your changes, including any
necessary setup or configuration. Please provide logs or screenshots to help
reviewers better understand the fix.

Checklist

  • I have read the CONTRIBUTING.md document.
  • I have performed a self-review of my own code.
  • I have commented my code, particularly in hard-to-understand areas.
  • I have added tests that prove my fix is effective or that my feature works.
  • New and existing unit tests pass locally with my changes.
  • I have manually tested my changes end-to-end.
  • Any dependent changes have been merged and published in downstream modules.

Additional context

@google-cla
Copy link

google-cla bot commented Oct 23, 2025

Thanks for your pull request! It looks like this may be your first contribution to a Google open source project. Before we can look at your pull request, you'll need to sign a Contributor License Agreement (CLA).

View this failed invocation of the CLA check for more information.

For the most up to date status, view the checks section at the bottom of the pull request.

@adk-bot
Copy link
Collaborator

adk-bot commented Oct 23, 2025

Response from ADK Triaging Agent

Hello @eranco74, thank you for creating this PR!

Before we can proceed with the review, could you please address the following points from our contribution guidelines:

  • Sign our Contributor License Agreement (CLA): It appears the CLA check has failed. Please visit https://cla.developers.google.com/ to sign the agreement.
  • Testing Plan: Could you please provide a testing plan for your changes? This should include details on unit tests and/or manual end-to-end tests as described in our testing requirements.

This information is necessary to ensure the quality and maintainability of the project. Thanks!

@eranco74 eranco74 force-pushed the fix_message_parts_order branch from 8e8f7ef to 626425c Compare October 23, 2025 11:38
@eranco74
Copy link
Author

Unit tests:

python3.13 -m pytest tests/unittests/agents/test_remote_a2a_agent.py -v
==================================================================================================================== test session starts =====================================================================================================================
platform linux -- Python 3.13.1, pytest-8.4.1, pluggy-1.5.0 -- /usr/bin/python3.13
cachedir: .pytest_cache
rootdir: /home/eran/go/src/github/eranco74/adk-python
configfile: pyproject.toml
plugins: langsmith-0.3.45, mock-3.14.1, asyncio-1.1.0, anyio-4.11.0
asyncio: mode=Mode.AUTO, asyncio_default_fixture_loop_scope=function, asyncio_default_test_loop_scope=function
collected 67 items                                                                                                                                                                                                                                           

tests/unittests/agents/test_remote_a2a_agent.py::TestRemoteA2aAgentInit::test_init_with_agent_card_object PASSED                                                                                                                                       [  1%]
tests/unittests/agents/test_remote_a2a_agent.py::TestRemoteA2aAgentInit::test_init_with_url_string PASSED                                                                                                                                              [  2%]
tests/unittests/agents/test_remote_a2a_agent.py::TestRemoteA2aAgentInit::test_init_with_file_path PASSED                                                                                                                                               [  4%]
tests/unittests/agents/test_remote_a2a_agent.py::TestRemoteA2aAgentInit::test_init_with_shared_httpx_client PASSED                                                                                                                                     [  5%]
tests/unittests/agents/test_remote_a2a_agent.py::TestRemoteA2aAgentInit::test_init_with_factory PASSED                                                                                                                                                 [  7%]
tests/unittests/agents/test_remote_a2a_agent.py::TestRemoteA2aAgentInit::test_init_with_none_agent_card PASSED                                                                                                                                         [  8%]
tests/unittests/agents/test_remote_a2a_agent.py::TestRemoteA2aAgentInit::test_init_with_empty_string_agent_card PASSED                                                                                                                                 [ 10%]
tests/unittests/agents/test_remote_a2a_agent.py::TestRemoteA2aAgentInit::test_init_with_invalid_type_agent_card PASSED                                                                                                                                 [ 11%]
tests/unittests/agents/test_remote_a2a_agent.py::TestRemoteA2aAgentInit::test_init_with_custom_timeout PASSED                                                                                                                                          [ 13%]
tests/unittests/agents/test_remote_a2a_agent.py::TestRemoteA2aAgentResolution::test_ensure_httpx_client_creates_new_client PASSED                                                                                                                      [ 14%]
tests/unittests/agents/test_remote_a2a_agent.py::TestRemoteA2aAgentResolution::test_ensure_httpx_client_reuses_existing_client PASSED                                                                                                                  [ 16%]
tests/unittests/agents/test_remote_a2a_agent.py::TestRemoteA2aAgentResolution::test_ensure_factory_reuses_existing_client PASSED                                                                                                                       [ 17%]
tests/unittests/agents/test_remote_a2a_agent.py::TestRemoteA2aAgentResolution::test_ensure_httpx_client_updates_factory_with_new_client PASSED                                                                                                         [ 19%]
tests/unittests/agents/test_remote_a2a_agent.py::TestRemoteA2aAgentResolution::test_ensure_httpx_client_reregisters_transports_with_new_client PASSED                                                                                                  [ 20%]
tests/unittests/agents/test_remote_a2a_agent.py::TestRemoteA2aAgentResolution::test_resolve_agent_card_from_url_success PASSED                                                                                                                         [ 22%]
tests/unittests/agents/test_remote_a2a_agent.py::TestRemoteA2aAgentResolution::test_resolve_agent_card_from_url_invalid_url PASSED                                                                                                                     [ 23%]
tests/unittests/agents/test_remote_a2a_agent.py::TestRemoteA2aAgentResolution::test_resolve_agent_card_from_file_success PASSED                                                                                                                        [ 25%]
tests/unittests/agents/test_remote_a2a_agent.py::TestRemoteA2aAgentResolution::test_resolve_agent_card_from_file_not_found PASSED                                                                                                                      [ 26%]
tests/unittests/agents/test_remote_a2a_agent.py::TestRemoteA2aAgentResolution::test_resolve_agent_card_from_file_invalid_json PASSED                                                                                                                   [ 28%]
tests/unittests/agents/test_remote_a2a_agent.py::TestRemoteA2aAgentResolution::test_validate_agent_card_success PASSED                                                                                                                                 [ 29%]
tests/unittests/agents/test_remote_a2a_agent.py::TestRemoteA2aAgentResolution::test_validate_agent_card_no_url PASSED                                                                                                                                  [ 31%]
tests/unittests/agents/test_remote_a2a_agent.py::TestRemoteA2aAgentResolution::test_validate_agent_card_invalid_url PASSED                                                                                                                             [ 32%]
tests/unittests/agents/test_remote_a2a_agent.py::TestRemoteA2aAgentResolution::test_ensure_resolved_with_direct_agent_card PASSED                                                                                                                      [ 34%]
tests/unittests/agents/test_remote_a2a_agent.py::TestRemoteA2aAgentResolution::test_ensure_resolved_with_direct_agent_card_with_factory PASSED                                                                                                         [ 35%]
tests/unittests/agents/test_remote_a2a_agent.py::TestRemoteA2aAgentResolution::test_ensure_resolved_with_url_source PASSED                                                                                                                             [ 37%]
tests/unittests/agents/test_remote_a2a_agent.py::TestRemoteA2aAgentResolution::test_ensure_resolved_already_resolved PASSED                                                                                                                            [ 38%]
tests/unittests/agents/test_remote_a2a_agent.py::TestRemoteA2aAgentMessageHandling::test_create_a2a_request_for_user_function_response_no_function_call PASSED                                                                                         [ 40%]
tests/unittests/agents/test_remote_a2a_agent.py::TestRemoteA2aAgentMessageHandling::test_create_a2a_request_for_user_function_response_success PASSED                                                                                                  [ 41%]
tests/unittests/agents/test_remote_a2a_agent.py::TestRemoteA2aAgentMessageHandling::test_construct_message_parts_from_session_success PASSED                                                                                                           [ 43%]
tests/unittests/agents/test_remote_a2a_agent.py::TestRemoteA2aAgentMessageHandling::test_construct_message_parts_from_session_empty_events PASSED                                                                                                      [ 44%]
tests/unittests/agents/test_remote_a2a_agent.py::TestRemoteA2aAgentMessageHandling::test_handle_a2a_response_success_with_message PASSED                                                                                                               [ 46%]
tests/unittests/agents/test_remote_a2a_agent.py::TestRemoteA2aAgentMessageHandling::test_handle_a2a_response_with_task_completed_and_no_update PASSED                                                                                                  [ 47%]
tests/unittests/agents/test_remote_a2a_agent.py::TestRemoteA2aAgentMessageHandling::test_handle_a2a_response_with_task_submitted_and_no_update PASSED                                                                                                  [ 49%]
tests/unittests/agents/test_remote_a2a_agent.py::TestRemoteA2aAgentMessageHandling::test_handle_a2a_response_with_task_status_update_with_message PASSED                                                                                               [ 50%]
tests/unittests/agents/test_remote_a2a_agent.py::TestRemoteA2aAgentMessageHandling::test_handle_a2a_response_with_task_status_working_update_with_message PASSED                                                                                       [ 52%]
tests/unittests/agents/test_remote_a2a_agent.py::TestRemoteA2aAgentMessageHandling::test_handle_a2a_response_with_task_status_update_no_message PASSED                                                                                                 [ 53%]
tests/unittests/agents/test_remote_a2a_agent.py::TestRemoteA2aAgentMessageHandling::test_handle_a2a_response_with_artifact_update PASSED                                                                                                               [ 55%]
tests/unittests/agents/test_remote_a2a_agent.py::TestRemoteA2aAgentMessageHandling::test_handle_a2a_response_with_partial_artifact_update PASSED                                                                                                       [ 56%]
tests/unittests/agents/test_remote_a2a_agent.py::TestRemoteA2aAgentMessageHandlingFromFactory::test_create_a2a_request_for_user_function_response_no_function_call PASSED                                                                              [ 58%]
tests/unittests/agents/test_remote_a2a_agent.py::TestRemoteA2aAgentMessageHandlingFromFactory::test_create_a2a_request_for_user_function_response_success PASSED                                                                                       [ 59%]
tests/unittests/agents/test_remote_a2a_agent.py::TestRemoteA2aAgentMessageHandlingFromFactory::test_construct_message_parts_from_session_success PASSED                                                                                                [ 61%]
tests/unittests/agents/test_remote_a2a_agent.py::TestRemoteA2aAgentMessageHandlingFromFactory::test_construct_message_parts_from_session_empty_events PASSED                                                                                           [ 62%]
tests/unittests/agents/test_remote_a2a_agent.py::TestRemoteA2aAgentMessageHandlingFromFactory::test_handle_a2a_response_success_with_message PASSED                                                                                                    [ 64%]
tests/unittests/agents/test_remote_a2a_agent.py::TestRemoteA2aAgentMessageHandlingFromFactory::test_handle_a2a_response_with_task_completed_and_no_update PASSED                                                                                       [ 65%]
tests/unittests/agents/test_remote_a2a_agent.py::TestRemoteA2aAgentMessageHandlingFromFactory::test_handle_a2a_response_with_task_submitted_and_no_update PASSED                                                                                       [ 67%]
tests/unittests/agents/test_remote_a2a_agent.py::TestRemoteA2aAgentMessageHandlingFromFactory::test_handle_a2a_response_with_task_status_update_with_message PASSED                                                                                    [ 68%]
tests/unittests/agents/test_remote_a2a_agent.py::TestRemoteA2aAgentMessageHandlingFromFactory::test_handle_a2a_response_with_task_status_working_update_with_message PASSED                                                                            [ 70%]
tests/unittests/agents/test_remote_a2a_agent.py::TestRemoteA2aAgentMessageHandlingFromFactory::test_handle_a2a_response_with_task_status_update_no_message PASSED                                                                                      [ 71%]
tests/unittests/agents/test_remote_a2a_agent.py::TestRemoteA2aAgentMessageHandlingFromFactory::test_handle_a2a_response_with_artifact_update PASSED                                                                                                    [ 73%]
tests/unittests/agents/test_remote_a2a_agent.py::TestRemoteA2aAgentMessageHandlingFromFactory::test_handle_a2a_response_with_partial_artifact_update PASSED                                                                                            [ 74%]
tests/unittests/agents/test_remote_a2a_agent.py::TestRemoteA2aAgentExecution::test_run_async_impl_initialization_failure PASSED                                                                                                                        [ 76%]
tests/unittests/agents/test_remote_a2a_agent.py::TestRemoteA2aAgentExecution::test_run_async_impl_no_message_parts PASSED                                                                                                                              [ 77%]
tests/unittests/agents/test_remote_a2a_agent.py::TestRemoteA2aAgentExecution::test_run_async_impl_successful_request PASSED                                                                                                                            [ 79%]
tests/unittests/agents/test_remote_a2a_agent.py::TestRemoteA2aAgentExecution::test_run_async_impl_a2a_client_error PASSED                                                                                                                              [ 80%]
tests/unittests/agents/test_remote_a2a_agent.py::TestRemoteA2aAgentExecution::test_run_live_impl_not_implemented PASSED                                                                                                                                [ 82%]
tests/unittests/agents/test_remote_a2a_agent.py::TestRemoteA2aAgentExecutionFromFactory::test_run_async_impl_initialization_failure PASSED                                                                                                             [ 83%]
tests/unittests/agents/test_remote_a2a_agent.py::TestRemoteA2aAgentExecutionFromFactory::test_run_async_impl_no_message_parts PASSED                                                                                                                   [ 85%]
tests/unittests/agents/test_remote_a2a_agent.py::TestRemoteA2aAgentExecutionFromFactory::test_run_async_impl_successful_request PASSED                                                                                                                 [ 86%]
tests/unittests/agents/test_remote_a2a_agent.py::TestRemoteA2aAgentExecutionFromFactory::test_run_async_impl_a2a_client_error PASSED                                                                                                                   [ 88%]
tests/unittests/agents/test_remote_a2a_agent.py::TestRemoteA2aAgentExecutionFromFactory::test_run_live_impl_not_implemented PASSED                                                                                                                     [ 89%]
tests/unittests/agents/test_remote_a2a_agent.py::TestRemoteA2aAgentCleanup::test_cleanup_owns_httpx_client PASSED                                                                                                                                      [ 91%]
tests/unittests/agents/test_remote_a2a_agent.py::TestRemoteA2aAgentCleanup::test_cleanup_owns_httpx_client_factory PASSED                                                                                                                              [ 92%]
tests/unittests/agents/test_remote_a2a_agent.py::TestRemoteA2aAgentCleanup::test_cleanup_does_not_own_httpx_client PASSED                                                                                                                              [ 94%]
tests/unittests/agents/test_remote_a2a_agent.py::TestRemoteA2aAgentCleanup::test_cleanup_does_not_own_httpx_client_factory PASSED                                                                                                                      [ 95%]
tests/unittests/agents/test_remote_a2a_agent.py::TestRemoteA2aAgentCleanup::test_cleanup_client_close_error PASSED                                                                                                                                     [ 97%]
tests/unittests/agents/test_remote_a2a_agent.py::TestRemoteA2aAgentIntegration::test_full_workflow_with_direct_agent_card PASSED                                                                                                                       [ 98%]
tests/unittests/agents/test_remote_a2a_agent.py::TestRemoteA2aAgentIntegration::test_full_workflow_with_direct_agent_card_and_factory PASSED                                                                                                           [100%]

...
============================================================================================================== 67 passed, 77 warnings in 4.81s ===============================================================================================================

@adk-bot adk-bot added the core [Component] This issue is related to the core interface and implementation label Oct 23, 2025
@adk-bot adk-bot requested a review from Jacksunwei October 23, 2025 11:41
@adk-bot
Copy link
Collaborator

adk-bot commented Oct 23, 2025

Response from ADK Triaging Agent

Hello @eranco74, thank you for the update and for providing the unit test results!

Before we can proceed with a full review, could you please address the remaining items from our contribution guidelines?

  • Sign our Contributor License Agreement (CLA): The CLA check is still failing. You can sign the agreement at https://cla.developers.google.com/.
  • Associate a GitHub Issue: For bug fixes, we require an associated GitHub issue. If one doesn't exist, please create one and link it in the PR description.
  • Manual End-to-End (E2E) Tests: Could you please provide logs or screenshots from a manual E2E test to demonstrate that the fix works as expected? This is very helpful for reviewers to understand the impact of the change.

You can find more details in our CONTRIBUTING.md. Thanks for your contribution!

@eranco74 eranco74 force-pushed the fix_message_parts_order branch from 626425c to 0578d43 Compare October 23, 2025 12:18
@eranco74 eranco74 marked this pull request as ready for review October 23, 2025 17:55
The overall logic processes events in reverse chronological order and then
reverses the entire list of collected parts at the end to restore the
correct sequence of messages.

However, the parts *within* a single message were being appended in their
original forward order. This resulted in their sequence being incorrectly
inverted by the final list reversal.

This change fixes the issue by iterating over an event's parts in reverse.
This pre-reversal ensures that after the final list-wide reversal, the
internal order of parts within each message is correctly maintained.
Signed-off-by: Eran Cohen <[email protected]>
@eranco74 eranco74 force-pushed the fix_message_parts_order branch from 0578d43 to a7f01bc Compare October 23, 2025 17:55
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

core [Component] This issue is related to the core interface and implementation

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants