Skip to content

feat(core): add LocalSessionInvocation#26665

Merged
adamfweidman merged 18 commits into
mainfrom
agent-session/local-invocation
May 18, 2026
Merged

feat(core): add LocalSessionInvocation#26665
adamfweidman merged 18 commits into
mainfrom
agent-session/local-invocation

Conversation

@adamfweidman
Copy link
Copy Markdown
Contributor

@adamfweidman adamfweidman commented May 7, 2026

Summary

Implements LocalSessionInvocation to enable session-based local subagent invocation, wrapping LocalAgentExecutor behind AgentProtocol. This branch is stacked on top of the refactor/subagent-progress-enums branch.

Details

  • Added LocalSessionInvocation class in packages/core/src/agents/local-session-invocation.ts.
  • Integrated with the AgentProtocol interface to abstract local execution.
  • Added comprehensive unit tests in local-session-invocation.test.ts.

Related Issues

Progress towards #22700

How to Validate

Run the unit tests:

npx vitest run packages/core/src/agents/local-session-invocation.test.ts

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 7, 2026 19:21
@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 introduces a new infrastructure for managing subagent sessions, specifically adding LocalSessionInvocation for local agents and defining standardized protocols to encapsulate agent execution logic. These changes are part of the broader ADK integration effort to unify how different agent types interact with the core system, ensuring consistent handling of streaming activity and execution results.

Highlights

  • LocalSessionInvocation: Added a new class to handle session-based local subagent execution, providing a bridge for streaming activity and result formatting.
  • Subagent Protocols: Introduced RemoteSubagentProtocol and LocalSubagentProtocol to standardize communication patterns across different agent types.
  • ADK Integration: Refactored agent communication patterns to support the ongoing ADK migration effort.
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.

@gemini-cli
Copy link
Copy Markdown
Contributor

gemini-cli Bot commented May 7, 2026

Hi @adamfweidman, thank you so much for your contribution to Gemini CLI! We really appreciate the time and effort you've put into this.

We're making some updates to our contribution process to improve how we track and review changes. Please take a moment to review our recent discussion post: Improving Our Contribution Process & Introducing New Guidelines.

Key Update: Starting January 26, 2026, the Gemini CLI project will require all pull requests to be associated with an existing issue. Any pull requests not linked to an issue by that date will be automatically closed.

Thank you for your understanding and for being a part of our community!

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 LocalSessionInvocation and RemoteSubagentProtocol to manage local and remote subagent executions via session-based protocols, including progress streaming and abort handling. Comprehensive unit tests for these new components are also added. Feedback identifies that LocalSessionInvocation lacks nullish checks when accessing activity data, which could display 'undefined' in the UI, and notes that THOUGHT_CHUNK updates should append content instead of overwriting it to maintain the full thought history.

Comment thread packages/core/src/agents/local-session-invocation.ts Outdated
Comment thread packages/core/src/agents/local-session-invocation.ts
@gemini-cli gemini-cli Bot added the status/need-issue Pull requests that need to have an associated issue. label May 7, 2026
@adamfweidman adamfweidman force-pushed the agent-session/local-protocol branch from 33ed68f to 5cb3bd5 Compare May 8, 2026 18:27
Base automatically changed from agent-session/local-protocol to main May 8, 2026 19:43
@adamfweidman adamfweidman requested review from a team as code owners May 12, 2026 04:09
@adamfweidman adamfweidman force-pushed the agent-session/local-invocation branch from c6e26af to 07e94be Compare May 12, 2026 04:12
@github-actions
Copy link
Copy Markdown

github-actions Bot commented May 12, 2026

Size Change: -386 B (0%)

Total Size: 33.8 MB

