From 25e2673cd28c144f25f72a95fdd5ca0faddc2029 Mon Sep 17 00:00:00 2001 From: Adam Weidman Date: Tue, 12 May 2026 17:28:56 -0400 Subject: [PATCH] feat(core): use composite key for remote session state --- .../src/agents/remote-session-invocation.ts | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/packages/core/src/agents/remote-session-invocation.ts b/packages/core/src/agents/remote-session-invocation.ts index 77765cfd7d..d15e39bb6e 100644 --- a/packages/core/src/agents/remote-session-invocation.ts +++ b/packages/core/src/agents/remote-session-invocation.ts @@ -18,6 +18,7 @@ import { type AgentInputs, type SubagentProgress, SubagentState, + getRemoteAgentTargetUrl, } from './types.js'; import { type AgentLoopContext } from '../config/agent-loop-context.js'; import type { MessageBus } from '../confirmation-bus/message-bus.js'; @@ -53,6 +54,15 @@ export class RemoteSessionInvocation extends BaseToolInvocation< { contextId?: string; taskId?: string } >(); + /** + * Builds a composite key for the sessionState map. + * Format: `name::targetUrl` (or just `name` if no URL can be derived). + */ + private static sessionKey(definition: RemoteAgentDefinition): string { + const url = getRemoteAgentTargetUrl(definition); + return url ? `${definition.name}::${url}` : definition.name; + } + private readonly _onAgentEvent?: (event: AgentEvent) => void; constructor( @@ -107,9 +117,8 @@ export class RemoteSessionInvocation extends BaseToolInvocation< const agentName = this.definition.displayName ?? this.definition.name; // Seed session with prior A2A conversation state - const priorState = RemoteSessionInvocation.sessionState.get( - this.definition.name, - ); + const stateKey = RemoteSessionInvocation.sessionKey(this.definition); + const priorState = RemoteSessionInvocation.sessionState.get(stateKey); const session = new RemoteSubagentSession( this.definition, this.context, @@ -216,7 +225,7 @@ export class RemoteSessionInvocation extends BaseToolInvocation< } finally { // Persist A2A state for next invocation — even on abort/error RemoteSessionInvocation.sessionState.set( - this.definition.name, + stateKey, session.getSessionState(), ); _signal.removeEventListener('abort', abortListener);