* Document how to check whether the context cache was used
The caching page explained how to turn caching on and never how to tell whether
it is working. CacheMetadata has been available since adk-kotlin 0.6.0 and is
undocumented: adk-python has fourteen code references to cache_metadata, while
adk-docs mentions it twice, both incidental -- a BigQuery schema table and a
bullet in the Live dev guide.
The snippet reads it from Event.cacheMetadata and covers both states the type
can be in, because the constructor enforces the split: cacheName, expireTime and
invocationsUsed must either all be set (an active cache) or all be null (the
fingerprint-only state used for prefix matching before a cache exists).
Notes that token counts live on LlmResponse.usageMetadata rather than here,
which the KDoc calls out to avoid duplication and a reader would otherwise
reasonably look for on CacheMetadata.
Badged Kotlin v0.6.0 and verified rather than assumed: the snippet compiles
against a temporary 0.6.0 pin as well as the current 0.7.0 one.
Transcluded and registered, so CI compiles and lints it. Exercised all four
paths with synthetic events: no metadata, fingerprint-only, active, and active
with expireSoon true.
* Correct when CacheMetadata is present on an event
The section claimed every event backed by an LLM response carries a
CacheMetadata. It does not: LlmResponse.cacheMetadata is null when caching
is disabled and also when the call produced no cache information, so the
claim was wrong even with caching on.
Say "can carry", name both null cases, and explain why the snippet checks
before reading. The snippet's own comment made the same overstatement.
* docs: clarify the behavior of expireSoon and cache status in documentation and snippets
* Document createHttpOptions on the Kotlin context cache config
ContextCacheConfig gained a fourth parameter, createHttpOptions, in adk-kotlin
0.7.0. It bounds the CachedContent.create() call specifically, and is fail-open:
when the create exceeds the timeout it fails and the request proceeds uncached,
so it is a latency guard rather than a correctness switch. The snippet says so,
since that is the part the signature does not convey.
No other language documents this. Python and Java have no equivalent parameter
at all -- the Java record has exactly three components -- so this is Kotlin-first
rather than a backfill.
HttpOptions is ADK's own com.google.adk.kt.types.HttpOptions, deliberately not
the backend SDK's, so the import matters: two other types share the name.
Extracted, compiled and ran the snippet against the 0.7.0 pin: OK timeout=10s.
* docs: add create_http_options parameter documentation for cache configuration
* Add Kotlin snippet for VertexAiSessionService
The VertexAiSessionService section showed Python, Go and Java. Kotlin gained
the service in adk-kotlin 0.7.0, so add a Kotlin tab and Kotlin to that
section's language-support badge.
Kotlin addresses the reasoning engine differently from every sibling tab on
the page, so the snippet says so at the point of use:
- The engine is fixed at construction via `reasoningEngineId`. The 0.7.0 KDoc
is explicit that, unlike the Python and Java ADK, `SessionKey.appName` is
never parsed to derive the engine -- it is only a label. The Python tab
above passes the engine through `app_name` on each call.
- `reasoningEngineId` must be the bare numeric id. The constructor rejects a
full resource name outright (`require(reasoningEngineId.all { it.isDigit() })`),
while the Python tab passes
`projects/.../locations/.../reasoningEngines/...`.
A reader copying the adjacent Python idiom would therefore fail twice over.
Written inline to match the two existing Kotlin tabs on this page. Inline
snippets never reach Gradle, so this one was additionally compiled against the
0.7.0 pin in a scratch file that is not part of the commit.
* Address review: JVM-only note, wire the service to a Runner
Five fixes from self-review against the 0.7.0 sources and upstream's own
VertexAiSessionServiceExample.kt, which I should have consulted before writing
the first version:
- State that the service is JVM-only. It lives in core/src/jvmMain, so it does
not exist on Android. Kotlin is the only language on this page where that
distinction applies, so if the Kotlin tab omits it, nothing carries it.
- Show the service actually being used. The snippet stopped at an uncalled
`suspend fun`; it now hands the service to an InMemoryRunner, which is what
the section is about and what the upstream example does.
- Use `runBlocking` in a `main`, matching upstream, instead of a suspend
function nothing calls.
- Drop `state = mapOf(...)`. It defaults to null, upstream omits it, and the
Java tab explicitly notes no initial state is needed, so it introduced a
concept the sibling tabs deliberately avoid.
- Widen the comparison from "the Python and Java tabs" to all the other tabs.
The KDoc phrasing names Python and Java, but this page also has a Go tab.
The added LlmAgent needs an explicit `model`; the first draft would not have
compiled without it, which the scratch compile caught.
* Trim the snippet back to parity with the sibling tabs
The previous revision added an LlmAgent, a Gemini model and an InMemoryRunner,
taking the tab to 30 code lines against Python's 5, Go's 8 and Java's 12. No
sibling tab on this page constructs a runner or an agent, and this section's
prose never mentions one -- it is a characteristics list, not a wiring guide.
That change came from misapplying a review finding. On sessions/memory the
equivalent note was right: the prose there says "instantiating the
VertexAiMemoryBankService and passing it to the Runner" and the Python tab
shows exactly that. Neither holds here, so the runner was answering a question
this page does not ask.
Now scoped like the Java tab, the closest analogue: construct the service, then
create one session. That is still enough to demonstrate both divergences -- the
engine pinned at construction as a bare numeric id, and appName being only a
label -- since showing the second requires a SessionKey.
`runBlocking` stays, because createSession is a suspend function; it is the
direct counterpart of the Java tab's `.blockingGet()`, and the comment now says
so. Recompiled against the 0.7.0 pin in a scratch file.
* docs: update experimental annotation placement and refine context caching documentation note
* Add Kotlin snippet for context caching configuration
The context caching page showed Python and Java only. `ContextCacheConfig` and
the `App`-level wiring are available in adk-kotlin as of 0.7.0, so add a Kotlin
tab and advertise Kotlin support in the page badge.
The snippet is inline rather than transcluded to match the Python and Java tabs
on this page. It opts in at file level via `ExperimentalContextCachingFeature`,
which the API still requires, and uses `kotlin.time` durations so the TTL reads
as `10.minutes` rather than a `Duration.ofMinutes` call.
* Fix broken links to adk-python plugin samples
The three plugin sample links 404. adk-python renamed
`contributing/samples/plugin/` to `contributing/samples/plugins/`; the
directory contents are otherwise unchanged, so only the path segment moves.
This is what the repo-wide `link-check` job has been failing on. It is
unrelated to the 0.7.0 upgrade in this PR, but the check gates the merge and
the fix is confined to the three URLs.
Verified all three targets return 200.
* Use a minTokens value that actually has an effect
The snippet carried Python's `minTokens = 2048`. The 0.7.0 KDoc is explicit
that "Gemini enforces a hard 4096-token minimum that always applies, so values
below 4096 have no additional effect" -- so as written the line was inert and
the comment implied otherwise. Use a value above the floor and say where the
floor comes from.