Filename Size Change
./bundle/chunk-47QARUE7.js 0 B -2.78 MB (removed) 🏆
./bundle/chunk-GKUXJ5DK.js 0 B -19.5 kB (removed) 🏆
./bundle/chunk-JHVACMSL.js 0 B -3.43 kB (removed) 🏆
./bundle/chunk-ON54WSZP.js 0 B -49.2 kB (removed) 🏆
./bundle/chunk-QBB2LVA3.js 0 B -3.77 kB (removed) 🏆
./bundle/chunk-UJDVUFYH.js 0 B -16.5 MB (removed) 🏆
./bundle/chunk-X6FZ2CDR.js 0 B -12.5 kB (removed) 🏆
./bundle/chunk-YZK33LDU.js 0 B -659 kB (removed) 🏆
./bundle/core-4DPAZXHV.js 0 B -49.1 kB (removed) 🏆
./bundle/devtoolsService-DEKBO2LJ.js 0 B -28 kB (removed) 🏆
./bundle/gemini-CJTNRCHS.js 0 B -586 kB (removed) 🏆
./bundle/interactiveCli-SH7UBMZI.js 0 B -1.3 MB (removed) 🏆
./bundle/liteRtServerManager-JDXEVYRX.js 0 B -2.08 kB (removed) 🏆
./bundle/oauth2-provider-ICBXMBJX.js 0 B -9.12 kB (removed) 🏆
./bundle/chunk-36GHQF47.js 2.78 MB +2.78 MB (new file) 🆕
./bundle/chunk-3CSIIYAW.js 3.77 kB +3.77 kB (new file) 🆕
./bundle/chunk-4TCIWBJM.js 49.2 kB +49.2 kB (new file) 🆕
./bundle/chunk-A42T6XAP.js 16.5 MB +16.5 MB (new file) 🆕
./bundle/chunk-HDUBSJCD.js 659 kB +659 kB (new file) 🆕
./bundle/chunk-KQYFQOYY.js 12.5 kB +12.5 kB (new file) 🆕
./bundle/chunk-UMLLQLC7.js 19.5 kB +19.5 kB (new file) 🆕
./bundle/chunk-USS6MLIQ.js 3.43 kB +3.43 kB (new file) 🆕
./bundle/core-OXRORHFC.js 49.1 kB +49.1 kB (new file) 🆕
./bundle/devtoolsService-253RNH7V.js 28 kB +28 kB (new file) 🆕
./bundle/gemini-TD4BBTU2.js 586 kB +586 kB (new file) 🆕
./bundle/interactiveCli-IPZPKUKM.js 1.3 MB +1.3 MB (new file) 🆕
./bundle/liteRtServerManager-NW6SE4GQ.js 2.08 kB +2.08 kB (new file) 🆕
./bundle/oauth2-provider-MYIWADKJ.js 9.12 kB +9.12 kB (new file) 🆕
ℹ️ View Unchanged
Filename Size Change
./bundle/bundled/third_party/index.js 8 MB 0 B
./bundle/chunk-34MYV7JD.js 2.45 kB 0 B
./bundle/chunk-5AUYMPVF.js 858 B 0 B
./bundle/chunk-5PS3AYFU.js 1.18 kB 0 B
./bundle/chunk-664ZODQF.js 124 kB 0 B
./bundle/chunk-CTHYVDCX.js 39.8 kB 0 B
./bundle/chunk-DAHVX5MI.js 206 kB 0 B
./bundle/chunk-IUUIT4SU.js 56.5 kB 0 B
./bundle/cleanup-HLPJZRP3.js 0 B -902 B (removed) 🏆
./bundle/devtools-36NN55EP.js 696 kB 0 B
./bundle/dist-JYLQM7LS.js 373 B 0 B
./bundle/events-XB7DADIJ.js 418 B 0 B
./bundle/examples/hooks/scripts/on-start.js 188 B 0 B
./bundle/examples/mcp-server/example.js 1.43 kB 0 B
./bundle/gemini.js 5.07 kB 0 B
./bundle/getMachineId-bsd-TXG52NKR.js 1.55 kB 0 B
./bundle/getMachineId-darwin-7OE4DDZ6.js 1.55 kB 0 B
./bundle/getMachineId-linux-SHIFKOOX.js 1.34 kB 0 B
./bundle/getMachineId-unsupported-5U5DOEYY.js 1.06 kB 0 B
./bundle/getMachineId-win-6KLLGOI4.js 1.72 kB 0 B
./bundle/multipart-parser-KPBZEGQU.js 11.7 kB 0 B
./bundle/node_modules/@google/gemini-cli-devtools/dist/client/main.js 222 kB 0 B
./bundle/node_modules/@google/gemini-cli-devtools/dist/src/_client-assets.js 229 kB 0 B
./bundle/node_modules/@google/gemini-cli-devtools/dist/src/index.js 13.4 kB 0 B
./bundle/node_modules/@google/gemini-cli-devtools/dist/src/types.js 132 B 0 B
./bundle/sandbox-macos-permissive-open.sb 890 B 0 B
./bundle/sandbox-macos-permissive-proxied.sb 1.31 kB 0 B
./bundle/sandbox-macos-restrictive-open.sb 3.36 kB 0 B
./bundle/sandbox-macos-restrictive-proxied.sb 3.56 kB 0 B
./bundle/sandbox-macos-strict-open.sb 4.82 kB 0 B
./bundle/sandbox-macos-strict-proxied.sb 5.02 kB 0 B
./bundle/src-QVCVGIUX.js 47 kB 0 B
./bundle/start-GIZ6HWR3.js 0 B -622 B (removed) 🏆
./bundle/tree-sitter-7U6MW5PS.js 274 kB 0 B
./bundle/tree-sitter-bash-34ZGLXVX.js 1.84 MB 0 B
./bundle/cleanup-AXGEUNTA.js 902 B +902 B (new file) 🆕
./bundle/start-JLKXQJ5D.js 622 B +622 B (new file) 🆕

