-
-
Notifications
You must be signed in to change notification settings - Fork 18
feat: add chat name update functionality and improve AI response handling #1548
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull request overview
Adds automatic chat naming for new AI conversations and tightens AI JSON-output handling to reduce parsing failures.
Changes:
- Generate a chat title on first user message for newly created AI chats and persist it.
- Extend
IUserAiChatRepositorywithupdateChatNameand implement it in the repository extension. - Strengthen the AI prompt guidance and post-processing for JSON responses (remove comments / trailing commas).
Reviewed changes
Copilot reviewed 5 out of 5 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
| backend/src/entities/ai/use-cases/request-info-from-table-with-ai-v7.use.case.ts | Triggers background chat-title generation for new chats and updates the persisted chat name. |
| backend/src/entities/ai/ai.service.ts | Updates the LLM prompt to emphasize strict JSON-only output with no comments. |
| backend/src/entities/ai/ai-conversation-history/user-ai-chat/repository/user-ai-chat-repository.interface.ts | Adds updateChatName to the repository interface. |
| backend/src/entities/ai/ai-conversation-history/user-ai-chat/repository/user-ai-chat-repository.extension.ts | Implements updateChatName via a TypeORM update query. |
| backend/src/ai-core/tools/query-validators.ts | Expands AI JSON cleaning to strip comment syntax and trailing commas before parsing. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| this.generateAndUpdateChatName(foundUserAiChat.id, user_message).catch((error) => { | ||
| Sentry.captureException(error); | ||
| }); |
Copilot
AI
Jan 30, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
generateAndUpdateChatName() already catches and reports errors internally, so the additional .catch(...) here will never run and makes the async fire-and-forget behavior harder to reason about. Either remove the outer .catch and explicitly mark the call as fire-and-forget (e.g., void ...), or remove the internal try/catch and handle errors only at the call site (but avoid double-reporting).
| this.generateAndUpdateChatName(foundUserAiChat.id, user_message).catch((error) => { | |
| Sentry.captureException(error); | |
| }); | |
| void this.generateAndUpdateChatName(foundUserAiChat.id, user_message); |
| findChatByIdAndUserId(chatId: string, userId: string): Promise<UserAiChatEntity | null>; | ||
| findChatWithMessagesByIdAndUserId(chatId: string, userId: string): Promise<UserAiChatEntity | null>; | ||
| createChatForUser(userId: string, name?: string): Promise<UserAiChatEntity>; | ||
| updateChatName(chatId: string, name: string): Promise<void>; |
Copilot
AI
Jan 30, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
updateChatName is defined without a userId parameter, unlike the other repository methods that scope operations by chatId + userId. To avoid accidental cross-tenant updates, consider changing this API to updateChatName(chatId: string, userId: string, name: string) (or similar) so implementations can enforce ownership at the data layer.
| updateChatName(chatId: string, name: string): Promise<void>; | |
| updateChatName(chatId: string, userId: string, name: string): Promise<void>; |
| async updateChatName(chatId: string, name: string): Promise<void> { | ||
| await this.createQueryBuilder() | ||
| .update(UserAiChatEntity) | ||
| .set({ name }) | ||
| .where('id = :chatId', { chatId }) |
Copilot
AI
Jan 30, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This update query scopes only by id. Since chats are user-owned (and other repo methods require userId), this should also include user_id = :userId (and accept userId as a parameter) to prevent updating another user's chat if a UUID is ever reused/leaked/passed incorrectly.
| async updateChatName(chatId: string, name: string): Promise<void> { | |
| await this.createQueryBuilder() | |
| .update(UserAiChatEntity) | |
| .set({ name }) | |
| .where('id = :chatId', { chatId }) | |
| async updateChatName(chatId: string, userId: string, name: string): Promise<void> { | |
| await this.createQueryBuilder() | |
| .update(UserAiChatEntity) | |
| .set({ name }) | |
| .where('id = :chatId AND user_id = :userId', { chatId, userId }) |
| cleanedResponse = cleanedResponse.replace(/^\s*\/\/.*$/gm, ''); | ||
| cleanedResponse = cleanedResponse.replace(/\/\*[\s\S]*?\*\//g, ''); | ||
| cleanedResponse = cleanedResponse.replace(/,(\s*[}\]])/g, '$1'); |
Copilot
AI
Jan 30, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The block-comment stripping regex (/\/\*[\s\S]*?\*\//g) will also remove /* ... */ sequences that appear inside valid JSON string values, mutating otherwise-correct AI responses (e.g., a description containing those characters). Consider using a comment-tolerant parser (e.g., JSON5) or implementing a small scanner that removes comments only when not inside quoted strings.
No description provided.