sitelooper 0.3.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 (87) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +625 -0
  3. package/bin/sitelooper.js +6 -0
  4. package/dist/agent/llm.js +460 -0
  5. package/dist/agent/llm.js.map +1 -0
  6. package/dist/agent/loop.js +870 -0
  7. package/dist/agent/loop.js.map +1 -0
  8. package/dist/agent/prompt.js +40 -0
  9. package/dist/agent/prompt.js.map +1 -0
  10. package/dist/agent/report.js +545 -0
  11. package/dist/agent/report.js.map +1 -0
  12. package/dist/agent/tools.js +1147 -0
  13. package/dist/agent/tools.js.map +1 -0
  14. package/dist/cli.js +1692 -0
  15. package/dist/cli.js.map +1 -0
  16. package/dist/daemon/browser.js +218 -0
  17. package/dist/daemon/browser.js.map +1 -0
  18. package/dist/daemon/codegen.js +241 -0
  19. package/dist/daemon/codegen.js.map +1 -0
  20. package/dist/daemon/dialogs.js +57 -0
  21. package/dist/daemon/dialogs.js.map +1 -0
  22. package/dist/daemon/diff.js +198 -0
  23. package/dist/daemon/diff.js.map +1 -0
  24. package/dist/daemon/fingerprint.js +98 -0
  25. package/dist/daemon/fingerprint.js.map +1 -0
  26. package/dist/daemon/inputs.js +134 -0
  27. package/dist/daemon/inputs.js.map +1 -0
  28. package/dist/daemon/recorder.js +1232 -0
  29. package/dist/daemon/recorder.js.map +1 -0
  30. package/dist/daemon/refs.js +194 -0
  31. package/dist/daemon/refs.js.map +1 -0
  32. package/dist/daemon/server.js +1724 -0
  33. package/dist/daemon/server.js.map +1 -0
  34. package/dist/daemon/state.js +239 -0
  35. package/dist/daemon/state.js.map +1 -0
  36. package/dist/doctor.js +90 -0
  37. package/dist/doctor.js.map +1 -0
  38. package/dist/shared/paths.js +80 -0
  39. package/dist/shared/paths.js.map +1 -0
  40. package/dist/shared/protocol.js +28 -0
  41. package/dist/shared/protocol.js.map +1 -0
  42. package/dist/shared/secrets.js +92 -0
  43. package/dist/shared/secrets.js.map +1 -0
  44. package/dist/shared/text.js +39 -0
  45. package/dist/shared/text.js.map +1 -0
  46. package/dist/skills/compile.js +1420 -0
  47. package/dist/skills/compile.js.map +1 -0
  48. package/dist/skills/components.js +456 -0
  49. package/dist/skills/components.js.map +1 -0
  50. package/dist/skills/flow.js +1041 -0
  51. package/dist/skills/flow.js.map +1 -0
  52. package/dist/skills/learn.js +406 -0
  53. package/dist/skills/learn.js.map +1 -0
  54. package/dist/skills/ledger.js +304 -0
  55. package/dist/skills/ledger.js.map +1 -0
  56. package/dist/skills/relabel.js +206 -0
  57. package/dist/skills/relabel.js.map +1 -0
  58. package/dist/skills/repair.js +570 -0
  59. package/dist/skills/repair.js.map +1 -0
  60. package/dist/skills/replay.js +1281 -0
  61. package/dist/skills/replay.js.map +1 -0
  62. package/dist/skills/store.js +147 -0
  63. package/dist/skills/store.js.map +1 -0
  64. package/dist/spec/check.js +428 -0
  65. package/dist/spec/check.js.map +1 -0
  66. package/dist/spec/diagnostics.js +58 -0
  67. package/dist/spec/diagnostics.js.map +1 -0
  68. package/dist/spec/emit.js +2084 -0
  69. package/dist/spec/emit.js.map +1 -0
  70. package/dist/spec/index.js +62 -0
  71. package/dist/spec/index.js.map +1 -0
  72. package/dist/spec/ir.js +216 -0
  73. package/dist/spec/ir.js.map +1 -0
  74. package/dist/spec/lift.js +162 -0
  75. package/dist/spec/lift.js.map +1 -0
  76. package/dist/spec/locators.js +270 -0
  77. package/dist/spec/locators.js.map +1 -0
  78. package/dist/spec/lower.js +124 -0
  79. package/dist/spec/lower.js.map +1 -0
  80. package/dist/spec/repair.js +657 -0
  81. package/dist/spec/repair.js.map +1 -0
  82. package/dist/spec/rerecord.js +169 -0
  83. package/dist/spec/rerecord.js.map +1 -0
  84. package/dist/spec/rethread.js +120 -0
  85. package/dist/spec/rethread.js.map +1 -0
  86. package/package.json +50 -0
  87. package/skills/sitelooper/SKILL.md +228 -0
