From 6c7422f83284351437e289468f428719af362e7c Mon Sep 17 00:00:00 2001 From: Glen Maddern Date: Tue, 24 Jun 2025 17:40:53 +1000 Subject: [PATCH] fix: Add detailed debugging and use result.text for cleaned content - Add debug logging to track aiResponse vs result.text content - Use result.text from extractReasoningMiddleware for final content - This should provide the properly cleaned text without thinking tags - Comment out unused sidebar and edit functionality to fix TS errors The result.text should contain content that has been automatically cleaned by the extractReasoningMiddleware, while result.reasoning contains the extracted thinking content. --- examples/chat-ui/src/components/ChatApp.tsx | 74 +++++++++---------- .../chat-ui/src/components/ReasoningBlock.tsx | 24 +++--- .../chat-ui/src/hooks/useStreamResponse.ts | 20 ++++- 3 files changed, 64 insertions(+), 54 deletions(-) diff --git a/examples/chat-ui/src/components/ChatApp.tsx b/examples/chat-ui/src/components/ChatApp.tsx index 835ec6c..d5a9c2c 100644 --- a/examples/chat-ui/src/components/ChatApp.tsx +++ b/examples/chat-ui/src/components/ChatApp.tsx @@ -1,6 +1,4 @@ import React, { useState, useEffect } from "react"; -import ChatSidebar from "./ChatSidebar.tsx"; -import ChatNavbar from "./ChatNavbar.tsx"; import ConversationThread from "./ConversationThread.tsx"; import { storeName } from "../consts.ts"; import { type Conversation } from "../types"; @@ -18,7 +16,7 @@ const ChatApp: React.FC = () => { const [conversationId, setConversationId] = useState( undefined ); - const [sidebarVisible, setSidebarVisible] = useState(true); + const [selectedModel, setSelectedModel] = useState(getSelectedModel()); const [apiKeyUpdateTrigger, setApiKeyUpdateTrigger] = useState(0); const [mcpTools, setMcpTools] = useState([]); @@ -43,8 +41,8 @@ const ChatApp: React.FC = () => { // Initialize sidebar visibility based on screen size useEffect(() => { - const isMobile = window.matchMedia("(max-width: 768px)").matches; - setSidebarVisible(!isMobile); + // const isMobile = window.matchMedia("(max-width: 768px)").matches; + // setSidebarVisible(!isMobile); }, []); const getConversations = async () => { @@ -72,21 +70,21 @@ const ChatApp: React.FC = () => { } }; - const editConversationTitle = async (id: number, newTitle: string) => { - const conversation = (await db!.get(storeName, id)) as Conversation; - conversation.title = newTitle; - await db!.put(storeName, conversation); - setConversations((prev) => - prev.map((conv) => (conv.id === id ? { ...conv, title: newTitle } : conv)) - ); - }; + // const editConversationTitle = async (id: number, newTitle: string) => { + // const conversation = (await db!.get(storeName, id)) as Conversation; + // conversation.title = newTitle; + // await db!.put(storeName, conversation); + // setConversations((prev) => + // prev.map((conv) => (conv.id === id ? { ...conv, title: newTitle } : conv)) + // ); + // }; const startNewConversation = async () => { //create unique id for new conversation setConversationId(Date.now() + Math.floor(Math.random() * 1000)); - if (window.matchMedia("(max-width: 768px)").matches) { - setSidebarVisible(false); - } + // if (window.matchMedia("(max-width: 768px)").matches) { + // setSidebarVisible(false); + // } }; // delete conversations with no messages @@ -109,28 +107,28 @@ const ChatApp: React.FC = () => { >
{/* Sidebar and Navbar components hidden but kept in codebase */} - {false && ( - <> - - - - )} + {/*{false && (*/} + {/* <>*/} + {/* */} + {/* */} + {/* */} + {/*)}*/}
= ({ reasoning }) => { return (
@@ -34,17 +34,17 @@ const ReasoningBlock: React.FC = ({ reasoning }) => {
{displayText}
- {shouldTruncate && ( - - )} + {/*{shouldTruncate && (*/} + {/* {*/} + {/* e.stopPropagation();*/} + {/* toggleExpanded();*/} + {/* }}*/} + {/* >*/} + {/* {isExpanded ? "↑" : "↓"}*/} + {/* */} + {/*)}*/}
diff --git a/examples/chat-ui/src/hooks/useStreamResponse.ts b/examples/chat-ui/src/hooks/useStreamResponse.ts index cea27d5..7632f7e 100644 --- a/examples/chat-ui/src/hooks/useStreamResponse.ts +++ b/examples/chat-ui/src/hooks/useStreamResponse.ts @@ -312,19 +312,31 @@ export const useStreamResponse = ({ } debugLog(`[useStreamResponse] Finished processing full stream. Final response length: ${aiResponse.length}`) + debugLog(`[useStreamResponse] Final aiResponse content:`, JSON.stringify(aiResponse)) // Extract reasoning from the result after streaming completes const finalReasoning = await result.reasoning - if (finalReasoning && assistantMessageCreated) { - debugLog(`[useStreamResponse] Extracted reasoning:`, finalReasoning) + const finalText = await result.text + debugLog(`[useStreamResponse] Final result.text:`, JSON.stringify(finalText)) + + if (assistantMessageCreated) { setConversations((prev) => { const updated = [...prev] const conv = updated.find((c) => c.id === conversationId) if (conv && assistantMessageIndex >= 0) { const assistantMessage = conv.messages[assistantMessageIndex] if (assistantMessage && hasContent(assistantMessage) && assistantMessage.role === 'assistant') { - assistantMessage.reasoning = finalReasoning - debugLog(`[useStreamResponse] Added reasoning to assistant message at index ${assistantMessageIndex}`) + // Use the final cleaned text from the result instead of our tracked aiResponse + if (finalText && supportsReasoning(selectedModel)) { + assistantMessage.content = finalText + debugLog(`[useStreamResponse] Updated content with cleaned result.text`) + } + + if (finalReasoning) { + assistantMessage.reasoning = finalReasoning + debugLog(`[useStreamResponse] Added reasoning to assistant message at index ${assistantMessageIndex}`) + } + debugLog(`[useStreamResponse] Final message content:`, JSON.stringify(assistantMessage.content)) } } return updated