feat(threads): auto-generate first-turn thread titles#1375
feat(threads): auto-generate first-turn thread titles#1375maria-rcks wants to merge 9 commits intopingdotgg:mainfrom
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 Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
b256e14 to
5335f66
Compare
5335f66 to
6e727cd
Compare
af6a180 to
aefb74c
Compare
| ); | ||
|
|
||
| await waitFor(() => harness.generateBranchName.mock.calls.length === 1); | ||
| expect(harness.generateBranchName.mock.calls[0]?.[0]).toMatchObject({ |
There was a problem hiding this comment.
🟠 High Layers/ProviderCommandReactor.test.ts:417
The assertion at line 417 checks for a top-level model field, but generateBranchName receives BranchNameGenerationInput which has modelSelection: { provider, model } — no model key exists at the top level. The test will fail because toMatchObject({ model: "gpt-5.4-mini" }) doesn't match the actual object structure. Update the assertion to check modelSelection.model instead.
🤖 Copy this AI Prompt to have your agent fix this:
In file apps/server/src/orchestration/Layers/ProviderCommandReactor.test.ts around line 417:
The assertion at line 417 checks for a top-level `model` field, but `generateBranchName` receives `BranchNameGenerationInput` which has `modelSelection: { provider, model }` — no `model` key exists at the top level. The test will fail because `toMatchObject({ model: "gpt-5.4-mini" })` doesn't match the actual object structure. Update the assertion to check `modelSelection.model` instead.
Evidence trail:
- apps/server/src/orchestration/Layers/ProviderCommandReactor.test.ts:417: Test asserts `toMatchObject({ model: "gpt-5.4-mini" })`
- apps/server/src/git/Services/TextGeneration.ts:52-58: `BranchNameGenerationInput` defines `modelSelection: ModelSelection` (no top-level `model`)
- packages/contracts/src/orchestration.ts:47-62: `ModelSelection` is a union of types with `{ provider, model }` structure
- apps/server/src/orchestration/Layers/ProviderCommandReactor.ts:426-434: Actual call passes `{ modelSelection: { provider: "codex", model: ... } }`
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 1 potential issue.
Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
| expect(harness.generateBranchName.mock.calls[0]?.[0]).toMatchObject({ | ||
| model: "gpt-5.4-mini", | ||
| message: "Add a safer reconnect backoff.", | ||
| }); |
There was a problem hiding this comment.
Test asserts wrong path for nested model property
Medium Severity
The test asserts toMatchObject({ model: "gpt-5.4-mini" }) expecting a top-level model property, but generateBranchName receives the model nested inside modelSelection: { provider: "codex", model: "gpt-5.4-mini" } per the BranchNameGenerationInput interface. There is no top-level model on the input object, so the toMatchObject assertion will fail. The mock's "model" in input check (line 391) is similarly wrong—it always evaluates to false, making the mock always return "feature/generated" instead of the model-derived branch. The correct assertion path is modelSelection: { model: "gpt-5.4-mini" }.


Closes #990
What Changed
Why
Thread titles were still just truncated prompt text.
This makes new threads easier to scan while keeping the model selection simpler and reusing the same text generation path we already have for commit, PR, and branch text.
UI Changes
Settings now says
Text generation modelChecklist
Note
Medium Risk
Touches orchestration flow and shared contracts by introducing a new
textGenerationModelfield and server-side async title/branch generation on first turn; failures are logged and forked but could still impact thread metadata updates.Overview
Auto-generates a thread title on the first user turn by forking a server-side
generateThreadTitlecall and dispatchingthread.meta.updatewhen it succeeds (kept off the critical path for turn start).Extends the
TextGenerationservice withgenerateThreadTitle(implemented via Codex with title sanitization/truncation and attachment-aware prompting; Claude explicitly errors), and reuses the same per-threadtextGenerationModelfor both first-turn title generation and temporary worktree branch renaming.Plumbs
textGenerationModelthrough the orchestration contract and web UIthread.turn.startdispatch, and updates settings copy from “Git writing model” to “Text generation model”.Written by Cursor Bugbot for commit aefb74c. This will update automatically on new commits. Configure here.
Note
Auto-generate thread titles on the first user turn using Codex
ProviderCommandReactornow forks two concurrent tasks: rename the worktree branch and generate a thread title viaTextGeneration.generateThreadTitle.CodexTextGenerationwith asanitizeThreadTitlehelper that trims, removes surrounding quotes/backticks, collapses whitespace, defaults to"New thread"if blank, and truncates to 50 characters with ellipsis.ClaudeTextGenerationreturns aTextGenerationErrorforgenerateThreadTitlesince it is Codex-only;RoutingTextGenerationalways delegates this method to Codex regardless of provider.thread.turn.startcommand andthread.turn-start-requestedevent now carry an optionaltextGenerationModelfield, passed from the web client's selected text generation model setting.Macroscope summarized aefb74c.