@chances-ai/engine 29.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.
Files changed (109) hide show
  1. package/dist/agents/index.js +1 -1
  2. package/dist/ai/adapters/ai-sdk-stream.d.ts +13 -1
  3. package/dist/ai/adapters/ai-sdk-stream.d.ts.map +1 -1
  4. package/dist/ai/adapters/ai-sdk-stream.js +140 -39
  5. package/dist/ai/adapters/ai-sdk-stream.js.map +1 -1
  6. package/dist/ai/adapters/ai-sdk.d.ts +8 -0
  7. package/dist/ai/adapters/ai-sdk.d.ts.map +1 -1
  8. package/dist/ai/adapters/ai-sdk.js +40 -2
  9. package/dist/ai/adapters/ai-sdk.js.map +1 -1
  10. package/dist/ai/adapters/mock.d.ts.map +1 -1
  11. package/dist/ai/adapters/mock.js +6 -2
  12. package/dist/ai/adapters/mock.js.map +1 -1
  13. package/dist/ai/adapters/native-anthropic.d.ts +51 -0
  14. package/dist/ai/adapters/native-anthropic.d.ts.map +1 -0
  15. package/dist/ai/adapters/native-anthropic.js +179 -0
  16. package/dist/ai/adapters/native-anthropic.js.map +1 -0
  17. package/dist/ai/adapters/openai-compatible.d.ts +17 -1
  18. package/dist/ai/adapters/openai-compatible.d.ts.map +1 -1
  19. package/dist/ai/adapters/openai-compatible.js +105 -1
  20. package/dist/ai/adapters/openai-compatible.js.map +1 -1
  21. package/dist/ai/compat.d.ts +30 -0
  22. package/dist/ai/compat.d.ts.map +1 -0
  23. package/dist/ai/compat.js +93 -0
  24. package/dist/ai/compat.js.map +1 -0
  25. package/dist/ai/cost.d.ts +9 -0
  26. package/dist/ai/cost.d.ts.map +1 -1
  27. package/dist/ai/cost.js +15 -2
  28. package/dist/ai/cost.js.map +1 -1
  29. package/dist/ai/index.d.ts +6 -2
  30. package/dist/ai/index.d.ts.map +1 -1
  31. package/dist/ai/index.js +5 -1
  32. package/dist/ai/index.js.map +1 -1
  33. package/dist/ai/known-models.d.ts +20 -6
  34. package/dist/ai/known-models.d.ts.map +1 -1
  35. package/dist/ai/known-models.generated.d.ts +3 -0
  36. package/dist/ai/known-models.generated.d.ts.map +1 -0
  37. package/dist/ai/known-models.generated.js +518 -0
  38. package/dist/ai/known-models.generated.js.map +1 -0
  39. package/dist/ai/known-models.js +29 -128
  40. package/dist/ai/known-models.js.map +1 -1
  41. package/dist/ai/provider-table.d.ts +36 -0
  42. package/dist/ai/provider-table.d.ts.map +1 -0
  43. package/dist/ai/provider-table.js +80 -0
  44. package/dist/ai/provider-table.js.map +1 -0
  45. package/dist/ai/retry.d.ts +74 -3
  46. package/dist/ai/retry.d.ts.map +1 -1
  47. package/dist/ai/retry.js +246 -6
  48. package/dist/ai/retry.js.map +1 -1
  49. package/dist/ai/router.d.ts +12 -0
  50. package/dist/ai/router.d.ts.map +1 -1
  51. package/dist/ai/router.js +19 -0
  52. package/dist/ai/router.js.map +1 -1
  53. package/dist/ai/sampling.d.ts +37 -0
  54. package/dist/ai/sampling.d.ts.map +1 -0
  55. package/dist/ai/sampling.js +34 -0
  56. package/dist/ai/sampling.js.map +1 -0
  57. package/dist/ai/setup.d.ts +1 -1
  58. package/dist/ai/setup.d.ts.map +1 -1
  59. package/dist/ai/setup.js +28 -4
  60. package/dist/ai/setup.js.map +1 -1
  61. package/dist/ai/summarizer.d.ts.map +1 -1
  62. package/dist/ai/summarizer.js +6 -1
  63. package/dist/ai/summarizer.js.map +1 -1
  64. package/dist/ai/think-filter.d.ts +30 -0
  65. package/dist/ai/think-filter.d.ts.map +1 -0
  66. package/dist/ai/think-filter.js +193 -0
  67. package/dist/ai/think-filter.js.map +1 -0
  68. package/dist/ai/thinking.d.ts +77 -0
  69. package/dist/ai/thinking.d.ts.map +1 -0
  70. package/dist/ai/thinking.js +174 -0
  71. package/dist/ai/thinking.js.map +1 -0
  72. package/dist/ai/types.d.ts +135 -8
  73. package/dist/ai/types.d.ts.map +1 -1
  74. package/dist/core/compaction/compactor.d.ts.map +1 -1
  75. package/dist/core/compaction/compactor.js +44 -6
  76. package/dist/core/compaction/compactor.js.map +1 -1
  77. package/dist/core/engine.d.ts +19 -4
  78. package/dist/core/engine.d.ts.map +1 -1
  79. package/dist/core/engine.js +123 -19
  80. package/dist/core/engine.js.map +1 -1
  81. package/dist/core/index.d.ts +1 -1
  82. package/dist/core/index.d.ts.map +1 -1
  83. package/dist/core/index.js +1 -1
  84. package/dist/core/index.js.map +1 -1
  85. package/dist/core/task-tool.d.ts +1 -1
  86. package/dist/core/task-tool.js +1 -1
  87. package/dist/core/workspace-query.d.ts +1 -1
  88. package/dist/core/workspace-query.js +1 -1
  89. package/dist/local-vault/index.d.ts +1 -1
  90. package/dist/local-vault/index.js +1 -1
  91. package/dist/lsp/index.d.ts +1 -1
  92. package/dist/lsp/index.js +1 -1
  93. package/dist/lsp/types.d.ts +2 -2
  94. package/dist/mcp/host.d.ts +3 -3
  95. package/dist/mcp/load-mcp-host.d.ts +4 -4
  96. package/dist/mcp/load-mcp-host.js +4 -4
  97. package/dist/mcp/oauth/provider.d.ts.map +1 -1
  98. package/dist/mcp/oauth/provider.js +10 -1
  99. package/dist/mcp/oauth/provider.js.map +1 -1
  100. package/dist/plugin-api/index.d.ts +10 -2
  101. package/dist/plugin-api/index.d.ts.map +1 -1
  102. package/dist/plugin-api/index.js +15 -0
  103. package/dist/plugin-api/index.js.map +1 -1
  104. package/dist/tools/approval.d.ts +1 -1
  105. package/dist/tools/approval.js +1 -1
  106. package/dist/tools/builtins/lsp.js +1 -1
  107. package/dist/tools/builtins/pty.d.ts +1 -1
  108. package/dist/tools/types.d.ts +1 -1
  109. package/package.json +3 -3
