Skip to content

Conversation

brendan-kellam
Copy link
Contributor

@brendan-kellam brendan-kellam commented Aug 7, 2025

This PR fixes (or at least reduces) a issue we've seen where the first message in a thread takes longer to generate. I believe this was caused because the "generate title" step was blocking the actual chat stream. I observed ~10-15s generation times for gemini-2.5-pro.

This PR does not address making the title generation faster. Instead, I've made it so the title generation happens asynchronously from the chat stream s.t., it won't block it.

Summary by CodeRabbit

  • New Features

    • Chat names are now automatically generated from the first user message using AI, providing concise and relevant titles for new chats.
  • Bug Fixes

    • Improved validation for chat existence and readonly status before processing messages.
    • Resolved long generation times for the first message in a chat thread.
  • Style

    • Minor stylistic updates to code formatting (no user-facing changes).
  • Refactor

    • Streamlined chat message streaming for improved reliability and maintainability.

@brendan-kellam brendan-kellam requested a review from msukkari August 7, 2025 23:50
Copy link

coderabbitai bot commented Aug 7, 2025

Walkthrough

The changes introduce and integrate a new mechanism for generating and updating chat names using AI models. The chat API route is refactored for clarity and modularity, delegating model selection and streaming logic to new helpers. The chat UI now triggers AI-based chat name generation after the first message, and style fixes are made in a utility file.

Changes

Cohort / File(s) Change Summary
Chat API Refactor & Streaming
packages/web/src/app/api/(server)/chat/route.ts
Refactored chat POST handler: inlined logic, improved validation, delegated model instantiation to a new helper, and introduced createMessageStreamResponse for streaming. Removed chatHandler, simplified flow, and updated error handling.
AI Model Helpers & Chat Name Generation
packages/web/src/features/chat/actions.ts
Added generateAndUpdateChatNameFromMessage to generate chat names using AI models. Introduced _getAISDKLanguageModelAndOptions for model instantiation and provider option resolution. Integrated credential management for multiple providers. No changes to existing functions; new exports added.
Chat UI Integration
packages/web/src/features/chat/components/chatThread/chatThread.tsx
Enhanced sendMessage callback to trigger AI-powered chat name generation after the first user message. Displays error toasts on failure. Updated callback dependencies accordingly. No changes to exports.
Style Fixes
packages/web/src/features/chat/utils.ts
Added missing semicolons to import statements; no functional changes.
Changelog Update
CHANGELOG.md
Added a fixed issue entry for resolving long generation times on the first message in a chat thread.

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant ChatThread (UI)
    participant API Route (POST)
    participant Auth & Org Middleware
    participant Model Helper
    participant AI Model
    participant DB

    User->>ChatThread (UI): Send first message
    ChatThread (UI)->>API Route (POST): POST /chat (message)
    API Route (POST)->>Auth & Org Middleware: Authenticate & check org
    Auth & Org Middleware-->>API Route (POST): Auth result
    API Route (POST)->>DB: Validate chat, check readonly
    DB-->>API Route (POST): Chat info
    API Route (POST)->>Model Helper: Get model & options
    Model Helper-->>API Route (POST): Model instance/options
    API Route (POST)->>AI Model: Stream message response
    AI Model-->>API Route (POST): Streamed data
    API Route (POST)-->>ChatThread (UI): Stream response

    Note over ChatThread (UI): After first message sent
    ChatThread (UI)->>actions.ts: generateAndUpdateChatNameFromMessage
    actions.ts->>Auth & Org Middleware: Authenticate & check org
    actions.ts->>Model Helper: Get AI model
    Model Helper-->>actions.ts: Model instance
    actions.ts->>AI Model: generateText(prompt)
    AI Model-->>actions.ts: Chat name
    actions.ts->>DB: updateChatName
    DB-->>actions.ts: Success
    actions.ts-->>ChatThread (UI): Success/failure
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~40 minutes

Possibly related PRs

  • feat(ask_sb): OpenAI compatible language models #424: Adds support for an "openai-compatible" language model provider in the helper function _getAISDKLanguageModelAndOptions, which is introduced and refactored in this PR, enabling provider support and schema/UI updates.

Suggested reviewers

  • msukkari

Poem

In the warren of code, a new name is spun,
With AI's gentle nudge, chat titles are begun.
Messages stream, models deftly select,
Semicolons align—syntax to perfect!
A rabbit hops by, with a proud little grin,
For chats now have names, where stories begin.
🐇✨

Note

🔌 MCP (Model Context Protocol) integration is now available in Early Access!

Pro users can now connect to remote MCP servers under the Integrations page to get reviews and chat conversations that understand additional development context.

