Repository navigation
Sonny: a guess at your next message, for Tab to take - #329
Conversation
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: b67899bd12
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
4c58ecd to
bcd6b1b
Compare
💡 Codex ReviewLines 342 to 343 in bcd6b1b When an MCP server has credentials in AGENTS.md reference: AGENTS.md:L98-L99 Lines 743 to 744 in bcd6b1b A script that repeatedly calls Lines 482 to 486 in bcd6b1b When an enabled server starts slowly or fails to initialize, the preceding Lines 299 to 301 in bcd6b1b If a thread's bot is deleted and another bot is created with the same name, resuming that thread silently attaches it to the replacement conversation. AGENTS.md reference: AGENTS.md:L32-L32 Lines 469 to 473 in bcd6b1b When two enabled servers or tools normalize to the same JavaScript identifier, this insertion silently overwrites the earlier dispatch target while both declarations remain advertised. For example, the configuration accepts servers named ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
If Codex has suggestions, it will comment; otherwise it will react with 👍. Codex can also answer questions or update the PR. Try commenting "@codex address that feedback". |
bcd6b1b to
7b7b8bd
Compare
|
The five findings above are in Generated by Claude Code |
After a turn the person started from this window ends well, a copy of the agent, forked with its tools and model but allowed no call, guesses the next message in 2 to 12 words, as Claude Code's prompt suggestions and Codex's composer predictions do. The empty composer shows it dim; Tab takes it in, unsent. Claude Code's ask and filters, in Sonny's words. `[sonny] suggest` (default true) turns it off, listed in /config. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_013jkdGGhx2HU91as8RRz2mY
…t's own bytes A steer is its own submission that ends as steered, so the turn the person's words go to is the one it joins. A label is matched on the original text's bytes, since a lowercase can change a letter's length. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_013jkdGGhx2HU91as8RRz2mY
7b7b8bd to
d0670db
Compare
Requested by George · project thread
Rebased onto main on its own; it no longer depends on #315. Whichever of the two lands second lists
sonny.suggestin/config.What changes
When a turn you started from this window ends well, a copy of the agent guesses what you'll type next. The guess shows dim in the empty composer, and Tab puts it in the composer for you to edit or send. It never sends itself.
This follows the two harnesses that ship the feature:
[SUGGESTION MODE ...]prompt, filters the reply, and shows it dim in the empty composer for Tab to take. Enter does not submit it.How Sonny does it (
sonny/src/suggest.rs):{bot}.suggest-…withallow: []andexpire_ms: 60s. The request keeps the bot's tool list (the daemon sendsrecord.toolsand only refuses calls), its cache key, and the window's turn model. So the request reads like the agent's next one and the prompt cache stays warm. In a live run on this head, the guess request carried the same 15 tools as the turn before it. The copy is deleted once it answers, andexpire_mscovers a crash. Like the side chat, it's hidden from fleet,/statusand the lookout.Suggestion:labels are stripped. It refuses: saying nothing, meta text, bracketed notes,Label:prefixes, fewer than 2 words (exceptyes,pushand similar), more than 12 words, 100 characters or more, several sentences, formatting, evaluative words ("looks good"), and the agent's own voice ("Let me…").completed, and not when it ended on anask. A message sent here counts (sendwith noorigin); so does a steer, which counts for the turn it joins. Turns started by the lead, the lookout, a!commandrecord or another window get no guess. So a task window or a task opened in the pane spends nothing.[sonny] suggest = falsein~/.agent/config.tomlturns it off./statusopen, and keys not in the pane. Otherwise Tab does what it did before. This PR binds no other key; Shift+Tab, or Ctrl+\ after Sonny: full screen only, buttons, folds, quiet agent messages, tasks in the pane, pane keys and a little color #326, still moves into the pane. Agreed with the full-screen thread: once both land, the unfocused pane's title will readctrl+\instead oftabwhile a guess shows.I left out some of Claude Code's gates: the terminal-focus check, the unused-streak back-off (it suggests every 10th turn after a run of ignored ones), and the cold-cache skip. Any of them is easy to add if the cost shows up in
/usage.Screenshots
The guess after a reply, and Tab taking it:
The same composer in a side chat in the pane:
These come from a real daemon (
agent serve) with a scripted Responses model, Sonny in tmux, andtmux capture-pane -erendered to PNG. After the rebase I ran the same check again on this head: the guess showed after the reply, and Tab took it.Tests
cargo test -p sonny -p agent-clientpasses, andcargo clippy -p sonny -p agent-client --all-targets -D warningsis clean. New tests:allow: []and deleted, the composer row reads› run the tests tab, typing hides it, and Tab fills the composer without a send[sonny] suggestparses, defaults to true, and must be a booleanNoticed, not fixed here
The pane reads a side chat's screen through
vt1000.15, which drops SGR 2 (dim). So every dim hint in a side chat or a task in the pane shows at full brightness. The guess is italic as well as dim so it still reads as a ghost there. Moving to vt100 ≥0.16 (which hasdim()) clashes with ratatui 0.29'sunicode-widthpin.🤖 Generated with Claude Code
https://claude.ai/code/session_013jkdGGhx2HU91as8RRz2mY