Skip to content

fix(a2a): use protocol-standard contextId as sessionId instead of req…#1827

Open
pymBupt wants to merge 1 commit into
agentscope-ai:mainfrom
pymBupt:fix/a2a-session-id-use-contextId
Open

fix(a2a): use protocol-standard contextId as sessionId instead of req…#1827
pymBupt wants to merge 1 commit into
agentscope-ai:mainfrom
pymBupt:fix/a2a-session-id-use-contextId

Conversation

@pymBupt

@pymBupt pymBupt commented Jun 18, 2026

Copy link
Copy Markdown

…uiring metadata hardcoded key

Previously, AgentScopeAgentExecutor.getSessionId() read sessionId exclusively from message.metadata["sessionId"], forcing all A2A clients to hardcode this custom metadata key — inappropriate for multi-client interoperability.

The A2A protocol defines Message.contextId as the standard field for session/conversation context tracking.

Changes:

  • Prefer contextId (via RequestContext.getContextId()) as the sessionId source
  • Fallback to metadata["sessionId"] for backward compatibility
  • Add 3 unit tests covering the resolution strategy

Resolves #1603
Related: #820

AgentScope-Java Version

[The version of AgentScope-Java you are working on, e.g. 1.0.12, check your pom.xml dependency version or run mvn dependency:tree | grep agentscope-parent:pom(only mac/linux)]

Description

[Please describe the background, purpose, changes made, and how to test this PR]

Checklist

Please check the following items before code is ready to be reviewed.

  • Code has been formatted with mvn spotless:apply
  • All tests are passing (mvn test)
  • Javadoc comments are complete and follow project conventions
  • Related documentation has been updated (e.g. links, examples, etc.)
  • Code is ready for review

…uiring metadata hardcoded key

Previously, AgentScopeAgentExecutor.getSessionId() read sessionId exclusively
from message.metadata["sessionId"], forcing all A2A clients to hardcode this
custom metadata key — inappropriate for multi-client interoperability.

The A2A protocol defines Message.contextId as the standard field for
session/conversation context tracking.

Changes:
- Prefer contextId (via RequestContext.getContextId()) as the sessionId source
- Fallback to metadata["sessionId"] for backward compatibility
- Add 3 unit tests covering the resolution strategy

Resolves agentscope-ai#1603
Related: agentscope-ai#820
@pymBupt pymBupt requested a review from a team June 18, 2026 06:01
@CLAassistant

Copy link
Copy Markdown

CLA assistant check
Thank you for your submission! We really appreciate it. Like many open source projects, we ask that you sign our Contributor License Agreement before we can accept your contribution.
You have signed the CLA already but the status is still pending? Let us recheck it.

@codecov

codecov Bot commented Jun 18, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 75.00000% with 1 line in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
...e/a2a/server/executor/AgentScopeAgentExecutor.java 75.00% 0 Missing and 1 partial ⚠️

📢 Thoughts on this report? Let us know!

@AgentScopeJavaBot AgentScopeJavaBot left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

🤖 AI Review

This PR changes AgentScopeAgentExecutor.getSessionId() to prefer the A2A protocol-standard Message.contextId field over the custom metadata["sessionId"] key, while maintaining backward compatibility via fallback. This correctly addresses issue #1603 where all A2A clients were forced to hardcode a custom metadata key. The change is minimal (~24 lines in production code), backward-compatible, and well-documented with Javadoc. Three new unit tests cover the priority resolution strategy. The direction is correct and the implementation is clean. Minor suggestion: add test coverage for the edge case where context.getContextId() returns null.


@Test
@DisplayName("Should use contextId as sessionId when contextId is present")
void testSessionIdFromContextId() throws JSONRPCError {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

[recommended] Test coverage gap: The existing 3 tests cover contextId present, metadata fallback, and both present. Consider adding a test for the edge case where context.getContextId() returns null (not empty string) and no metadata sessionId exists — verifying the method returns empty string. This path is handled correctly in the code (contextId != null check) but has no test.


@Test
@DisplayName("Should use contextId as sessionId when contextId is present")
void testSessionIdFromContextId() throws JSONRPCError {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

[nitpick] Test code duplication: The three test cases share extensive mock setup boilerplate (MessageSendParams mock, AtomicReference<AgentRequestOptions> capture, mockAgentRunner.stream stubbing, executor.execute call). Consider extracting a private helper method like executeAndCaptureOptions(contextId, metadataMap) to reduce duplication.

@AgentScopeJavaBot AgentScopeJavaBot left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

🤖 AI Review

This PR changes AgentScopeAgentExecutor.getSessionId() to prefer the A2A protocol-standard Message.contextId field over the custom metadata["sessionId"] key, while maintaining backward compatibility via fallback. This correctly addresses issue #1603 where all A2A clients were forced to hardcode a custom metadata key. The change is minimal (~24 lines in production code), backward-compatible, and well-documented with Javadoc. Three new unit tests cover the priority resolution strategy. The direction is correct and the implementation is clean. Minor suggestion: add test coverage for the edge case where context.getContextId() returns null.


@Test
@DisplayName("Should use contextId as sessionId when contextId is present")
void testSessionIdFromContextId() throws JSONRPCError {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

[recommended] Test coverage gap: The existing 3 tests cover contextId present, metadata fallback, and both present. Consider adding a test for the edge case where context.getContextId() returns null (not empty string) and no metadata sessionId exists — verifying the method returns empty string. This path is handled correctly in the code (contextId != null check) but has no test.


@Test
@DisplayName("Should use contextId as sessionId when contextId is present")
void testSessionIdFromContextId() throws JSONRPCError {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

[nitpick] Test code duplication: The three test cases share extensive mock setup boilerplate (MessageSendParams mock, AtomicReference<AgentRequestOptions> capture, mockAgentRunner.stream stubbing, executor.execute call). Consider extracting a private helper method like executeAndCaptureOptions(contextId, metadataMap) to reduce duplication.

@AgentScopeJavaBot AgentScopeJavaBot added bug Something isn't working area/ext/integration External protocols & middleware integrations labels Jun 19, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area/ext/integration External protocols & middleware integrations bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]:A2A在传递userId、sessionId时发送逻辑和取值逻辑不一致,导致userId、sessionId在server端丢失。

3 participants