diff --git a/backend/src/entities/ai/use-cases/request-info-from-table-with-ai-v7.use.case.ts b/backend/src/entities/ai/use-cases/request-info-from-table-with-ai-v7.use.case.ts index 837190d3b..e9fbd93cf 100644 --- a/backend/src/entities/ai/use-cases/request-info-from-table-with-ai-v7.use.case.ts +++ b/backend/src/entities/ai/use-cases/request-info-from-table-with-ai-v7.use.case.ts @@ -171,9 +171,8 @@ export class RequestInfoFromTableWithAIUseCaseV7 for await (const chunk of stream) { if (chunk.type === 'text' && chunk.content) { - response.write(chunk.content); accumulatedContent += chunk.content; - totalAccumulatedResponse += chunk.content; + this.writeChunk(response, { type: 'thinking', content: chunk.content }); } if (chunk.type === 'tool_call' && chunk.toolCall) { @@ -191,13 +190,15 @@ export class RequestInfoFromTableWithAIUseCaseV7 ); if (pendingToolCalls.length === 0) { + this.writeChunk(response, { type: 'thinking_commit' }); + totalAccumulatedResponse += accumulatedContent; break; } + this.writeChunk(response, { type: 'thinking_reset' }); + for (const toolCall of pendingToolCalls) { - this.logger.log( - `Tool call: ${toolCall.name}, arguments=${JSON.stringify(toolCall.arguments)}`, - ); + this.logger.log(`Tool call: ${toolCall.name}, arguments=${JSON.stringify(toolCall.arguments)}`); } const toolResults = await this.executeToolCalls( @@ -209,9 +210,7 @@ export class RequestInfoFromTableWithAIUseCaseV7 ); for (const toolResult of toolResults) { - this.logger.log( - `Tool result for ${toolResult.toolCallId}: resultLength=${toolResult.result.length}`, - ); + this.logger.log(`Tool result for ${toolResult.toolCallId}: resultLength=${toolResult.result.length}`); } if (this.aiProvider === AIProviderType.OPENAI && lastResponseId) { @@ -227,9 +226,7 @@ export class RequestInfoFromTableWithAIUseCaseV7 depth++; } catch (loopError) { - this.logger.error( - `Error in tool loop at depth ${depth + 1}: ${loopError.message}`, - ); + this.logger.error(`Error in tool loop at depth ${depth + 1}: ${loopError.message}`); throw loopError; } } @@ -238,13 +235,24 @@ export class RequestInfoFromTableWithAIUseCaseV7 this.logger.warn(`Tool loop reached max depth (${this.maxDepth})`); const maxDepthMessage = '\n\nYour question is too complex to process at this time. Please try simplifying it or breaking it down into smaller parts.'; - response.write(maxDepthMessage); + this.writeChunk(response, { type: 'text', content: maxDepthMessage }); totalAccumulatedResponse += maxDepthMessage; } return { lastResponseId, accumulatedResponse: totalAccumulatedResponse }; } + private writeChunk( + response: Response, + chunk: + | { type: 'thinking'; content: string } + | { type: 'thinking_reset' } + | { type: 'thinking_commit' } + | { type: 'text'; content: string }, + ): void { + response.write(JSON.stringify(chunk) + '\n'); + } + private async executeToolCalls( toolCalls: AIToolCall[], dataAccessObject: IDataAccessObject | IDataAccessObjectAgent, @@ -306,9 +314,7 @@ export class RequestInfoFromTableWithAIUseCaseV7 result = encodeError({ error: `Unknown tool: ${toolCall.name}` }); } } catch (error) { - this.logger.error( - `Tool call ${toolCall.name} (${toolCall.id}) failed: ${error.message}`, - ); + this.logger.error(`Tool call ${toolCall.name} (${toolCall.id}) failed: ${error.message}`); result = encodeError({ error: error.message }); } diff --git a/frontend/src/app/components/dashboard/db-table-view/db-table-ai-panel/db-table-ai-panel.component.css b/frontend/src/app/components/dashboard/db-table-view/db-table-ai-panel/db-table-ai-panel.component.css index 7d13c206f..507a5c926 100644 --- a/frontend/src/app/components/dashboard/db-table-view/db-table-ai-panel/db-table-ai-panel.component.css +++ b/frontend/src/app/components/dashboard/db-table-view/db-table-ai-panel/db-table-ai-panel.component.css @@ -298,6 +298,21 @@ } } +.ai-thinking { + font-size: 12px; + line-height: 1.5; + color: rgba(0, 0, 0, 0.5); + font-style: italic; + white-space: pre-wrap; + word-break: break-word; +} + +@media (prefers-color-scheme: dark) { + .ai-thinking { + color: rgba(255, 255, 255, 0.5); + } +} + .ai-error-message { border-radius: 8px; padding: 8px 8px 0; diff --git a/frontend/src/app/components/dashboard/db-table-view/db-table-ai-panel/db-table-ai-panel.component.html b/frontend/src/app/components/dashboard/db-table-view/db-table-ai-panel/db-table-ai-panel.component.html index 5c23eb5fd..4007b624e 100644 --- a/frontend/src/app/components/dashboard/db-table-view/db-table-ai-panel/db-table-ai-panel.component.html +++ b/frontend/src/app/components/dashboard/db-table-view/db-table-ai-panel/db-table-ai-panel.component.html @@ -9,10 +9,10 @@
{{category.title}}