Show Qwen3 thinking output in chat as collapsible Reasoning block
Ollama streams message.thinking tokens alongside message.content when think=True — previously silently dropped. Now forwarded end-to-end. Backend: - llm.py: ChatChunk type gains "thinking" variant; stream_chat_with_tools yields ChatChunk(type="thinking") for msg.thinking chunks before content - generation_task.py: thinking chunks emit "thinking_chunk" SSE events (not added to content_so_far — not persisted to DB) Frontend: - types/chat.ts: Message.thinking?: string (session-only, not from DB) - stores/chat.ts: streamingThinking ref; thinking_chunk handler accumulates chunks; on done, thinking carried into committed Message object then cleared - ChatMessage.vue: collapsible <details class="thinking-block"> shown for messages that have .thinking content (collapsed by default) - ChatView.vue + ChatPanel.vue: live thinking block in streaming bubble — open while only thinking is flowing, auto-collapses when content arrives; typing indicator hidden while thinking is active Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -27,6 +27,7 @@ export const useChatStore = defineStore("chat", () => {
|
||||
const loading = ref(false);
|
||||
const streaming = ref(false);
|
||||
const streamingContent = ref("");
|
||||
const streamingThinking = ref("");
|
||||
const streamingToolCalls = ref<ToolCallRecord[]>([]);
|
||||
const streamingStatus = ref("");
|
||||
const streamingPendingTool = ref<ToolPendingRecord | null>(null);
|
||||
@@ -206,6 +207,9 @@ export const useChatStore = defineStore("chat", () => {
|
||||
case "status":
|
||||
streamingStatus.value = event.data.status as string;
|
||||
break;
|
||||
case "thinking_chunk":
|
||||
streamingThinking.value += event.data.chunk as string;
|
||||
break;
|
||||
case "chunk":
|
||||
streamingContent.value += event.data.chunk as string;
|
||||
streamingStatus.value = "";
|
||||
@@ -235,11 +239,13 @@ export const useChatStore = defineStore("chat", () => {
|
||||
: null,
|
||||
created_at: new Date().toISOString(),
|
||||
timing: event.data.timing as GenerationTiming | undefined,
|
||||
thinking: streamingThinking.value || undefined,
|
||||
};
|
||||
if (currentConversation.value?.id === convId) {
|
||||
currentConversation.value.messages.push(assistantMsg);
|
||||
}
|
||||
streamingContent.value = "";
|
||||
streamingThinking.value = "";
|
||||
streamingToolCalls.value = [];
|
||||
streamingStatus.value = "";
|
||||
streamingPendingTool.value = null;
|
||||
@@ -257,6 +263,7 @@ export const useChatStore = defineStore("chat", () => {
|
||||
gotDone = true;
|
||||
streaming.value = false;
|
||||
streamingContent.value = "";
|
||||
streamingThinking.value = "";
|
||||
streamingToolCalls.value = [];
|
||||
streamingStatus.value = "";
|
||||
streamingPendingTool.value = null;
|
||||
@@ -296,6 +303,7 @@ export const useChatStore = defineStore("chat", () => {
|
||||
|
||||
streaming.value = false;
|
||||
streamingContent.value = "";
|
||||
streamingThinking.value = "";
|
||||
streamingToolCalls.value = [];
|
||||
streamingStatus.value = "";
|
||||
streamingPendingTool.value = null;
|
||||
@@ -397,6 +405,7 @@ export const useChatStore = defineStore("chat", () => {
|
||||
loading,
|
||||
streaming,
|
||||
streamingContent,
|
||||
streamingThinking,
|
||||
streamingToolCalls,
|
||||
streamingStatus,
|
||||
streamingPendingTool,
|
||||
|
||||
Reference in New Issue
Block a user