Skip to content

feat(skills): add SkillDiscoveryMode to skip the discovery turn - #7093

Closed
thomaslprr wants to merge 4 commits into
google:mainfrom
thomaslprr:feat/include-list-skills
Closed

thomaslprr wants to merge 4 commits into
google:mainfrom
thomaslprr:feat/include-list-skills

Conversation

@thomaslprr

@thomaslprr thomaslprr commented Sep 11, 2026

Copy link
Copy Markdown

Link to Issue or Description of Change

1. Link to an existing issue (if applicable):

Problem:
There is no public way to inject the L1 skill catalog into the system instruction. Hiding list_skills required mutating _tools.

Solution:
Add SkillToolset(discovery_mode=SkillDiscoveryMode.EAGER|LAZY).

  • LAZY (default): expose list_skills.
  • EAGER: hide list_skills and inject <available_skills> XML so the model can call load_skill directly.
    Non-enum values raise TypeError.

Testing Plan

Unit Tests:

  • I have added or updated unit tests for my change.
  • All unit tests pass locally.
.venv/bin/python -m pytest tests/unittests/tools/test_skill_toolset.py -q
# 159 passed

Manual End-to-End (E2E) Tests:

  • Local sample based on contributing/samples/environment_and_skills/skills_agent with discovery_mode=SkillDiscoveryMode.EAGER:
    • no list_skills tool
    • <available_skills> present in the system instruction (greeting-skill, weather-skill)
    • agent can call load_skill directly
  • Default LAZY still exposes list_skills.
  • With a registry, search_skills remains available in EAGER.

Checklist

  • I have read the CONTRIBUTING.md document.
  • I have performed a self-review of my own code.
  • 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.

Expose a public flag so the L1 catalog can be injected into the
system instruction without mutating SkillToolset._tools.
Fixes google#7092
@google-cla

google-cla Bot commented Sep 11, 2026

Copy link
Copy Markdown

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.

@wukath

wukath commented Sep 11, 2026

Copy link
Copy Markdown
Collaborator

Hi @thomaslprr, thanks for the PR! We like the idea of skipping the discovery turn, but we reshaped it slightly to use an enum (discovery_mode=SkillDiscoveryMode.EAGER vs LAZY) since omitting list_skills has the major side effect of injecting the catalog into the system prompt. We kept your core logic and all your tests -- would this approach work for you?

@thomaslprr

thomaslprr commented Sep 12, 2026

Copy link
Copy Markdown
Author

Hi @thomaslprr, thanks for the PR! We like the idea of skipping the discovery turn, but we reshaped it slightly to use an enum (discovery_mode=SkillDiscoveryMode.EAGER vs LAZY) since omitting list_skills has the major side effect of injecting the catalog into the system prompt. We kept your core logic and all your tests -- would this approach work for you?

Hi @wukath, yes, that works for me - discovery_mode=SkillDiscoveryMode.EAGER|LAZY is clearer than a boolean given the system-prompt side effect. Happy for you to land it that way. Thanks!

Would you like me to update this PR to the enum API, or will you land the reshaped version on your side? I already have the changes ready locally if you'd like me to push them.

thomaslprr and others added 2 commits September 12, 2026 21:47
Use discovery_mode=EAGER|LAZY so the API names the coupled behavior
(hide list_skills + inject <available_skills>). Reject non-enum values
with TypeError.

Fixes google#7092
@thomaslprr thomaslprr changed the title feat(skills): add include_list_skills to skip the discovery turn feat(skills): add SkillDiscoveryMode to skip the discovery turn Sep 14, 2026
@thomaslprr

Copy link
Copy Markdown
Author

@wukath, I pushed the enum reshape as discussed:

  • discovery_mode=SkillDiscoveryMode.LAZY (default): keep list_skills
  • discovery_mode=SkillDiscoveryMode.EAGER: hide list_skills and inject <available_skills>
  • non-enum values raise TypeError

Core logic and tests are updated (159 passed locally). I also set up a local ADK sample based on skills_agent with discovery_mode=EAGER and confirmed the agent run path: no list_skills, catalog injected, load_skill available. Ready for another look.

Thanks!

copybara-service Bot pushed a commit that referenced this pull request Sep 14, 2026
… is disclosed

Merge #7093

By default, SkillToolset provides the `list_skills` tool, which requires the
model to spend an extra turn discovering available skills before calling
`load_skill`. For small, static skill sets, this discovery turn adds latency
and token overhead.

This change introduces `SkillDiscoveryMode` to control catalog disclosure:
- `LAZY` (default): Retains the `list_skills` tool so skills are discovered on
  demand. The system instruction remains free of skill listings.
- `EAGER`: Omits `list_skills` and injects the local catalog directly into the
  system instruction as `<available_skills>` XML, allowing the model to call
  `load_skill` immediately.

Additionally, deprecates using `tool_filter` to hide `list_skills` as a way to
trigger prompt injection. Filtering tools should not implicitly rewrite the
system prompt; callers should pass `discovery_mode=SkillDiscoveryMode.EAGER`
instead.

Fixes #7092

Co-authored-by: Thomas Lapierre <thomaslapierre.dev@gmail.com>

Co-authored-by: Kathy Wu <wukathy@google.com>
PiperOrigin-RevId: 981254533
@adk-bot

adk-bot commented Sep 14, 2026

Copy link
Copy Markdown
Collaborator

Thank you @thomaslprr for your contribution! 🎉

Your changes have been successfully imported and merged via Copybara in commit 3d3c1d9.

Closing this PR as the changes are now in the main branch.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

merged [Status] This PR is merged

Projects

None yet

Development

Successfully merging this pull request may close these issues.

feat(skills): add include_list_skills to inject the L1 catalog without list_skills

3 participants