Enable automatic web search by default; improve toggle behavior and search planning.
CI / check (22) (push) Successful in 9m35s
CI / check (24) (push) Successful in 9m34s

This commit is contained in:
2026-10-06 08:50:03 +02:00
parent 674abf78f6
commit 7be654af11
17 changed files with 300 additions and 54 deletions
+24 -2
View File
@@ -2,6 +2,7 @@ import test from "node:test";
import assert from "node:assert/strict";
import {createComposerController} from "../public/js/composerController.js";
import {createConversationState} from "../public/js/conversationState.js";
import {createWebSearchToggle} from "../public/js/webSearch.js";
const deferred = () => { let resolve; const promise = new Promise(done => { resolve = done; }); return {promise, resolve}; };
const noop = () => {};
@@ -11,9 +12,11 @@ function fixture(overrides = {}) {
const state = createConversationState();
const elements = {msgInput: element(), sendBtn: element(), messagesDiv: element(), modelSelect: {value: "original-model"}};
const calls = {create: 0, streams: [], refresh: [], notices: []};
const webSearchButton = {...element(), addEventListener: (_event, handler) => { webSearchButton.click = handler; }};
const webSearchToggle = createWebSearchToggle(webSearchButton);
const controller = createComposerController({state, elements,
attachmentComposer: {pending: false, attachments: [], setBusy: noop, clear: noop, clearSentDraft: noop},
webSearchButton: element(), reasoningToggle: {enabled: true, setBusy: noop, reset: noop}, webSearchToggle: {enabled: true, reset: noop},
webSearchButton, reasoningToggle: {enabled: true, setBusy: noop, reset: noop}, webSearchToggle,
setChatActivity: noop, updateComposerPlaceholder: noop, setNotice: message => calls.notices.push(message),
createNewChat: async () => {
calls.create++;
@@ -32,9 +35,28 @@ function fixture(overrides = {}) {
handlers.onDone({reply: "Done"});
}}
});
return {state, elements, calls, ...controller};
return {state, elements, calls, webSearchButton, webSearchToggle, ...controller};
}
test("search stays enabled across sends and honors a persistent manual opt-out", async () => {
const s = fixture();
for (const message of ["First question", "Follow-up question"]) {
s.elements.msgInput.value = message;
await s.sendMessage();
}
s.webSearchButton.click();
for (const message of ["Offline question", "Another offline question"]) {
s.elements.msgInput.value = message;
await s.sendMessage();
}
assert.deepEqual(s.calls.streams.map(payload => payload.webSearch), [true, true, false, false]);
assert.equal(s.webSearchToggle.enabled, false);
s.webSearchButton.click();
s.elements.msgInput.value = "Search is allowed again";
await s.sendMessage();
assert.equal(s.calls.streams.at(-1).webSearch, true);
});
test("rapid sends lock before chat creation and keep the captured chat/model after navigation during rename", async () => {
const creation = deferred(), rename = deferred();
const s = fixture({creation: creation.promise, rename: rename.promise});