Skip to content

feat(composer): opt-in QA suggestions with a customizable model and prompt - #1

Closed
sittitanaporn-a11y wants to merge 1 commit into
Type-Delta:mainfrom
sittitanaporn-a11y:feat/qa-suggestions
Closed

sittitanaporn-a11y wants to merge 1 commit into
Type-Delta:mainfrom
sittitanaporn-a11y:feat/qa-suggestions

Conversation

@sittitanaporn-a11y

Copy link
Copy Markdown

What

Opt-in QA suggestions: after a turn settles, the composer can ask a model what you would plausibly send next and shows it as faded ghost text in the empty composer — press Tab to accept.

How it works

  • The server reads an end-preserving tail of the thread through the existing projection and text-generation boundary, so no thread turn, event, message, or provider session is created. Requests are bound to the latest completed assistant message and rechecked before provider launch; worktree-backed threads skip the project lookup.
  • Suggestions clear as soon as you type, stay dismissed for that turn, and reset only when the model, thread, or latest message changes. Mobile has no toggle or request path.

Not hardwired to "QA"

Three Settings → General controls make it reusable as a docs / security / UX reviewer:

  • QA suggestion model (composerSuggestionModelSelection, nullable) — lock suggestions to one model, or fall back to the thread's own model.
  • Suggestion name (composerSuggestionLabel) — rename the feature.
  • Suggestion instructions (composerSuggestionInstructions) — rewrite the persona and focus.

Custom instructions replace only the persona and focus rules; the JSON output contract, the one-line length limit, and the untrusted-transcript guard are always appended after them, so a rewritten focus cannot change the response shape or disable the injection guard.

Verification

  • vp run typecheck (15/15) and vp check clean.
  • Focused tests: text-generation prompt (incl. custom-instructions swap + safety-rule survival), settings round-trip, composer gating (152 passing in the touched suites).

Split out from a combined feature branch so this PR contains only the QA-suggestions work.

🤖 Generated with Claude Code — model: Claude Opus 4.8 (1M context)

…rompt

After a turn settles, the web composer can ask a model what the user would
plausibly send next and render it as faded ghost text in the empty composer;
Tab accepts it. The server reads an end-preserving tail of the thread through
the existing projection and text-generation boundary, so no thread turn, event,
message, or provider session is created; requests are bound to the latest
completed assistant message and rechecked before provider launch.

The feature is not hardwired to "QA": a dedicated model (composerSuggestionModelSelection,
nullable, falling back to the thread model), a display name (composerSuggestionLabel),
and custom instructions (composerSuggestionInstructions) let it act as a docs,
security, or UX reviewer. Custom instructions replace only the persona and focus
rules; the JSON output contract, the one-line limit, and the untrusted-transcript
guard are always appended. Mobile has no toggle or request path.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@github-actions github-actions Bot added size:XL vouch:unvouched PR author is not yet trusted in the VOUCHED list. labels Sep 8, 2026
@Type-Delta

Copy link
Copy Markdown
Owner

Thanks for the original implementation. We are taking the feature in a different direction based on testing and remote-client behavior.

We kept the core UX: suggestions come from the agent's own turn, appear as ghost text in the composer, and can be accepted with Tab.

The main architectural change is that the original design created a separate model request after each turn using only a short recent-message tail. That adds usage and latency, and the reduced context can make the suggestion miss what the agent just understood. The new implementation generates the suggestion as part of the agent's existing turn, so it uses the full conversation context and returns without another request or extra wait.

The preference is now stored per client and sent with each turn instead of being persisted as a server-wide setting. Different clients can therefore use different preferences against the same remote server. Codex applies the choice per turn. Claude keeps the choice selected when its first session starts in a thread because its system prompt is session-scoped.

The dedicated suggestion model and QA-specific defaults were removed so suggestions follow the current conversation and the user's existing instructions. Thanks for the ghost-text and keyboard interaction work. We kept that part in the new implementation.

@Type-Delta

Copy link
Copy Markdown
Owner

Closing this PR because the feature has been replaced by the client-preference implementation on feat/prompt-suggestion.

@Type-Delta Type-Delta closed this Sep 13, 2026
Wisawathep pushed a commit to Wisawathep/t3code that referenced this pull request Sep 24, 2026
…'s own turn

Opt-in server setting asks Codex and Claude sessions to end each reply with a
tagged one-line proposal for the user's next prompt. Ingestion holds the tag
back from streamed deltas, strips it at completion, and carries the suggestion
on the assistant message through the projection and SQLite (migration 058).
The web composer shows it as ghost text when idle and empty; Tab accepts it.

Replaces the side-call design from PR Type-Delta#1: no extra model call, no separate
suggestion model, no rename setting.

Model: claude-fable-5-1 orchestrating gpt-6-astra, gpt-5.6-luna, claude-opus-5 subagents (Codex harness in T3 Code)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:XL vouch:unvouched PR author is not yet trusted in the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants