Skip to content

feat(core): wire AgentSession invocations into agent-tool#26948

Open
adamfweidman wants to merge 8 commits into
experimental-flagfrom
agent-session/agent-tool
Open

feat(core): wire AgentSession invocations into agent-tool#26948
adamfweidman wants to merge 8 commits into
experimental-flagfrom
agent-session/agent-tool

Conversation

@adamfweidman
Copy link
Copy Markdown
Contributor

@adamfweidman adamfweidman commented May 12, 2026

Summary

Wires AgentSession invocations into AgentTool behind the adk.agentSessionSubagentEnabled feature flag.

Details

  • Updated packages/core/src/agents/agent-tool.ts to check context.config.isAgentSessionEnabled().
  • If the flag is enabled, it uses RemoteSessionInvocation and LocalSessionInvocation for subagent calls.
  • This branch is stacked on top of experimental-flag.

Related Issues

Relates to #22700

How to Validate

Verified that the codebase builds successfully. Unit tests for agent-tool should be run to confirm behavior.

Pre-Merge Checklist

  • Updated relevant documentation and README (if needed)
  • Added/updated tests (if needed)
  • Noted breaking changes (if any)
  • Validated on required platforms/methods:
    • MacOS
      • npm run
      • npx
      • Docker
      • Podman
      • Seatbelt

@adamfweidman adamfweidman requested a review from a team as a code owner May 12, 2026 21:13
@gemini-code-assist
Copy link
Copy Markdown
Contributor

Summary of Changes

Hello, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request enables AgentSession support within the AgentTool framework, allowing for more robust subagent interactions behind a feature flag. It also includes critical improvements to session state management for remote agents and adds validation logic to the AgentRegistry to prevent and surface duplicate agent name conflicts.

Highlights

  • Feature Flag Integration: Integrated AgentSession invocations into AgentTool, gated by the adk.agentSessionSubagentEnabled feature flag.
  • Session State Isolation: Updated RemoteSessionInvocation to use a composite key (name::url) for session state, ensuring agents with identical names but different endpoints maintain independent state.
  • Registry Validation: Enhanced AgentRegistry to emit warnings and feedback events when duplicate agent names are registered, improving configuration debugging.
  • Event Threading: Updated AgentTool and DelegateInvocation to correctly thread onAgentEvent callbacks to session invocations.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize the Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counterproductive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for GitHub and other Google products, sign up here.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

@adamfweidman adamfweidman force-pushed the agent-session/agent-tool branch from 6833fa1 to 926a4e3 Compare May 12, 2026 21:21
Copy link
Copy Markdown
Contributor

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request implements session-based subagent invocations, gated by a feature flag, and adds a warning mechanism for duplicate agent names in the registry. It also updates remote session state management to use a composite key of name and URL. Review feedback highlights security concerns and potential memory leaks regarding the use of a static map for session state, suggesting a refactor to session-scoped storage or an LRU cache. Additionally, a redundant method definition in the configuration class was identified for removal.

I am having trouble creating individual review comments. Click here to see my feedback.

packages/core/src/agents/remote-session-invocation.ts (62-65)

security-high high

The sessionKey method generates a key for the static sessionState Map using only the agent name and URL, but it omits the sessionId. Because sessionState is a static member, it is shared across all instances of RemoteSessionInvocation within the same process. In multi-tenant environments (e.g., if this core library is used in a server-side application), this will cause different user sessions to share the same A2A conversation state (contextId and taskId) if they invoke the same remote agent. This leads to session collision or hijacking, where one user could inadvertently continue or access another user's conversation.

To remediate this, the sessionId should be incorporated into the session key to ensure that conversation state is isolated per session. This will require passing the AgentLoopContext to the sessionKey method.

References
  1. Avoid module-level global variables for state to prevent race conditions in concurrent environments. Instead, use instance-scoped properties, such as within a session class, for state that is primarily used within that scope.

packages/core/src/agents/remote-session-invocation.ts (53-56)

high

