Skip to content

feat: add manual chat title regeneration#23633

Draft
ibetitsmike wants to merge 10 commits intomainfrom
mike/regenerate-chat-title
Draft

feat: add manual chat title regeneration#23633
ibetitsmike wants to merge 10 commits intomainfrom
mike/regenerate-chat-title

Conversation

@ibetitsmike
Copy link
Collaborator

Summary

Adds a "Generate new title" action that lets users manually regenerate a chat's title using richer conversation context than the automatic first-message title path.

Changes

Backend

  • New endpoint: POST /api/experimental/chats/{chatID}/title/regenerate returns the updated Chat with a regenerated title
  • Manual title algorithm: Extracts useful user/assistant text turns → selects first user turn + last 3 turns → builds context with gap markers → renders prompt with anti-recency guidance → calls lightweight model → normalizes output
  • Helpers: extractManualTitleTurns, selectManualTitleTurnIndexes, buildManualTitleContext, renderManualTitlePrompt, generateManualTitle — all private, with the public Server.RegenerateChatTitle method
  • SDK: ExperimentalClient.RegenerateChatTitle(ctx, chatID) (Chat, error)
  • Persists title via existing UpdateChatByID and broadcasts ChatEventKindTitleChange

Frontend

  • API client method + React Query mutation with cache invalidation
  • "Generate new title" menu item (with wand icon) in both TopBar and Sidebar dropdown menus
  • Loading/disabled state while regeneration is in-flight
  • Error toast on failure
  • Stories updated for both menus

Tests

  • quickgen_test.go: Table-driven tests for all 4 helper functions (turn extraction, index selection, context building, prompt rendering)
  • exp_chats_test.go: Handler tests (ChatNotFound, NotFoundForDifferentUser, NoDaemon)

Design notes

  • The existing auto-title path (maybeGenerateChatTitle, titleInput) is completely unchanged
  • Manual regeneration uses richer context (first user turn + last 3 turns + gap markers) vs the auto path's single first message
  • Endpoint is experimental and marked with @x-apidocgen {"skip": true}

@ibetitsmike ibetitsmike changed the title feat(coderd/x/chatd): add manual chat title regeneration feat: add manual chat title regeneration Mar 25, 2026
@ibetitsmike
Copy link
Collaborator Author

@codex review

Copy link

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: b3f2716058

ℹ️ 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".

@ibetitsmike
Copy link
Collaborator Author

@codex review

Copy link

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 961c2449db

ℹ️ 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".

@ibetitsmike
Copy link
Collaborator Author

@codex review

Copy link

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: ca1ea4ef2d

ℹ️ 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".

@ibetitsmike
Copy link
Collaborator Author

@codex review

Copy link

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: d03c928f19

ℹ️ 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".

seedInfiniteChats(queryClient, [cachedChat]);

const mutation = regenerateChatTitle(queryClient);
const updatedChat = makeChat(chatId, { title: "New title" });

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P3 Badge Use an actual partial response in merge test

This test claims to verify behavior when the regenerate API returns a partial chat, but makeChat(chatId, { title: "New title" }) still produces a fully populated object. That means the test cannot catch regressions where omitted fields (for example diff_status) are accidentally dropped during merge, so the new coverage does not validate the scenario it names.

Useful? React with 👍 / 👎.

@ibetitsmike
Copy link
Collaborator Author

@codex review

Copy link

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 7782b3ac63

ℹ️ 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".

return database.Chat{}, xerrors.Errorf("resolve chat model: %w", err)
}

title, err := generateManualTitle(ctx, chat, messages, model, keys, p.logger)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Enforce spend limits before manual title regeneration

RegenerateChatTitle invokes generateManualTitle (an LLM call) without running checkUsageLimit, unlike the existing chat write paths (CreateChat, SendMessage, and EditMessage) that block over-limit users before model work. As written, a user who has already hit their chat spend cap can still repeatedly call POST /api/experimental/chats/{chat}/title/regenerate and incur additional model usage; add the same owner-based limit check before resolving models or generating the title.

Useful? React with 👍 / 👎.

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.

1 participant