@@ -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: "rate-limit" | "server-5xx" | "network" | "non-retryable";
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
- /** Backoff before each retry attempt, in ms. Length caps the retry count. */
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
@@ -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,YAAY,GAAG,SAAS,GAAG,eAAe,CAAC;CACnE;AAMD,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,MAAM,GAAG,aAAa,CAKpE;AAED,MAAM,WAAW,WAAW;IAC1B,6EAA6E;IAC7E,QAAQ,EAAE,SAAS,MAAM,EAAE,CAAC;CAC7B;AAED,eAAO,MAAM,kBAAkB,EAAE,WAA6C,CAAC"}
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-5xx" };
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: "non-retryable" };
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
@@ -1 +1 @@
1
- {"version":3,"file":"retry.js","sourceRoot":"","sources":["../../src/ai/retry.ts"],"names":[],"mappings":"AAKA,MAAM,aAAa,GAAG,qEAAqE,CAAC;AAC5F,MAAM,aAAa,GAAG,uIAAuI,CAAC;AAC9J,MAAM,UAAU,GAAG,2IAA2I,CAAC;AAE/J,MAAM,UAAU,qBAAqB,CAAC,OAAe;IACnD,IAAI,aAAa,CAAC,IAAI,CAAC,OAAO,CAAC;QAAE,OAAO,EAAE,SAAS,EAAE,IAAI,EAAE,MAAM,EAAE,YAAY,EAAE,CAAC;IAClF,IAAI,aAAa,CAAC,IAAI,CAAC,OAAO,CAAC;QAAE,OAAO,EAAE,SAAS,EAAE,IAAI,EAAE,MAAM,EAAE,YAAY,EAAE,CAAC;IAClF,IAAI,UAAU,CAAC,IAAI,CAAC,OAAO,CAAC;QAAE,OAAO,EAAE,SAAS,EAAE,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,CAAC;IAC5E,OAAO,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,EAAE,eAAe,EAAE,CAAC;AACvD,CAAC;AAOD,MAAM,CAAC,MAAM,kBAAkB,GAAgB,EAAE,QAAQ,EAAE,CAAC,GAAG,EAAE,IAAI,EAAE,IAAI,CAAC,EAAE,CAAC"}
1
+ {"version":3,"file":"retry.js","sourceRoot":"","sources":["../../src/ai/retry.ts"],"names":[],"mappings":"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"}
@@ -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
@@ -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;CACtB;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;CAyBpC"}
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
@@ -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;AAkB1D;;;;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;CACF"}
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"}
@@ -17,7 +17,7 @@ export declare function buildRegistry(opts: RegistryOptions): ModelRegistry;
17
17
  /**
18
18
  * Convenience: turn the provider table into the `envByProvider` map that
19
19
  * `AuthStore` needs. Used at boot so the env-name list lives in one place
20
- * (here) rather than being duplicated in `@chances-ai/config`.
20
+ * (here) rather than being duplicated in `@chances-ai/runtime/config`.
21
21
  */
