Skip to content

Fix: suppress affective dialog and proactivity for Gemini 3.x Live models - #820

Open
AmaadMartin wants to merge 2 commits into
mainfrom
fix/gemini-3x-live-affective-dialog-proactivity
Open

Fix: suppress affective dialog and proactivity for Gemini 3.x Live models#820
AmaadMartin wants to merge 2 commits into
mainfrom
fix/gemini-3x-live-affective-dialog-proactivity

Conversation

@AmaadMartin

@AmaadMartin AmaadMartin commented Aug 8, 2026

Copy link
Copy Markdown
Owner

Please ensure you have read the contribution guide before creating a pull request.

Link to Issue or Description of Change

  1. Link to an existing issue (if applicable):
    N/A
  2. Or, if no issue exists, describe the change:
    Problem: BasicLlmRequestProcessor copies enableAffectiveDialog and proactivity from the run config for every model. Gemini 3.x Live models reject both fields. createRunConfig defaults enableAffectiveDialog to false, so a caller who configures nothing still sends one of them.

Solution: Skip the two assignments when the model is a Gemini 3.x Live model. This mirrors adk-python flows/llm_flows/basic.py, which assigns None on the same condition. Python writes None because it clears a pre-existing value; here liveConnectConfig is a fresh {} (core/src/agents/llm_agent.ts:804) and this processor runs first, so a guard is equivalent. The other five liveConnectConfig assignments stay ungated.

Parity notes:

  • adk-js has no canonicalLiveModel, so the gate reads llmRequest.model. The processor sets that field from agent.canonicalModel.model a few lines earlier. This is the fallback branch adk-python takes when canonical_live_model is absent.
  • The predicate reused is isGemini3xFlashLive from core/src/utils/model_name.ts. It is narrower than adk-python's _is_gemini_3_x_live: it requires -flash-live rather than any -live, and it has no Live Translate carve-out. Widening it is separate, already-queued work (fork PR Fix: match adk-python in the Gemini 3.x Live model predicate #715) and is deliberately out of scope here.

Collision check: gh pr list --repo AmaadMartin/adk-js --state open --limit 300. Fork PR #715 (fix/gemini-3x-live-predicate-parity) is the only adjacent PR. It renames and widens the predicate; it touches no file in this diff. This PR branches from main and imports the name main has today. If #715 lands first, this import needs the same one-line rename to isGemini3xLive.

Testing Plan

Please describe the tests that you ran to verify your changes. This is required for all PRs that are not small documentation or typo fixes.
Unit Tests:
[x] I have added or updated unit tests for my change.
[x] All unit tests pass locally.

Two new cases in core/test/agents/processors/basic_llm_request_processor_test.ts. No existing case was edited.

  • gemini-3.1-flash-live drops both fields, and still receives responseModalities, which proves the gate is narrow.
  • gemini-2.5-flash keeps both fields.

Mutation proof, on the exact gated lines:

  1. Removed the guard, leaving the unconditional assignments. Case 1 failed: AssertionError: expected true to be undefined.
  2. Inverted the guard to if (isGemini3xFlashLive(llmRequest.model)). Three tests failed, including the untouched should populate liveConnectConfig from runConfig: AssertionError: expected undefined to be true.

Coverage of core/src/agents/processors/basic_llm_request_processor.ts from the targeted run: 100% statements, 100% lines, 100% functions, 90.9% branches. The one uncovered branch is line 41, agent.generateContentConfig ?? {}, which this PR does not touch. Both branches of the new guard are covered.

Commands run on the pushed commit:

npx vitest run --project unit:core core/test/agents/processors/basic_llm_request_processor_test.ts   # 14 passed
npm run ts:check
npx eslint core/src/agents/processors/basic_llm_request_processor.ts core/test/agents/processors/basic_llm_request_processor_test.ts   # clean
npx prettier --check core/src/agents/processors/basic_llm_request_processor.ts core/test/agents/processors/basic_llm_request_processor_test.ts   # clean

npm run ts:check reports 4 pre-existing errors in this test file, at lines 98, 174, 195 and 320 on main. The same 4 errors, at the same sites, remain after this change. This PR adds none.

CI note: the first run-tests (windows-latest) job failed with 3 timeouts in tests/integration/app_loader and tests/integration/build_setup. Those tests run npm install per fixture and are unrelated to this diff. A rerun of the same commit passed, and Ubuntu and macOS passed on the first attempt.

Manual End-to-End (E2E) Tests:
Not run. Observing the field on the wire needs a live WebSocket session against a Gemini 3.x Live model, which needs credentials CI does not have. To check by hand, build an LlmAgent on gemini-3.1-flash-live, run it with RunConfig {enableAffectiveDialog: true, proactivity: {}}, and inspect llmRequest.liveConnectConfig after BASIC_LLM_REQUEST_PROCESSOR.runAsync.

Checklist

[x] I have read the CONTRIBUTING.md document.
[x] I have performed a self-review of my own code.
[x] I have commented my code, particularly in hard-to-understand areas.
[x] I have added tests that prove my fix is effective or that my feature works.
[x] New and existing unit tests pass locally with my changes.

Amaad Martin added 2 commits August 8, 2026 12:35
Gemini 3.x Live models reject enableAffectiveDialog and proactivity, but
BasicLlmRequestProcessor copied both from the run config for every model.
Gate the two assignments on the model, matching adk-python basic.py.
…aries

liveConnectConfig is a fresh object when the processor runs, so writing
undefined clears nothing. The guard leaves both assignments as they were.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant