@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.
- package/dist/generated/bundled-assets.d.ts +1 -1
- package/dist/generated/bundled-assets.js +1 -1
- package/dist/index.d.ts +4 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +10 -1
- package/dist/index.js.map +1 -1
- package/dist/prompt-cache.d.ts +33 -0
- package/dist/prompt-cache.d.ts.map +1 -0
- package/dist/prompt-cache.js +46 -0
- package/dist/prompt-cache.js.map +1 -0
- package/dist/prompt-cache.test.d.ts +2 -0
- package/dist/prompt-cache.test.d.ts.map +1 -0
- package/dist/prompt-cache.test.js +53 -0
- package/dist/prompt-cache.test.js.map +1 -0
- package/dist/providers/anthropic-batch.test.d.ts +2 -0
- package/dist/providers/anthropic-batch.test.d.ts.map +1 -0
- package/dist/providers/anthropic-batch.test.js +178 -0
- package/dist/providers/anthropic-batch.test.js.map +1 -0
- package/dist/providers/anthropic.d.ts +17 -1
- package/dist/providers/anthropic.d.ts.map +1 -1
- package/dist/providers/anthropic.js +126 -12
- package/dist/providers/anthropic.js.map +1 -1
- package/dist/providers/anthropic.test.js +69 -0
- package/dist/providers/anthropic.test.js.map +1 -1
- package/dist/providers/batch-window.d.ts +89 -0
- package/dist/providers/batch-window.d.ts.map +1 -0
- package/dist/providers/batch-window.js +309 -0
- package/dist/providers/batch-window.js.map +1 -0
- package/dist/providers/batch-window.test.d.ts +2 -0
- package/dist/providers/batch-window.test.d.ts.map +1 -0
- package/dist/providers/batch-window.test.js +317 -0
- package/dist/providers/batch-window.test.js.map +1 -0
- package/dist/providers/batch.d.ts +55 -0
- package/dist/providers/batch.d.ts.map +1 -0
- package/dist/providers/batch.js +35 -0
- package/dist/providers/batch.js.map +1 -0
- package/dist/providers/claude-code.d.ts.map +1 -1
- package/dist/providers/claude-code.js +72 -1
- package/dist/providers/claude-code.js.map +1 -1
- package/dist/providers/claude-code.test.js +95 -0
- package/dist/providers/claude-code.test.js.map +1 -1
- package/dist/providers/ollama.d.ts.map +1 -1
- package/dist/providers/ollama.js +4 -2
- package/dist/providers/ollama.js.map +1 -1
- package/dist/providers/openai-responses.d.ts.map +1 -1
- package/dist/providers/openai-responses.js +24 -18
- package/dist/providers/openai-responses.js.map +1 -1
- package/dist/providers/openai.d.ts.map +1 -1
- package/dist/providers/openai.js +26 -10
- package/dist/providers/openai.js.map +1 -1
- package/dist/providers/provider.d.ts +3 -6
- package/dist/providers/provider.d.ts.map +1 -1
- package/dist/providers/provider.js.map +1 -1
- package/dist/runner.d.ts +7 -6
- package/dist/runner.d.ts.map +1 -1
- package/dist/runner.js +17 -8
- package/dist/runner.js.map +1 -1
- package/dist/runner.test.js +137 -0
- package/dist/runner.test.js.map +1 -1
- 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
|
-
//
|
|
57
|
-
//
|
|
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,
|
|
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
|
-
|
|
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
|
-
|
|
112
|
-
|
|
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":";AAAA;;GAEG;;;;;;
|
|
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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"}
|