docs(runtime): correct TypeScript claims in RunConfig streaming docs - #2101
docs(runtime): correct TypeScript claims in RunConfig streaming docs#2101kazunori279 wants to merge 2 commits into
Conversation
The streaming sections of runtime/runconfig.md told TypeScript readers three things that are not true of the TypeScript SDK. - The BIDI bullet directed readers to `runner.run_live()`. That entry point does not exist in TypeScript: `Runner` exposes no `runLive()` and `LlmAgent.runLiveFlow` throws. The bullet also omitted that passing BIDI degrades to non-streaming with no error and no warning. - The TypeScript tab recommended `supportCfc: true`. Copying it yields a single event with `errorCode: 'UNKNOWN_ERROR'` and `errorMessage: 'CFC is not yet supported in callLlmAsync'` and no response text at all. Removed from the snippet and documented in the existing experimental admonition. - "Configure live agents" carried a TypeScript support tag and a TypeScript snippet, but the whole section describes `run_live()` parameters. The three fields the TypeScript `RunConfig` declares feed only `liveConnectConfig`, which nothing reachable consumes. Tag and snippet removed, with a note explaining why the fields exist but do nothing. Verified against @google/adk 1.6.0 and adk-js at HEAD; `mkdocs build --strict` is clean.
✅ Deploy Preview for adk-docs-preview ready!
To edit notification comments on pull requests, go to your Netlify project configuration. |
The prose said "set the `streaming_mode` parameter" in a language-neutral sentence, but the TypeScript property is `streamingMode` (as the TypeScript code tab below it already shows).
|
@kazunori279 - please have a looks at these findings Technical review reportReview: adk-docs#2101 —
|
| Repo | HEAD |
|---|---|
| adk-js | 48165a8 |
| adk-python | dd998a7 |
| adk-go | 2325d1c |
| adk-java | 527ff4e |
| adk-kotlin | 998a002 |
The timing problem
The author's evidence was sound. At the main-v1.6.0 tag (72f89b0, 2026‑08‑05 — still latest on npm today), all three TypeScript claims hold:
runner.ts#L580—// TODO - b/425992518: Implement runLive and related methods.llm_agent.ts#L760—throw new Error('LlmAgent.runLiveFlow not implemented');llm_agent.ts#L1092—throw new Error('CFC is not yet supported in callLlmAsync');
Two upstream merges then moved the ground:
- adk-js#692 (merged 2026‑08‑13), closing adk-js#676 — "StreamingMode.BIDI is accepted but has no effect — silently degrades to NONE". BIDI now throws.
- adk-js#523 (merged 2026‑08‑18) —
feat(core): implement Runner.runLive and LlmAgent live flow.
1. BIDI bullet — ❌ now wrong for TypeScript, imprecise for Go/Java/Kotlin
"Passing it does not enable streaming, and no error or warning is raised — the run behaves as if
StreamingMode.NONEhad been set."
TypeScript (HEAD): it throws. runAsync funnels through createRunConfig, which rejects BIDI:
runner.ts#L257—const runConfig = createRunConfig(params.runConfig);run_config.ts#L155-L161—throw new Error('StreamingMode.BIDI is not supported; use StreamingMode.SSE.')
Python: the claim holds. base_llm_flow.py#L1648 gates streaming on == StreamingMode.SSE only, with no validation; the enum docstring at _streaming_mode.py#L139-L147 says as much.
Go: BIDI isn't reachable from the public API. The exported agent.RunConfig declares only NONE and SSE — agent/run_config.go#L20-L26. StreamingModeBidi lives only in internal/agent/runconfig/run_config.go#L28.
Kotlin: BIDI does not exist. The enum is NONE and SSE — RunConfig.kt#L29-L50.
Java: BIDI is not inert on the standard path. It changes function-call dispatch:
BaseLlmFlow.java#L763-L766— BIDI selectsFunctions.handleFunctionCallsLiveinstead ofhandleFunctionCallsBaseLlmFlow.java#L746-L747— BIDI changes event-emission filtering
So "behaves as if NONE had been set" is accurate for exactly one of the five SDKs.
2. run_live() warning admonition — ❌ stale
"
Runnerexposes norunLive(), and the agent-level live path throwsError: LlmAgent.runLiveFlow not implemented."
Both are implemented at HEAD:
runner.ts#L648—async *runLive(params: {...})llm_agent.ts#L955-L989— fullrunLiveFlowwith reconnect/session-resumption- 1,115 lines of coverage in
core/test/runner/run_live_test.ts
Caveat in the PR's favor: npm latest is still 1.6.0 (published 2026‑08‑06), so the warning is true for anyone on the current release. But it's written as unversioned prose and will be false the moment 1.7.0 ships.
3. supportCfc removal from the TypeScript snippet — ✅ correct, still verifies
- Throw site:
llm_agent.ts#L1821-L1825 - Surfaced as an event rather than propagating:
llm_agent.ts#L1945-L2007catches theError, and with no JSONerrorpayload to parse falls through toerrorCode = 'UNKNOWN_ERROR'witherrorMessage = modelError.message— exactly theerrorCode/errorMessagepair quoted in the admonition. - Scoping the note to TypeScript is right: Python implements CFC by routing to the live path (
base_llm_flow.py#L1612-L1614,runners.py#L2320-L2331).
Keep this change.
4. "Configure live agents" — TS tag + snippet removal — ❌ stale
"…they only feed the live connection, which the TypeScript SDK does not implement yet."
The first half was and is true — the fields are written into liveConnectConfig at basic_llm_request_processor.ts#L65-L70. The second half no longer is: all three are in LIVE_KEYS (llm_agent.ts#L138-L147) and applied by the now-working live flow at llm_agent.ts#L989.
Separately, narrowing the tag to Python-only is too aggressive independent of the TS question: Java has Runner.runLive and implements one of the section's documented parameters, avatar_config (RunConfig.java#L74); Go drives a live path too (runner.go#L447).
5. Minor — the new naming parenthetical is wrong for 3 of 5 SDKs
"(
streaming_modein Python, Go, Java and Kotlin;streamingModein TypeScript)"
| SDK | Actual identifier | Source |
|---|---|---|
| Python | streaming_mode ✅ |
run_config.py#L102 |
| TypeScript | streamingMode ✅ |
run_config.ts#L66 |
| Go | StreamingMode ❌ |
agent/run_config.go#L31 |
| Java | streamingMode() / setStreamingMode() ❌ |
RunConfig.java#L78, #L188 |
| Kotlin | streamingMode ❌ |
RunConfig.kt#L61 |
The page's own Go and Java snippets (StreamingMode: agent.StreamingModeSSE, .streamingMode(StreamingMode.SSE)) already contradict the sentence added right above them.
Non-issues
../live/index.md resolves (docs/live/index.md). Diff is confined to docs/runtime/runconfig.md as stated.
Recommendation
Land §3 (the CFC changes) as-is — that's a real, still-current bug in the docs where the copy-pasteable snippet produces an error event and no answer. Ask the author to rebase the other three against adk-js HEAD:
- Replace the generic BIDI paragraph with per-language behavior, since the five SDKs now do four different things (TS throws; Python silently degrades; Go/Kotlin have no BIDI in the public API; Java changes function-call dispatch).
- Drop the
run_live()warning, or rewrite it as version-scoped ("not available in@google/adk≤ 1.6.0") — and note thatRunner.runLiveis documented as experimental at HEAD. - Restore the TypeScript tag and snippet under "Configure live agents", and drop the "typed but inert" note.
joefernandez
left a comment
There was a problem hiding this comment.
This needs some work.
Don't explicitly call out TS not supporting Live, it's distracting, unnecessary, and creates technical debt. (see comments)
|
|
||
| To control how the agent delivers responses, set the `streaming_mode` parameter: | ||
| To control how the agent delivers responses, set the streaming mode parameter | ||
| (`streaming_mode` in Python, Go, Java and Kotlin; `streamingMode` in |
There was a problem hiding this comment.
Remove. The example code above shows the syntax for each language, so don't repeat it, here.
| ## Enable streaming | ||
|
|
||
| To control how the agent delivers responses, set the `streaming_mode` parameter: | ||
| To control how the agent delivers responses, set the streaming mode parameter |
There was a problem hiding this comment.
we need to more thoroughly disambiguate streamed text responses from the Live / voice functionality. Here's a new intro:
You can control how an agent responds in text mode, including
word-by-word as generated or full responses, use the
***Streaming Mode*** parameter, as described below:
| !!! example "Experimental" | ||
| CFC support is experimental and its API or behavior may change in future | ||
| releases. | ||
| releases. It is not yet implemented in the TypeScript SDK: setting |
There was a problem hiding this comment.
remove.
mentioning this parameter is not yet implemented in TS just adds unnecessary detail to this note, and creates maintenance debt for us to clean up later.
| @@ -94,24 +94,39 @@ whether the context window is compressed: | |||
|
|
|||
| ## Enable streaming | |||
There was a problem hiding this comment.
change for clarity:
## Text response options
to avoid confusion with Live and voice functionality
| streaming. For bidirectional streaming, use `runner.run_live()` in the | ||
| languages that support it; see [Live and Voice Agents](../live/index.md). | ||
|
|
||
| !!! warning "`run_live()` is not available in the TypeScript SDK" |
There was a problem hiding this comment.
remove this warning.
If a feature is not supported, don't need to mention it unless is strongly expected. If we mentioned everything the software didn't do, the documentation would be nothing but "it doesn't do this" statements.
|
|
||
| <div class="language-support-tag"> | ||
| <span class="lst-supported">Supported in ADK</span><span class="lst-python">Python</span><span class="lst-typescript">TypeScript</span> | ||
| <span class="lst-supported">Supported in ADK</span><span class="lst-python">Python</span> |
| Not all parameters are available in every language. See the | ||
| [API reference](#api-reference) for language-specific details. | ||
|
|
||
| !!! note "TypeScript" |
There was a problem hiding this comment.
remove
If a feature is not supported, don't need to mention it unless is strongly expected. If we mentioned everything the software didn't do, the documentation would be nothing but "it doesn't do this" statements.
| - **`StreamingMode.BIDI`**: Reserved for bidirectional streaming, but **not | ||
| used** in the standard `run_async()` path. For bidirectional streaming, use | ||
| `runner.run_live()` instead. | ||
| - **`StreamingMode.BIDI`**: Reserved for bidirectional streaming and **not |
There was a problem hiding this comment.
remove this bullet. don't list BIDI as a parallel option because that's not helpful and a bit misleading.
replace this with a new paragraph mentioning Live and pointing to that resource:
There is another setting for the ***Streaming Mode*** parameter which
enables bidirectional streaming of data, including voice input and output.
This feature requires additional configuration beyond simple agents. For
more information about this feature, see [Live and Voice Agents](/live/).
| <span class="lst-supported">Supported in ADK</span><span class="lst-python">Python</span> | ||
| </div> | ||
|
|
||
| When using `runner.run_live()`, configure real-time behavior with these |
There was a problem hiding this comment.
Add this as the leading sentences of the intro for this section:
ADK agents can support [Live and Voice Agents](/live/) to create interactive
agent experiences. You configure agents that support this functionality
using the `runner.run_live()` method. When using...
| @@ -296,19 +316,6 @@ Not all parameters are available in every language. See the | |||
| with pure Python CPU-bound code since the GIL prevents true parallel | |||
| execution of Python bytecode. | |||
|
|
|||
There was a problem hiding this comment.
recommend adding a Java RunConfig code example here
The streaming sections of
docs/runtime/runconfig.mdtell TypeScript readers three things that are not true of the TypeScript SDK. Surfaced while reviewing #2076, where a contributor hit the same gap from the other direction.All three were verified by running the documented code against
@google/adk1.6.0 (Node 25,gemini-2.5-flashover Vertex AI) and by readinggoogle/adk-jsat HEAD.1. The
BIDIbullet pointed at an entry point TypeScript does not haveIt read: "For bidirectional streaming, use
runner.run_live()instead." — on a page tagged for TypeScript.Runnerexposes norunLive()(runner.tshas only a TODO) andLlmAgent.runLiveFlowthrowsError: LlmAgent.runLiveFlow not implemented.The bullet also omitted the behaviour that actually bites: passing
BIDIdoes not error, does not warn, and does not stream. Measured on the same agent and prompt:streamingModeSSENONE)BIDIA reader who reasons "bidi is a superset of sse" gets strictly worse behaviour than if they had asked for less. Now stated explicitly, with a warning admonition for the TypeScript case.
2. The TypeScript tab recommended
supportCfc: true, which breaks the runThe snippet was copy-pasteable and produced no answer. With the documented config:
The throw is at
llm_agent.tsin thecallLlmAsyncpath and is surfaced as an error event, so a reader who does not checkevent.errorCodesees silence rather than a failure. Removed from the TypeScript snippet; the existing "Experimental" admonition now records the exact symptom.3. "Configure live agents" claimed TypeScript support for a
run_live()-only sectionThe section documents
run_live()parameters and carried a TypeScript support tag plus a TypeScript snippet. The three fields the TypeScriptRunConfigdoes declare —enableAffectiveDialog,proactivity,realtimeInputConfig— are assigned only intollmRequest.liveConnectConfig, which is consumed only by the live path that throws. They are typed but inert.Removed the tag and the snippet, and added a note explaining why the fields exist and do nothing, so the next reader who finds them in the type does not have to work this out.
Checks
mkdocs build --strict— clean../live/index.mdresolvesdocs/runtime/runconfig.md