@@ -0,0 +1,6 @@
1
+ #!/usr/bin/env node
2
+ import('../dist/cli.js').catch((err) => {
3
+ console.error('sitelooper: failed to start. The install looks incomplete; try reinstalling with `npm install -g sitelooper`.');
4
+ console.error(err?.stack || String(err));
5
+ process.exit(2);
6
+ });
@@ -0,0 +1,460 @@
1
+ /**
2
+ * Provider adapter (thin, swappable). One implementation — OpenAI-compatible
3
+ * chat completions — parameterised by named presets (zhipu, novita, openai,
4
+ * openrouter) or a fully custom base URL. Endpoint/model ids drift; every
5
+ * preset value is overridable by config file, env, or flag, so doc drift is
6
+ * a config change, not a code change.
7
+ */
8
+ import fs from 'node:fs';
9
+ import path from 'node:path';
10
+ import { rootDir } from '../shared/paths.js';
11
+ export const PROVIDER_PRESETS = {
12
+ // Z.ai international endpoint; mainland alternative: https://open.bigmodel.cn/api/paas/v4
13
+ // (Coding Plan subscriptions use /api/coding/paas/v4 instead.)
14
+ zhipu: {
15
+ baseUrl: 'https://api.z.ai/api/paas/v4',
16
+ defaultModel: 'glm-5.2',
17
+ keyEnvVars: ['GLM_API_KEY', 'ZHIPU_API_KEY'],
18
+ },
19
+ // Model picks are benchmarked, not guessed: deepseek-v4-flash drove the real
20
+ // agent loop ~2x faster and ~12x cheaper than glm-5.2 at the same pass rate,
21
+ // and glm-5.3 solved the hardest probe in the fewest turns of anything tried
22
+ // (at glm-5.2's list price), which is what you want on the escalation path.
23
+ novita: {
24
+ baseUrl: 'https://api.novita.ai/openai',
25
+ defaultModel: 'deepseek/deepseek-v4-flash',
26
+ fallbackModel: 'zai-org/glm-5.3',
27
+ keyEnvVars: ['NOVITA_API_KEY'],
28
+ },
29
+ openrouter: {
30
+ baseUrl: 'https://openrouter.ai/api/v1',
31
+ defaultModel: 'z-ai/glm-5.2',
32
+ keyEnvVars: ['OPENROUTER_API_KEY'],
33
+ },
34
+ openai: {
35
+ baseUrl: 'https://api.openai.com/v1',
36
+ defaultModel: 'gpt-5-mini',
37
+ keyEnvVars: ['OPENAI_API_KEY'],
38
+ },
39
+ // Not OpenAI-compatible — see AnthropicProvider. A stronger, pricier fallback
40
+ // tier: useful for escalating specific instructions that a cheaper model
41
+ // couldn't complete, without paying Anthropic prices for the whole session.
42
+ anthropic: {
43
+ baseUrl: 'https://api.anthropic.com',
44
+ defaultModel: 'claude-sonnet-5',
45
+ keyEnvVars: ['ANTHROPIC_API_KEY'],
46
+ },
47
+ };
48
+ export const DEFAULT_PROVIDER = 'zhipu';
49
+ const CONFIG_KEYS = ['provider', 'model', 'fallbackModel', 'baseUrl', 'apiKey'];
50
+ export function globalConfigPath() {
51
+ return path.join(rootDir(), 'config.json');
52
+ }
53
+ export function readGlobalConfig() {
54
+ try {
55
+ const raw = JSON.parse(fs.readFileSync(globalConfigPath(), 'utf8'));
56
+ const out = {};
57
+ for (const key of CONFIG_KEYS) {
58
+ if (typeof raw[key] === 'string' && raw[key])
59
+ out[key] = raw[key];
60
+ }
61
+ return out;
62
+ }
63
+ catch {
64
+ return {};
65
+ }
66
+ }
67
+ export function writeGlobalConfig(updates) {
68
+ for (const key of Object.keys(updates)) {
69
+ if (!CONFIG_KEYS.includes(key)) {
70
+ throw new Error(`unknown config key "${key}" (allowed: ${CONFIG_KEYS.join(', ')})`);
71
+ }
72
+ }
73
+ const merged = { ...readGlobalConfig(), ...updates };
74
+ for (const key of CONFIG_KEYS) {
75
+ if (merged[key] === '')
76
+ delete merged[key]; // setting to "" clears a key
77
+ }
78
+ fs.mkdirSync(rootDir(), { recursive: true });
79
+ fs.writeFileSync(globalConfigPath(), JSON.stringify(merged, null, 2));
80
+ return merged;
81
+ }
82
+ /**
83
+ * Precedence per field: explicit override (flag) > env > global config file >
84
+ * provider preset. The preset is chosen the same way, then supplies defaults
85
+ * for whatever remains unset.
86
+ */
87
+ export function resolveProviderConfig(overrides = {}) {
88
+ const file = readGlobalConfig();
89
+ const provider = overrides.provider || process.env.SITELOOPER_PROVIDER || file.provider || DEFAULT_PROVIDER;
90
+ const preset = PROVIDER_PRESETS[provider];
91
+ if (!preset) {
92
+ throw new Error(`unknown provider "${provider}" (available: ${Object.keys(PROVIDER_PRESETS).join(', ')}; ` +
93
+ `or use any OpenAI-compatible endpoint via SITELOOPER_BASE_URL / config set baseUrl)`);
94
+ }
95
+ const keyEnvVars = [...preset.keyEnvVars, 'SITELOOPER_API_KEY'];
96
+ const apiKey = overrides.apiKey ||
97
+ keyEnvVars.map((v) => process.env[v]).find(Boolean) ||
98
+ file.apiKey ||
99
+ '';
100
+ return {
101
+ provider,
102
+ baseUrl: overrides.baseUrl || process.env.SITELOOPER_BASE_URL || file.baseUrl || preset.baseUrl,
103
+ model: overrides.model || process.env.SITELOOPER_MODEL || file.model || preset.defaultModel,
104
+ // "none"/"off" is how a caller disables a preset's escalation tier without
105
+ // having to clear a config key it never set.
106
+ fallbackModel: normalizeFallback(overrides.fallbackModel ||
107
+ process.env.SITELOOPER_FALLBACK_MODEL ||
108
+ file.fallbackModel ||
109
+ preset.fallbackModel),
110
+ apiKey,
111
+ temperature: overrides.temperature ?? 0,
112
+ extraBody: parseExtraBody(process.env.SITELOOPER_EXTRA_BODY, 'SITELOOPER_EXTRA_BODY'),
113
+ fallbackExtraBody: parseExtraBody(process.env.SITELOOPER_FALLBACK_EXTRA_BODY, 'SITELOOPER_FALLBACK_EXTRA_BODY'),
114
+ keyEnvVars,
115
+ };
116
+ }
117
+ function parseExtraBody(raw, envVar) {
118
+ if (!raw || !raw.trim())
119
+ return undefined;
120
+ try {
121
+ const parsed = JSON.parse(raw);
122
+ if (parsed && typeof parsed === 'object' && !Array.isArray(parsed)) {
123
+ return parsed;
124
+ }
125
+ }
126
+ catch {
127
+ // fall through to the throw below
128
+ }
129
+ // A malformed value silently ignored would defeat the point of setting it:
130
+ // the caller believes a routing pin is in force when it is not.
131
+ throw new Error(`${envVar} must be a JSON object`);
132
+ }
133
+ function normalizeFallback(value) {
134
+ if (!value)
135
+ return undefined;
136
+ const trimmed = value.trim();
137
+ if (!trimmed || /^(none|off|false)$/i.test(trimmed))
138
+ return undefined;
139
+ return trimmed;
140
+ }
141
+ export class OpenAICompatProvider {
142
+ config;
143
+ model;
144
+ constructor(config) {
145
+ this.config = config;
146
+ this.model = config.model;
147
+ }
148
+ async complete(messages, tools, opts = {}) {
149
+ if (!this.config.apiKey) {
150
+ throw new Error(`no API key for provider "${this.config.provider}": set ${this.config.keyEnvVars.join(' or ')} ` +
151
+ `(or \`sitelooper config set apiKey <key>\`)`);
152
+ }
153
+ const body = {
154
+ model: this.config.model,
155
+ temperature: this.config.temperature,
156
+ messages,
157
+ tools: tools.map((t) => ({
158
+ type: 'function',
159
+ function: { name: t.name, description: t.description, parameters: t.parameters },
160
+ })),
161
+ tool_choice: 'auto',
162
+ // See CompleteOptions.effort — openrouter-only by design.
163
+ ...(opts.effort && this.config.provider === 'openrouter' ? { reasoning: { effort: opts.effort } } : {}),
164
+ // Spread last on purpose: extraBody is the caller's explicit override
165
+ // channel (see ProviderConfig.extraBody) and must win over defaults.
166
+ ...this.config.extraBody,
167
+ };
168
+ const url = this.config.baseUrl.replace(/\/$/, '') + '/chat/completions';
169
+ let lastErr = null;
170
+ for (let attempt = 0; attempt < MAX_LLM_ATTEMPTS; attempt++) {
171
+ if (opts.signal?.aborted)
172
+ throw new Error('LLM request aborted');
173
+ try {
174
+ const res = await fetch(url, {
175
+ method: 'POST',
176
+ headers: {
177
+ 'content-type': 'application/json',
178
+ authorization: `Bearer ${this.config.apiKey}`,
179
+ },
180
+ body: JSON.stringify(body),
181
+ signal: opts.signal,
182
+ });
183
+ if (res.status === 429 || res.status >= 500) {
184
+ lastErr = new Error(`LLM HTTP ${res.status}: ${(await res.text()).slice(0, 300)}`);
185
+ // A 429 against a per-minute cap needs minute-scale patience, not
186
+ // seconds: flow-replay recovery fires requests far faster than the
187
+ // interactive loop and killed whole flowruns on OpenRouter's
188
+ // 20 rpm tier (fwgr2-n2/n3). Honor the server's own hint first.
189
+ await sleep(retryDelayMs(res, attempt), opts.signal);
190
+ continue;
191
+ }
192
+ if (!res.ok) {
193
+ throw new Error(`LLM HTTP ${res.status}: ${(await res.text()).slice(0, 500)}`);
194
+ }
195
+ return parseCompletion((await res.json()));
196
+ }
197
+ catch (err) {
198
+ // An abort is a decision, not a transport failure — never retry it.
199
+ if (opts.signal?.aborted)
200
+ throw new Error('LLM request aborted');
201
+ if (err instanceof Error && err.message.startsWith('LLM HTTP 4'))
202
+ throw err;
203
+ lastErr = err;
204
+ await sleep(1000 * (attempt + 1), opts.signal);
205
+ }
206
+ }
207
+ throw lastErr ?? new Error('LLM request failed');
208
+ }
209
+ }
210
+ function parseCompletion(json) {
211
+ const choice = json.choices?.[0];
212
+ const msg = choice?.message;
213
+ if (!msg)
214
+ throw new Error(`LLM returned no choices: ${JSON.stringify(json).slice(0, 300)}`);
215
+ const rawCalls = (msg.tool_calls ?? []).filter((c) => c?.function?.name);
216
+ const toolCalls = rawCalls.map((c, i) => {
217
+ let args = null;
218
+ try {
219
+ args = c.function.arguments ? JSON.parse(c.function.arguments) : {};
220
+ }
221
+ catch {
222
+ args = null;
223
+ }
224
+ return { id: c.id || `call_${i}`, name: c.function.name, args, rawArgs: c.function.arguments ?? '' };
225
+ });
226
+ const assistantMessage = {
227
+ role: 'assistant',
228
+ content: msg.content ?? null,
229
+ ...(rawCalls.length
230
+ ? {
231
+ tool_calls: rawCalls.map((c, i) => ({
232
+ id: c.id || `call_${i}`,
233
+ type: 'function',
234
+ function: { name: c.function.name, arguments: c.function.arguments ?? '' },
235
+ })),
236
+ }
237
+ : {}),
238
+ };
239
+ return {
240
+ text: msg.content ?? null,
241
+ toolCalls,
242
+ assistantMessage,
243
+ usage: {
244
+ promptTokens: json.usage?.prompt_tokens ?? 0,
245
+ completionTokens: json.usage?.completion_tokens ?? 0,
246
+ // Both OpenAI and z.ai/novita nest the cache hit here; absent → 0.
247
+ cachedTokens: json.usage?.prompt_tokens_details?.cached_tokens ?? 0,
248
+ },
249
+ };
250
+ }
251
+ /**
252
+ * Anthropic Messages API adapter. A genuinely different wire format from the
253
+ * OpenAI-compatible providers above (system is a top-level field, not a
254
+ * message; tool calls/results are typed content blocks, not a role:'tool'
255
+ * message; usage splits fresh vs. cache-write vs. cache-read tokens instead
256
+ * of reporting one total with a cached subset) — so this translates rather
257
+ * than reusing OpenAICompatProvider. No SDK dependency: same thin-fetch style
258
+ * as the rest of this file.
259
+ */
260
+ export class AnthropicProvider {
261
+ config;
262
+ model;
263
+ baseUrl;
264
+ constructor(config) {
265
+ this.config = config;
266
+ this.model = config.model;
267
+ this.baseUrl = config.baseUrl.replace(/\/$/, '');
268
+ }
269
+ async complete(messages, tools, opts = {}) {
270
+ if (!this.config.apiKey) {
271
+ throw new Error(`no API key for provider "${this.config.provider}": set ${this.config.keyEnvVars.join(' or ')} ` +
272
+ `(or \`sitelooper config set apiKey <key>\`)`);
273
+ }
274
+ const system = messages
275
+ .filter((m) => m.role === 'system')
276
+ .map((m) => m.content)
277
+ .join('\n\n');
278
+ const anthMessages = toAnthropicMessages(messages.filter((m) => m.role !== 'system'));
279
+ // Prompt caching: unlike the OpenAI-compatible providers above (which cache
280
+ // automatically server-side), Anthropic only caches up to an explicit
281
+ // cache_control breakpoint. Without one, every turn re-bills the entire
282
+ // growing conversation at full price. Two breakpoints: the system prompt
283
+ // (large, stable across the whole session) and the last content block of
284
+ // the latest message (so each turn's identical prefix — everything before
285
+ // this turn's new content — hits cache on the next call).
286
+ const lastMsg = anthMessages[anthMessages.length - 1];
287
+ const lastBlock = lastMsg?.content[lastMsg.content.length - 1];
288
+ if (lastBlock)
289
+ lastBlock.cache_control = { type: 'ephemeral' };
290
+ const body = {
291
+ model: this.config.model,
292
+ max_tokens: 8192,
293
+ ...(system ? { system: [{ type: 'text', text: system, cache_control: { type: 'ephemeral' } }] } : {}),
294
+ messages: anthMessages,
295
+ tools: tools.map((t) => ({ name: t.name, description: t.description, input_schema: t.parameters })),
296
+ tool_choice: { type: 'auto' },
297
+ };
298
+ let lastErr = null;
299
+ for (let attempt = 0; attempt < MAX_LLM_ATTEMPTS; attempt++) {
300
+ if (opts.signal?.aborted)
301
+ throw new Error('LLM request aborted');
302
+ try {
303
+ const res = await fetch(`${this.baseUrl}/v1/messages`, {
304
+ method: 'POST',
305
+ headers: {
306
+ 'content-type': 'application/json',
307
+ 'x-api-key': this.config.apiKey,
308
+ 'anthropic-version': '2023-06-01',
309
+ },
310
+ body: JSON.stringify(body),
311
+ signal: opts.signal,
312
+ });
313
+ if (res.status === 429 || res.status >= 500) {
314
+ lastErr = new Error(`LLM HTTP ${res.status}: ${(await res.text()).slice(0, 300)}`);
315
+ await sleep(retryDelayMs(res, attempt), opts.signal);
316
+ continue;
317
+ }
318
+ if (!res.ok) {
319
+ throw new Error(`LLM HTTP ${res.status}: ${(await res.text()).slice(0, 500)}`);
320
+ }
321
+ return parseAnthropicCompletion((await res.json()));
322
+ }
323
+ catch (err) {
324
+ if (opts.signal?.aborted)
325
+ throw new Error('LLM request aborted');
326
+ if (err instanceof Error && err.message.startsWith('LLM HTTP 4'))
327
+ throw err;
328
+ lastErr = err;
329
+ await sleep(1000 * (attempt + 1), opts.signal);
330
+ }
331
+ }
332
+ throw lastErr ?? new Error('LLM request failed');
333
+ }
334
+ }
335
+ /**
336
+ * Our internal history is OpenAI-shaped (role:'tool' per call, tool_calls on
337
+ * the assistant message). Anthropic instead wants tool_use/tool_result as
338
+ * typed content blocks, with all of one assistant turn's tool_results merged
339
+ * into a single following user message — so consecutive role:'tool' entries
340
+ * (one per call in that turn) are collapsed here rather than sent as
341
+ * separate messages.
342
+ */
343
+ function toAnthropicMessages(messages) {
344
+ const out = [];
345
+ for (const m of messages) {
346
+ if (m.role === 'tool') {
347
+ const block = { type: 'tool_result', tool_use_id: m.tool_call_id, content: m.content };
348
+ const prev = out[out.length - 1];
349
+ if (prev && prev.role === 'user' && prev.content.every((b) => b.type === 'tool_result')) {
350
+ prev.content.push(block);
351
+ }
352
+ else {
353
+ out.push({ role: 'user', content: [block] });
354
+ }
355
+ continue;
356
+ }
357
+ if (m.role === 'user') {
358
+ out.push({ role: 'user', content: [{ type: 'text', text: m.content }] });
359
+ continue;
360
+ }
361
+ if (m.role !== 'assistant')
362
+ continue; // 'system' — caller already strips these; defensive only
363
+ const content = [];
364
+ if (m.content)
365
+ content.push({ type: 'text', text: m.content });
366
+ for (const tc of m.tool_calls ?? []) {
367
+ let input = {};
368
+ try {
369
+ input = tc.function.arguments ? JSON.parse(tc.function.arguments) : {};
370
+ }
371
+ catch {
372
+ /* malformed args — send empty input rather than fail the whole request */
373
+ }
374
+ content.push({ type: 'tool_use', id: tc.id, name: tc.function.name, input });
375
+ }
376
+ // An empty assistant turn (a reasoning model that emitted only reasoning)
377
+ // is a 400 on this API; keep the turn so the tool/user pairing holds.
378
+ if (!content.length)
379
+ content.push({ type: 'text', text: '(no output)' });
380
+ out.push({ role: 'assistant', content });
381
+ }
382
+ return out;
383
+ }
384
+ function parseAnthropicCompletion(json) {
385
+ const blocks = json.content ?? [];
386
+ if (!blocks.length && !json.usage) {
387
+ throw new Error(`LLM returned no content: ${JSON.stringify(json).slice(0, 300)}`);
388
+ }
389
+ const textBlocks = blocks.filter((b) => b.type === 'text');
390
+ const toolUseBlocks = blocks.filter((b) => b.type === 'tool_use');
391
+ const text = textBlocks.length ? textBlocks.map((b) => b.text).join('\n') : null;
392
+ const toolCalls = toolUseBlocks.map((b) => ({
393
+ id: b.id,
394
+ name: b.name,
395
+ args: (b.input ?? {}),
396
+ rawArgs: JSON.stringify(b.input ?? {}),
397
+ }));
398
+ const assistantMessage = {
399
+ role: 'assistant',
400
+ content: text,
401
+ ...(toolUseBlocks.length
402
+ ? {
403
+ tool_calls: toolUseBlocks.map((b) => ({
404
+ id: b.id,
405
+ type: 'function',
406
+ function: { name: b.name, arguments: JSON.stringify(b.input ?? {}) },
407
+ })),
408
+ }
409
+ : {}),
410
+ };
411
+ const u = json.usage ?? {};
412
+ return {
413
+ text,
414
+ toolCalls,
415
+ assistantMessage,
416
+ usage: {
417
+ // Our Usage.promptTokens is documented as the TOTAL prompt (OpenAI
418
+ // convention); Anthropic's input_tokens is only the fresh portion, so
419
+ // fold cache writes/reads back in to keep that contract, and surface
420
+ // reads (the cheap-billed subset) as cachedTokens same as the other
421
+ // providers.
422
+ promptTokens: (u.input_tokens ?? 0) + (u.cache_creation_input_tokens ?? 0) + (u.cache_read_input_tokens ?? 0),
423
+ completionTokens: u.output_tokens ?? 0,
424
+ cachedTokens: u.cache_read_input_tokens ?? 0,
425
+ },
426
+ };
427
+ }
428
+ /** Backoff sleep that gives up early if the request is aborted mid-wait. */
429
+ const MAX_LLM_ATTEMPTS = 5;
430
+ /**
431
+ * How long to wait before retrying a 429/5xx. The server's own hint wins
432
+ * (Retry-After seconds, or an X-RateLimit-Reset epoch-ms as OpenRouter
433
+ * sends); otherwise escalate on a scale that can outlast a per-MINUTE rate
434
+ * cap rather than a transient blip. Capped so a bad header cannot wedge a
435
+ * turn for longer than the caller's own deadlines.
436
+ */
437
+ function retryDelayMs(res, attempt) {
438
+ const cap = 65_000;
439
+ const retryAfter = Number(res.headers.get('retry-after'));
440
+ if (Number.isFinite(retryAfter) && retryAfter > 0)
441
+ return Math.min(retryAfter * 1000, cap);
442
+ const reset = Number(res.headers.get('x-ratelimit-reset'));
443
+ if (Number.isFinite(reset) && reset > Date.now())
444
+ return Math.min(reset - Date.now() + 500, cap);
445
+ if (res.status === 429)
446
+ return Math.min(5_000 * 2 ** attempt, cap);
447
+ return 1_000 * (attempt + 1);
448
+ }
449
+ function sleep(ms, signal) {
450
+ return new Promise((resolve) => {
451
+ const timer = setTimeout(done, ms);
452
+ function done() {
453
+ clearTimeout(timer);
454
+ signal?.removeEventListener('abort', done);
455
+ resolve();
456
+ }
457
+ signal?.addEventListener('abort', done, { once: true });
458
+ });
459
+ }
460
+ //# sourceMappingURL=llm.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"llm.js","sourceRoot":"","sources":["../../src/agent/llm.ts"],"names":[],"mappings":"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"}