✨ Finishing Touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch bkellam/unblocked_chat_name_gen

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.

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Explain this complex logic.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai explain this code block.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and explain its main purpose.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this PR.
  • @coderabbitai generate unit tests to generate unit tests for this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

This comment has been minimized.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

🧹 Nitpick comments (2)
packages/web/src/features/chat/actions.ts (2)

207-221: Consider extracting the prompt and adding validation.

The prompt is well-crafted but could be extracted to a constant for better maintainability. Additionally, consider validating the generated text length before updating the chat name.

+const CHAT_NAME_GENERATION_PROMPT = `Convert this question into a short topic title (max 50 characters). 
+
+Rules:
+- Do NOT include question words (what, where, how, why, when, which)
+- Do NOT end with a question mark
+- Capitalize the first letter of the title
+- Focus on the subject/topic being discussed
+- Make it sound like a file name or category
+
+Examples:
+"Where is the authentication code?" → "Authentication Code"
+"How to setup the database?" → "Database Setup"
+"What are the API endpoints?" → "API Endpoints"
+
+User question: `;

 export const generateAndUpdateChatNameFromMessage = async ({ chatId, languageModelId, message }: { chatId: string, languageModelId: string, message: string }, domain: string) => sew(() =>
     // ... existing code ...
-            const prompt = `Convert this question into a short topic title (max 50 characters). 
-
-Rules:
-- Do NOT include question words (what, where, how, why, when, which)
-- Do NOT end with a question mark
-- Capitalize the first letter of the title
-- Focus on the subject/topic being discussed
-- Make it sound like a file name or category
-
-Examples:
-"Where is the authentication code?" → "Authentication Code"
-"How to setup the database?" → "Database Setup"
-"What are the API endpoints?" → "API Endpoints"
-
-User question: ${message}`;
+            const prompt = CHAT_NAME_GENERATION_PROMPT + message;

375-562: Add a default case for defensive programming.

While TypeScript should ensure exhaustiveness, adding a default case would provide better runtime safety if an unexpected provider value is encountered.

Add after line 560:

             return {
                 model: xai(modelId),
             };
         }
+        default: {
+            throw new Error(`Unsupported provider: ${provider}`);
+        }
     }
 }
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 26c553c and eaf60ef.

📒 Files selected for processing (4)
  • packages/web/src/app/api/(server)/chat/route.ts (3 hunks)
  • packages/web/src/features/chat/actions.ts (3 hunks)
  • packages/web/src/features/chat/components/chatThread/chatThread.tsx (2 hunks)
  • packages/web/src/features/chat/utils.ts (2 hunks)
