Skip to content

feat(google): add RealtimeSession.sendText() for realtime text input#1724

Open
tianqiwuben wants to merge 1 commit into
livekit:mainfrom
tianqiwuben:feat/google-realtime-send-text
Open

feat(google): add RealtimeSession.sendText() for realtime text input#1724
tianqiwuben wants to merge 1 commit into
livekit:mainfrom
tianqiwuben:feat/google-realtime-send-text

Conversation

@tianqiwuben
Copy link
Copy Markdown

Description

Adds a public sendText(text) method to the Google plugin's realtime RealtimeSession, so callers can inject a text turn into a live Gemini session.

This fills a gap on gemini-3.1 live models: generateReply() throws on them because they don't support mid-session client content updates (midSessionChatCtxUpdate is false), and sendClientEvent is private — so there is currently no public way to programmatically send a text turn to a 3.1 live session. sendText() delivers the text via the Live API's realtime input (send_realtime_input({ text })), which the model treats as a completed user turn and responds to. It works across all live models, not just 3.1.

Motivating use case: server-driven nudges (e.g. "the caller has been silent — check if they're still there") on a gemini-3.1-flash-live-preview voice agent, where generateReply() is unavailable.

Changes Made

  • plugins/google/src/realtime/realtime_api.ts: add RealtimeSession.sendText(text: string). It honors the same pending-tool guard as pushAudio, and under manual activity detection wraps the text in activityStart/activityEnd so it forms a complete turn (unless an activity is already open via startUserActivity()).
  • plugins/google/src/realtime/realtime_api.test.ts: tests for the default single-event path, the pending-blocking-tools no-op, and the manual-activity-detection wrapping.
  • .changeset/: minor bump for @livekit/agents-plugin-google.

Pre-Review Checklist

  • Build passes: turbo run build (incl. tsc typecheck), plugin lint, and vitest pass locally
  • AI-generated code reviewed: reviewed for quality, minimal surface
  • Changes explained: see above
  • Scope appropriate: all changes relate to the new method
  • Video demo: n/a (additive API method; covered by unit tests)

Testing

  • Automated tests added/updated
  • All tests pass (vitest run plugins/google/src/realtime/realtime_api.test.ts → 10 passed)
  • restaurant_agent.ts / realtime_agent.ts — not exercised (additive method, no change to existing paths)

Additional Notes

Lint shows 3 pre-existing @typescript-eslint/no-explicit-any warnings in realtime_api.ts (lines ~1347/1376/1384) that are unrelated to this change. api:check also fails on a clean checkout (missing release tags across existing exports), so it's not affected by this PR.

Alternative considered: making generateReply() route through realtime input on 3.1. That would fix the standard AgentSession.generateReply({ userInput }) path, but instructions (a model-role steer) doesn't map cleanly onto user-side realtime input, so a dedicated sendText() is the smaller, clearer change. Happy to follow up on generateReply if preferred.

generateReply() throws on gemini-3.1 live models because they don't support
mid-session client content updates (midSessionChatCtxUpdate is false), leaving
no public way to inject a text turn programmatically. Add a sendText() method
that delivers the text via the Live API's realtime input
(send_realtime_input({ text })), which the model treats as a completed user
turn and responds to. Works across all live models. Under manual activity
detection the text is wrapped in activityStart/activityEnd so it forms a
complete turn, unless an activity is already open via startUserActivity().
@changeset-bot
Copy link
Copy Markdown

changeset-bot Bot commented Jun 5, 2026

🦋 Changeset detected

Latest commit: 1981237

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 34 packages
Name Type
@livekit/agents-plugin-google Major
@livekit/agents Major
@livekit/agents-plugin-anam Major
@livekit/agents-plugin-assemblyai Major
@livekit/agents-plugin-baseten Major
@livekit/agents-plugin-bey Major
@livekit/agents-plugin-cartesia Major
@livekit/agents-plugin-cerebras Major
@livekit/agents-plugin-deepgram Major
@livekit/agents-plugin-elevenlabs Major
@livekit/agents-plugin-fishaudio Major
@livekit/agents-plugin-hedra Major
@livekit/agents-plugin-hume Major
@livekit/agents-plugin-inworld Major
@livekit/agents-plugin-lemonslice Major
@livekit/agents-plugin-liveavatar Major
@livekit/agents-plugin-livekit Major
@livekit/agents-plugin-minimax Major
@livekit/agents-plugin-mistral Major
@livekit/agents-plugin-mistralai Major
@livekit/agents-plugin-neuphonic Major
@livekit/agents-plugin-openai Major
@livekit/agents-plugin-perplexity Major
@livekit/agents-plugin-phonic Major
@livekit/agents-plugin-resemble Major
@livekit/agents-plugin-rime Major
@livekit/agents-plugin-runway Major
@livekit/agents-plugin-sarvam Major
@livekit/agents-plugin-silero Major
@livekit/agents-plugin-soniox Major
@livekit/agents-plugin-tavus Major
@livekit/agents-plugin-trugen Major
@livekit/agents-plugin-xai Major
@livekit/agents-plugins-test Major

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@CLAassistant
Copy link
Copy Markdown

CLAassistant commented Jun 5, 2026

CLA assistant check
All committers have signed the CLA.

Copy link
Copy Markdown
Contributor

@devin-ai-integration devin-ai-integration Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ Devin Review: No Issues Found

Devin Review analyzed this PR and found no potential bugs to report.

View in Devin Review to see 2 additional findings.

Open in Devin Review

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.

2 participants