22
22
  export declare function envByProviderFrom(providers?: ProviderEntry[]): Record<string, string>;
23
23
  //# sourceMappingURL=setup.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"setup.d.ts","sourceRoot":"","sources":["../../src/ai/setup.ts"],"names":[],"mappings":"AAGA,OAAO,EAAgB,KAAK,aAAa,EAAE,MAAM,mBAAmB,CAAC;AACrE,OAAO,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAE9C,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"}
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";
@@ -25,15 +26,24 @@ export function buildRegistry(opts) {
25
26
  /**
26
27
  * Convenience: turn the provider table into the `envByProvider` map that
27
28
  * `AuthStore` needs. Used at boot so the env-name list lives in one place
28
- * (here) rather than being duplicated in `@chances-ai/config`.
29
+ * (here) rather than being duplicated in `@chances-ai/runtime/config`.
29
30
  */
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-compatible") {
44
+ if (entry.api === "openai-completions") {
35
45
  if (!entry.baseURL) {
36
- throw new Error(`provider '${entry.id}' is api=openai-compatible but has no baseURL`);
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
- return new AiSdkAdapter({ provider: entry.api, apiKey, models: entry.models });
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
@@ -1 +1 @@
1
- {"version":3,"file":"setup.js","sourceRoot":"","sources":["../../src/ai/setup.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AACpD,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACjD,OAAO,EAAE,uBAAuB,EAAE,MAAM,iCAAiC,CAAC;AAC1E,OAAO,EAAE,YAAY,EAAsB,MAAM,mBAAmB,CAAC;AACrE,OAAO,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAS9C;;;;;;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,SAAS,YAAY,CAAC,KAAoB,EAAE,MAAc;IACxD,IAAI,KAAK,CAAC,GAAG,KAAK,mBAAmB,EAAE,CAAC;QACtC,IAAI,CAAC,KAAK,CAAC,OAAO,EAAE,CAAC;YACnB,MAAM,IAAI,KAAK,CAAC,aAAa,KAAK,CAAC,EAAE,+CAA+C,CAAC,CAAC;QACxF,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,OAAO,IAAI,YAAY,CAAC,EAAE,QAAQ,EAAE,KAAK,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,CAAC,MAAM,EAAE,CAAC,CAAC;AACjF,CAAC"}
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,CAyBjB"}
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"}
@@ -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
  }