@ia-qa/qa-discovery 0.3.0 → 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (52) hide show
  1. package/README.md +109 -3
  2. package/ROADMAP.md +37 -4
  3. package/TUTORIAL.md +85 -2
  4. package/dist/ai/classify.d.ts +13 -36
  5. package/dist/ai/classify.js +23 -166
  6. package/dist/ai/classify.js.map +1 -1
  7. package/dist/ai/model.d.ts +93 -0
  8. package/dist/ai/model.js +192 -0
  9. package/dist/ai/model.js.map +1 -0
  10. package/dist/ai/plan.d.ts +224 -0
  11. package/dist/ai/plan.js +0 -0
  12. package/dist/ai/plan.js.map +1 -0
  13. package/dist/cli/args.js +2 -0
  14. package/dist/cli/args.js.map +1 -1
  15. package/dist/cli/generate.d.ts +56 -0
  16. package/dist/cli/generate.js +293 -0
  17. package/dist/cli/generate.js.map +1 -0
  18. package/dist/cli/index.d.ts +1 -1
  19. package/dist/cli/index.js +32 -0
  20. package/dist/cli/index.js.map +1 -1
  21. package/dist/cli/skill.d.ts +20 -0
  22. package/dist/cli/skill.js +63 -0
  23. package/dist/cli/skill.js.map +1 -0
  24. package/dist/cli-ai/index.d.ts +3 -2
  25. package/dist/cli-ai/index.js +268 -4
  26. package/dist/cli-ai/index.js.map +1 -1
  27. package/dist/coverage.d.ts +52 -2
  28. package/dist/coverage.js +67 -7
  29. package/dist/coverage.js.map +1 -1
  30. package/dist/coverageView.js +17 -1
  31. package/dist/coverageView.js.map +1 -1
  32. package/dist/generate.d.ts +62 -0
  33. package/dist/generate.js +163 -0
  34. package/dist/generate.js.map +1 -0
  35. package/dist/htmlReport.js +20 -4
  36. package/dist/htmlReport.js.map +1 -1
  37. package/dist/index.d.ts +6 -0
  38. package/dist/index.js +32 -1
  39. package/dist/index.js.map +1 -1
  40. package/dist/mcp/server.d.ts +49 -0
  41. package/dist/mcp/server.js +143 -20
  42. package/dist/mcp/server.js.map +1 -1
  43. package/dist/overview.d.ts +9 -0
  44. package/dist/overview.js +9 -4
  45. package/dist/overview.js.map +1 -1
  46. package/dist/overviewFile.js +5 -0
  47. package/dist/overviewFile.js.map +1 -1
  48. package/dist/planView.d.ts +141 -0
  49. package/dist/planView.js +345 -0
  50. package/dist/planView.js.map +1 -0
  51. package/package.json +3 -2
  52. package/skills/ia-qa-discover/SKILL.md +166 -0
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.CLASSIFICATION_FILENAME = exports.CLASSIFICATION_SCHEMA = void 0;
3
+ exports.providerError = exports.CLASSIFICATION_FILENAME = exports.CLASSIFICATION_SCHEMA = void 0;
4
4
  exports.entryPointsOf = entryPointsOf;
5
5
  exports.offeredPaths = offeredPaths;
6
6
  exports.buildPrompt = buildPrompt;
@@ -8,10 +8,11 @@ exports.parseClassifications = parseClassifications;
8
8
  exports.validate = validate;
9
9
  exports.collect = collect;
10
10
  exports.egressNotice = egressNotice;
11
- exports.providerError = providerError;
12
11
  exports.classifyPage = classifyPage;
13
12
  const taxonomy_1 = require("../taxonomy");
14
13
  const citations_1 = require("../citations");
14
+ const model_1 = require("./model");
15
+ Object.defineProperty(exports, "providerError", { enumerable: true, get: function () { return model_1.providerError; } });
15
16
  /**
16
17
  * F2 — classify each entry point, offline, from F1's capture.
17
18
  *
@@ -22,14 +23,15 @@ const citations_1 = require("../citations");
22
23
  * **On duplication, stated because this project punishes silent drift:** the
23
24
  * provider/model catalogue is imported from `@ia-qa/self-healing` rather than
24
25
  * copied — there must not be a third model list in this repo. The HTTP transport
25
- * below *is* a second implementation, because self-healing does not export its
26
- * own (`callModel` is internal). Any change to a provider's request shape owes an
27
- * edit here as well as there.
26
+ * now lives in `./model.ts`, which is a second implementation of something
27
+ * self-healing keeps internal (`callModel`); it moved out of this file when a
28
+ * second BYOK verb arrived, so the cost stays at two copies instead of three.
29
+ * Any change to a provider's request shape owes an edit there as well as in
30
+ * self-healing.
28
31
  */
29
32
  /** The document writes, and the two strings a later stage keys on. */
30
33
  exports.CLASSIFICATION_SCHEMA = 'qa-discovery-classification@1';
31
34
  exports.CLASSIFICATION_FILENAME = 'classification.json';
32
- const DEFAULTS = { timeoutMs: 30000, temperature: 0 };
33
35
  /**
34
36
  * The citable units of a page.
35
37
  *
@@ -140,28 +142,7 @@ function buildPrompt(page, entryPoints) {
140
142
  }
141
143
  /** Pull the JSON object out of a model reply, tolerating fences and prose around it. */
142
144
  function parseClassifications(text) {
143
- if (!text || typeof text !== 'string')
144
- return null;
145
- const attempts = [text];
146
- const fenced = /```(?:json)?\s*([\s\S]*?)```/i.exec(text);
147
- if (fenced)
148
- attempts.push(fenced[1]);
149
- const first = text.indexOf('{');
150
- const last = text.lastIndexOf('}');
151
- if (first !== -1 && last > first)
152
- attempts.push(text.slice(first, last + 1));
153
- for (const candidate of attempts) {
154
- try {
155
- const parsed = JSON.parse(candidate.trim());
156
- const list = Array.isArray(parsed) ? parsed : parsed?.classifications;
157
- if (Array.isArray(list))
158
- return list;
159
- }
160
- catch {
161
- /* try the next shape */
162
- }
163
- }
164
- return null;
145
+ return (0, model_1.parseJsonList)(text, 'classifications');
165
146
  }
166
147
  /**
167
148
  * Validate one classification against the closed taxonomy, then against the
@@ -241,19 +222,14 @@ function collect(raws, index, offered) {
241
222
  }
242
223
  return { taxonomyVersion: taxonomy_1.TAXONOMY_VERSION, kept, refused, dropped };
243
224
  }
244
- // ── Provider transport ───────────────────────────────────────────────────────
245
- const HOSTS = {
246
- anthropic: 'api.anthropic.com',
247
- openai: 'api.openai.com',
248
- google: 'generativelanguage.googleapis.com',
249
- };
225
+ // ── What leaves this machine ─────────────────────────────────────────────────
250
226
  /**
251
227
  * What leaves this machine, said before it leaves — the one thing that makes
252
228
  * "everything is local except the model call" a promise rather than a claim.
253
229
  *
254
- * It lives beside `HOSTS` on purpose: the notice names the very constant
255
- * `buildRequest` sends to, so a new provider cannot be reachable while the
256
- * notice still lists three. And it is derived from `buildPrompt` — every line
230
+ * It resolves the host through `egressHost` rather than naming one of its own: the notice names the
231
+ * very constant `buildRequest` sends to, so a new provider cannot be reachable
232
+ * while the notice still lists three. And it is derived from `buildPrompt` — every line
257
233
  * below is a field that function actually puts in the payload; adding one there
258
234
  * owes a line here.
259
235
  *
@@ -272,125 +248,21 @@ const HOSTS = {
272
248
  * the token here. The word "full" is gone from that line for the same reason the
273
249
  * allowlist is named: the two statements must not contradict each other.
274
250
  */
