Skip to content

console: render agent-initiated messages in text mode - #6578

Open
ben-xiao-io wants to merge 4 commits into
livekit:mainfrom
ben-xiao-io:fix/console-text-mode-agent-initiated-turns
Open

console: render agent-initiated messages in text mode#6578
ben-xiao-io wants to merge 4 commits into
livekit:mainfrom
ben-xiao-io:fix/console-text-mode-agent-initiated-turns

Conversation

@ben-xiao-io

@ben-xiao-io ben-xiao-io commented Jul 28, 2026

Copy link
Copy Markdown

Fixes #6577.

What

Text mode rendered agent output only from session.run() events, so any assistant turn produced outside a typed exchange never reached the screen: the on_enter greeting (generate_reply() during session start), a background tool result delivered between turns, a handoff greeting. The streaming path can't cover them either — text mode detaches sess.output.transcription.

This PR renders assistant ChatMessages from conversation_item_added when text mode is active and no typed exchange is in flight. A printed-item id set deduplicates against run() rendering. Audio mode is untouched.

Verification

A/B on a minimal FakeLLM agent that greets in on_enter, driven through a pty running console --text with LIVEKIT_LOG_LEVEL=warn:

  • before: the greeting never renders; the TUI shows nothing until the user types, and the greeting text never appears at all.
  • after: the greeting renders as a normal ● Agent block (with llm_ttft metrics) before any input; typed exchanges render exactly as before, with no duplicates:
  ● Agent
    SCRIPTED-GREETING: welcome, how can I help?
    llm_ttft: 10ms
❯ hello agent
  ● You
    hello agent
  ● Agent
    SCRIPTED-REPLY: nice to hear from you.

ruff check / ruff format --check pass; tests/test_cli_log_level.py passes.

Notes

  • The mid-run suppression (_text_run_active) is reset in a finally, so a failed run can't permanently mute agent-initiated output.
  • The new TCP console (cli/cli.py) has the same structural gap on the Python side; its rendering lives in the Go CLI, so this PR fixes the Python TUI only.

Text mode printed agent output only from session.run() events, so any
assistant turn produced outside a typed exchange never reached the
screen: the on_enter greeting (generate_reply during session start),
a background tool result delivered between turns, a handoff greeting.
The streaming path can't cover them either — text mode detaches
sess.output.transcription.

Render assistant ChatMessages from conversation_item_added when text
mode is active and no typed exchange is in flight, with a catch-up
scan at IO acquisition for messages committed before the subscription
existed. A printed-item id set deduplicates against run() rendering;
audio mode is untouched (it hears these turns via the transcript
synchronizer).
@ben-xiao-io
ben-xiao-io requested a review from a team as a code owner July 28, 2026 02:29
@CLAassistant

CLAassistant commented Jul 28, 2026

Copy link
Copy Markdown

CLA assistant check
All committers have signed the CLA.

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

Copy link
Copy Markdown
Contributor

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 1 additional finding.

Open in Devin Review

console_mode is set before the session exists, so the item_added handler
is armed from the first commit — the acquire-time history scan defended a
race that cannot happen. The module-level renderer had one caller.
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.

console text mode never displays agent-initiated messages (e.g. the on_enter greeting)

3 participants