Enable thinking mode in full chat view, keep disabled in widget/panel
stream_chat_with_tools now accepts a think parameter. run_generation forwards it to Ollama. The message POST route reads think from the request body. ChatView passes think=true so qwen3 uses chain-of-thought reasoning for full conversations; the dashboard widget and ChatPanel omit it, staying fast. Dashboard button updated to "Think it through in Chat →" to signal the deeper capability. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -120,6 +120,7 @@ export const useChatStore = defineStore("chat", () => {
|
|||||||
content: string,
|
content: string,
|
||||||
contextNoteId?: number | null,
|
contextNoteId?: number | null,
|
||||||
excludeNoteIds?: number[],
|
excludeNoteIds?: number[],
|
||||||
|
think = false,
|
||||||
) {
|
) {
|
||||||
if (!currentConversation.value) return;
|
if (!currentConversation.value) return;
|
||||||
|
|
||||||
@@ -165,6 +166,7 @@ export const useChatStore = defineStore("chat", () => {
|
|||||||
content,
|
content,
|
||||||
context_note_id: contextNoteId,
|
context_note_id: contextNoteId,
|
||||||
exclude_note_ids: excludeNoteIds?.length ? excludeNoteIds : undefined,
|
exclude_note_ids: excludeNoteIds?.length ? excludeNoteIds : undefined,
|
||||||
|
think,
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
assistantMessageId = resp.assistant_message_id;
|
assistantMessageId = resp.assistant_message_id;
|
||||||
|
|||||||
@@ -161,6 +161,7 @@ async function sendMessage() {
|
|||||||
content,
|
content,
|
||||||
contextNoteId,
|
contextNoteId,
|
||||||
excludedNoteIds.value.size ? [...excludedNoteIds.value] : undefined,
|
excludedNoteIds.value.size ? [...excludedNoteIds.value] : undefined,
|
||||||
|
true, // enable thinking in the full chat view
|
||||||
);
|
);
|
||||||
sending.value = false;
|
sending.value = false;
|
||||||
|
|
||||||
|
|||||||
@@ -378,7 +378,7 @@ function clearDashboardResponse() {
|
|||||||
class="btn-open-chat"
|
class="btn-open-chat"
|
||||||
:class="{ prominent: isConversational }"
|
:class="{ prominent: isConversational }"
|
||||||
>
|
>
|
||||||
{{ isConversational ? 'Continue this conversation →' : 'Continue in Chat →' }}
|
{{ isConversational ? 'Continue the conversation →' : 'Think it through in Chat →' }}
|
||||||
</router-link>
|
</router-link>
|
||||||
<button class="btn-clear" @click="clearDashboardResponse">Clear</button>
|
<button class="btn-clear" @click="clearDashboardResponse">Clear</button>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -106,6 +106,7 @@ async def send_message_route(conv_id: int):
|
|||||||
return jsonify({"error": "content is required"}), 400
|
return jsonify({"error": "content is required"}), 400
|
||||||
context_note_id = data.get("context_note_id")
|
context_note_id = data.get("context_note_id")
|
||||||
exclude_note_ids = data.get("exclude_note_ids") or []
|
exclude_note_ids = data.get("exclude_note_ids") or []
|
||||||
|
think = bool(data.get("think", False))
|
||||||
|
|
||||||
# Reject if generation already running for this conversation
|
# Reject if generation already running for this conversation
|
||||||
existing = get_buffer(conv_id)
|
existing = get_buffer(conv_id)
|
||||||
@@ -134,6 +135,7 @@ async def send_message_route(conv_id: int):
|
|||||||
uid, conv_id, conv.title, content,
|
uid, conv_id, conv.title, content,
|
||||||
context_note_id=context_note_id,
|
context_note_id=context_note_id,
|
||||||
exclude_note_ids=exclude_note_ids,
|
exclude_note_ids=exclude_note_ids,
|
||||||
|
think=think,
|
||||||
))
|
))
|
||||||
|
|
||||||
return jsonify({
|
return jsonify({
|
||||||
|
|||||||
@@ -166,6 +166,7 @@ async def run_generation(
|
|||||||
user_content: str,
|
user_content: str,
|
||||||
context_note_id: int | None = None,
|
context_note_id: int | None = None,
|
||||||
exclude_note_ids: list[int] | None = None,
|
exclude_note_ids: list[int] | None = None,
|
||||||
|
think: bool = False,
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Stream LLM response into buffer with periodic DB flushes."""
|
"""Stream LLM response into buffer with periodic DB flushes."""
|
||||||
MAX_TOOL_ROUNDS = 5
|
MAX_TOOL_ROUNDS = 5
|
||||||
@@ -349,7 +350,7 @@ async def run_generation(
|
|||||||
|
|
||||||
buf.append_event("status", {"status": "Generating response..." if _round == 0 else "Composing response..."})
|
buf.append_event("status", {"status": "Generating response..." if _round == 0 else "Composing response..."})
|
||||||
t_stream = time.monotonic()
|
t_stream = time.monotonic()
|
||||||
async for chunk in stream_chat_with_tools(messages, model, tools=tools):
|
async for chunk in stream_chat_with_tools(messages, model, tools=tools, think=think):
|
||||||
if buf.cancel_event.is_set():
|
if buf.cancel_event.is_set():
|
||||||
cancelled = True
|
cancelled = True
|
||||||
break
|
break
|
||||||
|
|||||||
@@ -114,12 +114,17 @@ async def stream_chat_with_tools(
|
|||||||
messages: list[dict],
|
messages: list[dict],
|
||||||
model: str,
|
model: str,
|
||||||
tools: list[dict] | None = None,
|
tools: list[dict] | None = None,
|
||||||
|
think: bool = False,
|
||||||
) -> AsyncGenerator[ChatChunk, None]:
|
) -> AsyncGenerator[ChatChunk, None]:
|
||||||
"""Stream chat completion from Ollama with tool support.
|
"""Stream chat completion from Ollama with tool support.
|
||||||
|
|
||||||
Yields ChatChunk objects. If the model returns tool_calls, a
|
Yields ChatChunk objects. If the model returns tool_calls, a
|
||||||
ChatChunk(type="tool_calls") is yielded. Always ends with
|
ChatChunk(type="tool_calls") is yielded. Always ends with
|
||||||
ChatChunk(type="done").
|
ChatChunk(type="done").
|
||||||
|
|
||||||
|
Set think=True to enable the model's chain-of-thought reasoning (qwen3+).
|
||||||
|
Thinking tokens are consumed by Ollama and not forwarded to the caller;
|
||||||
|
only the final response content is yielded. Expect higher TTFT when enabled.
|
||||||
"""
|
"""
|
||||||
options: dict = {"num_ctx": 32768}
|
options: dict = {"num_ctx": 32768}
|
||||||
if tools:
|
if tools:
|
||||||
@@ -129,7 +134,7 @@ async def stream_chat_with_tools(
|
|||||||
"messages": messages,
|
"messages": messages,
|
||||||
"stream": True,
|
"stream": True,
|
||||||
"options": options,
|
"options": options,
|
||||||
"think": False,
|
"think": think,
|
||||||
}
|
}
|
||||||
if tools:
|
if tools:
|
||||||
payload["tools"] = tools
|
payload["tools"] = tools
|
||||||
|
|||||||
Reference in New Issue
Block a user