ai-functions 2.1.1 → 2.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.
- package/.turbo/turbo-build.log +1 -4
- package/CHANGELOG.md +68 -1
- package/README.md +397 -157
- package/dist/ai-promise.d.ts +50 -3
- package/dist/ai-promise.d.ts.map +1 -1
- package/dist/ai-promise.js +410 -51
- package/dist/ai-promise.js.map +1 -1
- package/dist/ai-schemas.d.ts +56 -0
- package/dist/ai-schemas.d.ts.map +1 -0
- package/dist/ai-schemas.js +53 -0
- package/dist/ai-schemas.js.map +1 -0
- package/dist/ai.d.ts +16 -242
- package/dist/ai.d.ts.map +1 -1
- package/dist/ai.js +54 -837
- package/dist/ai.js.map +1 -1
- package/dist/batch/anthropic.d.ts +6 -4
- package/dist/batch/anthropic.d.ts.map +1 -1
- package/dist/batch/anthropic.js +83 -145
- package/dist/batch/anthropic.js.map +1 -1
- package/dist/batch/bedrock.d.ts +8 -30
- package/dist/batch/bedrock.d.ts.map +1 -1
- package/dist/batch/bedrock.js +155 -338
- package/dist/batch/bedrock.js.map +1 -1
- package/dist/batch/cloudflare.d.ts +8 -20
- package/dist/batch/cloudflare.d.ts.map +1 -1
- package/dist/batch/cloudflare.js +68 -189
- package/dist/batch/cloudflare.js.map +1 -1
- package/dist/batch/google.d.ts +6 -20
- package/dist/batch/google.d.ts.map +1 -1
- package/dist/batch/google.js +70 -238
- package/dist/batch/google.js.map +1 -1
- package/dist/batch/index.d.ts +4 -1
- package/dist/batch/index.d.ts.map +1 -1
- package/dist/batch/index.js +4 -1
- package/dist/batch/index.js.map +1 -1
- package/dist/batch/memory.d.ts +1 -1
- package/dist/batch/memory.d.ts.map +1 -1
- package/dist/batch/memory.js +14 -10
- package/dist/batch/memory.js.map +1 -1
- package/dist/batch/openai.d.ts +11 -14
- package/dist/batch/openai.d.ts.map +1 -1
- package/dist/batch/openai.js +52 -156
- package/dist/batch/openai.js.map +1 -1
- package/dist/batch/provider.d.ts +111 -0
- package/dist/batch/provider.d.ts.map +1 -0
- package/dist/batch/provider.js +233 -0
- package/dist/batch/provider.js.map +1 -0
- package/dist/batch-map.d.ts.map +1 -1
- package/dist/batch-map.js +23 -17
- package/dist/batch-map.js.map +1 -1
- package/dist/batch-queue.d.ts +65 -0
- package/dist/batch-queue.d.ts.map +1 -1
- package/dist/batch-queue.js +169 -14
- package/dist/batch-queue.js.map +1 -1
- package/dist/budget.d.ts +272 -0
- package/dist/budget.d.ts.map +1 -0
- package/dist/budget.js +513 -0
- package/dist/budget.js.map +1 -0
- package/dist/cache.d.ts +295 -0
- package/dist/cache.d.ts.map +1 -0
- package/dist/cache.js +433 -0
- package/dist/cache.js.map +1 -0
- package/dist/context.d.ts +42 -8
- package/dist/context.d.ts.map +1 -1
- package/dist/context.js +64 -62
- package/dist/context.js.map +1 -1
- package/dist/digital-objects-registry.d.ts +229 -0
- package/dist/digital-objects-registry.d.ts.map +1 -0
- package/dist/digital-objects-registry.js +617 -0
- package/dist/digital-objects-registry.js.map +1 -0
- package/dist/embeddings.d.ts +2 -2
- package/dist/embeddings.d.ts.map +1 -1
- package/dist/errors.d.ts +22 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +35 -0
- package/dist/errors.js.map +1 -0
- package/dist/eval/runner.d.ts +10 -1
- package/dist/eval/runner.d.ts.map +1 -1
- package/dist/eval/runner.js +41 -35
- package/dist/eval/runner.js.map +1 -1
- package/dist/eval-log/in-memory.d.ts +34 -0
- package/dist/eval-log/in-memory.d.ts.map +1 -0
- package/dist/eval-log/in-memory.js +84 -0
- package/dist/eval-log/in-memory.js.map +1 -0
- package/dist/eval-log/index.d.ts +29 -0
- package/dist/eval-log/index.d.ts.map +1 -0
- package/dist/eval-log/index.js +39 -0
- package/dist/eval-log/index.js.map +1 -0
- package/dist/eval-log/types.d.ts +101 -0
- package/dist/eval-log/types.d.ts.map +1 -0
- package/dist/eval-log/types.js +16 -0
- package/dist/eval-log/types.js.map +1 -0
- package/dist/function-registry.d.ts +116 -0
- package/dist/function-registry.d.ts.map +1 -0
- package/dist/function-registry.js +546 -0
- package/dist/function-registry.js.map +1 -0
- package/dist/generate.d.ts +9 -3
- package/dist/generate.d.ts.map +1 -1
- package/dist/generate.js +18 -22
- package/dist/generate.js.map +1 -1
- package/dist/index.d.ts +35 -20
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +89 -42
- package/dist/index.js.map +1 -1
- package/dist/logger.d.ts +118 -0
- package/dist/logger.d.ts.map +1 -0
- package/dist/logger.js +187 -0
- package/dist/logger.js.map +1 -0
- package/dist/middleware/budget.d.ts +84 -0
- package/dist/middleware/budget.d.ts.map +1 -0
- package/dist/middleware/budget.js +110 -0
- package/dist/middleware/budget.js.map +1 -0
- package/dist/middleware/cache.d.ts +103 -0
- package/dist/middleware/cache.d.ts.map +1 -0
- package/dist/middleware/cache.js +228 -0
- package/dist/middleware/cache.js.map +1 -0
- package/dist/middleware/embed-cache.d.ts +99 -0
- package/dist/middleware/embed-cache.d.ts.map +1 -0
- package/dist/middleware/embed-cache.js +128 -0
- package/dist/middleware/embed-cache.js.map +1 -0
- package/dist/middleware/index.d.ts +11 -0
- package/dist/middleware/index.d.ts.map +1 -0
- package/dist/middleware/index.js +11 -0
- package/dist/middleware/index.js.map +1 -0
- package/dist/middleware/trace.d.ts +103 -0
- package/dist/middleware/trace.d.ts.map +1 -0
- package/dist/middleware/trace.js +176 -0
- package/dist/middleware/trace.js.map +1 -0
- package/dist/primitives.d.ts +120 -1
- package/dist/primitives.d.ts.map +1 -1
- package/dist/primitives.js +398 -26
- package/dist/primitives.js.map +1 -1
- package/dist/retry.d.ts +368 -0
- package/dist/retry.d.ts.map +1 -0
- package/dist/retry.js +646 -0
- package/dist/retry.js.map +1 -0
- package/dist/schema.d.ts.map +1 -1
- package/dist/schema.js +2 -10
- package/dist/schema.js.map +1 -1
- package/dist/telemetry.d.ts +128 -0
- package/dist/telemetry.d.ts.map +1 -0
- package/dist/telemetry.js +285 -0
- package/dist/telemetry.js.map +1 -0
- package/dist/template.d.ts.map +1 -1
- package/dist/template.js +6 -1
- package/dist/template.js.map +1 -1
- package/dist/tool-orchestration.d.ts +453 -0
- package/dist/tool-orchestration.d.ts.map +1 -0
- package/dist/tool-orchestration.js +763 -0
- package/dist/tool-orchestration.js.map +1 -0
- package/dist/type-guards.d.ts +28 -0
- package/dist/type-guards.d.ts.map +1 -0
- package/dist/type-guards.js +29 -0
- package/dist/type-guards.js.map +1 -0
- package/dist/types.d.ts +135 -17
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +36 -1
- package/dist/types.js.map +1 -1
- package/dist/wrap-for-v3.d.ts +80 -0
- package/dist/wrap-for-v3.d.ts.map +1 -0
- package/dist/wrap-for-v3.js +89 -0
- package/dist/wrap-for-v3.js.map +1 -0
- package/examples/00-quickstart.ts +232 -0
- package/examples/01-rag-chatbot.ts +212 -0
- package/examples/02-multi-agent-research.ts +290 -0
- package/examples/03-email-classification.ts +379 -0
- package/examples/04-content-moderation.ts +400 -0
- package/examples/05-document-extraction.ts +455 -0
- package/examples/06-streaming-chat-nextjs.ts +437 -0
- package/examples/07-cloudflare-worker.ts +483 -0
- package/examples/08-batch-processing.ts +491 -0
- package/examples/09-budget-constrained.ts +527 -0
- package/examples/10-tool-orchestration.ts +565 -0
- package/examples/11-retry-resilience.ts +403 -0
- package/examples/12-caching-strategies.ts +422 -0
- package/examples/README.md +145 -0
- package/package.json +10 -6
- package/src/ai-promise.ts +528 -99
- package/src/ai-schemas.ts +122 -0
- package/src/ai.ts +69 -1153
- package/src/batch/anthropic.ts +96 -161
- package/src/batch/bedrock.ts +203 -454
- package/src/batch/cloudflare.ts +99 -282
- package/src/batch/google.ts +91 -297
- package/src/batch/index.ts +4 -1
- package/src/batch/memory.ts +15 -10
- package/src/batch/openai.ts +65 -193
- package/src/batch/provider.ts +336 -0
- package/src/batch-map.ts +29 -24
- package/src/batch-queue.ts +200 -11
- package/src/budget.ts +740 -0
- package/src/cache.ts +681 -0
- package/src/context.ts +122 -76
- package/src/digital-objects-registry.ts +750 -0
- package/src/errors.ts +37 -0
- package/src/eval/runner.ts +63 -38
- package/src/eval-log/in-memory.ts +90 -0
- package/src/eval-log/index.ts +46 -0
- package/src/eval-log/types.ts +110 -0
- package/src/function-registry.ts +671 -0
- package/src/generate.ts +33 -33
- package/src/index.ts +325 -49
- package/src/logger.ts +232 -0
- package/src/middleware/budget.ts +171 -0
- package/src/middleware/cache.ts +299 -0
- package/src/middleware/embed-cache.ts +195 -0
- package/src/middleware/index.ts +23 -0
- package/src/middleware/trace.ts +248 -0
- package/src/primitives.ts +589 -62
- package/src/retry.ts +902 -0
- package/src/schema.ts +8 -17
- package/src/telemetry.ts +403 -0
- package/src/template.ts +8 -4
- package/src/tool-orchestration.ts +1173 -0
- package/src/type-guards.ts +31 -0
- package/src/types.ts +164 -25
- package/src/wrap-for-v3.ts +105 -0
- package/test/ai-promise.test.ts +1080 -0
- package/test/ai-proxy.test.ts +1 -1
- package/test/backward-compat.test.ts +147 -0
- package/test/batch-autosubmit-errors.test.ts +610 -0
- package/test/batch-blog-posts.test.ts +87 -129
- package/test/budget-tracking.test.ts +800 -0
- package/test/cache.test.ts +712 -0
- package/test/context-isolation.test.ts +687 -0
- package/test/core-functions.test.ts +183 -579
- package/test/decide.test.ts +154 -322
- package/test/define.test.ts +211 -8
- package/test/digital-objects-registry.test.ts +760 -0
- package/test/embedding-cache-middleware.test.ts +140 -0
- package/test/evals/deterministic.eval.test.ts +376 -0
- package/test/generate-core.test.ts +140 -229
- package/test/implicit-batch.test.ts +22 -65
- package/test/json-parse-error-handling.test.ts +463 -0
- package/test/retry-policy-integration.test.ts +117 -0
- package/test/retry.test.ts +1016 -0
- package/test/schema.test.ts +55 -19
- package/test/streaming.test.ts +316 -0
- package/test/template.test.ts +1164 -0
- package/test/tool-orchestration.test.ts +1040 -0
- package/test/wrap-for-v3.test.ts +612 -0
- package/vitest.config.js +6 -0
- package/vitest.config.ts +20 -0
- package/dist/rpc/auth.d.ts +0 -69
- package/dist/rpc/auth.d.ts.map +0 -1
- package/dist/rpc/auth.js +0 -136
- package/dist/rpc/auth.js.map +0 -1
- package/dist/rpc/client.d.ts +0 -62
- package/dist/rpc/client.d.ts.map +0 -1
- package/dist/rpc/client.js +0 -103
- package/dist/rpc/client.js.map +0 -1
- package/dist/rpc/deferred.d.ts +0 -60
- package/dist/rpc/deferred.d.ts.map +0 -1
- package/dist/rpc/deferred.js +0 -96
- package/dist/rpc/deferred.js.map +0 -1
- package/dist/rpc/index.d.ts +0 -22
- package/dist/rpc/index.d.ts.map +0 -1
- package/dist/rpc/index.js +0 -38
- package/dist/rpc/index.js.map +0 -1
- package/dist/rpc/local.d.ts +0 -42
- package/dist/rpc/local.d.ts.map +0 -1
- package/dist/rpc/local.js +0 -50
- package/dist/rpc/local.js.map +0 -1
- package/dist/rpc/server.d.ts +0 -165
- package/dist/rpc/server.d.ts.map +0 -1
- package/dist/rpc/server.js +0 -405
- package/dist/rpc/server.js.map +0 -1
- package/dist/rpc/session.d.ts +0 -32
- package/dist/rpc/session.d.ts.map +0 -1
- package/dist/rpc/session.js +0 -43
- package/dist/rpc/session.js.map +0 -1
- package/dist/rpc/transport.d.ts +0 -306
- package/dist/rpc/transport.d.ts.map +0 -1
- package/dist/rpc/transport.js +0 -731
- package/dist/rpc/transport.js.map +0 -1
- package/src/batch/anthropic.js +0 -256
- package/src/batch/bedrock.js +0 -584
- package/src/batch/cloudflare.js +0 -287
- package/src/batch/google.js +0 -359
- package/src/batch/index.js +0 -30
- package/src/batch/memory.js +0 -187
- package/src/batch/openai.js +0 -402
- package/src/eval/index.js +0 -7
- package/src/eval/models.js +0 -119
- package/src/eval/runner.js +0 -147
- package/test/schema.test.js +0 -96
package/src/batch/anthropic.ts
CHANGED
|
@@ -6,25 +6,32 @@
|
|
|
6
6
|
* - 24-hour turnaround
|
|
7
7
|
* - Up to 10,000 requests per batch
|
|
8
8
|
*
|
|
9
|
+
* This file is a small adapter on top of the BatchProvider port (`./provider.js`).
|
|
10
|
+
* It owns only the Anthropic-specific request/response shapes and HTTP calls;
|
|
11
|
+
* shared concerns (polling, JSON-Schema conversion, JSON parsing) live in the port.
|
|
12
|
+
*
|
|
9
13
|
* @see https://docs.anthropic.com/en/docs/build-with-claude/message-batches
|
|
10
14
|
*
|
|
11
15
|
* @packageDocumentation
|
|
12
16
|
*/
|
|
13
17
|
|
|
18
|
+
import { schema as convertSchema } from '../schema.js'
|
|
14
19
|
import {
|
|
20
|
+
pollUntilComplete,
|
|
15
21
|
registerBatchAdapter,
|
|
22
|
+
tryParseJson,
|
|
23
|
+
zodToJsonSchema,
|
|
16
24
|
type BatchAdapter,
|
|
17
25
|
type BatchItem,
|
|
18
26
|
type BatchJob,
|
|
19
27
|
type BatchQueueOptions,
|
|
20
28
|
type BatchResult,
|
|
21
|
-
type BatchSubmitResult,
|
|
22
29
|
type BatchStatus,
|
|
23
|
-
|
|
24
|
-
|
|
30
|
+
type BatchSubmitResult,
|
|
31
|
+
} from './provider.js'
|
|
25
32
|
|
|
26
33
|
// ============================================================================
|
|
27
|
-
//
|
|
34
|
+
// Provider-specific types
|
|
28
35
|
// ============================================================================
|
|
29
36
|
|
|
30
37
|
interface AnthropicBatchRequest {
|
|
@@ -87,7 +94,7 @@ interface AnthropicBatch {
|
|
|
87
94
|
}
|
|
88
95
|
|
|
89
96
|
// ============================================================================
|
|
90
|
-
// Anthropic
|
|
97
|
+
// Anthropic client
|
|
91
98
|
// ============================================================================
|
|
92
99
|
|
|
93
100
|
let anthropicApiKey: string | undefined
|
|
@@ -95,37 +102,40 @@ let anthropicBaseUrl = 'https://api.anthropic.com/v1'
|
|
|
95
102
|
const ANTHROPIC_VERSION = '2023-06-01'
|
|
96
103
|
const ANTHROPIC_BETA = 'message-batches-2024-09-24'
|
|
97
104
|
|
|
98
|
-
/**
|
|
99
|
-
* Configure the Anthropic client
|
|
100
|
-
*/
|
|
105
|
+
/** Configure the Anthropic client. */
|
|
101
106
|
export function configureAnthropic(options: { apiKey?: string; baseUrl?: string }): void {
|
|
102
107
|
if (options.apiKey) anthropicApiKey = options.apiKey
|
|
103
108
|
if (options.baseUrl) anthropicBaseUrl = options.baseUrl
|
|
104
109
|
}
|
|
105
110
|
|
|
106
111
|
function getApiKey(): string {
|
|
107
|
-
const key = anthropicApiKey || process.env
|
|
112
|
+
const key = anthropicApiKey || process.env['ANTHROPIC_API_KEY']
|
|
108
113
|
if (!key) {
|
|
109
|
-
throw new Error(
|
|
114
|
+
throw new Error(
|
|
115
|
+
'Anthropic API key not configured. Set ANTHROPIC_API_KEY or call configureAnthropic()'
|
|
116
|
+
)
|
|
110
117
|
}
|
|
111
118
|
return key
|
|
112
119
|
}
|
|
113
120
|
|
|
121
|
+
function anthropicHeaders(): Record<string, string> {
|
|
122
|
+
return {
|
|
123
|
+
'x-api-key': getApiKey(),
|
|
124
|
+
'anthropic-version': ANTHROPIC_VERSION,
|
|
125
|
+
'anthropic-beta': ANTHROPIC_BETA,
|
|
126
|
+
'Content-Type': 'application/json',
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
|
|
114
130
|
async function anthropicRequest<T>(
|
|
115
131
|
method: 'GET' | 'POST',
|
|
116
132
|
path: string,
|
|
117
133
|
body?: unknown
|
|
118
134
|
): Promise<T> {
|
|
119
|
-
const
|
|
120
|
-
const response = await fetch(url, {
|
|
135
|
+
const response = await fetch(`${anthropicBaseUrl}${path}`, {
|
|
121
136
|
method,
|
|
122
|
-
headers:
|
|
123
|
-
|
|
124
|
-
'anthropic-version': ANTHROPIC_VERSION,
|
|
125
|
-
'anthropic-beta': ANTHROPIC_BETA,
|
|
126
|
-
'Content-Type': 'application/json',
|
|
127
|
-
},
|
|
128
|
-
body: body ? JSON.stringify(body) : undefined,
|
|
137
|
+
headers: anthropicHeaders(),
|
|
138
|
+
...(body !== undefined && { body: JSON.stringify(body) }),
|
|
129
139
|
})
|
|
130
140
|
|
|
131
141
|
if (!response.ok) {
|
|
@@ -136,10 +146,6 @@ async function anthropicRequest<T>(
|
|
|
136
146
|
return response.json()
|
|
137
147
|
}
|
|
138
148
|
|
|
139
|
-
// ============================================================================
|
|
140
|
-
// Status Mapping
|
|
141
|
-
// ============================================================================
|
|
142
|
-
|
|
143
149
|
function mapStatus(batch: AnthropicBatch): BatchStatus {
|
|
144
150
|
if (batch.cancel_initiated_at) {
|
|
145
151
|
return batch.processing_status === 'ended' ? 'cancelled' : 'cancelling'
|
|
@@ -150,8 +156,30 @@ function mapStatus(batch: AnthropicBatch): BatchStatus {
|
|
|
150
156
|
return 'in_progress'
|
|
151
157
|
}
|
|
152
158
|
|
|
159
|
+
function toBatchJob(batch: AnthropicBatch, totalItemsHint?: number): BatchJob {
|
|
160
|
+
const totalFromCounts =
|
|
161
|
+
batch.request_counts.processing +
|
|
162
|
+
batch.request_counts.succeeded +
|
|
163
|
+
batch.request_counts.errored +
|
|
164
|
+
batch.request_counts.canceled +
|
|
165
|
+
batch.request_counts.expired
|
|
166
|
+
|
|
167
|
+
return {
|
|
168
|
+
id: batch.id,
|
|
169
|
+
provider: 'anthropic',
|
|
170
|
+
status: mapStatus(batch),
|
|
171
|
+
totalItems: totalItemsHint ?? totalFromCounts,
|
|
172
|
+
completedItems: batch.request_counts.succeeded,
|
|
173
|
+
failedItems:
|
|
174
|
+
batch.request_counts.errored + batch.request_counts.expired + batch.request_counts.canceled,
|
|
175
|
+
createdAt: new Date(batch.created_at),
|
|
176
|
+
...(batch.ended_at && { completedAt: new Date(batch.ended_at) }),
|
|
177
|
+
expiresAt: new Date(batch.expires_at),
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
|
|
153
181
|
// ============================================================================
|
|
154
|
-
// Anthropic
|
|
182
|
+
// Anthropic adapter (BatchProvider port)
|
|
155
183
|
// ============================================================================
|
|
156
184
|
|
|
157
185
|
const anthropicAdapter: BatchAdapter = {
|
|
@@ -159,7 +187,6 @@ const anthropicAdapter: BatchAdapter = {
|
|
|
159
187
|
const model = options.model || 'claude-sonnet-4-20250514'
|
|
160
188
|
const maxTokens = 4096
|
|
161
189
|
|
|
162
|
-
// Build batch requests
|
|
163
190
|
const requests: AnthropicBatchRequest[] = items.map((item) => {
|
|
164
191
|
const request: AnthropicBatchRequest = {
|
|
165
192
|
custom_id: item.id,
|
|
@@ -167,21 +194,20 @@ const anthropicAdapter: BatchAdapter = {
|
|
|
167
194
|
model,
|
|
168
195
|
max_tokens: item.options?.maxTokens || maxTokens,
|
|
169
196
|
messages: [{ role: 'user', content: item.prompt }],
|
|
170
|
-
system: item.options
|
|
171
|
-
|
|
197
|
+
...(item.options?.system !== undefined && { system: item.options.system }),
|
|
198
|
+
...(item.options?.temperature !== undefined && {
|
|
199
|
+
temperature: item.options.temperature,
|
|
200
|
+
}),
|
|
172
201
|
},
|
|
173
202
|
}
|
|
174
203
|
|
|
175
|
-
// Add JSON schema as a tool if provided
|
|
176
204
|
if (item.schema) {
|
|
177
205
|
const zodSchema = convertSchema(item.schema)
|
|
178
|
-
const jsonSchema = zodToJsonSchema(zodSchema)
|
|
179
|
-
|
|
180
206
|
request.params.tools = [
|
|
181
207
|
{
|
|
182
208
|
name: 'structured_response',
|
|
183
209
|
description: 'Generate a structured response matching the schema',
|
|
184
|
-
input_schema:
|
|
210
|
+
input_schema: zodToJsonSchema(zodSchema),
|
|
185
211
|
},
|
|
186
212
|
]
|
|
187
213
|
request.params.tool_choice = { type: 'tool', name: 'structured_response' }
|
|
@@ -190,48 +216,22 @@ const anthropicAdapter: BatchAdapter = {
|
|
|
190
216
|
return request
|
|
191
217
|
})
|
|
192
218
|
|
|
193
|
-
// Create the batch
|
|
194
219
|
const batch = await anthropicRequest<AnthropicBatch>('POST', '/messages/batches', {
|
|
195
220
|
requests,
|
|
196
221
|
})
|
|
197
222
|
|
|
198
|
-
const job
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
status: mapStatus(batch),
|
|
202
|
-
totalItems: items.length,
|
|
203
|
-
completedItems: batch.request_counts.succeeded,
|
|
204
|
-
failedItems: batch.request_counts.errored + batch.request_counts.expired + batch.request_counts.canceled,
|
|
205
|
-
createdAt: new Date(batch.created_at),
|
|
206
|
-
expiresAt: new Date(batch.expires_at),
|
|
207
|
-
webhookUrl: options.webhookUrl,
|
|
223
|
+
const job = toBatchJob(batch, items.length)
|
|
224
|
+
if (options.webhookUrl !== undefined) {
|
|
225
|
+
job.webhookUrl = options.webhookUrl
|
|
208
226
|
}
|
|
209
227
|
|
|
210
|
-
// Create completion promise
|
|
211
228
|
const completion = this.waitForCompletion(batch.id)
|
|
212
|
-
|
|
213
229
|
return { job, completion }
|
|
214
230
|
},
|
|
215
231
|
|
|
216
232
|
async getStatus(batchId: string): Promise<BatchJob> {
|
|
217
233
|
const batch = await anthropicRequest<AnthropicBatch>('GET', `/messages/batches/${batchId}`)
|
|
218
|
-
|
|
219
|
-
return {
|
|
220
|
-
id: batch.id,
|
|
221
|
-
provider: 'anthropic',
|
|
222
|
-
status: mapStatus(batch),
|
|
223
|
-
totalItems:
|
|
224
|
-
batch.request_counts.processing +
|
|
225
|
-
batch.request_counts.succeeded +
|
|
226
|
-
batch.request_counts.errored +
|
|
227
|
-
batch.request_counts.canceled +
|
|
228
|
-
batch.request_counts.expired,
|
|
229
|
-
completedItems: batch.request_counts.succeeded,
|
|
230
|
-
failedItems: batch.request_counts.errored + batch.request_counts.expired + batch.request_counts.canceled,
|
|
231
|
-
createdAt: new Date(batch.created_at),
|
|
232
|
-
completedAt: batch.ended_at ? new Date(batch.ended_at) : undefined,
|
|
233
|
-
expiresAt: new Date(batch.expires_at),
|
|
234
|
-
}
|
|
234
|
+
return toBatchJob(batch)
|
|
235
235
|
},
|
|
236
236
|
|
|
237
237
|
async cancel(batchId: string): Promise<void> {
|
|
@@ -245,129 +245,64 @@ const anthropicAdapter: BatchAdapter = {
|
|
|
245
245
|
throw new Error(`Batch not complete. Status: ${status.status}`)
|
|
246
246
|
}
|
|
247
247
|
|
|
248
|
-
//
|
|
248
|
+
// Anthropic returns results via a signed URL on the batch object.
|
|
249
249
|
const batch = await anthropicRequest<AnthropicBatch>('GET', `/messages/batches/${batchId}`)
|
|
250
|
-
|
|
251
250
|
if (!batch.results_url) {
|
|
252
251
|
throw new Error('No results URL available')
|
|
253
252
|
}
|
|
254
253
|
|
|
255
|
-
|
|
256
|
-
const response = await fetch(batch.results_url, {
|
|
257
|
-
headers: {
|
|
258
|
-
'x-api-key': getApiKey(),
|
|
259
|
-
'anthropic-version': ANTHROPIC_VERSION,
|
|
260
|
-
'anthropic-beta': ANTHROPIC_BETA,
|
|
261
|
-
},
|
|
262
|
-
})
|
|
263
|
-
|
|
254
|
+
const response = await fetch(batch.results_url, { headers: anthropicHeaders() })
|
|
264
255
|
if (!response.ok) {
|
|
265
256
|
throw new Error(`Failed to fetch results: ${response.status}`)
|
|
266
257
|
}
|
|
267
258
|
|
|
268
|
-
const
|
|
269
|
-
|
|
270
|
-
const results: BatchResult[] = []
|
|
271
|
-
|
|
272
|
-
for (const line of lines) {
|
|
273
|
-
const result: AnthropicBatchResult = JSON.parse(line)
|
|
274
|
-
|
|
275
|
-
if (result.result.type === 'succeeded' && result.result.message) {
|
|
276
|
-
const message = result.result.message
|
|
277
|
-
let extractedResult: unknown
|
|
278
|
-
|
|
279
|
-
// Extract from tool use or text
|
|
280
|
-
const toolUse = message.content.find((c) => c.type === 'tool_use')
|
|
281
|
-
const textContent = message.content.find((c) => c.type === 'text')
|
|
282
|
-
|
|
283
|
-
if (toolUse?.input) {
|
|
284
|
-
extractedResult = toolUse.input
|
|
285
|
-
} else if (textContent?.text) {
|
|
286
|
-
// Try to parse as JSON
|
|
287
|
-
try {
|
|
288
|
-
extractedResult = JSON.parse(textContent.text)
|
|
289
|
-
} catch {
|
|
290
|
-
extractedResult = textContent.text
|
|
291
|
-
}
|
|
292
|
-
}
|
|
293
|
-
|
|
294
|
-
results.push({
|
|
295
|
-
id: result.custom_id,
|
|
296
|
-
customId: result.custom_id,
|
|
297
|
-
status: 'completed',
|
|
298
|
-
result: extractedResult,
|
|
299
|
-
usage: {
|
|
300
|
-
promptTokens: message.usage.input_tokens,
|
|
301
|
-
completionTokens: message.usage.output_tokens,
|
|
302
|
-
totalTokens: message.usage.input_tokens + message.usage.output_tokens,
|
|
303
|
-
},
|
|
304
|
-
})
|
|
305
|
-
} else {
|
|
306
|
-
results.push({
|
|
307
|
-
id: result.custom_id,
|
|
308
|
-
customId: result.custom_id,
|
|
309
|
-
status: 'failed',
|
|
310
|
-
error: result.result.error?.message || `Request ${result.result.type}`,
|
|
311
|
-
})
|
|
312
|
-
}
|
|
313
|
-
}
|
|
314
|
-
|
|
315
|
-
return results
|
|
259
|
+
const lines = (await response.text()).trim().split('\n')
|
|
260
|
+
return lines.map(parseAnthropicResult)
|
|
316
261
|
},
|
|
317
262
|
|
|
318
263
|
async waitForCompletion(batchId: string, pollInterval = 5000): Promise<BatchResult[]> {
|
|
319
|
-
|
|
320
|
-
const status = await this.getStatus(batchId)
|
|
321
|
-
|
|
322
|
-
if (status.status === 'completed' || status.status === 'cancelled') {
|
|
323
|
-
return this.getResults(batchId)
|
|
324
|
-
}
|
|
325
|
-
|
|
326
|
-
await new Promise((resolve) => setTimeout(resolve, pollInterval))
|
|
327
|
-
}
|
|
264
|
+
return pollUntilComplete(this, batchId, { pollInterval })
|
|
328
265
|
},
|
|
329
266
|
}
|
|
330
267
|
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
// ============================================================================
|
|
268
|
+
function parseAnthropicResult(line: string): BatchResult {
|
|
269
|
+
const result: AnthropicBatchResult = JSON.parse(line)
|
|
334
270
|
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
const schema = zodSchema as { _def?: { typeName?: string; shape?: unknown } }
|
|
271
|
+
if (result.result.type === 'succeeded' && result.result.message) {
|
|
272
|
+
const message = result.result.message
|
|
273
|
+
const toolUse = message.content.find((c) => c.type === 'tool_use')
|
|
274
|
+
const textContent = message.content.find((c) => c.type === 'text')
|
|
340
275
|
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
276
|
+
let extractedResult: unknown
|
|
277
|
+
if (toolUse?.input) {
|
|
278
|
+
extractedResult = toolUse.input
|
|
279
|
+
} else if (textContent?.text) {
|
|
280
|
+
extractedResult = tryParseJson(textContent.text)
|
|
281
|
+
}
|
|
344
282
|
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
return { type: 'array', items: zodToJsonSchema((schema._def as any).type) }
|
|
356
|
-
case 'ZodObject': {
|
|
357
|
-
const shape = (schema._def as any).shape()
|
|
358
|
-
const properties: Record<string, unknown> = {}
|
|
359
|
-
for (const [key, value] of Object.entries(shape)) {
|
|
360
|
-
properties[key] = zodToJsonSchema(value)
|
|
361
|
-
}
|
|
362
|
-
return { type: 'object', properties, required: Object.keys(properties) }
|
|
283
|
+
return {
|
|
284
|
+
id: result.custom_id,
|
|
285
|
+
customId: result.custom_id,
|
|
286
|
+
status: 'completed',
|
|
287
|
+
result: extractedResult,
|
|
288
|
+
usage: {
|
|
289
|
+
promptTokens: message.usage.input_tokens,
|
|
290
|
+
completionTokens: message.usage.output_tokens,
|
|
291
|
+
totalTokens: message.usage.input_tokens + message.usage.output_tokens,
|
|
292
|
+
},
|
|
363
293
|
}
|
|
364
|
-
|
|
365
|
-
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
return {
|
|
297
|
+
id: result.custom_id,
|
|
298
|
+
customId: result.custom_id,
|
|
299
|
+
status: 'failed',
|
|
300
|
+
error: result.result.error?.message || `Request ${result.result.type}`,
|
|
366
301
|
}
|
|
367
302
|
}
|
|
368
303
|
|
|
369
304
|
// ============================================================================
|
|
370
|
-
// Register
|
|
305
|
+
// Register adapter
|
|
371
306
|
// ============================================================================
|
|
372
307
|
|
|
373
308
|
registerBatchAdapter('anthropic', anthropicAdapter)
|