improve reasoning toggle tests and refactor model capability checks
This commit is contained in:
+76
-4
@@ -4,7 +4,7 @@ import {createServer} from "node:http";
|
||||
import {createApp} from "../src/app.js";
|
||||
import {createChatService} from "../src/services/chatService.js";
|
||||
import {runMigrations} from "../src/db/schema.js";
|
||||
import {SearXNGSearchProvider, WebSearchError, buildWebSearchContext, buildWebSearchQuery, decideWebSearch, selectSearchResults} from "../src/services/webSearchService.js";
|
||||
import {SearXNGSearchProvider, WebSearchError, buildWebSearchContext, buildWebSearchQuery, decideWebSearch, selectSearchResults, retrieveWebSearch} from "../src/services/webSearchService.js";
|
||||
import {createModelService} from "../src/services/modelService.js";
|
||||
import {formatChatMessage} from "../src/services/chatMessageHelpers.js";
|
||||
import {appendSources, createWebSearchToggle} from "../public/app/webSearch.js";
|
||||
@@ -57,7 +57,8 @@ test("SearXNG encodes queries, limits results and treats result data as untruste
|
||||
});
|
||||
|
||||
test("search decisions and source selection use only relevant, renumbered evidence", () => {
|
||||
assert.deepEqual(decideWebSearch("What date is it today?"), {needsSearch: false, intent: "runtime"});
|
||||
assert.equal(decideWebSearch("What date is it today?").shouldSearch, false);
|
||||
assert.equal(decideWebSearch("What date is it today?").intent, "runtime");
|
||||
assert.equal(decideWebSearch("What is the latest Node.js release?").needsSearch, true);
|
||||
assert.equal(decideWebSearch("What happened on 10.09.2025?").intent, "news");
|
||||
const selected = selectSearchResults("What happened on 10.09.2025?", [
|
||||
@@ -195,11 +196,11 @@ test("chat search integrates with streaming, persistence, personas, settings, re
|
||||
assert.deepEqual(events.map((event) => event.event), ["status", "status", "status", "chunk", "chunk", "done"]);
|
||||
assert.equal(events[0].data.status, "accepted");
|
||||
assert.equal(events[1].data.status, "searching");
|
||||
assert.deepEqual(events[2].data, {status: "generating", sourceCount: 1});
|
||||
assert.deepEqual(events[2].data, {status: "generating", searchState: "succeeded", sourceCount: 1});
|
||||
assert.deepEqual(events.at(-1).data.sources, [source]);
|
||||
assert.equal(searchCount, 1);
|
||||
assert.equal(lastSearchQuery, "major news events September 10, 2025 2025-09-10");
|
||||
assert.equal(lastSearchCategory, "news");
|
||||
assert.equal(lastSearchCategory, null);
|
||||
const call = calls.at(-1);
|
||||
assert.equal(call.model, "chosen:model");
|
||||
assert.deepEqual(call.options.generation, {temperature: 0.4, contextLength: 4096, responseLength: 300});
|
||||
@@ -286,6 +287,77 @@ test("chat search integrates with streaming, persistence, personas, settings, re
|
||||
assert.ok(chatService.listActiveBranchMessages(localChat.id).length >= 4);
|
||||
});
|
||||
|
||||
test("explicit search intent overrides smart skipping and preserves the requested year", () => {
|
||||
for (const question of [
|
||||
"Search the internet for the average lifespan in 2026",
|
||||
"Search the web for what is 2 + 2",
|
||||
"Look this up online", "Find sources for life expectancy",
|
||||
"Check online for life expectancy", "Use the internet for this",
|
||||
"Find the latest information on life expectancy", "Can you search for life expectancy?",
|
||||
"Google this", "Find current information on life expectancy",
|
||||
"Search the internet for what date it is today",
|
||||
"Explain recursion and look it up online"
|
||||
]) {
|
||||
const decision = decideWebSearch(question);
|
||||
assert.equal(decision.explicitSearchIntent, true, question);
|
||||
assert.equal(decision.shouldSearch, true, question);
|
||||
assert.equal(decideWebSearch(question, false).shouldSearch, false);
|
||||
}
|
||||
for (const question of ["What is 2 + 2?", "What date is it today?", "Rewrite this sentence", "Explain recursion"]) {
|
||||
const decision = decideWebSearch(question);
|
||||
assert.equal(decision.explicitSearchIntent, false);
|
||||
assert.equal(decision.automaticSearchDecision, false);
|
||||
assert.equal(decision.shouldSearch, false);
|
||||
}
|
||||
assert.equal(buildWebSearchQuery("Search the internet for the average lifespan in 2026"), "the average life expectancy in 2026");
|
||||
});
|
||||
|
||||
test("date evidence admits individual events, rejects empty/wrong dates, and bounds fallback searches", async () => {
|
||||
const question = "what happened on 10.09.2025?";
|
||||
const useful = [
|
||||
{title: "Satellite launched", url: "https://space.example/launch", content: "On September 10, 2025, researchers launched a satellite into orbit."},
|
||||
{title: "Agreement signed", url: "https://diplomacy.example/deal", content: "Officials signed a cooperation agreement on 10 September 2025."}
|
||||
];
|
||||
const weak = [
|
||||
{title: "September 10, 2025 major world news", url: "https://empty.example", content: ""},
|
||||
{title: "October 9, 2025 world news", url: "https://wrong.example", content: "On October 9, 2025, officials signed an unrelated agreement."},
|
||||
{title: "On This Day", url: "https://calendar.example", content: "Browse the latest headlines and on this day pages for September 10, 2025."}
|
||||
];
|
||||
assert.deepEqual(selectSearchResults(question, weak), []);
|
||||
const selected = selectSearchResults(question, [...weak, ...useful]);
|
||||
assert.equal(selected.length, 2);
|
||||
assert.deepEqual(selected.map(source => source.snippet), useful.map(item => item.content));
|
||||
const queries = [];
|
||||
const search = await retrieveWebSearch(question, {async search(query, options) {
|
||||
queries.push(query);
|
||||
assert.equal(options.category, undefined);
|
||||
return queries.length === 1 ? weak : [...useful, useful[0]];
|
||||
}});
|
||||
assert.equal(search.state, "succeeded");
|
||||
assert.equal(queries.length, 2);
|
||||
assert.ok(queries.every(query => query.includes("2025")));
|
||||
assert.deepEqual(search.sources, selected);
|
||||
let duplicateCalls = 0;
|
||||
const refreshed = await retrieveWebSearch(question, {async search() {
|
||||
duplicateCalls++;
|
||||
return duplicateCalls === 1
|
||||
? [{...useful[0], content: "Browse the latest headlines and on this day pages."}]
|
||||
: [useful[0]];
|
||||
}});
|
||||
assert.equal(refreshed.sources[0].snippet, useful[0].content);
|
||||
let calls = 0;
|
||||
await retrieveWebSearch(question, {async search() { calls++; return useful; }});
|
||||
assert.equal(calls, 1);
|
||||
for (const [results, state] of [[[], "no_results"], [weak, "no_relevant_results"]]) {
|
||||
const outcome = await retrieveWebSearch(question, {async search() { return results; }});
|
||||
assert.equal(outcome.state, state);
|
||||
assert.equal(outcome.queries.length, 2);
|
||||
}
|
||||
const skipped = await retrieveWebSearch("What is 2 + 2?", {search() { assert.fail("Must not search"); }});
|
||||
assert.equal(skipped.state, "skipped");
|
||||
assert.equal(skipped.sources, null);
|
||||
});
|
||||
|
||||
class Element {
|
||||
constructor(tag) { this.tag = tag; this.children = []; this.attributes = {}; this.listeners = {}; }
|
||||
append(...nodes) { this.children.push(...nodes); }
|
||||
|
||||
Reference in New Issue
Block a user