1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
|
/**
* Engine selection, and the promise that an unsupported recency window is
* refused rather than dropped.
*/
import assert from "node:assert/strict";
import { test } from "node:test";
import { ENGINE_ENV_VAR, DEFAULT_ENGINE, resolveEngine } from "../src/engine-target.ts";
import { enginesSupportingRecency, parseEngineId } from "../src/engines.ts";
import { selectEngine } from "../src/search.ts";
const ok = (r: ReturnType<typeof resolveEngine>) => {
assert.equal(r.kind, "ok");
if (r.kind !== "ok") throw new Error("unreachable");
return r;
};
test("nothing configured means the built-in default", () => {
const r = ok(resolveEngine(null, {}, null));
assert.equal(r.id, DEFAULT_ENGINE);
assert.equal(r.source, "default");
});
test("precedence is parameter, then env, then stored", () => {
assert.equal(ok(resolveEngine(null, {}, "bing")).id, "bing");
assert.equal(ok(resolveEngine(null, { [ENGINE_ENV_VAR]: "brave" }, "bing")).id, "brave");
// The parameter beating the env var is the deliberate difference from the CDP
// target: it is what lets the agent fall back when an engine is blocked.
const r = ok(resolveEngine("duckduckgo", { [ENGINE_ENV_VAR]: "brave" }, "bing"));
assert.equal(r.id, "duckduckgo");
assert.equal(r.source, "parameter");
});
test("aliases resolve, including the short ones a human would type", () => {
for (const [raw, expected] of [
["ddg", "duckduckgo"],
["duck", "duckduckgo"],
["DuckDuckGo", "duckduckgo"],
[" bing ", "bing"],
["g", "google"],
["BRAVE", "brave"],
] as const) {
assert.equal(parseEngineId(raw), expected, raw);
}
});
test("an unknown name is reported, never quietly skipped for the next source", () => {
// A typo in the env var must not silently search Google instead.
const r = resolveEngine(null, { [ENGINE_ENV_VAR]: "gooogle" }, "bing");
assert.equal(r.kind, "invalid");
if (r.kind !== "invalid") throw new Error("unreachable");
assert.equal(r.source, "env");
assert.equal(r.raw, "gooogle");
});
test("blank values fall through rather than counting as a choice", () => {
assert.equal(ok(resolveEngine(" ", { [ENGINE_ENV_VAR]: " " }, "bing")).id, "bing");
});
test("an unsupported recency window is refused, and names engines that support it", async () => {
// Bing has no year window and Brave has no time filter; both must say so
// rather than returning unfiltered results that look filtered.
for (const engine of ["bing", "brave"] as const) {
const error = await selectEngine({ query: "q", numResults: 5, recency: "year", engine }).then(
() => null,
(e: Error) => e,
);
assert.ok(error, `${engine} should have refused`);
assert.equal(error.name, "RecencyUnsupportedError", engine);
for (const alt of enginesSupportingRecency("year")) assert.match(error.message, new RegExp(alt), engine);
}
});
test("windows an engine does support are accepted", async () => {
for (const [engine, recency] of [
["google", "year"],
["duckduckgo", "year"],
["bing", "month"],
] as const) {
const chosen = await selectEngine({ query: "q", numResults: 5, recency, engine });
assert.equal(chosen.engine.id, engine);
}
});
test("brave with no recency is fine — the refusal is about the window, not the engine", async () => {
const chosen = await selectEngine({ query: "q", numResults: 5, engine: "brave" });
assert.equal(chosen.engine.id, "brave");
});
|