@chances-ai/engine 30.0.0 → 31.0.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.
- package/dist/ai/adapters/ai-sdk-stream.d.ts +13 -1
- package/dist/ai/adapters/ai-sdk-stream.d.ts.map +1 -1
- package/dist/ai/adapters/ai-sdk-stream.js +140 -39
- package/dist/ai/adapters/ai-sdk-stream.js.map +1 -1
- package/dist/ai/adapters/ai-sdk.d.ts +8 -0
- package/dist/ai/adapters/ai-sdk.d.ts.map +1 -1
- package/dist/ai/adapters/ai-sdk.js +39 -1
- package/dist/ai/adapters/ai-sdk.js.map +1 -1
- package/dist/ai/adapters/mock.d.ts.map +1 -1
- package/dist/ai/adapters/mock.js +6 -2
- package/dist/ai/adapters/mock.js.map +1 -1
- package/dist/ai/adapters/native-anthropic.d.ts +51 -0
- package/dist/ai/adapters/native-anthropic.d.ts.map +1 -0
- package/dist/ai/adapters/native-anthropic.js +179 -0
- package/dist/ai/adapters/native-anthropic.js.map +1 -0
- package/dist/ai/adapters/openai-compatible.d.ts +17 -1
- package/dist/ai/adapters/openai-compatible.d.ts.map +1 -1
- package/dist/ai/adapters/openai-compatible.js +105 -1
- package/dist/ai/adapters/openai-compatible.js.map +1 -1
- package/dist/ai/compat.d.ts +30 -0
- package/dist/ai/compat.d.ts.map +1 -0
- package/dist/ai/compat.js +93 -0
- package/dist/ai/compat.js.map +1 -0
- package/dist/ai/cost.d.ts +9 -0
- package/dist/ai/cost.d.ts.map +1 -1
- package/dist/ai/cost.js +15 -2
- package/dist/ai/cost.js.map +1 -1
- package/dist/ai/index.d.ts +6 -2
- package/dist/ai/index.d.ts.map +1 -1
- package/dist/ai/index.js +5 -1
- package/dist/ai/index.js.map +1 -1
- package/dist/ai/known-models.d.ts +20 -6
- package/dist/ai/known-models.d.ts.map +1 -1
- package/dist/ai/known-models.generated.d.ts +3 -0
- package/dist/ai/known-models.generated.d.ts.map +1 -0
- package/dist/ai/known-models.generated.js +518 -0
- package/dist/ai/known-models.generated.js.map +1 -0
- package/dist/ai/known-models.js +29 -128
- package/dist/ai/known-models.js.map +1 -1
- package/dist/ai/provider-table.d.ts +36 -0
- package/dist/ai/provider-table.d.ts.map +1 -0
- package/dist/ai/provider-table.js +80 -0
- package/dist/ai/provider-table.js.map +1 -0
- package/dist/ai/retry.d.ts +74 -3
- package/dist/ai/retry.d.ts.map +1 -1
- package/dist/ai/retry.js +246 -6
- package/dist/ai/retry.js.map +1 -1
- package/dist/ai/router.d.ts +12 -0
- package/dist/ai/router.d.ts.map +1 -1
- package/dist/ai/router.js +19 -0
- package/dist/ai/router.js.map +1 -1
- package/dist/ai/sampling.d.ts +37 -0
- package/dist/ai/sampling.d.ts.map +1 -0
- package/dist/ai/sampling.js +34 -0
- package/dist/ai/sampling.js.map +1 -0
- package/dist/ai/setup.d.ts.map +1 -1
- package/dist/ai/setup.js +27 -3
- package/dist/ai/setup.js.map +1 -1
- package/dist/ai/summarizer.d.ts.map +1 -1
- package/dist/ai/summarizer.js +6 -1
- package/dist/ai/summarizer.js.map +1 -1
- package/dist/ai/think-filter.d.ts +30 -0
- package/dist/ai/think-filter.d.ts.map +1 -0
- package/dist/ai/think-filter.js +193 -0
- package/dist/ai/think-filter.js.map +1 -0
- package/dist/ai/thinking.d.ts +77 -0
- package/dist/ai/thinking.d.ts.map +1 -0
- package/dist/ai/thinking.js +174 -0
- package/dist/ai/thinking.js.map +1 -0
- package/dist/ai/types.d.ts +134 -7
- package/dist/ai/types.d.ts.map +1 -1
- package/dist/core/compaction/compactor.d.ts.map +1 -1
- package/dist/core/compaction/compactor.js +44 -6
- package/dist/core/compaction/compactor.js.map +1 -1
- package/dist/core/engine.d.ts +16 -1
- package/dist/core/engine.d.ts.map +1 -1
- package/dist/core/engine.js +122 -18
- package/dist/core/engine.js.map +1 -1
- package/dist/core/index.d.ts +1 -1
- package/dist/core/index.d.ts.map +1 -1
- package/dist/core/index.js +1 -1
- package/dist/core/index.js.map +1 -1
- package/package.json +3 -3
package/dist/ai/retry.d.ts
CHANGED
|
@@ -1,11 +1,82 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* (7.10 §3.6) Typed provider-error classification + retry policy. Ported from
|
|
3
|
+
* goose (`errors.rs` taxonomy + `http_status.rs` Retry-After parse + `retry.rs`
|
|
4
|
+
* jitter). This is the TS implementation — the always-on path; a Rust mirror
|
|
5
|
+
* (`retry_after.rs`/`provider_error.rs`) lands in W6 alongside the native
|
|
6
|
+
* anthropic client that surfaces structured status/headers (where it's
|
|
7
|
+
* consumed), with native↔JS equivalence tests there.
|
|
8
|
+
*
|
|
9
|
+
* Two classification entry points:
|
|
10
|
+
* - {@link classifyProviderError} — from an error STRING (the AI-SDK path,
|
|
11
|
+
* which doesn't surface a structured status), via regex + a best-effort
|
|
12
|
+
* Retry-After hint scraped from the message.
|
|
13
|
+
* - {@link classifyByStatus} — from an HTTP status + body (the W6 native path),
|
|
14
|
+
* the precise classifier.
|
|
15
|
+
*/
|
|
16
|
+
/** Low-cardinality error taxonomy (mirrors goose `telemetry_type`). */
|
|
17
|
+
export type ProviderErrorKind = "auth" | "context-length" | "rate-limit" | "server" | "network" | "credits" | "request" | "unknown";
|
|
1
18
|
export interface RetryDecision {
|
|
2
19
|
retryable: boolean;
|
|
3
|
-
reason:
|
|
20
|
+
reason: ProviderErrorKind;
|
|
21
|
+
/** Server-directed delay (ms) — honored OVER exponential backoff when present
|
|
22
|
+
* (from a Retry-After header / OpenRouter body, or scraped from the message). */
|
|
23
|
+
retryAfterMs?: number;
|
|
4
24
|
}
|
|
5
|
-
export declare function classifyProviderError(message: string): RetryDecision;
|
|
6
25
|
export interface RetryConfig {
|
|
7
|
-
/**
|
|
26
|
+
/** Base backoff before each retry attempt, in ms. Length caps the retry count. */
|
|
8
27
|
delaysMs: readonly number[];
|
|
28
|
+
/** Cap any single delay (after backoff, before jitter). Default 60s. */
|
|
29
|
+
maxIntervalMs?: number;
|
|
30
|
+
/** Whether a generic 4xx `request` failure is retryable. Default false. */
|
|
31
|
+
transientOnly?: boolean;
|
|
32
|
+
/** Injectable RNG for the jitter factor (tests pin it). Default Math.random. */
|
|
33
|
+
random?: () => number;
|
|
9
34
|
}
|
|
10
35
|
export declare const defaultRetryConfig: RetryConfig;
|
|
36
|
+
/**
|
|
37
|
+
* (7.10 TS re-review) Apply a per-request `maxRetries` (from `SamplingOptions`,
|
|
38
|
+
* already clamped to [0,10]) to a base config. `delaysMs.length` IS the retry
|
|
39
|
+
* count, so we resize it: a smaller `n` truncates (0 ⇒ no retries — fail on the
|
|
40
|
+
* first error); a larger `n` extends by repeating the last base delay. Returns
|
|
41
|
+
* the base unchanged when `n` is undefined.
|
|
42
|
+
*/
|
|
43
|
+
export declare function withMaxRetries(cfg: RetryConfig, n: number | undefined): RetryConfig;
|
|
44
|
+
/** Headers as either a `Headers` instance or a plain object (case-insensitive). */
|
|
45
|
+
export type HeadersLike = Headers | Record<string, string | undefined>;
|
|
46
|
+
/**
|
|
47
|
+
* (goose `extract_retry_after`) The retry delay a server directed, in SECONDS.
|
|
48
|
+
* Precedence: the body's `error.metadata.retry_after_seconds` (OpenRouter, more
|
|
49
|
+
* precise than the integer header) → the `Retry-After` header in either its
|
|
50
|
+
* delay-seconds form or one of the three RFC 7231 HTTP-date forms. A past date
|
|
51
|
+
* is honored as "retry now" (0). Returns undefined when there's no usable hint.
|
|
52
|
+
*/
|
|
53
|
+
export declare function extractRetryAfterSeconds(headers?: HeadersLike, body?: unknown): number | undefined;
|
|
54
|
+
/**
|
|
55
|
+
* Classify a provider error STRING into a retry decision (the AI-SDK path).
|
|
56
|
+
* Precedence (codex W5 R2-S1; refined in the 7.10 TS re-review):
|
|
57
|
+
* 1. auth — a wrong key won't fix on retry; wins even over a co-occurring 429.
|
|
58
|
+
* 2. STRONG credits — terminal exhaustion (402 / payment required / insufficient
|
|
59
|
+
* credits|balance|funds|quota / credits exhausted / "exceeded your current
|
|
60
|
+
* quota"). Beats rate-limit because OpenAI returns `insufficient_quota` AS a
|
|
61
|
+
* 429 — retrying a billing dead-end just burns attempts.
|
|
62
|
+
* 3. rate-limit — a 429 / rate-limit / quota WINDOW is retryable even if the
|
|
63
|
+
* message also mentions weak "billing" (so "429 upgrade your billing" retries).
|
|
64
|
+
* 4. weak credits — bare "billing" without a 429, terminal.
|
|
65
|
+
* 5. context-length — terminal (overflow→compact recovery handles it elsewhere).
|
|
66
|
+
* 6. server / network — retryable.
|
|
67
|
+
* 7. unknown — not retryable (don't gamble on a mystery error).
|
|
68
|
+
*/
|
|
69
|
+
export declare function classifyProviderError(message: string): RetryDecision;
|
|
70
|
+
/**
|
|
71
|
+
* Classify from an HTTP status + body — the precise path (W6 native client,
|
|
72
|
+
* which has structured status/headers). Mirrors goose `map_http_error`.
|
|
73
|
+
*/
|
|
74
|
+
export declare function classifyByStatus(status: number, body?: unknown, headers?: HeadersLike, config?: RetryConfig): RetryDecision;
|
|
75
|
+
/**
|
|
76
|
+
* (goose `retry.rs`) The delay before a retry attempt. A server-directed
|
|
77
|
+
* `retryAfterMs` wins outright (no jitter — honor the server). Otherwise the
|
|
78
|
+
* base backoff is capped at `maxIntervalMs` and multiplied by a jitter factor in
|
|
79
|
+
* [0.8, 1.2) to avoid a thundering herd.
|
|
80
|
+
*/
|
|
81
|
+
export declare function computeRetryDelayMs(baseMs: number, retryAfterMs: number | undefined, config?: RetryConfig): number;
|
|
11
82
|
//# sourceMappingURL=retry.d.ts.map
|
package/dist/ai/retry.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"retry.d.ts","sourceRoot":"","sources":["../../src/ai/retry.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,aAAa;IAC5B,SAAS,EAAE,OAAO,CAAC;IACnB,MAAM,EAAE,YAAY,GAAG,
|
|
1
|
+
{"version":3,"file":"retry.d.ts","sourceRoot":"","sources":["../../src/ai/retry.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,uEAAuE;AACvE,MAAM,MAAM,iBAAiB,GACzB,MAAM,GACN,gBAAgB,GAChB,YAAY,GACZ,QAAQ,GACR,SAAS,GACT,SAAS,GACT,SAAS,GACT,SAAS,CAAC;AAEd,MAAM,WAAW,aAAa;IAC5B,SAAS,EAAE,OAAO,CAAC;IACnB,MAAM,EAAE,iBAAiB,CAAC;IAC1B;sFACkF;IAClF,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,WAAW;IAC1B,kFAAkF;IAClF,QAAQ,EAAE,SAAS,MAAM,EAAE,CAAC;IAC5B,wEAAwE;IACxE,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,2EAA2E;IAC3E,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,gFAAgF;IAChF,MAAM,CAAC,EAAE,MAAM,MAAM,CAAC;CACvB;AAED,eAAO,MAAM,kBAAkB,EAAE,WAA6C,CAAC;AAE/E;;;;;;GAMG;AACH,wBAAgB,cAAc,CAAC,GAAG,EAAE,WAAW,EAAE,CAAC,EAAE,MAAM,GAAG,SAAS,GAAG,WAAW,CAMnF;AAqBD,mFAAmF;AACnF,MAAM,MAAM,WAAW,GAAG,OAAO,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,CAAC;AAmBvE;;;;;;GAMG;AACH,wBAAgB,wBAAwB,CAAC,OAAO,CAAC,EAAE,WAAW,EAAE,IAAI,CAAC,EAAE,OAAO,GAAG,MAAM,GAAG,SAAS,CAUlG;AAuED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,MAAM,GAAG,aAAa,CAUpE;AAcD;;;GAGG;AACH,wBAAgB,gBAAgB,CAC9B,MAAM,EAAE,MAAM,EACd,IAAI,CAAC,EAAE,OAAO,EACd,OAAO,CAAC,EAAE,WAAW,EACrB,MAAM,CAAC,EAAE,WAAW,GACnB,aAAa,CAoBf;AAeD;;;;;GAKG;AACH,wBAAgB,mBAAmB,CACjC,MAAM,EAAE,MAAM,EACd,YAAY,EAAE,MAAM,GAAG,SAAS,EAChC,MAAM,CAAC,EAAE,WAAW,GACnB,MAAM,CAMR"}
|
package/dist/ai/retry.js
CHANGED
|
@@ -1,14 +1,254 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* (7.10 §3.6) Typed provider-error classification + retry policy. Ported from
|
|
3
|
+
* goose (`errors.rs` taxonomy + `http_status.rs` Retry-After parse + `retry.rs`
|
|
4
|
+
* jitter). This is the TS implementation — the always-on path; a Rust mirror
|
|
5
|
+
* (`retry_after.rs`/`provider_error.rs`) lands in W6 alongside the native
|
|
6
|
+
* anthropic client that surfaces structured status/headers (where it's
|
|
7
|
+
* consumed), with native↔JS equivalence tests there.
|
|
8
|
+
*
|
|
9
|
+
* Two classification entry points:
|
|
10
|
+
* - {@link classifyProviderError} — from an error STRING (the AI-SDK path,
|
|
11
|
+
* which doesn't surface a structured status), via regex + a best-effort
|
|
12
|
+
* Retry-After hint scraped from the message.
|
|
13
|
+
* - {@link classifyByStatus} — from an HTTP status + body (the W6 native path),
|
|
14
|
+
* the precise classifier.
|
|
15
|
+
*/
|
|
16
|
+
export const defaultRetryConfig = { delaysMs: [500, 1000, 2000] };
|
|
17
|
+
/**
|
|
18
|
+
* (7.10 TS re-review) Apply a per-request `maxRetries` (from `SamplingOptions`,
|
|
19
|
+
* already clamped to [0,10]) to a base config. `delaysMs.length` IS the retry
|
|
20
|
+
* count, so we resize it: a smaller `n` truncates (0 ⇒ no retries — fail on the
|
|
21
|
+
* first error); a larger `n` extends by repeating the last base delay. Returns
|
|
22
|
+
* the base unchanged when `n` is undefined.
|
|
23
|
+
*/
|
|
24
|
+
export function withMaxRetries(cfg, n) {
|
|
25
|
+
if (n === undefined)
|
|
26
|
+
return cfg;
|
|
27
|
+
const base = cfg.delaysMs;
|
|
28
|
+
const last = base[base.length - 1] ?? 1000;
|
|
29
|
+
const delaysMs = Array.from({ length: n }, (_, i) => base[i] ?? last);
|
|
30
|
+
return { ...cfg, delaysMs };
|
|
31
|
+
}
|
|
32
|
+
// One hour — past any legitimate rate-limit window. A malformed
|
|
33
|
+
// `retry_after: 1e30` degrades to "no hint" rather than freezing the agent.
|
|
34
|
+
const MAX_RETRY_AFTER_SECS = 3600;
|
|
1
35
|
const RATE_LIMIT_RX = /(rate.?limit|\b429\b|too\s+many\s+requests|throttl|quota\s+exceed)/i;
|
|
2
36
|
const SERVER_5XX_RX = /(\b5\d\d\b|service\s+unavailable|gateway\s+timeout|internal\s+server\s+error|bad\s+gateway|overloaded_error|model\s+is\s+overloaded)/i;
|
|
3
|
-
const NETWORK_RX = /(econnreset|econnrefused|etimedout|enotfound|socket\s+hang\s+up|connection\s+refused|network\s+error|fetch\s+failed|deadline\s+exceeded)/i;
|
|
37
|
+
const NETWORK_RX = /(econnreset|econnrefused|etimedout|enotfound|socket\s+hang\s+up|connection\s+refused|network\s+error|fetch\s+failed|deadline\s+exceeded|timed\s*out)/i;
|
|
38
|
+
const AUTH_RX = /(\b401\b|\b403\b|unauthorized|invalid\s+(?:api\s+)?key|authentication|forbidden|permission\s+denied)/i;
|
|
39
|
+
// Credits/billing only — NOT bare "quota exceeded" (that's a rate-limit window,
|
|
40
|
+
// retryable; real credit exhaustion comes as 402 via classifyByStatus).
|
|
41
|
+
const CREDITS_RX = /(\b402\b|insufficient\s+(?:credit|balance|funds)|billing|payment\s+required|credits?\s+exhaust)/i;
|
|
42
|
+
// (7.10 TS re-review) STRONG, terminal exhaustion that must beat a co-occurring
|
|
43
|
+
// 429 — OpenAI returns `insufficient_quota` AS a 429 ("you exceeded your current
|
|
44
|
+
// quota"), which is a billing dead-end, not a retryable rate window. Retrying it
|
|
45
|
+
// just burns attempts. The bare word "billing" stays WEAK (in CREDITS_RX, after
|
|
46
|
+
// rate-limit) so "429 upgrade your billing plan" still retries.
|
|
47
|
+
const STRONG_CREDITS_RX = /(\b402\b|payment\s+required|insufficient[_\s]?(?:credit|credits|balance|funds|quota)|credits?\s+exhaust|exceeded\s+your\s+current\s+quota)/i;
|
|
48
|
+
const CONTEXT_RX = /(context\s+length|context\s+window|too\s+long|maximum\s+context|token\s+limit|reduce\s+the\s+length)/i;
|
|
49
|
+
function headerValue(headers, name) {
|
|
50
|
+
if (!headers)
|
|
51
|
+
return undefined;
|
|
52
|
+
if (typeof headers.get === "function") {
|
|
53
|
+
return headers.get(name) ?? undefined;
|
|
54
|
+
}
|
|
55
|
+
const obj = headers;
|
|
56
|
+
const lower = name.toLowerCase();
|
|
57
|
+
for (const k of Object.keys(obj))
|
|
58
|
+
if (k.toLowerCase() === lower)
|
|
59
|
+
return obj[k];
|
|
60
|
+
return undefined;
|
|
61
|
+
}
|
|
62
|
+
/** Clamp a finite, non-negative seconds value into range; else undefined. */
|
|
63
|
+
function finiteSecs(secs) {
|
|
64
|
+
if (!Number.isFinite(secs) || secs < 0)
|
|
65
|
+
return undefined;
|
|
66
|
+
return Math.min(secs, MAX_RETRY_AFTER_SECS);
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* (goose `extract_retry_after`) The retry delay a server directed, in SECONDS.
|
|
70
|
+
* Precedence: the body's `error.metadata.retry_after_seconds` (OpenRouter, more
|
|
71
|
+
* precise than the integer header) → the `Retry-After` header in either its
|
|
72
|
+
* delay-seconds form or one of the three RFC 7231 HTTP-date forms. A past date
|
|
73
|
+
* is honored as "retry now" (0). Returns undefined when there's no usable hint.
|
|
74
|
+
*/
|
|
75
|
+
export function extractRetryAfterSeconds(headers, body) {
|
|
76
|
+
const fromBody = body?.error
|
|
77
|
+
?.metadata?.retry_after_seconds;
|
|
78
|
+
if (typeof fromBody === "number") {
|
|
79
|
+
const d = finiteSecs(fromBody);
|
|
80
|
+
if (d !== undefined)
|
|
81
|
+
return d;
|
|
82
|
+
}
|
|
83
|
+
const header = headerValue(headers, "retry-after")?.trim();
|
|
84
|
+
if (!header)
|
|
85
|
+
return undefined;
|
|
86
|
+
return parseRetryAfterHeader(header);
|
|
87
|
+
}
|
|
88
|
+
/** RFC 7231 §7.1.3: a non-negative integer seconds, OR an HTTP-date. */
|
|
89
|
+
function parseRetryAfterHeader(value) {
|
|
90
|
+
if (/^\d+$/.test(value))
|
|
91
|
+
return finiteSecs(Number(value));
|
|
92
|
+
const target = parseHttpDate(value);
|
|
93
|
+
if (target === undefined)
|
|
94
|
+
return undefined;
|
|
95
|
+
const delayMs = target - nowMs();
|
|
96
|
+
return finiteSecs(Math.max(0, delayMs) / 1000);
|
|
97
|
+
}
|
|
98
|
+
// Indirection so tests can hold time still without touching Date.now globally.
|
|
99
|
+
function nowMs() {
|
|
100
|
+
return Date.now();
|
|
101
|
+
}
|
|
102
|
+
const MONTHS = {
|
|
103
|
+
jan: 0, feb: 1, mar: 2, apr: 3, may: 4, jun: 5, jul: 6, aug: 7, sep: 8, oct: 9, nov: 10, dec: 11,
|
|
104
|
+
};
|
|
105
|
+
/**
|
|
106
|
+
* The three HTTP-date forms RFC 7231 requires recipients to accept, ALL in GMT:
|
|
107
|
+
* IMF-fixdate (`Sun, 06 Nov 1994 08:49:37 GMT`), the obsolete RFC 850
|
|
108
|
+
* (`Sunday, 06-Nov-94 08:49:37 GMT`), and asctime (`Sun Nov 6 08:49:37 1994`).
|
|
109
|
+
* `Date.parse` handles IMF-fixdate (it carries `GMT`); RFC 850 + asctime are
|
|
110
|
+
* parsed manually with {@link Date.UTC} — asctime has NO timezone, so leaving it
|
|
111
|
+
* to `Date.parse` would interpret it in LOCAL time on a non-UTC host (codex W5
|
|
112
|
+
* R2-M2). Returns epoch ms, or undefined.
|
|
113
|
+
*/
|
|
114
|
+
function parseHttpDate(value) {
|
|
115
|
+
const v = value.trim();
|
|
116
|
+
// RFC 850: `Weekday, DD-Mon-YY HH:MM:SS GMT`.
|
|
117
|
+
const rfc850 = /^[A-Za-z]+,\s*(\d{2})-([A-Za-z]{3})-(\d{2})\s+(\d{2}):(\d{2}):(\d{2})\s*GMT$/.exec(v);
|
|
118
|
+
if (rfc850) {
|
|
119
|
+
const [, dd, mon, yy, hh, mm, ss] = rfc850;
|
|
120
|
+
// RFC 6265 / chrono 2-digit-year window: 00-69 → 2000s, 70-99 → 1900s.
|
|
121
|
+
const year = Number(yy) < 70 ? 2000 + Number(yy) : 1900 + Number(yy);
|
|
122
|
+
return utcFrom(year, mon, dd, hh, mm, ss);
|
|
123
|
+
}
|
|
124
|
+
// asctime: `Wkd Mon D HH:MM:SS YYYY` (single-digit day → two spaces). No tz → GMT.
|
|
125
|
+
const asctime = /^[A-Za-z]+\s+([A-Za-z]{3})\s+(\d{1,2})\s+(\d{2}):(\d{2}):(\d{2})\s+(\d{4})$/.exec(v);
|
|
126
|
+
if (asctime) {
|
|
127
|
+
const [, mon, dd, hh, mm, ss, yyyy] = asctime;
|
|
128
|
+
return utcFrom(Number(yyyy), mon, dd, hh, mm, ss);
|
|
129
|
+
}
|
|
130
|
+
// IMF-fixdate carries an explicit GMT → Date.parse is timezone-correct.
|
|
131
|
+
const ms = Date.parse(v);
|
|
132
|
+
return Number.isNaN(ms) ? undefined : ms;
|
|
133
|
+
}
|
|
134
|
+
function utcFrom(year, mon, dd, hh, mm, ss) {
|
|
135
|
+
const month = MONTHS[mon.toLowerCase()];
|
|
136
|
+
if (month === undefined)
|
|
137
|
+
return undefined;
|
|
138
|
+
const ms = Date.UTC(year, month, Number(dd), Number(hh), Number(mm), Number(ss));
|
|
139
|
+
return Number.isNaN(ms) ? undefined : ms;
|
|
140
|
+
}
|
|
141
|
+
/** Scrape a Retry-After hint from a free-text error message (AI-SDK path). */
|
|
142
|
+
function retryAfterFromMessage(message) {
|
|
143
|
+
const m = /(?:retry[\s-]?after|try\s+again\s+in|retry\s+in)\D{0,8}(\d+(?:\.\d+)?)\s*(ms|milliseconds?|s|sec|secs|seconds?)?/i.exec(message);
|
|
144
|
+
if (!m)
|
|
145
|
+
return undefined;
|
|
146
|
+
const n = Number(m[1]);
|
|
147
|
+
if (!Number.isFinite(n))
|
|
148
|
+
return undefined;
|
|
149
|
+
const unit = (m[2] ?? "s").toLowerCase();
|
|
150
|
+
const secs = unit.startsWith("ms") || unit.startsWith("milli") ? n / 1000 : n;
|
|
151
|
+
const clamped = finiteSecs(secs);
|
|
152
|
+
return clamped === undefined ? undefined : Math.round(clamped * 1000);
|
|
153
|
+
}
|
|
154
|
+
/**
|
|
155
|
+
* Classify a provider error STRING into a retry decision (the AI-SDK path).
|
|
156
|
+
* Precedence (codex W5 R2-S1; refined in the 7.10 TS re-review):
|
|
157
|
+
* 1. auth — a wrong key won't fix on retry; wins even over a co-occurring 429.
|
|
158
|
+
* 2. STRONG credits — terminal exhaustion (402 / payment required / insufficient
|
|
159
|
+
* credits|balance|funds|quota / credits exhausted / "exceeded your current
|
|
160
|
+
* quota"). Beats rate-limit because OpenAI returns `insufficient_quota` AS a
|
|
161
|
+
* 429 — retrying a billing dead-end just burns attempts.
|
|
162
|
+
* 3. rate-limit — a 429 / rate-limit / quota WINDOW is retryable even if the
|
|
163
|
+
* message also mentions weak "billing" (so "429 upgrade your billing" retries).
|
|
164
|
+
* 4. weak credits — bare "billing" without a 429, terminal.
|
|
165
|
+
* 5. context-length — terminal (overflow→compact recovery handles it elsewhere).
|
|
166
|
+
* 6. server / network — retryable.
|
|
167
|
+
* 7. unknown — not retryable (don't gamble on a mystery error).
|
|
168
|
+
*/
|
|
4
169
|
export function classifyProviderError(message) {
|
|
170
|
+
const retryAfterMs = retryAfterFromMessage(message);
|
|
171
|
+
if (AUTH_RX.test(message))
|
|
172
|
+
return { retryable: false, reason: "auth" };
|
|
173
|
+
if (STRONG_CREDITS_RX.test(message))
|
|
174
|
+
return { retryable: false, reason: "credits" };
|
|
5
175
|
if (RATE_LIMIT_RX.test(message))
|
|
6
|
-
return { retryable: true, reason: "rate-limit" };
|
|
176
|
+
return { retryable: true, reason: "rate-limit", retryAfterMs };
|
|
177
|
+
if (CREDITS_RX.test(message))
|
|
178
|
+
return { retryable: false, reason: "credits" };
|
|
179
|
+
if (CONTEXT_RX.test(message))
|
|
180
|
+
return { retryable: false, reason: "context-length" };
|
|
7
181
|
if (SERVER_5XX_RX.test(message))
|
|
8
|
-
return { retryable: true, reason: "server
|
|
182
|
+
return { retryable: true, reason: "server", retryAfterMs };
|
|
9
183
|
if (NETWORK_RX.test(message))
|
|
10
|
-
return { retryable: true, reason: "network" };
|
|
11
|
-
return { retryable: false, reason: "
|
|
184
|
+
return { retryable: true, reason: "network", retryAfterMs };
|
|
185
|
+
return { retryable: false, reason: "unknown" };
|
|
186
|
+
}
|
|
187
|
+
/** Phrases that mark a 4xx/error body as a context-window overflow (goose). */
|
|
188
|
+
const CONTEXT_PHRASES = [
|
|
189
|
+
"too long",
|
|
190
|
+
"context length",
|
|
191
|
+
"context_length_exceeded",
|
|
192
|
+
"reduce the length",
|
|
193
|
+
"token count",
|
|
194
|
+
"exceeds",
|
|
195
|
+
"context limit",
|
|
196
|
+
"maximum prompt length",
|
|
197
|
+
];
|
|
198
|
+
/**
|
|
199
|
+
* Classify from an HTTP status + body — the precise path (W6 native client,
|
|
200
|
+
* which has structured status/headers). Mirrors goose `map_http_error`.
|
|
201
|
+
*/
|
|
202
|
+
export function classifyByStatus(status, body, headers, config) {
|
|
203
|
+
const retryAfterSecs = extractRetryAfterSeconds(headers, body);
|
|
204
|
+
const retryAfterMs = retryAfterSecs === undefined ? undefined : Math.round(retryAfterSecs * 1000);
|
|
205
|
+
if (status === 401 || status === 403)
|
|
206
|
+
return { retryable: false, reason: "auth" };
|
|
207
|
+
if (status === 402)
|
|
208
|
+
return { retryable: false, reason: "credits" };
|
|
209
|
+
if (status === 429) {
|
|
210
|
+
// (7.10 TS re-review) A 429 whose body signals strong exhaustion (OpenAI's
|
|
211
|
+
// `insufficient_quota`) is terminal billing, not a retryable rate window.
|
|
212
|
+
if (bodyMentionsStrongCredits(body))
|
|
213
|
+
return { retryable: false, reason: "credits" };
|
|
214
|
+
return { retryable: true, reason: "rate-limit", retryAfterMs };
|
|
215
|
+
}
|
|
216
|
+
if (status >= 500)
|
|
217
|
+
return { retryable: true, reason: "server", retryAfterMs };
|
|
218
|
+
if (status === 408)
|
|
219
|
+
return { retryable: true, reason: "network", retryAfterMs };
|
|
220
|
+
if (status === 413 || (status === 400 && bodyMentionsContext(body))) {
|
|
221
|
+
return { retryable: false, reason: "context-length" };
|
|
222
|
+
}
|
|
223
|
+
// A generic 4xx is goose's RequestFailed: retryable unless transient-only is on
|
|
224
|
+
// (default off → retryable). codex W5 R2-M3: undefined config must NOT invert this.
|
|
225
|
+
if (status >= 400)
|
|
226
|
+
return { retryable: !(config?.transientOnly ?? false), reason: "request" };
|
|
227
|
+
return { retryable: false, reason: "unknown" };
|
|
228
|
+
}
|
|
229
|
+
function bodyMentionsContext(body) {
|
|
230
|
+
const text = (typeof body === "string" ? body : JSON.stringify(body ?? "")).toLowerCase();
|
|
231
|
+
return CONTEXT_PHRASES.some((p) => text.includes(p));
|
|
232
|
+
}
|
|
233
|
+
/** (7.10 TS re-review) Whether an error body signals STRONG credit exhaustion
|
|
234
|
+
* (e.g. OpenAI's `insufficient_quota` on a 429) — terminal billing, not a
|
|
235
|
+
* retryable rate window. */
|
|
236
|
+
function bodyMentionsStrongCredits(body) {
|
|
237
|
+
const text = typeof body === "string" ? body : JSON.stringify(body ?? "");
|
|
238
|
+
return STRONG_CREDITS_RX.test(text);
|
|
239
|
+
}
|
|
240
|
+
/**
|
|
241
|
+
* (goose `retry.rs`) The delay before a retry attempt. A server-directed
|
|
242
|
+
* `retryAfterMs` wins outright (no jitter — honor the server). Otherwise the
|
|
243
|
+
* base backoff is capped at `maxIntervalMs` and multiplied by a jitter factor in
|
|
244
|
+
* [0.8, 1.2) to avoid a thundering herd.
|
|
245
|
+
*/
|
|
246
|
+
export function computeRetryDelayMs(baseMs, retryAfterMs, config) {
|
|
247
|
+
if (retryAfterMs !== undefined)
|
|
248
|
+
return retryAfterMs;
|
|
249
|
+
const capped = Math.min(baseMs, config?.maxIntervalMs ?? 60_000);
|
|
250
|
+
const random = config?.random ?? Math.random;
|
|
251
|
+
const jitter = 0.8 + random() * 0.4;
|
|
252
|
+
return Math.round(capped * jitter);
|
|
12
253
|
}
|
|
13
|
-
export const defaultRetryConfig = { delaysMs: [500, 1000, 2000] };
|
|
14
254
|
//# sourceMappingURL=retry.js.map
|
package/dist/ai/retry.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"retry.js","sourceRoot":"","sources":["../../src/ai/retry.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"retry.js","sourceRoot":"","sources":["../../src/ai/retry.ts"],"names":[],"mappings":"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"}
|
package/dist/ai/router.d.ts
CHANGED
|
@@ -7,6 +7,9 @@ export interface RouteHints {
|
|
|
7
7
|
preferredProvider?: string;
|
|
8
8
|
/** True when the turn may issue tool calls. */
|
|
9
9
|
needsTools?: boolean;
|
|
10
|
+
/** (7.10 §3.8) A cheaper model to prefer for low-stakes turns (summarization /
|
|
11
|
+
* compaction). Resolved by {@link ModelRouter.pickFast}; ignored by `pick`. */
|
|
12
|
+
preferredFastModel?: string;
|
|
10
13
|
}
|
|
11
14
|
export interface Route {
|
|
12
15
|
adapter: ProviderAdapter;
|
|
@@ -21,5 +24,14 @@ export declare class ModelRouter {
|
|
|
21
24
|
private readonly registry;
|
|
22
25
|
constructor(registry: ModelRegistry);
|
|
23
26
|
pick(hints?: RouteHints): Route;
|
|
27
|
+
/**
|
|
28
|
+
* (7.10 §3.8) Route for a low-stakes turn (summarization/compaction). Returns
|
|
29
|
+
* `preferredFastModel` when it resolves to a registered model with an adapter;
|
|
30
|
+
* otherwise falls back to {@link pick} — so with NO fast model configured the
|
|
31
|
+
* fast route IS the main route, and the caller's name-equality guard then skips
|
|
32
|
+
* the fallback (no behavior change). goose `complete_fast`: a configured fast
|
|
33
|
+
* model only helps if it's actually distinct from the main one.
|
|
34
|
+
*/
|
|
35
|
+
pickFast(hints?: RouteHints): Route;
|
|
24
36
|
}
|
|
25
37
|
//# sourceMappingURL=router.d.ts.map
|
package/dist/ai/router.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"router.d.ts","sourceRoot":"","sources":["../../src/ai/router.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AACnD,OAAO,KAAK,EAAE,eAAe,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAEnE,MAAM,WAAW,UAAU;IACzB,sDAAsD;IACtD,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,sCAAsC;IACtC,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,+CAA+C;IAC/C,UAAU,CAAC,EAAE,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"router.d.ts","sourceRoot":"","sources":["../../src/ai/router.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AACnD,OAAO,KAAK,EAAE,eAAe,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAEnE,MAAM,WAAW,UAAU;IACzB,sDAAsD;IACtD,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,sCAAsC;IACtC,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,+CAA+C;IAC/C,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB;oFACgF;IAChF,kBAAkB,CAAC,EAAE,MAAM,CAAC;CAC7B;AAED,MAAM,WAAW,KAAK;IACpB,OAAO,EAAE,eAAe,CAAC;IACzB,KAAK,EAAE,eAAe,CAAC;CACxB;AAED;;;;GAIG;AACH,qBAAa,WAAW;IACV,OAAO,CAAC,QAAQ,CAAC,QAAQ;gBAAR,QAAQ,EAAE,aAAa;IAEpD,IAAI,CAAC,KAAK,GAAE,UAAe,GAAG,KAAK;IA0BnC;;;;;;;OAOG;IACH,QAAQ,CAAC,KAAK,GAAE,UAAe,GAAG,KAAK;CAUxC"}
|
package/dist/ai/router.js
CHANGED
|
@@ -32,5 +32,24 @@ export class ModelRouter {
|
|
|
32
32
|
}
|
|
33
33
|
return { adapter, model };
|
|
34
34
|
}
|
|
35
|
+
/**
|
|
36
|
+
* (7.10 §3.8) Route for a low-stakes turn (summarization/compaction). Returns
|
|
37
|
+
* `preferredFastModel` when it resolves to a registered model with an adapter;
|
|
38
|
+
* otherwise falls back to {@link pick} — so with NO fast model configured the
|
|
39
|
+
* fast route IS the main route, and the caller's name-equality guard then skips
|
|
40
|
+
* the fallback (no behavior change). goose `complete_fast`: a configured fast
|
|
41
|
+
* model only helps if it's actually distinct from the main one.
|
|
42
|
+
*/
|
|
43
|
+
pickFast(hints = {}) {
|
|
44
|
+
if (hints.preferredFastModel) {
|
|
45
|
+
const model = this.registry.get(hints.preferredFastModel);
|
|
46
|
+
const adapter = model ? this.registry.adapterFor(model.id) : undefined;
|
|
47
|
+
if (model && adapter)
|
|
48
|
+
return { adapter, model };
|
|
49
|
+
// Configured but unresolvable (typo / unloaded provider) → fall through to
|
|
50
|
+
// the main pick rather than crashing the compaction.
|
|
51
|
+
}
|
|
52
|
+
return this.pick(hints);
|
|
53
|
+
}
|
|
35
54
|
}
|
|
36
55
|
//# sourceMappingURL=router.js.map
|
package/dist/ai/router.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"router.js","sourceRoot":"","sources":["../../src/ai/router.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;
|
|
1
|
+
{"version":3,"file":"router.js","sourceRoot":"","sources":["../../src/ai/router.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAqB1D;;;;GAIG;AACH,MAAM,OAAO,WAAW;IACO;IAA7B,YAA6B,QAAuB;QAAvB,aAAQ,GAAR,QAAQ,CAAe;IAAG,CAAC;IAExD,IAAI,CAAC,QAAoB,EAAE;QACzB,MAAM,UAAU,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,EAAE,CAAC;QACvC,IAAI,UAAU,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC5B,MAAM,IAAI,QAAQ,CAAC,SAAS,CAAC,QAAQ,EAAE,sBAAsB,CAAC,CAAC;QACjE,CAAC;QAED,IAAI,KAAkC,CAAC;QACvC,IAAI,KAAK,CAAC,cAAc;YAAE,KAAK,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,KAAK,CAAC,cAAc,CAAC,CAAC;QAC1E,IAAI,CAAC,KAAK,IAAI,KAAK,CAAC,iBAAiB,EAAE,CAAC;YACtC,KAAK,GAAG,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,KAAK,KAAK,CAAC,iBAAiB,CAAC,CAAC;QACzE,CAAC;QACD,IAAI,CAAC,KAAK,EAAE,CAAC;YACX,MAAM,IAAI,GAAG,KAAK,CAAC,UAAU,CAAC,CAAC,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC;YACvF,KAAK,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,IAAI,CACjD,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,gBAAgB,GAAG,CAAC,CAAC,gBAAgB,CAClD,CAAC,CAAC,CAAC,CAAC;QACP,CAAC;QACD,IAAI,CAAC,KAAK;YAAE,MAAM,IAAI,QAAQ,CAAC,SAAS,CAAC,QAAQ,EAAE,yBAAyB,CAAC,CAAC;QAE9E,MAAM,OAAO,GAAG,IAAI,CAAC,QAAQ,CAAC,UAAU,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;QACnD,IAAI,CAAC,OAAO,EAAE,CAAC;YACb,MAAM,IAAI,QAAQ,CAAC,SAAS,CAAC,QAAQ,EAAE,wBAAwB,KAAK,CAAC,EAAE,EAAE,CAAC,CAAC;QAC7E,CAAC;QACD,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC;IAC5B,CAAC;IAED;;;;;;;OAOG;IACH,QAAQ,CAAC,QAAoB,EAAE;QAC7B,IAAI,KAAK,CAAC,kBAAkB,EAAE,CAAC;YAC7B,MAAM,KAAK,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,KAAK,CAAC,kBAAkB,CAAC,CAAC;YAC1D,MAAM,OAAO,GAAG,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,UAAU,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;YACvE,IAAI,KAAK,IAAI,OAAO;gBAAE,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC;YAChD,2EAA2E;YAC3E,qDAAqD;QACvD,CAAC;QACD,OAAO,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAC1B,CAAC;CACF"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import type { SamplingOptions } from "./types.js";
|
|
2
|
+
/**
|
|
3
|
+
* (7.10 §3.5) The single source of truth for sampling bounds. Both the remote
|
|
4
|
+
* `set_options` path (wire) and the local `CHANCES_*` env seed (cli) run raw
|
|
5
|
+
* values through {@link clampSampling}, so an out-of-range value is clamped (not
|
|
6
|
+
* dropped) and a non-number is dropped — identically, no matter the entry point
|
|
7
|
+
* (codex W4 R2-S1).
|
|
8
|
+
*/
|
|
9
|
+
export declare const SAMPLING_BOUNDS: {
|
|
10
|
+
readonly temperature: {
|
|
11
|
+
readonly min: 0;
|
|
12
|
+
readonly max: 2;
|
|
13
|
+
};
|
|
14
|
+
readonly topP: {
|
|
15
|
+
readonly min: 0;
|
|
16
|
+
readonly max: 1;
|
|
17
|
+
};
|
|
18
|
+
readonly maxTokens: {
|
|
19
|
+
readonly min: 1;
|
|
20
|
+
readonly max: 1000000;
|
|
21
|
+
readonly int: true;
|
|
22
|
+
};
|
|
23
|
+
readonly timeoutMs: {
|
|
24
|
+
readonly min: 1;
|
|
25
|
+
readonly max: 3600000;
|
|
26
|
+
readonly int: true;
|
|
27
|
+
};
|
|
28
|
+
readonly maxRetries: {
|
|
29
|
+
readonly min: 0;
|
|
30
|
+
readonly max: 10;
|
|
31
|
+
readonly int: true;
|
|
32
|
+
};
|
|
33
|
+
};
|
|
34
|
+
/** Clamp a raw sampling object to the documented bounds, dropping absent/invalid
|
|
35
|
+
* fields. Returns undefined when nothing valid survives (so callers omit it). */
|
|
36
|
+
export declare function clampSampling(raw: Partial<Record<keyof SamplingOptions, unknown>> | undefined): SamplingOptions | undefined;
|
|
37
|
+
//# sourceMappingURL=sampling.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sampling.d.ts","sourceRoot":"","sources":["../../src/ai/sampling.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAElD;;;;;;GAMG;AACH,eAAO,MAAM,eAAe;;;;;;;;;;;;;;;;;;;;;;;;CAMlB,CAAC;AAQX;kFACkF;AAClF,wBAAgB,aAAa,CAAC,GAAG,EAAE,OAAO,CAAC,MAAM,CAAC,MAAM,eAAe,EAAE,OAAO,CAAC,CAAC,GAAG,SAAS,GAAG,eAAe,GAAG,SAAS,CAQ3H"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* (7.10 §3.5) The single source of truth for sampling bounds. Both the remote
|
|
3
|
+
* `set_options` path (wire) and the local `CHANCES_*` env seed (cli) run raw
|
|
4
|
+
* values through {@link clampSampling}, so an out-of-range value is clamped (not
|
|
5
|
+
* dropped) and a non-number is dropped — identically, no matter the entry point
|
|
6
|
+
* (codex W4 R2-S1).
|
|
7
|
+
*/
|
|
8
|
+
export const SAMPLING_BOUNDS = {
|
|
9
|
+
temperature: { min: 0, max: 2 },
|
|
10
|
+
topP: { min: 0, max: 1 },
|
|
11
|
+
maxTokens: { min: 1, max: 1_000_000, int: true },
|
|
12
|
+
timeoutMs: { min: 1, max: 3_600_000, int: true },
|
|
13
|
+
maxRetries: { min: 0, max: 10, int: true },
|
|
14
|
+
};
|
|
15
|
+
function clampField(v, b) {
|
|
16
|
+
if (typeof v !== "number" || !Number.isFinite(v))
|
|
17
|
+
return undefined;
|
|
18
|
+
const c = Math.min(b.max, Math.max(b.min, v));
|
|
19
|
+
return b.int ? Math.round(c) : c;
|
|
20
|
+
}
|
|
21
|
+
/** Clamp a raw sampling object to the documented bounds, dropping absent/invalid
|
|
22
|
+
* fields. Returns undefined when nothing valid survives (so callers omit it). */
|
|
23
|
+
export function clampSampling(raw) {
|
|
24
|
+
if (!raw)
|
|
25
|
+
return undefined;
|
|
26
|
+
const out = {};
|
|
27
|
+
for (const key of Object.keys(SAMPLING_BOUNDS)) {
|
|
28
|
+
const v = clampField(raw[key], SAMPLING_BOUNDS[key]);
|
|
29
|
+
if (v !== undefined)
|
|
30
|
+
out[key] = v;
|
|
31
|
+
}
|
|
32
|
+
return Object.keys(out).length > 0 ? out : undefined;
|
|
33
|
+
}
|
|
34
|
+
//# sourceMappingURL=sampling.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sampling.js","sourceRoot":"","sources":["../../src/ai/sampling.ts"],"names":[],"mappings":"AAEA;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,eAAe,GAAG;IAC7B,WAAW,EAAE,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE;IAC/B,IAAI,EAAE,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE;IACxB,SAAS,EAAE,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,SAAS,EAAE,GAAG,EAAE,IAAI,EAAE;IAChD,SAAS,EAAE,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,SAAS,EAAE,GAAG,EAAE,IAAI,EAAE;IAChD,UAAU,EAAE,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,EAAE,EAAE,GAAG,EAAE,IAAI,EAAE;CAClC,CAAC;AAEX,SAAS,UAAU,CAAC,CAAU,EAAE,CAA8C;IAC5E,IAAI,OAAO,CAAC,KAAK,QAAQ,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC;QAAE,OAAO,SAAS,CAAC;IACnE,MAAM,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC;IAC9C,OAAO,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AACnC,CAAC;AAED;kFACkF;AAClF,MAAM,UAAU,aAAa,CAAC,GAAgE;IAC5F,IAAI,CAAC,GAAG;QAAE,OAAO,SAAS,CAAC;IAC3B,MAAM,GAAG,GAAoB,EAAE,CAAC;IAChC,KAAK,MAAM,GAAG,IAAI,MAAM,CAAC,IAAI,CAAC,eAAe,CAAqC,EAAE,CAAC;QACnF,MAAM,CAAC,GAAG,UAAU,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,eAAe,CAAC,GAAG,CAAC,CAAC,CAAC;QACrD,IAAI,CAAC,KAAK,SAAS;YAAE,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IACpC,CAAC;IACD,OAAO,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,SAAS,CAAC;AACvD,CAAC"}
|
package/dist/ai/setup.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"setup.d.ts","sourceRoot":"","sources":["../../src/ai/setup.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"setup.d.ts","sourceRoot":"","sources":["../../src/ai/setup.ts"],"names":[],"mappings":"AAIA,OAAO,EAAgB,KAAK,aAAa,EAAE,MAAM,mBAAmB,CAAC;AACrE,OAAO,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAG9C,MAAM,WAAW,eAAe;IAC9B,yEAAyE;IACzE,SAAS,EAAE,CAAC,UAAU,EAAE,MAAM,KAAK,MAAM,GAAG,SAAS,CAAC;IACtD,yEAAyE;IACzE,SAAS,CAAC,EAAE,aAAa,EAAE,CAAC;CAC7B;AAED;;;;;;GAMG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,eAAe,GAAG,aAAa,CAWlE;AAED;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,SAAS,GAAE,aAAa,EAAiB,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAEnG"}
|
package/dist/ai/setup.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { AiSdkAdapter } from "./adapters/ai-sdk.js";
|
|
2
2
|
import { MockAdapter } from "./adapters/mock.js";
|
|
3
|
+
import { NativeAnthropicAdapter } from "./adapters/native-anthropic.js";
|
|
3
4
|
import { OpenAICompatibleAdapter } from "./adapters/openai-compatible.js";
|
|
4
5
|
import { KNOWN_MODELS } from "./known-models.js";
|
|
5
6
|
import { ModelRegistry } from "./registry.js";
|
|
@@ -30,10 +31,19 @@ export function buildRegistry(opts) {
|
|
|
30
31
|
export function envByProviderFrom(providers = KNOWN_MODELS) {
|
|
31
32
|
return Object.fromEntries(providers.map((p) => [p.id, p.envKey]));
|
|
32
33
|
}
|
|
34
|
+
/**
|
|
35
|
+
* (7.10) Map the wire protocol to the `@ai-sdk/<vendor>` family that backs it.
|
|
36
|
+
* `anthropic-messages` is handled separately by {@link NativeAnthropicAdapter}
|
|
37
|
+
* (native-first, AI-SDK fallback), so it's not in this table.
|
|
38
|
+
*/
|
|
39
|
+
const AI_SDK_FAMILY = {
|
|
40
|
+
"openai-responses": "openai",
|
|
41
|
+
google: "google",
|
|
42
|
+
};
|
|
33
43
|
function buildAdapter(entry, apiKey) {
|
|
34
|
-
if (entry.api === "openai-
|
|
44
|
+
if (entry.api === "openai-completions") {
|
|
35
45
|
if (!entry.baseURL) {
|
|
36
|
-
throw new Error(`provider '${entry.id}' is api=openai-
|
|
46
|
+
throw new Error(`provider '${entry.id}' is api=openai-completions but has no baseURL`);
|
|
37
47
|
}
|
|
38
48
|
return new OpenAICompatibleAdapter({
|
|
39
49
|
provider: entry.id,
|
|
@@ -42,6 +52,20 @@ function buildAdapter(entry, apiKey) {
|
|
|
42
52
|
models: entry.models,
|
|
43
53
|
});
|
|
44
54
|
}
|
|
45
|
-
|
|
55
|
+
// (7.10 W6) anthropic-messages → the hand-rolled native client (cache 3-anchor
|
|
56
|
+
// + thinking signatures + structured Retry-After), with @ai-sdk/anthropic as
|
|
57
|
+
// the addon-absent fallback baked into the adapter.
|
|
58
|
+
if (entry.api === "anthropic-messages") {
|
|
59
|
+
return new NativeAnthropicAdapter({
|
|
60
|
+
apiKey,
|
|
61
|
+
models: entry.models,
|
|
62
|
+
...(entry.baseURL ? { baseURL: entry.baseURL } : {}),
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
const family = AI_SDK_FAMILY[entry.api];
|
|
66
|
+
if (!family) {
|
|
67
|
+
throw new Error(`provider '${entry.id}' has unsupported api '${entry.api}'`);
|
|
68
|
+
}
|
|
69
|
+
return new AiSdkAdapter({ provider: family, apiKey, models: entry.models });
|
|
46
70
|
}
|
|
47
71
|
//# sourceMappingURL=setup.js.map
|
package/dist/ai/setup.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"setup.js","sourceRoot":"","sources":["../../src/ai/setup.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,
|
|
1
|
+
{"version":3,"file":"setup.js","sourceRoot":"","sources":["../../src/ai/setup.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAsB,MAAM,sBAAsB,CAAC;AACxE,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACjD,OAAO,EAAE,sBAAsB,EAAE,MAAM,gCAAgC,CAAC;AACxE,OAAO,EAAE,uBAAuB,EAAE,MAAM,iCAAiC,CAAC;AAC1E,OAAO,EAAE,YAAY,EAAsB,MAAM,mBAAmB,CAAC;AACrE,OAAO,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAU9C;;;;;;GAMG;AACH,MAAM,UAAU,aAAa,CAAC,IAAqB;IACjD,MAAM,QAAQ,GAAG,IAAI,aAAa,EAAE,CAAC;IACrC,QAAQ,CAAC,QAAQ,CAAC,IAAI,WAAW,EAAE,CAAC,CAAC;IAErC,MAAM,SAAS,GAAG,IAAI,CAAC,SAAS,IAAI,YAAY,CAAC;IACjD,KAAK,MAAM,KAAK,IAAI,SAAS,EAAE,CAAC;QAC9B,MAAM,MAAM,GAAG,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;QACxC,IAAI,CAAC,MAAM;YAAE,SAAS;QACtB,QAAQ,CAAC,QAAQ,CAAC,YAAY,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC,CAAC;IACjD,CAAC;IACD,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,iBAAiB,CAAC,YAA6B,YAAY;IACzE,OAAO,MAAM,CAAC,WAAW,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;AACpE,CAAC;AAED;;;;GAIG;AACH,MAAM,aAAa,GAAwC;IACzD,kBAAkB,EAAE,QAAQ;IAC5B,MAAM,EAAE,QAAQ;CACjB,CAAC;AAEF,SAAS,YAAY,CAAC,KAAoB,EAAE,MAAc;IACxD,IAAI,KAAK,CAAC,GAAG,KAAK,oBAAoB,EAAE,CAAC;QACvC,IAAI,CAAC,KAAK,CAAC,OAAO,EAAE,CAAC;YACnB,MAAM,IAAI,KAAK,CAAC,aAAa,KAAK,CAAC,EAAE,gDAAgD,CAAC,CAAC;QACzF,CAAC;QACD,OAAO,IAAI,uBAAuB,CAAC;YACjC,QAAQ,EAAE,KAAK,CAAC,EAAE;YAClB,OAAO,EAAE,KAAK,CAAC,OAAO;YACtB,MAAM;YACN,MAAM,EAAE,KAAK,CAAC,MAAM;SACrB,CAAC,CAAC;IACL,CAAC;IACD,+EAA+E;IAC/E,6EAA6E;IAC7E,oDAAoD;IACpD,IAAI,KAAK,CAAC,GAAG,KAAK,oBAAoB,EAAE,CAAC;QACvC,OAAO,IAAI,sBAAsB,CAAC;YAChC,MAAM;YACN,MAAM,EAAE,KAAK,CAAC,MAAM;YACpB,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;SACrD,CAAC,CAAC;IACL,CAAC;IACD,MAAM,MAAM,GAAG,aAAa,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IACxC,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,MAAM,IAAI,KAAK,CAAC,aAAa,KAAK,CAAC,EAAE,0BAA0B,KAAK,CAAC,GAAG,GAAG,CAAC,CAAC;IAC/E,CAAC;IACD,OAAO,IAAI,YAAY,CAAC,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,CAAC,MAAM,EAAE,CAAC,CAAC;AAC9E,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"summarizer.d.ts","sourceRoot":"","sources":["../../src/ai/summarizer.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,OAAO,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAE3D;;;;;;;;;;GAUG;AACH,eAAO,MAAM,sBAAsB,QASvB,CAAC;AAEb;;;;;;;;GAQG;AACH,wBAAsB,qBAAqB,CACzC,OAAO,EAAE,eAAe,EACxB,OAAO,EAAE,MAAM,EACf,QAAQ,EAAE,OAAO,EAAE,EACnB,MAAM,EAAE,WAAW,GAClB,OAAO,CAAC,MAAM,CAAC,
|
|
1
|
+
{"version":3,"file":"summarizer.d.ts","sourceRoot":"","sources":["../../src/ai/summarizer.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,OAAO,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAE3D;;;;;;;;;;GAUG;AACH,eAAO,MAAM,sBAAsB,QASvB,CAAC;AAEb;;;;;;;;GAQG;AACH,wBAAsB,qBAAqB,CACzC,OAAO,EAAE,eAAe,EACxB,OAAO,EAAE,MAAM,EACf,QAAQ,EAAE,OAAO,EAAE,EACnB,MAAM,EAAE,WAAW,GAClB,OAAO,CAAC,MAAM,CAAC,CA8BjB"}
|
package/dist/ai/summarizer.js
CHANGED
|
@@ -44,9 +44,14 @@ export async function summarizeConversation(adapter, modelId, messages, signal)
|
|
|
44
44
|
// Usage + done + any stray tool-call are intentionally ignored — the
|
|
45
45
|
// summarizer doesn't need token bookkeeping (caller can compare
|
|
46
46
|
// session size before/after) and tool calls during summarization are
|
|
47
|
-
// a provider misconfiguration, not a user-visible failure.
|
|
47
|
+
// a provider misconfiguration, not a user-visible failure. (7.10) Thinking
|
|
48
|
+
// blocks are likewise irrelevant to a summary — drop them explicitly so the
|
|
49
|
+
// switch stays exhaustive over ProviderEvent.
|
|
48
50
|
case "usage":
|
|
49
51
|
case "tool-call":
|
|
52
|
+
case "thinking-start":
|
|
53
|
+
case "thinking-delta":
|
|
54
|
+
case "thinking-end":
|
|
50
55
|
case "done":
|
|
51
56
|
break;
|
|
52
57
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"summarizer.js","sourceRoot":"","sources":["../../src/ai/summarizer.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAG1D;;;;;;;;;;GAUG;AACH,MAAM,CAAC,MAAM,sBAAsB,GAAG;IACpC,mDAAmD;IACnD,qDAAqD;IACrD,oDAAoD;IACpD,qDAAqD;IACrD,yCAAyC;IACzC,oDAAoD;IACpD,8EAA8E;IAC9E,2EAA2E;CAC5E,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAEb;;;;;;;;GAQG;AACH,MAAM,CAAC,KAAK,UAAU,qBAAqB,CACzC,OAAwB,EACxB,OAAe,EACf,QAAmB,EACnB,MAAmB;IAEnB,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,EAAE,CAAC;IACrC,IAAI,IAAI,GAAG,EAAE,CAAC;IACd,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,CAC3B,EAAE,KAAK,EAAE,OAAO,EAAE,MAAM,EAAE,sBAAsB,EAAE,QAAQ,EAAE,KAAK,EAAE,EAAE,EAAE,EACvE,MAAM,CACP,CAAC;IACF,IAAI,KAAK,EAAE,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;QACjC,QAAQ,KAAK,CAAC,IAAI,EAAE,CAAC;YACnB,KAAK,YAAY;gBACf,IAAI,IAAI,KAAK,CAAC,IAAI,CAAC;gBACnB,MAAM;YACR,KAAK,OAAO;gBACV,MAAM,IAAI,QAAQ,CAAC,SAAS,CAAC,QAAQ,EAAE,yBAAyB,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC;YACnF,qEAAqE;YACrE,gEAAgE;YAChE,qEAAqE;YACrE,
|
|
1
|
+
{"version":3,"file":"summarizer.js","sourceRoot":"","sources":["../../src/ai/summarizer.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAG1D;;;;;;;;;;GAUG;AACH,MAAM,CAAC,MAAM,sBAAsB,GAAG;IACpC,mDAAmD;IACnD,qDAAqD;IACrD,oDAAoD;IACpD,qDAAqD;IACrD,yCAAyC;IACzC,oDAAoD;IACpD,8EAA8E;IAC9E,2EAA2E;CAC5E,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAEb;;;;;;;;GAQG;AACH,MAAM,CAAC,KAAK,UAAU,qBAAqB,CACzC,OAAwB,EACxB,OAAe,EACf,QAAmB,EACnB,MAAmB;IAEnB,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,EAAE,CAAC;IACrC,IAAI,IAAI,GAAG,EAAE,CAAC;IACd,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,CAC3B,EAAE,KAAK,EAAE,OAAO,EAAE,MAAM,EAAE,sBAAsB,EAAE,QAAQ,EAAE,KAAK,EAAE,EAAE,EAAE,EACvE,MAAM,CACP,CAAC;IACF,IAAI,KAAK,EAAE,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;QACjC,QAAQ,KAAK,CAAC,IAAI,EAAE,CAAC;YACnB,KAAK,YAAY;gBACf,IAAI,IAAI,KAAK,CAAC,IAAI,CAAC;gBACnB,MAAM;YACR,KAAK,OAAO;gBACV,MAAM,IAAI,QAAQ,CAAC,SAAS,CAAC,QAAQ,EAAE,yBAAyB,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC;YACnF,qEAAqE;YACrE,gEAAgE;YAChE,qEAAqE;YACrE,2EAA2E;YAC3E,4EAA4E;YAC5E,8CAA8C;YAC9C,KAAK,OAAO,CAAC;YACb,KAAK,WAAW,CAAC;YACjB,KAAK,gBAAgB,CAAC;YACtB,KAAK,gBAAgB,CAAC;YACtB,KAAK,cAAc,CAAC;YACpB,KAAK,MAAM;gBACT,MAAM;QACV,CAAC;IACH,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC"}
|