Skip to content

StreamingMode.BIDI is accepted but has no effect — silently degrades to NONE with no error or warning #676

Description

@AmaadMartin

Describe the bug

StreamingMode.BIDI is a public enum member that has no effect. Passing it is accepted without error or warning and silently produces StreamingMode.NONE behaviour — one event per turn, no partials.

The enum member has no functional reference anywhere in core/src. After a doc-comment change I made in #628, the only occurrence in the whole tree was its own doc comment:

$ grep -rn 'StreamingMode\.BIDI' core/src/ | grep -v '\.test\.'
core/src/agents/run_config.ts:57:   * or {@link StreamingMode.BIDI}.

Streaming is gated solely on === StreamingMode.SSE (core/src/agents/llm_agent.ts:1100), so any value that isn't SSE — including BIDI — falls through to non-streaming.

The part that matters is the silence. A developer who reasons "bidi is a superset of sse, so it must include token streaming" gets strictly worse behaviour than if they had asked for less, and nothing tells them. There's no log line, no warning, no thrown error. The failure is indistinguishable from having set no runConfig at all, so the natural next step is to conclude streaming is broken in the SDK rather than that the mode is unimplemented.

To Reproduce

import {StreamingMode} from '@google/adk';

for await (const event of runner.runAsync({
  userId, sessionId,
  newMessage: {parts: [{text: 'Why is the sky blue?'}]},
  runConfig: {streamingMode: StreamingMode.BIDI},
})) {
  console.log(event.partial, event.content?.parts?.[0]?.text?.length);
}
streamingMode events partials
omitted 1 0
StreamingMode.SSE 6 5
StreamingMode.BIDI 1 0

Observed on @google/adk 1.5.0 and 1.6.0, Node 22 and Node 25, against gemini-2.5-flash. Independently reproduced by @kazunori279 while reviewing google/adk-docs#2076, who confirmed "BIDI yields one event with no error and no warning".

Expected behavior

Anything other than silent degradation. In rough order of preference:

  1. Reject it. Throw on an unsupported mode — StreamingMode.BIDI is not supported; use StreamingMode.SSE. Kaz's note on this was "an unsupported-mode error would be fine."
  2. Remove the enum member until bidirectional streaming exists, so it can't be selected.
  3. Warn and continue, logging that the mode is unimplemented and NONE behaviour is being used.

An enum member that does nothing is best removed or made to throw rather than described — the doc-comment fix in #628 is a mitigation, not the fix, since it only helps readers who consult the reference before choosing.

Additional context

This is adjacent to Runner.runLive not existing and LlmAgent.runLiveFlow throwing (llm_agent.ts:760) — BIDI looks like the surviving surface of a bidirectional path that was never wired up. If bidirectional streaming is planned, option 1 or 3 is probably the right interim state; if it isn't planned, option 2.

Found while writing TypeScript streaming documentation. Happy to send a PR for whichever option you prefer.

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions