@studio-foundation/runner 0.14.0 → 0.15.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 (60) hide show
  1. package/dist/generated/bundled-assets.d.ts +1 -1
  2. package/dist/generated/bundled-assets.js +1 -1
  3. package/dist/index.d.ts +4 -0
  4. package/dist/index.d.ts.map +1 -1
  5. package/dist/index.js +10 -1
  6. package/dist/index.js.map +1 -1
  7. package/dist/prompt-cache.d.ts +33 -0
  8. package/dist/prompt-cache.d.ts.map +1 -0
  9. package/dist/prompt-cache.js +46 -0
  10. package/dist/prompt-cache.js.map +1 -0
  11. package/dist/prompt-cache.test.d.ts +2 -0
  12. package/dist/prompt-cache.test.d.ts.map +1 -0
  13. package/dist/prompt-cache.test.js +53 -0
  14. package/dist/prompt-cache.test.js.map +1 -0
  15. package/dist/providers/anthropic-batch.test.d.ts +2 -0
  16. package/dist/providers/anthropic-batch.test.d.ts.map +1 -0
  17. package/dist/providers/anthropic-batch.test.js +178 -0
  18. package/dist/providers/anthropic-batch.test.js.map +1 -0
  19. package/dist/providers/anthropic.d.ts +17 -1
  20. package/dist/providers/anthropic.d.ts.map +1 -1
  21. package/dist/providers/anthropic.js +126 -12
  22. package/dist/providers/anthropic.js.map +1 -1
  23. package/dist/providers/anthropic.test.js +69 -0
  24. package/dist/providers/anthropic.test.js.map +1 -1
  25. package/dist/providers/batch-window.d.ts +89 -0
  26. package/dist/providers/batch-window.d.ts.map +1 -0
  27. package/dist/providers/batch-window.js +309 -0
  28. package/dist/providers/batch-window.js.map +1 -0
  29. package/dist/providers/batch-window.test.d.ts +2 -0
  30. package/dist/providers/batch-window.test.d.ts.map +1 -0
  31. package/dist/providers/batch-window.test.js +317 -0
  32. package/dist/providers/batch-window.test.js.map +1 -0
  33. package/dist/providers/batch.d.ts +55 -0
  34. package/dist/providers/batch.d.ts.map +1 -0
  35. package/dist/providers/batch.js +35 -0
  36. package/dist/providers/batch.js.map +1 -0
  37. package/dist/providers/claude-code.d.ts.map +1 -1
  38. package/dist/providers/claude-code.js +72 -1
  39. package/dist/providers/claude-code.js.map +1 -1
  40. package/dist/providers/claude-code.test.js +95 -0
  41. package/dist/providers/claude-code.test.js.map +1 -1
  42. package/dist/providers/ollama.d.ts.map +1 -1
  43. package/dist/providers/ollama.js +4 -2
  44. package/dist/providers/ollama.js.map +1 -1
  45. package/dist/providers/openai-responses.d.ts.map +1 -1
  46. package/dist/providers/openai-responses.js +24 -18
  47. package/dist/providers/openai-responses.js.map +1 -1
  48. package/dist/providers/openai.d.ts.map +1 -1
  49. package/dist/providers/openai.js +26 -10
  50. package/dist/providers/openai.js.map +1 -1
  51. package/dist/providers/provider.d.ts +3 -6
  52. package/dist/providers/provider.d.ts.map +1 -1
  53. package/dist/providers/provider.js.map +1 -1
  54. package/dist/runner.d.ts +7 -6
  55. package/dist/runner.d.ts.map +1 -1
  56. package/dist/runner.js +17 -8
  57. package/dist/runner.js.map +1 -1
  58. package/dist/runner.test.js +137 -0
  59. package/dist/runner.test.js.map +1 -1
  60. package/package.json +3 -3
@@ -7,10 +7,36 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
7
7
  };
8
8
  Object.defineProperty(exports, "__esModule", { value: true });
9
9
  exports.AnthropicProvider = void 0;
10
+ const contracts_1 = require("@studio-foundation/contracts");
10
11
  const sdk_1 = __importDefault(require("@anthropic-ai/sdk"));
11
12
  const race_signal_js_1 = require("../utils/race-signal.js");
13
+ const batch_js_1 = require("./batch.js");
14
+ /** Hard ceiling of the Message Batches API: 100k requests (or 256 MB) per batch. */
15
+ const ANTHROPIC_MAX_BATCH_SIZE = 100_000;
16
+ /** How often to ask whether a batch has ended. Batches typically end in well under an hour. */
17
+ const DEFAULT_POLL_INTERVAL_MS = 15_000;
18
+ /** The API expires a batch after 24h; waiting past that buys nothing. */
19
+ const DEFAULT_MAX_WAIT_MS = 24 * 60 * 60 * 1000;
20
+ function sleep(ms, signal) {
21
+ return new Promise((resolve, reject) => {
22
+ if (signal?.aborted) {
23
+ reject(new DOMException('Aborted', 'AbortError'));
24
+ return;
25
+ }
26
+ const timer = setTimeout(() => {
27
+ signal?.removeEventListener('abort', onAbort);
28
+ resolve();
29
+ }, ms);
30
+ const onAbort = () => {
31
+ clearTimeout(timer);
32
+ reject(new DOMException('Aborted', 'AbortError'));
33
+ };
34
+ signal?.addEventListener('abort', onAbort, { once: true });
35
+ });
36
+ }
12
37
  class AnthropicProvider {
13
38
  name = 'anthropic';
39
+ maxBatchSize = ANTHROPIC_MAX_BATCH_SIZE;
14
40
  client;
15
41
  constructor(apiKey) {
16
42
  this.client = new sdk_1.default({
@@ -37,6 +63,86 @@ class AnthropicProvider {
37
63
  const response = await (0, race_signal_js_1.raceSignal)(this.client.messages.create(params, { signal }), signal);
38
64
  return this.parseResponse(response);
39
65
  }
66
+ /**
67
+ * Message Batches API: submit every request as one job, poll until it ends,
68
+ * then collect the results by `custom_id`.
69
+ *
70
+ * Every token in a batch is billed at 50% of the synchronous rate, which is
71
+ * the whole reason this path exists — see the `batch:` option on a map stage
72
+ * for what decides which calls arrive here together.
73
+ *
74
+ * A request that failed on its own comes back with `error` set. The promise
75
+ * rejects only if the batch as a whole failed; on abort or wait-budget
76
+ * exhaustion the batch is cancelled best-effort so it stops billing.
77
+ */
78
+ async submitBatch(items, options = {}) {
79
+ if (items.length === 0)
80
+ return [];
81
+ if (items.length > this.maxBatchSize) {
82
+ throw new Error(`Batch of ${items.length} requests exceeds the Anthropic limit of ${this.maxBatchSize}.`);
83
+ }
84
+ (0, batch_js_1.assertValidBatch)(items);
85
+ const { signal, onProgress } = options;
86
+ const pollIntervalMs = options.poll_interval_ms ?? DEFAULT_POLL_INTERVAL_MS;
87
+ const maxWaitMs = options.max_wait_ms ?? DEFAULT_MAX_WAIT_MS;
88
+ const startedAt = Date.now();
89
+ const created = await (0, race_signal_js_1.raceSignal)(this.client.messages.batches.create({
90
+ requests: items.map(item => ({
91
+ custom_id: item.custom_id,
92
+ params: this.buildParams(item.request),
93
+ })),
94
+ }, { signal }), signal);
95
+ try {
96
+ let batch = created;
97
+ while (batch.processing_status !== 'ended') {
98
+ const elapsed = Date.now() - startedAt;
99
+ if (elapsed > maxWaitMs) {
100
+ throw new Error(`Anthropic batch ${batch.id} did not end within ${Math.round(maxWaitMs / 1000)}s ` +
101
+ `(${batch.request_counts.processing} of ${items.length} requests still processing).`);
102
+ }
103
+ await sleep(pollIntervalMs, signal);
104
+ batch = await (0, race_signal_js_1.raceSignal)(this.client.messages.batches.retrieve(created.id, { signal }), signal);
105
+ onProgress?.({
106
+ batch_id: batch.id,
107
+ status: batch.processing_status,
108
+ total: items.length,
109
+ succeeded: batch.request_counts.succeeded,
110
+ errored: batch.request_counts.errored,
111
+ processing: batch.request_counts.processing,
112
+ elapsed_ms: Date.now() - startedAt,
113
+ });
114
+ }
115
+ const collected = new Map();
116
+ const results = await (0, race_signal_js_1.raceSignal)(this.client.messages.batches.results(created.id, { signal }), signal);
117
+ for await (const entry of results) {
118
+ collected.set(entry.custom_id, this.parseBatchEntry(entry.custom_id, entry.result));
119
+ }
120
+ // Answer for every request that went in, even one the API never reported.
121
+ return items.map(item => collected.get(item.custom_id) ?? {
122
+ custom_id: item.custom_id,
123
+ error: `Anthropic batch ${created.id} returned no result for this request.`,
124
+ });
125
+ }
126
+ catch (err) {
127
+ // An abandoned batch keeps running (and billing) unless it is cancelled.
128
+ await this.client.messages.batches.cancel(created.id).catch(() => { });
129
+ throw err;
130
+ }
131
+ }
132
+ parseBatchEntry(customId, result) {
133
+ switch (result.type) {
134
+ case 'succeeded':
135
+ return { custom_id: customId, response: this.parseResponse(result.message) };
136
+ case 'errored':
137
+ return { custom_id: customId, error: `Anthropic batch request errored: ${JSON.stringify(result.error)}` };
138
+ case 'canceled':
139
+ return { custom_id: customId, error: 'Anthropic batch request was canceled before it ran.' };
140
+ case 'expired':
141
+ return { custom_id: customId, error: 'Anthropic batch request expired (the batch exceeded its 24h window).' };
142
+ default:
143
+ return { custom_id: customId, error: `Anthropic batch request ended with unknown result type "${result.type}".` };
144
+ }
145
+ }
40
146
  buildParams(request) {
41
147
  // Extract system messages (Anthropic handles them separately)
42
148
  const systemMessages = request.messages.filter(m => m.role === 'system');
@@ -53,8 +159,16 @@ class AnthropicProvider {
53
159
  }
54
160
  throw new Error(`Unsupported message role: ${msg.role}`);
55
161
  });
56
- // Convert tool definitions to Anthropic format
57
- // Mark the last tool with cache_control so Anthropic caches system + tools block
162
+ // Only the caller knows whether a second turn will read this prefix back, and
163
+ // a write it never reads costs more than not caching at all — so the marker
164
+ // goes on only when asked for. Default TTL (5 minutes) is deliberate: the 1h
165
+ // TTL doubles the write premium and needs three reads, not two, to break even.
166
+ const cacheControl = request.cache_prompt
167
+ ? { cache_control: { type: 'ephemeral' } }
168
+ : {};
169
+ // Convert tool definitions to Anthropic format.
170
+ // The prefix renders tools → system, so marking the last tool and the system
171
+ // block caches them as one span.
58
172
  const rawTools = request.tools ?? [];
59
173
  const tools = rawTools.length > 0
60
174
  ? rawTools.map((tool, index) => ({
@@ -64,14 +178,11 @@ class AnthropicProvider {
64
178
  type: 'object',
65
179
  ...tool.parameters
66
180
  },
67
- ...(index === rawTools.length - 1
68
- ? { cache_control: { type: 'ephemeral' } }
69
- : {})
181
+ ...(index === rawTools.length - 1 ? cacheControl : {})
70
182
  }))
71
183
  : undefined;
72
- // Mark system prompt with cache_control — stable across retries and group iterations
73
184
  const systemParam = systemContent
74
- ? [{ type: 'text', text: systemContent, cache_control: { type: 'ephemeral' } }]
185
+ ? [{ type: 'text', text: systemContent, ...cacheControl }]
75
186
  : undefined;
76
187
  return {
77
188
  model: request.model,
@@ -104,13 +215,16 @@ class AnthropicProvider {
104
215
  content: textContent,
105
216
  tool_calls,
106
217
  finish_reason: response.stop_reason || 'stop',
107
- usage: {
218
+ // Attributed to the model the API answered with, not the one requested —
219
+ // an alias like `claude-sonnet-4-5` resolves to a dated id, and the cost
220
+ // breakdown has to name what was actually billed.
221
+ usage: (0, contracts_1.withModel)(response.model, {
108
222
  prompt_tokens: response.usage.input_tokens,
109
223
  completion_tokens: response.usage.output_tokens,
110
- total_tokens: response.usage.input_tokens + response.usage.output_tokens,
111
- cached_input_tokens: cachedInputTokens > 0 ? cachedInputTokens : undefined,
112
- cache_creation_tokens: cacheCreationTokens > 0 ? cacheCreationTokens : undefined
113
- }
224
+ total_tokens: response.usage.input_tokens + response.usage.output_tokens + cachedInputTokens + cacheCreationTokens,
225
+ ...(cachedInputTokens > 0 ? { cached_input_tokens: cachedInputTokens } : {}),
226
+ ...(cacheCreationTokens > 0 ? { cache_creation_tokens: cacheCreationTokens } : {}),
227
+ })
114
228
  };
115
229
  }
116
230
  }
@@ -1 +1 @@
1
- {"version":3,"file":"anthropic.js","sourceRoot":"","sources":["../../src/providers/anthropic.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"anthropic.js","sourceRoot":"","sources":["../../src/providers/anthropic.ts"],"names":[],"mappings":"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"}
@@ -72,5 +72,74 @@ vitest_1.vi.mock('@anthropic-ai/sdk', () => {
72
72
  }, vitest_1.vi.fn(), controller.signal);
73
73
  (0, vitest_1.expect)(result).toBeDefined();
74
74
  });
75
+ (0, vitest_1.describe)('prompt caching', () => {
76
+ /** Run one non-streaming call and hand back the params the SDK was given. */
77
+ async function captureParams(request) {
78
+ const client = provider.client;
79
+ let captured;
80
+ client.messages.create = (params) => {
81
+ captured = params;
82
+ return Promise.resolve({
83
+ content: [{ type: 'text', text: '{}' }],
84
+ stop_reason: 'end_turn',
85
+ model: 'claude-haiku-4-20250514',
86
+ usage: { input_tokens: 10, output_tokens: 5 },
87
+ });
88
+ };
89
+ await provider.call({
90
+ model: 'claude-haiku-4-20250514',
91
+ messages: [{ role: 'system', content: 'you are a helpful agent' }, { role: 'user', content: 'hi' }],
92
+ tools: [{ name: 't', description: 'd', parameters: {} }],
93
+ ...request,
94
+ });
95
+ return captured;
96
+ }
97
+ (0, vitest_1.it)('writes no cache on a single-shot call', async () => {
98
+ const params = await captureParams({});
99
+ // The whole point: a call with no successor pays the plain input rate.
100
+ (0, vitest_1.expect)(params.system).toEqual([{ type: 'text', text: 'you are a helpful agent' }]);
101
+ (0, vitest_1.expect)(JSON.stringify(params.tools)).not.toContain('cache_control');
102
+ });
103
+ (0, vitest_1.it)('marks system and the last tool when the caller asks to cache', async () => {
104
+ const params = await captureParams({ cache_prompt: true });
105
+ (0, vitest_1.expect)(params.system).toEqual([
106
+ { type: 'text', text: 'you are a helpful agent', cache_control: { type: 'ephemeral' } },
107
+ ]);
108
+ (0, vitest_1.expect)(params.tools.at(-1).cache_control).toEqual({
109
+ type: 'ephemeral',
110
+ });
111
+ });
112
+ (0, vitest_1.it)('caches with the default 5m TTL, never the 1h one', async () => {
113
+ const params = await captureParams({ cache_prompt: true });
114
+ // A 1h write costs 2x input and needs three reads to break even; nothing
115
+ // in a pipeline run reuses a prefix that long.
116
+ (0, vitest_1.expect)(JSON.stringify(params)).not.toContain('"ttl"');
117
+ });
118
+ (0, vitest_1.it)('carries the caller decision into batched requests', async () => {
119
+ const client = provider.client;
120
+ let submitted;
121
+ client.messages.batches = {
122
+ create: (body) => {
123
+ submitted = body.requests;
124
+ return Promise.resolve({ id: 'batch_1', processing_status: 'ended', request_counts: {} });
125
+ },
126
+ retrieve: () => Promise.resolve({ id: 'batch_1', processing_status: 'ended', request_counts: {} }),
127
+ results: () => Promise.resolve([]),
128
+ cancel: () => Promise.resolve({}),
129
+ };
130
+ await provider.submitBatch([
131
+ {
132
+ custom_id: 'item_0',
133
+ request: {
134
+ model: 'claude-haiku-4-20250514',
135
+ messages: [{ role: 'system', content: 'stage prompt' }, { role: 'user', content: 'item' }],
136
+ },
137
+ },
138
+ ]);
139
+ // A batch item is the archetypal single-shot call — 50% off a surcharge is
140
+ // still a surcharge.
141
+ (0, vitest_1.expect)(JSON.stringify(submitted)).not.toContain('cache_control');
142
+ });
143
+ });
75
144
  });
76
145
  //# sourceMappingURL=anthropic.test.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"anthropic.test.js","sourceRoot":"","sources":["../../src/providers/anthropic.test.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"anthropic.test.js","sourceRoot":"","sources":["../../src/providers/anthropic.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,89 @@
1
+ import type { LLMRequest, LLMResponse } from '@studio-foundation/contracts';
2
+ import { type Provider } from './provider.js';
3
+ import { type BatchProgress, type BatchProvider } from './batch.js';
4
+ import { ProviderRegistry } from './registry.js';
5
+ /** Requests per batch before the window dispatches without waiting for the barrier. */
6
+ export declare const DEFAULT_MAX_BATCH_SIZE = 500;
7
+ /** Quiescence budget: dispatch what is parked after this long with no new arrival. */
8
+ export declare const DEFAULT_FLUSH_AFTER_MS = 30000;
9
+ export interface BatchDispatchInfo {
10
+ provider: string;
11
+ size: number;
12
+ /** 1-based, per window — batch 1 is the initial fan-out, later ones are retries or overflow. */
13
+ round: number;
14
+ }
15
+ export interface BatchSettledInfo extends BatchDispatchInfo {
16
+ succeeded: number;
17
+ failed: number;
18
+ duration_ms: number;
19
+ }
20
+ export interface BatchWindowOptions {
21
+ /** Cap per batch. Bounded by the provider's own `maxBatchSize`. */
22
+ max_size?: number;
23
+ poll_interval_ms?: number;
24
+ max_wait_ms?: number;
25
+ /** 0 disables the quiescence flush (the barrier alone decides). */
26
+ flush_after_ms?: number;
27
+ signal?: AbortSignal;
28
+ onDispatch?: (info: BatchDispatchInfo) => void;
29
+ onProgress?: (progress: BatchProgress) => void;
30
+ onSettled?: (info: BatchSettledInfo) => void;
31
+ /** Called once per provider name that cannot batch, so a caller can say so out loud. */
32
+ onFallback?: (providerName: string) => void;
33
+ }
34
+ /** One participant's handle on the window. Held for the lifetime of one map item. */
35
+ export interface BatchTicket {
36
+ /** Park a request until the window flushes; resolves with that request's response. */
37
+ submit(provider: BatchProvider, request: LLMRequest, signal?: AbortSignal): Promise<LLMResponse>;
38
+ /** This participant will make no further calls. Idempotent. */
39
+ leave(): void;
40
+ }
41
+ export declare class BatchWindow {
42
+ private readonly options;
43
+ private participants;
44
+ private parked;
45
+ private dispatching;
46
+ private seq;
47
+ private round;
48
+ private timer;
49
+ private closed;
50
+ private fallbacksReported;
51
+ constructor(options?: BatchWindowOptions);
52
+ /** Register a participant. Every join() must be matched by a leave(), or the barrier never completes. */
53
+ join(): BatchTicket;
54
+ /** Reject everything still parked and stop accepting new requests. */
55
+ close(reason?: unknown): void;
56
+ /** Note that `providerName` cannot batch. Reports through onFallback once per name. */
57
+ noteFallback(providerName: string): void;
58
+ private submit;
59
+ private settle;
60
+ private capFor;
61
+ /**
62
+ * Dispatch whatever is ready. `force` (the quiescence timer) sends everything
63
+ * parked regardless of who is still busy.
64
+ */
65
+ private maybeFlush;
66
+ private dispatch;
67
+ private armTimer;
68
+ private clearTimer;
69
+ }
70
+ /**
71
+ * A registry that hands out batched providers for the duration of one map item.
72
+ *
73
+ * Everything else passes through untouched: a provider that cannot batch, or
74
+ * one that owns its own agent loop (where there is no single call to intercept),
75
+ * is returned as-is — so `--provider mock` and `--provider claude-code` keep
76
+ * working under a `batch:` map, just without the discount.
77
+ */
78
+ export declare class BatchingProviderRegistry extends ProviderRegistry {
79
+ private readonly base;
80
+ private readonly ticket;
81
+ private readonly window;
82
+ constructor(base: ProviderRegistry, ticket: BatchTicket, window: BatchWindow);
83
+ register(provider: Provider): void;
84
+ registerLazy(name: string, factory: () => Provider): void;
85
+ get(name: string): Provider;
86
+ has(name: string): boolean;
87
+ list(): string[];
88
+ }
89
+ //# sourceMappingURL=batch-window.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"batch-window.d.ts","sourceRoot":"","sources":["../../src/providers/batch-window.ts"],"names":[],"mappings":"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"}