Add Kotlin snippets to the custom tools page, including toolset filtering - #2114
Conversation
The Toolsets section had no Kotlin. ToolFilter and ToolPredicate arrived in
adk-kotlin 0.7.0 and give Kotlin something the other languages do not have: a
filter that receives the ReadonlyContext, so a toolset's tool list can depend on
session state or the current user.
The Python tab in the Simple Math Toolset example only gestures at this, in a
commented-out branch inside get_tools(). This snippet implements it, showing all
three states: no filter selects everything, allowList selects by name, and a
Predicate decides per invocation.
Placed in its own subsection rather than as a fourth tab on the Simple Math
Toolset example. That group is one worked example explained by five bullets --
an agent, a greet tool, name prefixing, a tool_context.state write and close() --
and a filtering snippet satisfies none of them. Kotlin cannot satisfy the prefix
bullet at all, since BaseTool.name is a val and adk-kotlin has no prefix
mechanism. A tab there would have left readers with four bullets that do not
describe the code above them.
Transcluded, so CI compiles and lints it. Verified beyond compiling: the tools
are generated by KSP, filtering returns the expected sets for all three cases,
and the tool bodies run -- addNumbers(7,3) -> {result=10}.
✅ Deploy Preview for adk-docs-preview ready!
To edit notification comments on pull requests, go to your Netlify project configuration. |
wikaaaaa
left a comment
There was a problem hiding this comment.
Thanks, I checked the snippet against adk-kotlin v0.7.0 and the code is correct.
Just a comment to the PRs justification -- "gives Kotlin a capability the other languages don't have" isn't accurate. Context-aware tool filtering exists in other languages, ex. Python
Out of scope for this PR, but none of the other snippets in this file include Kotlin — should we add them?
… to ADK documentation
|
Thanks @wikaaaaa — both points addressed, and you were right on the first one. On "a capability the other languages don't have"Wrong, and I've corrected it. Python's More importantly, that claim had leaked into the page, not just the description. A single-language badge asserts exclusivity in this repo — the Python-only precedent I cited in the description ( Fixed by scoping the heading to the API rather than the concept: "Filtering which tools a toolset exposes with On the other snippets — done, all of themThe page had six language tab groups and not one had Kotlin. All six do now:
All transcluded, so CI compiles and lints them. Also fixed the These are execution-verified, not just compiled. I wired a temporary harness with a real
What I deliberately left out
Heads up that this outgrew the PR title, which I'll update along with the description. Happy to split the five backfilled snippets into their own PR if you'd rather review them separately from the |
…ilter # Conflicts: # tools/kotlin-snippets/files_to_test.txt
wikaaaaa
left a comment
There was a problem hiding this comment.
Thanks for filling in the other snippets!
…ilter # Conflicts: # tools/kotlin-snippets/files_to_test.txt
Technical review reportVerification method — the PR is entirely Kotlin, so verified against google/adk-kotlin Code: technically correct. Every API the six snippets use exists with the signature used — cited with line numbers in the artifact. Key ones:
[] Also flagged: the |
|
Follow up item from technical review: filed b/548652184 PR claims
That undercuts the reason given for making it a Kotlin-only subsection instead of a four-tab one. |
joefernandez
left a comment
There was a problem hiding this comment.
Approved with comments
Conflict in tools/kotlin-snippets/files_to_test.txt: main appended snippets/a2a/A2AConsumer.kt (#2118) while this branch appended its six snippets/tools/overview/ registrations at the same spot. Kept both, main's line first. Checked the merged tree for silent breakage as well, since main moved to adk-kotlin 0.8.0 (#2143) under this branch's snippets: ToolFilter, isToolSelected and Toolset are byte-identical between 0.7.0 and 0.8.0, and these snippets use BaseTool only as a return type, not as a supertype.
adk-kotlin 0.8.0 widened `BaseTool.run`'s args from `Map<String, Any>` to `Map<String, Any?>`, so the override in this snippet overrides nothing and the class no longer implements its abstract member. `compileKotlin` fails with "'run' overrides nothing" at MultiAgentExample.kt:61. The break arrived on main with the 0.8.0 bump in #2143, not from this branch. It surfaces here because the snippet runner builds the whole examples project, while that PR's own check only compiled the files it changed - and it changed no .kt files at all. Fixing it here because it blocks this PR; it is one character and unrelated to the toolset filtering content.
Four things from joefernandez's review: - Heading shortened to "Filter tools in toolsets" as suggested. - That shorter heading is conceptual, and the subsection carries a Kotlin-only badge, which would repeat the exclusivity claim his b/548652184 is about. Python, Java and TypeScript all filter toolsets by name or by a context-aware predicate on BaseToolset, so the section now says so in a sentence and the badge's title scopes the version to the Kotlin ToolFilter API rather than to filtering as a concept. - Page badge Kotlin v0.7.0 -> v0.1.0, and the Toolsets badge likewise. @tool, ToolContext and Toolset all exist at the v0.1.0 tag; only ToolFilter is new in v0.7.0, and function-tools.md already carries v0.1.0. - The Toolsets badge's bare "Java" span now reads v0.3.0, the first adk-java release containing BaseToolset (added in a211ac4c, tagged v0.3.0).
|
All four addressed in 840b9b0: heading shortened, badges corrected to v0.1.0 (Java v0.3.0), exclusivity claim dropped, description rewritten. Thanks for the catch. |
Summary
docs/tools-custom/index.mdhad six language tab groups and not one carriedKotlin. All six do now, plus a subsection on filtering a toolset's tools with
ToolFilter, which is genuinely new in adk-kotlin 0.7.0.WeatherSentiment.ktUserPreferenceTools.ktCustomerSupport.ktDocAnalysisTools.ktOrderTools.ktToolsetExample.kt:initToolsetExample.kt:filterAll transcluded, so CI compiles and lints every one of them.
Corrections made during review
ToolFilteris not a Kotlin-only capability. An earlier version of thisdescription, and of the page, said Python and TypeScript had no equivalent. They
do — Python's
BaseToolsettakestool_filter: Optional[Union[ToolPredicate, List[str]]]withreadonly_context, and Java and TypeScript match it;b/548652184 tracks the substance.
The subsection is still Kotlin-only in its code, but the heading is now the
plain "Filter tools in toolsets", the prose says outright that every SDK can do
this, and the badge's
titlescopes the version to the Kotlin API rather than tofiltering as a concept.
Badge versions were wrong. The page badge and the
## Toolsetsbadge bothclaimed Kotlin v0.7.0;
@Tool,ToolContextandToolsetall exist at thev0.1.0 tag, so both now read v0.1.0 — matching
function-tools.md. Only thefiltering subsection keeps v0.7.0, which is the release
ToolFilterlanded in.The
## Toolsetsbadge also had a bareJavaspan with no version; it now readsv0.3.0, the first adk-java release containing
BaseToolset.The
## Toolsetsbadge is rewritten by this PR — an earlier revision of thisdescription said it was untouched, which was wrong: commit
098bf00breplacedits stale
title="…available for Python and TypeScript"(stale because a Javatab already existed) and added the Java and Kotlin spans.
One unrelated fix, carried because it blocks CI
MultiAgentExample.ktoverrodeBaseTool.run(context, args: Map<String, Any>).adk-kotlin 0.8.0 widened that to
Map<String, Any?>, so the override compilesno more. The break came in with the 0.8.0 bump in #2143, not from this branch —
it surfaces here because the snippet runner builds the whole examples project,
while #2143 changed no
.ktfiles and so compiled nothing. One character.Notes for reviewers
McpToolsetConfig.toolFilterwentList<String>?(v0.6.0) →ToolFilter?(v0.7.0).
Math Toolset group. That group is one worked example explained by five bullets
— agent,
greet_tool, name prefixing, atool_context.statewrite,close()— and a filtering snippet satisfies none of them. Kotlin cannot satisfy the
prefix bullet at all:
BaseTool.nameis aval. A bullet now explains thatdeviation instead of leaving readers with prose that doesn't match the code.
search_memoryin the artifacts snippet (not onKotlin's
ToolContext; it lives onMemoryService, and the Java tab omits ittoo).
Verification
./gradlew compileKotlinclean; ktlint clean;check_kotlin_snippets.shpasses.
with a real
ToolContext:main()entry points need credentials, sothey are compile-verified only.