compressed-size-action

adamfweidman and others added 10 commits May 12, 2026 13:44
… invocation

New invocation class that delegates to LocalSubagentSession instead of
directly using LocalAgentExecutor. Existing LocalSubagentInvocation is
untouched — this will be wired in behind a feature flag in a later PR.
Use typeof check and trim to avoid displaying 'undefined' for missing properties in THOUGHT_CHUNK, TOOL_CALL_START, TOOL_CALL_END, and ERROR events.

TAG=agy
CONV=d4b1d79a-226d-4301-8d60-bdb5d4701569
@adamfweidman adamfweidman changed the base branch from main to refactor/subagent-progress-enums May 12, 2026 19:10
@adamfweidman adamfweidman changed the title feat(core): add LocalSessionInvocation and SubagentProtocols feat(core): add LocalSessionInvocation May 12, 2026
@adamfweidman
Copy link
Copy Markdown
Contributor Author

/gemini review

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 the LocalSessionInvocation class and its corresponding unit tests. LocalSessionInvocation orchestrates subagent execution, manages progress updates, and tracks activities like thoughts and tool calls. The review feedback highlights several critical security and logic improvements: sanitizing input parameters and error messages to prevent data leakage and prompt injection, correctly appending streaming thought chunks rather than replacing them, and utilizing unique call identifiers instead of names to reliably track parallel tool executions.

Comment thread packages/core/src/agents/local-session-invocation.ts
Comment thread packages/core/src/agents/local-session-invocation.ts
Comment thread packages/core/src/agents/local-session-invocation.ts
Comment thread packages/core/src/agents/local-session-invocation.ts
Comment thread packages/core/src/agents/local-session-invocation.ts
Comment thread packages/core/src/agents/local-session-invocation.ts
Comment thread packages/core/src/agents/local-session-invocation.ts Outdated
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 the LocalSessionInvocation class and a comprehensive test suite to handle local subagent execution via LocalSubagentSession. The implementation manages activity streaming for thoughts and tool calls, progress updates, and lifecycle management including abort and error handling. Feedback focuses on security enhancements to prevent prompt injection by sanitizing tool arguments and avoiding user-controlled error messages in llmContent. Additionally, a correction was suggested for the THOUGHT_CHUNK handling to ensure streaming deltas are appended rather than overwritten.

Comment thread packages/core/src/agents/local-session-invocation.ts
Comment thread packages/core/src/agents/local-session-invocation.ts
Comment thread packages/core/src/agents/local-session-invocation.ts Outdated
@jacob314
Copy link
Copy Markdown
Contributor

