fix(chat): gate qwen3 thinking on message content instead of always-on
The frontend hardcoded think=true on every chat send (ChatPanel full + widget variants, KnowledgeView minichat), which defeated the _should_think gate on the backend and made qwen3:14b spend 5-20s on chain-of-thought reasoning for every turn — even "hi". This was the root cause of the warm-path TTFT variance tracked in followup_ttft_variance.md: the logged ttft_ms was really prefill + full thinking phase, bouncing with the depth of the model's reasoning, not with cache or eviction. All three frontend callers now pass think=false and let _should_think be authoritative. The classifier is now a real content-based gate: explicit think_requested=True still forces on as an override (briefing discuss actions, future UI toggles, MCP callers), otherwise messages <80 chars without reasoning keywords skip thinking, messages >=400 chars or containing keywords like why/explain/analyze/debug/review/etc. get it. Generation timing now separately records think_requested, the final think decision, first_token_ms (first any chunk), and thinking_ms (duration of the thinking phase). ttft_ms keeps its existing semantic (first content token) so existing log analysis still works. The timing log line surfaces all four fields so the old "just a big ttft number" ambiguity is gone. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -208,7 +208,7 @@ async function onSubmit(payload: { content: string; contextNoteId?: number }) {
|
||||
payload.content,
|
||||
payload.contextNoteId,
|
||||
includedNoteIds.value.size ? [...includedNoteIds.value] : undefined,
|
||||
true,
|
||||
false,
|
||||
undefined,
|
||||
excludedNoteIds.value.length ? excludedNoteIds.value : undefined,
|
||||
props.projectId ?? store.ragProjectId,
|
||||
@@ -249,7 +249,7 @@ async function widgetSend(payload: { content: string; contextNoteId?: number })
|
||||
widgetConvId.value = conv.id
|
||||
emit('conversation-started', conv.id)
|
||||
|
||||
await store.sendMessage(payload.content, payload.contextNoteId, undefined, true)
|
||||
await store.sendMessage(payload.content, payload.contextNoteId, undefined, false)
|
||||
|
||||
const msgs = store.currentConversation?.messages ?? []
|
||||
const lastAssistant = [...msgs].reverse().find((m: Message) => m.role === 'assistant')
|
||||
|
||||
@@ -255,7 +255,7 @@ async function onMinichatSubmit(payload: { content: string; contextNoteId?: numb
|
||||
}
|
||||
chatOpen.value = true;
|
||||
chatCollapsed.value = false;
|
||||
await chatStore.sendMessage(payload.content, payload.contextNoteId, undefined, true);
|
||||
await chatStore.sendMessage(payload.content, payload.contextNoteId, undefined, false);
|
||||
}
|
||||
|
||||
// ─── Auto-refresh cards when chat creates/edits notes or tasks ───────────────
|
||||
|
||||
Reference in New Issue
Block a user