🧰 Additional context used
📓 Path-based instructions (1)
**/*

📄 CodeRabbit Inference Engine (.cursor/rules/style.mdc)

Filenames should always be camelCase. Exception: if there are filenames in the same directory with a format other than camelCase, use that format to keep things consistent.

Files:

  • packages/web/src/features/chat/utils.ts
  • packages/web/src/features/chat/components/chatThread/chatThread.tsx
  • packages/web/src/app/api/(server)/chat/route.ts
  • packages/web/src/features/chat/actions.ts
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: build
🔇 Additional comments (6)
packages/web/src/features/chat/utils.ts (1)

1-3: LGTM! Style improvements for consistency.

Adding semicolons to import statements improves code consistency and prevents potential ASI issues.

Also applies to: 17-17

packages/web/src/features/chat/components/chatThread/chatThread.tsx (2)

125-145: Well-implemented async chat name generation!

The fire-and-forget pattern for generating chat names is appropriate here, as it prevents blocking the message stream. Good error handling with user-friendly toast notifications.


146-154: Dependency array correctly updated.

All necessary dependencies are included for the enhanced sendMessage callback.

packages/web/src/features/chat/actions.ts (1)

418-420: Note: Beta header for Anthropic interleaved thinking.

The code uses a beta API feature. Ensure this is monitored for stability and migration when it becomes generally available.

packages/web/src/app/api/(server)/chat/route.ts (2)

54-91: Excellent validation improvements!

The added checks for chat existence and readonly status improve the API's robustness. The error messages are clear and helpful.


137-264: Well-structured stream response creation!

The extracted createMessageStreamResponse function improves code organization and readability. Good separation of concerns with clear parameter passing.

msukkari
msukkari previously approved these changes Aug 8, 2025
@brendan-kellam brendan-kellam force-pushed the bkellam/unblocked_chat_name_gen branch from b95408b to 2706754 Compare August 8, 2025 00:45
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (2)
packages/web/src/features/chat/actions.ts (2)

5-28: Consider dynamic imports for AI SDK providers to reduce bundle size.

While the comprehensive provider support is excellent, importing all AI SDK providers upfront may increase the bundle size significantly. Consider using dynamic imports within the switch cases of _getAISDKLanguageModelAndOptions to only load the required providers at runtime.

For example:

- import { createAmazonBedrock } from '@ai-sdk/amazon-bedrock';
  // ... other static imports

  case 'amazon-bedrock': {
+   const { createAmazonBedrock } = await import('@ai-sdk/amazon-bedrock');
    const aws = createAmazonBedrock({
      // ... configuration
    });

207-221: Consider extracting the prompt template for maintainability.

The hardcoded prompt is well-crafted but could benefit from being extracted to a constant or configuration for easier maintenance and potential localization.

+ const CHAT_NAME_PROMPT_TEMPLATE = `Convert this question into a short topic title (max 50 characters). 
+ 
+ Rules:
+ - Do NOT include question words (what, where, how, why, when, which)
+ - Do NOT end with a question mark
+ - Capitalize the first letter of the title
+ - Focus on the subject/topic being discussed
+ - Make it sound like a file name or category
+ 
+ Examples:
+ "Where is the authentication code?" → "Authentication Code"
+ "How to setup the database?" → "Database Setup"
+ "What are the API endpoints?" → "API Endpoints"
+ 
+ User question: `;

- const prompt = `Convert this question into a short topic title (max 50 characters). 
- 
- Rules:
- - Do NOT include question words (what, where, how, why, when, which)
- - Do NOT end with a question mark
- - Capitalize the first letter of the title
- - Focus on the subject/topic being discussed
- - Make it sound like a file name or category
- 
- Examples:
- "Where is the authentication code?" → "Authentication Code"
- "How to setup the database?" → "Database Setup"
- "What are the API endpoints?" → "API Endpoints"
- 
- User question: ${message}`;
+ const prompt = `${CHAT_NAME_PROMPT_TEMPLATE}${message}`;
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between b95408b and 2706754.

📒 Files selected for processing (5)
  • CHANGELOG.md (1 hunks)
  • packages/web/src/app/api/(server)/chat/route.ts (3 hunks)
  • packages/web/src/features/chat/actions.ts (3 hunks)
  • packages/web/src/features/chat/components/chatThread/chatThread.tsx (2 hunks)
  • packages/web/src/features/chat/utils.ts (2 hunks)
🚧 Files skipped from review as they are similar to previous changes (3)
  • packages/web/src/features/chat/utils.ts
  • CHANGELOG.md
  • packages/web/src/features/chat/components/chatThread/chatThread.tsx
🧰 Additional context used
📓 Path-based instructions (1)
**/*

📄 CodeRabbit Inference Engine (.cursor/rules/style.mdc)

Filenames should always be camelCase. Exception: if there are filenames in the same directory with a format other than camelCase, use that format to keep things consistent.

Files:

  • packages/web/src/features/chat/actions.ts
  • packages/web/src/app/api/(server)/chat/route.ts
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: build
🔇 Additional comments (5)
packages/web/src/features/chat/actions.ts (2)

188-238: LGTM! Well-structured async chat name generation.

The implementation properly addresses the PR objective of making title generation asynchronous. The function has excellent error handling, authentication checks, and prompt engineering with clear rules and examples.


375-562: Excellent centralization of AI model instantiation logic.

This helper function effectively consolidates provider-specific configuration and credential handling, which aligns perfectly with the DRY principle. The secure token retrieval and provider-specific options handling is well implemented.

packages/web/src/app/api/(server)/chat/route.ts (3)

54-106: Excellent refactoring with improved validation and structure.

The integration of validation logic directly into the POST handler improves code clarity and ensures proper checks are performed before processing. The use of the centralized _getAISDKLanguageModelAndOptions helper eliminates code duplication and follows the DRY principle.


137-264: Well-implemented streaming response handler.

The createMessageStreamResponse function effectively handles the complex streaming workflow with proper message processing, repository scope expansion, and metadata collection. The separation of concerns and error handling with Sentry integration demonstrates good architectural practices.


253-258: Good use of onFinish callback for database updates.

The placement of database updates in the onFinish callback ensures that messages are persisted only after successful streaming completion, which prevents partial data corruption in case of stream failures.

@brendan-kellam brendan-kellam merged commit 4f2644d into main Aug 8, 2025
6 checks passed
@brendan-kellam brendan-kellam deleted the bkellam/unblocked_chat_name_gen branch August 8, 2025 04:56
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.

2 participants