This review was performed by /review-frontend with manual review by Jacob. Note that review-frontend also noted that LocalSessionInvocation and LocalSubagentInvocation are nearly identical but I am assuming that is intentional.

Findings & Feedback

1. THOUGHT_CHUNK Streaming Bugs

There are two issues in the THOUGHT_CHUNK handler within local-session-invocation.ts:

  • Overwriting vs. Appending: lastItem.content = sanitizeThoughtContent(text); overwrites the content with the latest chunk. Since streaming chunks are typically deltas, this will cause the UI to only show the most recent fragment rather than the full thought. It should append the sanitized chunk instead.
  • Whitespace Trimming: Calling .trim() on each incoming chunk will strip intended leading/trailing spaces (e.g., words being smashed together). Trimming should likely only happen on the final result, not on individual stream chunks.

2. Missing Exhaustive Checks

The switch (activity.type) block in onActivity is missing a checkExhaustive call in the default case. Per the project's strict development rules, all switches on enums or discriminated unions should use this pattern to ensure compile-time safety.

3. Inconsistent State Handling

  • String Literals vs. Enums: The code inconsistently checks against the string literal 'running' (e.g., line 128) and the enum SubagentState.RUNNING (e.g., line 167). Please use the enum consistently.
  • execute Return Type: The llmContent property in the returned ToolResult is sometimes a Part[] (on success) and sometimes a string (on error). For consistency with other core services, it is recommended to always return Part[].

4. Registry & Integration

LocalSessionInvocation is added and tested but doesn't appear to be registered in AgentRegistry or utilized by AgentTool yet. If this is a staged rollout, that's fine, but please confirm if integration was introduced for this PR.

5. content-utils.ts Fallback

The PR includes changes to content-utils.ts to warn and serialize unknown ContentPart types instead of throwing. While this prevents crashes, it bypasses the type safety we usually aim for with checkExhaustive. Given the importance of these conversions, consider if we should instead be adding the missing types to the union or using a stricter exhaustive check during development.

@adamfweidman
Copy link
Copy Markdown
Contributor Author

  1. This mirrors existing behavior:

    lastItem.content = sanitizeThoughtContent(text);

  2. good catch! added.

  3. Valid. Addressed.

  4. Integrated in feat(core): wire AgentSession invocations into agent-tool #26948

  5. Will add typesafety check in followup PR. I think allowing runtime safety here is good. Added in fix(core): enforce compile-time exhaustiveness in content-utils #27207.

@github-actions
Copy link
Copy Markdown

github-actions Bot commented May 18, 2026

69 tests passed successfully on gemini-3-flash-preview.

🧠 Model Steering Guidance

This PR modifies files that affect the model's behavior (prompts, tools, or instructions).

  • ⚠️ Consider adding Evals: No behavioral evaluations (evals/*.eval.ts) were added or updated in this PR. Consider adding a test case to verify the new behavior and prevent regressions.
  • 🚀 Maintainer Reminder: Please ensure that these changes do not regress results on benchmark evals before merging.

This is an automated guidance message triggered by steering logic signatures.

Comment thread packages/core/src/agent/content-utils.test.ts
Comment thread packages/core/src/agents/local-session-invocation.test.ts Outdated
Comment thread packages/core/src/agents/local-session-invocation.ts Outdated
Comment thread packages/core/src/agents/local-session-invocation.ts Outdated
Comment thread packages/core/src/agents/local-session-invocation.ts Outdated
Copy link
Copy Markdown
Contributor

@jacob314 jacob314 left a comment

Choose a reason for hiding this comment

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

Approved with some nits.lgtm

…se year, description truncation, callId parallel tracking)
@adamfweidman adamfweidman force-pushed the agent-session/local-invocation branch from 7d5d1c5 to af3aadd Compare May 18, 2026 19:12
@adamfweidman adamfweidman enabled auto-merge May 18, 2026 19:18
@adamfweidman adamfweidman added this pull request to the merge queue May 18, 2026
Merged via the queue into main with commit 6973b96 May 18, 2026
28 of 29 checks passed
@adamfweidman adamfweidman deleted the agent-session/local-invocation branch May 18, 2026 19:45
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.

2 participants