The use of a static Map for sessionState violates the general rule against module-level global variables for state. This implementation poses a memory leak risk in long-running processes as the map grows indefinitely with every unique agent/URL combination. More critically, it introduces a security vulnerability in multi-session or concurrent environments (such as a server) where A2A conversation state (contextId, taskId) could leak between different users or sessions sharing the same process.

Please refactor this to use session-scoped state (e.g., stored within the Config or a session-scoped service) or, at minimum, use a standard LRUCache with a reasonable size limit to mitigate memory issues.

References
  1. Avoid module-level global variables for state like caches to prevent race conditions and memory issues in concurrent environments. Instead, use session-scoped or instance-scoped state and leverage standard cache implementations like LRUCache.
  2. For caching, use the existing LruCache dependency instead of clearing the entire cache or implementing a custom LRU policy.

packages/core/src/config/config.ts (2584-2586)

high

The method isAgentSessionEnabled is redundantly defined here. It is already present in the class at line 2560. Please remove this duplicate definition to maintain code clarity and avoid confusion.

Copy link
Copy Markdown
Contributor

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request introduces session-based agent invocations gated by a feature flag and adds duplicate agent name detection to the registry. It also updates remote session state management to use composite keys for improved isolation. Feedback identifies a critical security risk where the use of static maps for session state could lead to data leakage between concurrent sessions. Furthermore, the reviewer pointed out redundant and duplicate methods in the configuration class that should be consolidated.

I am having trouble creating individual review comments. Click here to see my feedback.

packages/core/src/agents/remote-session-invocation.ts (121-122)

security-high high

The RemoteSessionInvocation class uses a static Map named sessionState to persist A2A (Agent-to-Agent) conversation state. Because the map is static, it is shared across all instances within the same process, leading to state leakage between sessions in concurrent environments. Move the sessionState map to a session-scoped object, such as the Config instance or the AgentLoopContext.

References
  1. Avoid module-level global variables for state like caches to prevent race conditions and memory issues in concurrent environments. Instead, use session-scoped or instance-scoped state and leverage standard cache implementations like LRUCache.

packages/core/src/agents/remote-session-invocation.ts (228-231)

security-high high

This line persists the A2A conversation state into a static sessionState map. Using a static map for session-specific state leads to cross-session data leakage in long-lived processes. The state should be stored in a session-scoped container to ensure isolation.

References
  1. Avoid module-level global variables for state like caches to prevent race conditions and memory issues in concurrent environments. Instead, use session-scoped or instance-scoped state and leverage standard cache implementations like LRUCache.

packages/core/src/config/config.ts (2584-2587)

high

This method is a duplicate of the one already defined at line 2560. Please consolidate this logic to avoid duplication and improve maintainability, as per the project's architectural guidelines.

References
  1. When adding new functionality, such as filtering, consolidate it with existing similar logic to avoid duplication and improve maintainability.

packages/core/src/config/config.ts (3783-3786)

high

This method is redundant as it performs the exact same logic as isAgentSessionEnabled(). Instead of maintaining redundant logic or backward compatibility for configuration settings, remove the extra getter entirely to avoid confusion.

References
  1. Instead of maintaining backward compatibility for deprecated or unshipped configuration settings, remove them and their associated logic entirely to avoid confusion.

packages/core/src/agents/remote-session-invocation.ts (53-56)

security-high high

The use of a static map for storing session state violates the rule against module-level global variables for state. This approach can lead to race conditions and data leakage in concurrent environments. This state should be moved to a session-scoped store, such as a property on the Config instance.

References
  1. Avoid module-level global variables for state like caches to prevent race conditions and memory issues in concurrent environments. Instead, use session-scoped or instance-scoped state and leverage standard cache implementations like LRUCache.

Copy link
Copy Markdown
Contributor

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request introduces session-based subagent invocations and enhances the agent registry to handle duplicate agent names with warnings. Key changes include updating AgentTool to support event threading, implementing composite keys (name and URL) for remote session state isolation, and adding feature flag checks for session-enabled invocations. Review feedback identifies a critical TypeScript compilation error due to a duplicate method definition in the Config class, a security concern regarding session leakage from static state in RemoteSessionInvocation, and a logic improvement to prevent false-positive warnings in the AgentRegistry when an agent is disabled via overrides.

