feat(claude): show SDK prompt suggestions as ghost text in the composer - #8524
feat(claude): show SDK prompt suggestions as ghost text in the composer#8524getbrikly wants to merge 1 commit into
Conversation
|
Important Review skippedAuto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: Repository UI Review profile: CHILL Plan: Pro Plus Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
Comment |
There was a problem hiding this comment.
UI consistency review of the composer prompt-suggestion surface. Two findings on the new ghost-text affordance in ComposerPromptEditor / ChatComposer; the rest of the web changes (shared Kbd primitive reuse, text-placeholder token, work-log exclusion, derived-state helper + tests) look consistent with the existing composer patterns.
Posted via Macroscope — UI Consistency
6bfdf55 to
8b5643a
Compare
The Claude Agent SDK can predict the user's next prompt after each turn (`promptSuggestions: true` emits one `prompt_suggestion` message after `result`, generated off the turn's prompt cache). The adapter received that message but dropped it, and never opted in, so the composer sat empty at the exact moment the user has to decide what to ask next. Opt in and carry the suggestion over the existing activity channel: the adapter maps `prompt_suggestion` to a new `turn.prompt-suggestion` runtime event attributed to the turn that just completed; ingestion stores it as a `prompt-suggestion` activity, hidden from the work log on web and mobile. The web composer derives the suggestion for the latest completed turn and renders it as faded text in the empty editor with a Tab hint. Tab inserts it into the draft (never sends), typing ignores it, and it clears once a newer user message or turn exists. Claude only; the user's own Claude settings (`promptSuggestionEnabled: false`, `CLAUDE_CODE_ENABLE_PROMPT_SUGGESTION`) still suppress it, so there is no separate T3 toggle. Claude Fable 5 in Claude Code. Claude-Session: https://claude.ai/code/session_016YSyurTEFmMXRr9t8vNHTT
8b5643a to
1894b8e
Compare
ApprovabilityVerdict: Not approved Macroscope's review found this PR not approvable — This PR introduces a new Claude SDK capability and carries it through runtime events, persisted activities, and a new Tab-driven composer interaction. Its cross-layer production behavior and automatic SDK opt-in exceed the bounded additive scope suitable for automatic approval. You can add or adjust custom eligibility rules. Learn more. |
What Changed
Claude Code already predicts the user's next prompt after each turn; the Claude adapter receives that
prompt_suggestionmessage today and drops it (#4244 added the case as "no T3 surface"), and the SDK option that produces it is never passed. This PR gives it a surface, using only what the SDK provides — no second model call, no new dependency.ClaudeAdapter: passpromptSuggestions: truetoquery(); map the trailingprompt_suggestionmessage to a newturn.prompt-suggestionruntime event attributed to the turn that just completed (the message arrives afterresult, onceturnStateis cleared, so the adapter rememberslastCompletedTurnId).contracts: theturn.prompt-suggestionevent schema ({ suggestion }).ProviderRuntimeIngestion: persist it as oneprompt-suggestionactivity through the existing activity channel, so it reaches every client and survives reloads. Web and mobile keep it out of the work log.derivePromptSuggestionpicks the suggestion for the latest completed turn and drops it once anything newer exists (a later user message, a running turn). The composer renders it as faded text in the existing placeholder slot with aTabhint — only while the editor is empty and idle (not during approvals, questions, plan follow-ups, or while sending/connecting).Tabinserts it into the draft, never sends; typing ignores it.docs/user/composer.mdsection.13 files, +458/−2. Claude-only by construction — no other harness exposes an equivalent — but the event is provider-agnostic, so a provider that grows one later can emit it without client changes.
Deliberately not included: a T3 settings toggle. Suggestions follow the user's own Claude Code settings (
promptSuggestionEnabled: falseinsettings.jsonorCLAUDE_CODE_ENABLE_PROMPT_SUGGESTION=falsesuppresses them; Claude Code also skips the first turn, plan mode, and API-error turns), so there's no second switch to keep in sync. Easy to add if you'd rather have one in Settings.Why
Discussed in #6839 ("Suggest a follow-up prompt when a turn finishes"). The moment a turn settles is when the user has to re-derive context and decide what to ask next; Claude Code fills that gap in the terminal and the prediction is generated off the turn's own prompt cache, so it is nearly free. T3 was already receiving it. The original proposal in #6839 builds suggestions with a new text-generation operation; this is the SDK-native version I described in that thread, with much less machinery.
UI Changes
Empty composer after a completed turn shows the suggestion as placeholder-coloured text followed by a
Tabkey hint; pressing Tab fills the draft. A short screen recording is attached in the first comment below.Checklist
Built with Claude Fable 5 in Claude Code.
https://claude.ai/code/session_01Dzo12DZh4ZQF9mUjr26qzj
Note
Low Risk
Additive feature path with guarded client display rules and extensive tests; no auth or data-model breaking changes.
Overview
Wires Claude Code’s post-turn prompt suggestions through the stack and surfaces them in the web composer as ghost text (Tab to accept), instead of dropping SDK
prompt_suggestionmessages.Claude adapter opts into
promptSuggestions: true, rememberslastCompletedTurnIdafter each turn finishes, and emits provider-agnosticturn.prompt-suggestionevents (trimmed text, correct turn even when the suggestion arrives afterresultor a new turn has already started). Suggestions with no turn to attach to are dropped.Contracts + ingestion add the
turn.prompt-suggestionschema and persist it as aprompt-suggestionthread activity. Web usesderivePromptSuggestionto show the latest completed turn’s suggestion only while the composer is idle and empty (not on mobile, during approvals/questions/plan follow-up, or while connecting/sending); Tab fills the draft without sending. Work logs on web and mobile skip these activities; mobile has no composer UI yet.User docs describe behavior and that suggestions follow Claude Code settings (
promptSuggestionEnabled/ env var).Reviewed by Cursor Bugbot for commit 1894b8e. Bugbot is set up for automated code reviews on this repo. Configure here.
Note
Show Claude SDK prompt suggestions as ghost text in composer
promptSuggestions: trueto the SDK and mapsprompt_suggestionmessages toturn.prompt-suggestionprovider runtime events, attributed to the last completed turnprompt-suggestionorchestration activities; both web and mobilederiveWorkLogEntriesnow exclude them from work logsClaudeSessionContextgainslastCompletedTurnId; blank or unattributed suggestions are silently dropped rather than emittedMacroscope summarized 1894b8e.