275
- function egressNotice(provider, model, pages, planned = false) {
251
+ function egressNotice(provider, model, pages, planned = false, baseUrl) {
252
+ // The host it will REALLY reach. Throws when a configurable provider was given no URL —
253
+ // before anything is announced, because a notice printing `undefined` reads as a checked fact.
254
+ const host = (0, model_1.egressHost)(provider, baseUrl);
276
255
  const n = `${pages} page${pages === 1 ? '' : 's'}`;
277
- return (`\n 🌐 ${planned ? 'Would send' : 'Sending'} ${n} to ${HOSTS[provider]} (${provider} · ${model}) — your key, your account.\n` +
256
+ return (`\n 🌐 ${planned ? 'Would send' : 'Sending'} ${n} to ${host} (${provider} · ${model}) — your key, your account.\n` +
278
257
  ` Leaves this machine: each page's URL, title and description, up to 25 headings,\n` +
279
258
  ` every observed API call (method, normalised path, status), and each form field's name,\n` +
280
259
  ` type, label and selector. Headings and labels are live text from your app.\n` +
281
260
  ` Query values are stripped at capture EXCEPT an allowlist that includes \`q\` — a search\n` +
282
261
  ` term reaches the model as typed (\`capture.safeQueryParams\` in config.json narrows it).\n` +
283
262
  ` Does NOT leave: page HTML, screenshots, cookies or your session file, your test files,\n` +
284
- ` your API key (sent as a header to ${HOSTS[provider]} only).\n` +
263
+ ` your API key (sent as a header to ${host} only).\n` +
285
264
  ` ${planned ? '' : 'Ctrl-C to stop. '}Deterministic \`ia-qa-discover\` sends nothing, ever.\n`);
286
265
  }
287
- function buildRequest(provider, model, apiKey, prompt, temperature) {
288
- if (provider === 'anthropic') {
289
- const body = { model, max_tokens: 4096, messages: [{ role: 'user', content: prompt }] };
290
- if (temperature !== undefined)
291
- body.temperature = temperature;
292
- return {
293
- url: `https://${HOSTS.anthropic}/v1/messages`,
294
- headers: { 'content-type': 'application/json', 'x-api-key': apiKey, 'anthropic-version': '2023-06-01' },
295
- body,
296
- };
297
- }
298
- if (provider === 'openai') {
299
- const body = { model, messages: [{ role: 'user', content: prompt }] };
300
- if (temperature !== undefined)
301
- body.temperature = temperature;
302
- return {
303
- url: `https://${HOSTS.openai}/v1/chat/completions`,
304
- headers: { 'content-type': 'application/json', authorization: `Bearer ${apiKey}` },
305
- body,
306
- };
307
- }
308
- const body = { contents: [{ parts: [{ text: prompt }] }] };
309
- if (temperature !== undefined)
310
- body.generationConfig = { temperature };
311
- return {
312
- url: `https://${HOSTS.google}/v1beta/models/${encodeURIComponent(model)}:generateContent?key=${encodeURIComponent(apiKey)}`,
313
- headers: { 'content-type': 'application/json' },
314
- body,
315
- };
316
- }
317
- function extractText(provider, data) {
318
- if (provider === 'anthropic')
319
- return data?.content?.[0]?.text ?? '';
320
- if (provider === 'openai')
321
- return data?.choices?.[0]?.message?.content ?? '';
322
- return data?.candidates?.[0]?.content?.parts?.[0]?.text ?? '';
323
- }
324
- async function attempt(opts, prompt, temperature) {
325
- const fetchFn = opts.fetchFn ?? globalThis.fetch;
326
- if (typeof fetchFn !== 'function')
327
- return null;
328
- const req = buildRequest(opts.provider, opts.model, opts.apiKey, prompt, temperature);
329
- const controller = new AbortController();
330
- const timer = setTimeout(() => controller.abort(), opts.timeoutMs ?? DEFAULTS.timeoutMs);
331
- try {
332
- return await fetchFn(req.url, {
333
- method: 'POST',
334
- headers: req.headers,
335
- body: JSON.stringify(req.body),
336
- signal: controller.signal,
337
- });
338
- }
339
- catch {
340
- return null; // network error or timeout — never throws at the caller
341
- }
342
- finally {
343
- clearTimeout(timer);
344
- }
345
- }
346
- /**
347
- * What the provider itself said went wrong.
348
- *
349
- * Found by execution, not review: a Gemini key that is simply wrong comes back
350
- * **400**, not 401 — so the previous message read `refused the call with HTTP
351
- * 400`, said nothing about the key, and left the one person who could fix it in
352
- * sixty seconds with nothing to go on. Mapping more status codes by hand is the
353
- * wrong shape of fix (the list rots, and it is different per provider); the
354
- * providers already answer the question in the body, and all three happen to
355
- * use the same `{error:{message}}` envelope.
356
- *
357
- * Two guards. The body is untrusted text that lands in a terminal and in
358
- * `classification.json`, so it is capped and flattened. And anything shaped like
359
- * a credential is redacted before it is printed — a provider that echoes the
360
- * request back would otherwise put the user's own key in a file they commit.
361
- */
362
- async function providerError(res) {
363
- const status = `HTTP ${res.status}`;
364
- // Kept alongside the provider's own words, not replaced by them: a 401 with
365
- // an empty body still has exactly one likely cause, and an existing test went
366
- // red the moment this hint was dropped — correctly.
367
- const hint = res.status === 401 || res.status === 403 ? ' Check the API key.' : '';
368
- let body = '';
369
- try {
370
- body = await res.text();
371
- }
372
- catch {
373
- return `${status}.${hint}`;
374
- }
375
- let message = '';
376
- try {
377
- const parsed = JSON.parse(body);
378
- message = parsed?.error?.message ?? parsed?.message ?? '';
379
- }
380
- catch {
381
- message = body;
382
- }
383
- message = String(message).replace(/\s+/g, ' ').trim();
384
- // sk-…, AIza…, ghp_…, and any long opaque run that could be a secret.
385
- message = message.replace(/\b(?:sk-|AIza|ghp_|gsk_)[A-Za-z0-9_\-]{8,}/g, '[redacted]');
386
- if (!message)
387
- return `${status}.${hint}`;
388
- if (message.length > 200)
389
- message = message.slice(0, 200) + '…';
390
- if (hint && !/[.!?…]$/.test(message))
391
- message += '.';
392
- return `${status} — ${message}${hint}`;
393
- }
394
266
  /**
395
267
  * One page in, validated classifications out. Returns an empty result rather
396
268
  * than throwing on a network failure, an unparseable reply or an empty page:
@@ -411,25 +283,10 @@ async function classifyPage(page, index, opts) {
411
283
  return empty();
412
284
  const prompt = buildPrompt(page, entryPoints);
413
285
  const offered = offeredPaths(page, entryPoints);
414
- // The newest models reject sampling params outright (Anthropic Opus 4.8 /
415
- // Sonnet 5, OpenAI reasoning models) with a 400. Rather than maintain a
416
- // capability matrix, send temperature and retry once without it — the same
417
- // trick, and the same reasoning, as self-healing's resolver.
418
- let res = await attempt(opts, prompt, opts.temperature ?? DEFAULTS.temperature);
419
- if (res && res.status === 400)
420
- res = await attempt(opts, prompt, undefined);
421
- if (!res)
422
- return empty(`No reply from ${opts.provider} — network error or timeout.`);
423
- if (!res.ok)
424
- return empty(`${opts.provider} refused the call: ${await providerError(res)}`);
425
- let text;
426
- try {
427
- text = extractText(opts.provider, await res.json());
428
- }
429
- catch {
430
- return empty(`Could not read ${opts.provider}'s reply as JSON.`);
431
- }
432
- const raws = parseClassifications(text);
286
+ const call = await (0, model_1.callModel)(opts, prompt);
287
+ if (!call.ok)
288
+ return empty(call.reason);
289
+ const raws = parseClassifications(call.text);
433
290
  if (!raws)
434
291
  return empty(`${opts.provider} replied, but not with the JSON that was asked for.`);
435
292
  return collect(raws, index, offered);
@@ -1 +1 @@
1
- {"version":3,"file":"classify.js","sourceRoot":"","sources":["../../src/ai/classify.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"classify.js","sourceRoot":"","sources":["../../src/ai/classify.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,93 @@
1
+ import { egressHost, PROVIDER_HOST, type AiProvider } from '@ia-qa/self-healing';
2
+ /**
3
+ * The provider transport, in one place.
4
+ *
5
+ * It was written inside `classify.ts`, which stated plainly that it *is* a second
6
+ * implementation of something `@ia-qa/self-healing` keeps internal (`callModel`). A second
7
+ * copy is a documented cost; a third would be the drift this repo spends its design on
8
+ * refusing. So when a second BYOK verb arrived, the transport moved here rather than being
9
+ * pasted — `classify.ts` re-exports what its tests and `src/index.ts` already name, so the
10
+ * public surface is unchanged.
11
+ *
12
+ * **What must stay true of this file**: it knows nothing about entry points, plans,
13
+ * taxonomies or captures. It takes a prompt, returns text or a reason. Anything that knows
14
+ * what the text means belongs to the caller — which is what lets two verbs send different,
15
+ * differently-sized payloads and each announce its own.
16
+ *
17
+ * Any change to a provider's request shape owes an edit in `@ia-qa/self-healing` too.
18
+ */
19
+ /**
20
+ * The hosts this package talks to — imported from `@ia-qa/self-healing`, not restated.
21
+ *
22
+ * It was a copy here, and a copy of a security-relevant constant is the drift this repo
23
+ * spends its design refusing: the notice and the request have to read the same source. Every
24
+ * egress notice resolves its destination through `egressHost`, so a provider whose host is
25
+ * configured (`openai-compatible`) announces the host it will really reach, and one given no
26
+ * URL **throws before anything is sent or announced**.
27
+ */
28
+ export { PROVIDER_HOST as HOSTS, egressHost };
29
+ export interface ModelOptions {
30
+ provider: AiProvider;
31
+ model: string;
32
+ apiKey: string;
33
+ /** Required for openai-compatible: where that endpoint lives. */
34
+ baseUrl?: string;
35
+ /** Injected in tests; defaults to the global fetch. */
36
+ fetchFn?: typeof fetch;
37
+ timeoutMs?: number;
38
+ temperature?: number;
39
+ }
40
+ export declare const MODEL_DEFAULTS: {
41
+ timeoutMs: number;
42
+ temperature: number;
43
+ };
44
+ /**
45
+ * What the provider itself said went wrong.
46
+ *
47
+ * Found by execution, not review: a Gemini key that is simply wrong comes back
48
+ * **400**, not 401 — so the previous message read `refused the call with HTTP
49
+ * 400`, said nothing about the key, and left the one person who could fix it in
50
+ * sixty seconds with nothing to go on. Mapping more status codes by hand is the
51
+ * wrong shape of fix (the list rots, and it is different per provider); the
52
+ * providers already answer the question in the body, and all three happen to
53
+ * use the same `{error:{message}}` envelope.
54
+ *
55
+ * Two guards. The body is untrusted text that lands in a terminal and in a
56
+ * committed file, so it is capped and flattened. And anything shaped like a
57
+ * credential is redacted before it is printed — a provider that echoes the
58
+ * request back would otherwise put the user's own key in a file they commit.
59
+ */
60
+ export declare function providerError(res: {
61
+ status: number;
62
+ text: () => Promise<string>;
63
+ }): Promise<string>;
64
+ export type ModelCall = {
65
+ ok: true;
66
+ text: string;
67
+ } | {
68
+ ok: false;
69
+ reason: string;
70
+ };
71
+ /**
72
+ * One prompt in, the model's text out — or a reason, never a throw.
73
+ *
74
+ * Every BYOK verb in this package is optional by construction, so a broken key must not take
75
+ * down a deterministic capture that already succeeded. The reason is a sentence the person
76
+ * running it can act on, and it always names the provider: "nothing came back" and "your app
77
+ * has nothing there" must never be the same empty result.
78
+ *
79
+ * The newest models reject sampling params outright (Anthropic Opus 4.8 / Sonnet 5, OpenAI
80
+ * reasoning models) with a 400. Rather than maintain a capability matrix, send temperature
81
+ * and retry once without it — the same trick, and the same reasoning, as self-healing's
82
+ * resolver.
83
+ */
84
+ export declare function callModel(opts: ModelOptions, prompt: string): Promise<ModelCall>;
85
+ /**
86
+ * Pull JSON out of a model reply, tolerating fences and prose around it.
87
+ *
88
+ * `key` names the array a caller expects (`classifications`); a bare array is accepted too.
89
+ * With no key, the first JSON *object* is returned — the shape a one-answer prompt asks for.
90
+ */
91
+ export declare function parseJsonReply(text: string): unknown | null;
92
+ /** The list form: a bare array, or `{ [key]: [...] }`. */
93
+ export declare function parseJsonList(text: string, key: string): Record<string, unknown>[] | null;
@@ -0,0 +1,192 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.MODEL_DEFAULTS = exports.egressHost = exports.HOSTS = void 0;
4
+ exports.providerError = providerError;
5
+ exports.callModel = callModel;
6
+ exports.parseJsonReply = parseJsonReply;
7
+ exports.parseJsonList = parseJsonList;
8
+ const self_healing_1 = require("@ia-qa/self-healing");
9
+ Object.defineProperty(exports, "egressHost", { enumerable: true, get: function () { return self_healing_1.egressHost; } });
10
+ Object.defineProperty(exports, "HOSTS", { enumerable: true, get: function () { return self_healing_1.PROVIDER_HOST; } });
11
+ exports.MODEL_DEFAULTS = { timeoutMs: 30000, temperature: 0 };
12
+ function buildRequest(provider, model, apiKey, prompt, temperature, baseUrl) {
13
+ if (provider === 'anthropic') {
14
+ const body = { model, max_tokens: 4096, messages: [{ role: 'user', content: prompt }] };
15
+ if (temperature !== undefined)
16
+ body.temperature = temperature;
17
+ return {
18
+ url: `https://${self_healing_1.PROVIDER_HOST.anthropic}/v1/messages`,
19
+ headers: { 'content-type': 'application/json', 'x-api-key': apiKey, 'anthropic-version': '2023-06-01' },
20
+ body,
21
+ };
22
+ }
23
+ if (provider === 'openai' || provider === 'openai-compatible') {
24
+ const body = { model, messages: [{ role: 'user', content: prompt }] };
25
+ if (temperature !== undefined)
26
+ body.temperature = temperature;
27
+ return {
28
+ // One shape, two destinations. `baseUrl` is taken as given — trailing slash trimmed and
29
+ // nothing else invented — because a gateway that does not end in `/v1` is a real
30
+ // configuration, not a mistake to correct. `egressHost` has already refused an absent
31
+ // one, so this is never asked to build a URL out of nothing.
32
+ url: provider === 'openai-compatible'
33
+ ? `${(baseUrl ?? '').replace(/\/+$/, '')}/chat/completions`
34
+ : `https://${self_healing_1.PROVIDER_HOST.openai}/v1/chat/completions`,
35
+ headers: { 'content-type': 'application/json', authorization: `Bearer ${apiKey}` },
36
+ body,
37
+ };
38
+ }
39
+ const body = { contents: [{ parts: [{ text: prompt }] }] };
40
+ if (temperature !== undefined)
41
+ body.generationConfig = { temperature };
42
+ return {
43
+ url: `https://${self_healing_1.PROVIDER_HOST.google}/v1beta/models/${encodeURIComponent(model)}:generateContent?key=${encodeURIComponent(apiKey)}`,
44
+ headers: { 'content-type': 'application/json' },
45
+ body,
46
+ };
47
+ }
48
+ function extractText(provider, data) {
49
+ if (provider === 'anthropic')
50
+ return data?.content?.[0]?.text ?? '';
51
+ if (provider === 'openai' || provider === 'openai-compatible')
52
+ return data?.choices?.[0]?.message?.content ?? '';
53
+ return data?.candidates?.[0]?.content?.parts?.[0]?.text ?? '';
54
+ }
55
+ async function attempt(opts, prompt, temperature) {
56
+ const fetchFn = opts.fetchFn ?? globalThis.fetch;
57
+ if (typeof fetchFn !== 'function')
58
+ return null;
59
+ const req = buildRequest(opts.provider, opts.model, opts.apiKey, prompt, temperature, opts.baseUrl);
60
+ const controller = new AbortController();
61
+ const timer = setTimeout(() => controller.abort(), opts.timeoutMs ?? exports.MODEL_DEFAULTS.timeoutMs);
62
+ try {
63
+ return await fetchFn(req.url, {
64
+ method: 'POST',
65
+ headers: req.headers,
66
+ body: JSON.stringify(req.body),
67
+ signal: controller.signal,
68
+ });
69
+ }
70
+ catch {
71
+ return null; // network error or timeout — never throws at the caller
72
+ }
73
+ finally {
74
+ clearTimeout(timer);
75
+ }
76
+ }
77
+ /**
78
+ * What the provider itself said went wrong.
79
+ *
80
+ * Found by execution, not review: a Gemini key that is simply wrong comes back
81
+ * **400**, not 401 — so the previous message read `refused the call with HTTP
82
+ * 400`, said nothing about the key, and left the one person who could fix it in
83
+ * sixty seconds with nothing to go on. Mapping more status codes by hand is the
84
+ * wrong shape of fix (the list rots, and it is different per provider); the
85
+ * providers already answer the question in the body, and all three happen to
86
+ * use the same `{error:{message}}` envelope.
87
+ *
88
+ * Two guards. The body is untrusted text that lands in a terminal and in a
89
+ * committed file, so it is capped and flattened. And anything shaped like a
90
+ * credential is redacted before it is printed — a provider that echoes the
91
+ * request back would otherwise put the user's own key in a file they commit.
92
+ */
93
+ async function providerError(res) {
94
+ const status = `HTTP ${res.status}`;
95
+ // Kept alongside the provider's own words, not replaced by them: a 401 with
96
+ // an empty body still has exactly one likely cause, and an existing test went
97
+ // red the moment this hint was dropped — correctly.
98
+ const hint = res.status === 401 || res.status === 403 ? ' Check the API key.' : '';
99
+ let body = '';
100
+ try {
101
+ body = await res.text();
102
+ }
103
+ catch {
104
+ return `${status}.${hint}`;
105
+ }
106
+ let message = '';
107
+ try {
108
+ const parsed = JSON.parse(body);
109
+ message = parsed?.error?.message ?? parsed?.message ?? '';
110
+ }
111
+ catch {
112
+ message = body;
113
+ }
114
+ message = String(message).replace(/\s+/g, ' ').trim();
115
+ // sk-…, AIza…, ghp_…, and any long opaque run that could be a secret.
116
+ message = message.replace(/\b(?:sk-|AIza|ghp_|gsk_)[A-Za-z0-9_\-]{8,}/g, '[redacted]');
117
+ if (!message)
118
+ return `${status}.${hint}`;
119
+ if (message.length > 200)
120
+ message = message.slice(0, 200) + '…';
121
+ if (hint && !/[.!?…]$/.test(message))
122
+ message += '.';
123
+ return `${status} — ${message}${hint}`;
124
+ }
125
+ /**
126
+ * One prompt in, the model's text out — or a reason, never a throw.
127
+ *
128
+ * Every BYOK verb in this package is optional by construction, so a broken key must not take
129
+ * down a deterministic capture that already succeeded. The reason is a sentence the person
130
+ * running it can act on, and it always names the provider: "nothing came back" and "your app
131
+ * has nothing there" must never be the same empty result.
132
+ *
133
+ * The newest models reject sampling params outright (Anthropic Opus 4.8 / Sonnet 5, OpenAI
134
+ * reasoning models) with a 400. Rather than maintain a capability matrix, send temperature
135
+ * and retry once without it — the same trick, and the same reasoning, as self-healing's
136
+ * resolver.
137
+ */
138
+ async function callModel(opts, prompt) {
139
+ let res = await attempt(opts, prompt, opts.temperature ?? exports.MODEL_DEFAULTS.temperature);
140
+ if (res && res.status === 400)
141
+ res = await attempt(opts, prompt, undefined);
142
+ if (!res)
143
+ return { ok: false, reason: `No reply from ${opts.provider} — network error or timeout.` };
144
+ if (!res.ok)
145
+ return { ok: false, reason: `${opts.provider} refused the call: ${await providerError(res)}` };
146
+ try {
147
+ return { ok: true, text: extractText(opts.provider, await res.json()) };
148
+ }
149
+ catch {
150
+ return { ok: false, reason: `Could not read ${opts.provider}'s reply as JSON.` };
151
+ }
152
+ }
153
+ /**
154
+ * Pull JSON out of a model reply, tolerating fences and prose around it.
155
+ *
156
+ * `key` names the array a caller expects (`classifications`); a bare array is accepted too.
157
+ * With no key, the first JSON *object* is returned — the shape a one-answer prompt asks for.
158
+ */
159
+ function parseJsonReply(text) {
160
+ if (!text || typeof text !== 'string')
161
+ return null;
162
+ const attempts = [text];
163
+ const fenced = /```(?:json)?\s*([\s\S]*?)```/i.exec(text);
164
+ if (fenced)
165
+ attempts.push(fenced[1]);
166
+ const first = text.indexOf('{');
167
+ const last = text.lastIndexOf('}');
168
+ if (first !== -1 && last > first)
169
+ attempts.push(text.slice(first, last + 1));
170
+ const firstArray = text.indexOf('[');
171
+ const lastArray = text.lastIndexOf(']');
172
+ if (firstArray !== -1 && lastArray > firstArray)
173
+ attempts.push(text.slice(firstArray, lastArray + 1));
174
+ for (const candidate of attempts) {
175
+ try {
176
+ return JSON.parse(candidate.trim());
177
+ }
178
+ catch {
179
+ /* try the next shape */
180
+ }
181
+ }
182
+ return null;
183
+ }
184
+ /** The list form: a bare array, or `{ [key]: [...] }`. */
185
+ function parseJsonList(text, key) {
186
+ const parsed = parseJsonReply(text);
187
+ if (!parsed)
188
+ return null;
189
+ const list = Array.isArray(parsed) ? parsed : parsed?.[key];
190
+ return Array.isArray(list) ? list : null;
191
+ }
192
+ //# sourceMappingURL=model.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"model.js","sourceRoot":"","sources":["../../src/ai/model.ts"],"names":[],"mappings":"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"}