I am having trouble creating individual review comments. Click here to see my feedback.

packages/core/src/config/config.ts (2584-2587)

critical

The method isAgentSessionEnabled is being added here, but it is already defined earlier in the class (around line 2563 in the current branch state). This duplication will cause a TypeScript compilation error ("Duplicate identifier 'isAgentSessionEnabled'").

packages/core/src/agents/remote-session-invocation.ts (53-56)

security-high high

The sessionState Map is declared as static, which means it is shared across all instances of RemoteSessionInvocation within the same process. This Map stores A2A conversation state (such as contextId and taskId) for remote agents. In environments where the same process handles multiple user sessions or different conversations (e.g., a long-running interactive shell or a server-side deployment of the core library), this can lead to session leakage. One session could potentially retrieve or overwrite the conversation state of another session if they use a remote agent with the same name and URL. Consider moving this state to a session-scoped object like AgentLoopContext or Config.

References
  1. Avoid module-level global variables for state like caches to prevent race conditions and memory issues in concurrent environments. Instead, use session-scoped or instance-scoped state.

packages/core/src/agents/registry.ts (340-351)

high

The warning for duplicate agent names is emitted before checking if the new agent definition is actually enabled. If the later definition is disabled (via settings overrides), it will not actually override the existing one in this.agents (as registerLocalAgent/registerRemoteAgent will return early), making this warning a false positive. The check should verify enablement before emitting the feedback.

    const existing = this.agents.get(definition.name);
    const overrides = this.config.getAgentsSettings().overrides?.[definition.name];
    if (existing && existing !== definition && this.isAgentEnabled(definition, overrides)) {
      coreEvents.emitFeedback(
        'warning',
        'Duplicate agent name \'' + definition.name + '\' detected. ' +
          'The later definition will override the earlier one. ' +
          'Rename one of the agents to avoid this conflict.',
      );
      debugLogger.warn(
        '[AgentRegistry] Overriding agent \'' + definition.name + '\' — duplicate name from a different definition.',
      );
    }

@adamfweidman adamfweidman force-pushed the agent-session/agent-tool branch from 926a4e3 to 0dcda82 Compare May 12, 2026 21:29
@adamfweidman adamfweidman force-pushed the agent-session/agent-tool branch from 0dcda82 to 755885f Compare May 12, 2026 21:32
@gemini-cli gemini-cli Bot added the status/need-issue Pull requests that need to have an associated issue. label May 12, 2026
@adamfweidman adamfweidman force-pushed the agent-session/agent-tool branch 3 times, most recently from 712c435 to 4ad0926 Compare May 12, 2026 22:05
adamfweidman and others added 8 commits May 13, 2026 14:31
Two changes:

1. RemoteSessionInvocation now uses a composite key (name::targetUrl)
   for the static sessionState map. This ensures agents with the same
   name but different endpoints maintain independent A2A state. Falls
   back to name-only when no URL can be derived.

2. AgentRegistry.registerAgent now emits a visible warning when a
   different definition tries to register under an existing name.
   Override still proceeds to preserve existing precedence order
   (user → project → extension). The warning surfaces potential
   naming conflicts to users.
…ure flag

Add agentSessionSubagentEnabled setting under experimental.adk that
routes subagent invocations through LocalSessionInvocation and
RemoteSessionInvocation instead of legacy executors. When disabled
(default), all behavior is unchanged.

- Add agentSessionSubagentEnabled to ADKSettings, Config, and settings schema
- Thread onAgentEvent callback through AgentTool → DelegateInvocation
- Route local/remote agents to session invocations when flag is enabled
- Browser agent always uses BrowserAgentInvocation regardless of flag
- Copy local protocol files needed for the session invocation path
@adamfweidman adamfweidman force-pushed the agent-session/agent-tool branch from be3b6f6 to c0981bd Compare May 13, 2026 18:33
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

status/need-issue Pull requests that need to have an associated issue.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant