ai-functions 0.3.0 → 0.4.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 (400) hide show
  1. package/.turbo/turbo-build.log +5 -0
  2. package/.turbo/turbo-test.log +105 -0
  3. package/README.md +190 -86
  4. package/TODO.md +138 -0
  5. package/dist/ai-promise.d.ts +219 -0
  6. package/dist/ai-promise.d.ts.map +1 -0
  7. package/dist/ai-promise.js +610 -0
  8. package/dist/ai-promise.js.map +1 -0
  9. package/dist/ai.d.ts +285 -0
  10. package/dist/ai.d.ts.map +1 -0
  11. package/dist/ai.js +842 -0
  12. package/dist/ai.js.map +1 -0
  13. package/dist/batch/anthropic.d.ts +23 -0
  14. package/dist/batch/anthropic.d.ts.map +1 -0
  15. package/dist/batch/anthropic.js +257 -0
  16. package/dist/batch/anthropic.js.map +1 -0
  17. package/dist/batch/bedrock.d.ts +64 -0
  18. package/dist/batch/bedrock.d.ts.map +1 -0
  19. package/dist/batch/bedrock.js +586 -0
  20. package/dist/batch/bedrock.js.map +1 -0
  21. package/dist/batch/cloudflare.d.ts +37 -0
  22. package/dist/batch/cloudflare.d.ts.map +1 -0
  23. package/dist/batch/cloudflare.js +289 -0
  24. package/dist/batch/cloudflare.js.map +1 -0
  25. package/dist/batch/google.d.ts +41 -0
  26. package/dist/batch/google.d.ts.map +1 -0
  27. package/dist/batch/google.js +360 -0
  28. package/dist/batch/google.js.map +1 -0
  29. package/dist/batch/index.d.ts +31 -0
  30. package/dist/batch/index.d.ts.map +1 -0
  31. package/dist/batch/index.js +31 -0
  32. package/dist/batch/index.js.map +1 -0
  33. package/dist/batch/memory.d.ts +44 -0
  34. package/dist/batch/memory.d.ts.map +1 -0
  35. package/dist/batch/memory.js +188 -0
  36. package/dist/batch/memory.js.map +1 -0
  37. package/dist/batch/openai.d.ts +37 -0
  38. package/dist/batch/openai.d.ts.map +1 -0
  39. package/dist/batch/openai.js +403 -0
  40. package/dist/batch/openai.js.map +1 -0
  41. package/dist/batch-map.d.ts +125 -0
  42. package/dist/batch-map.d.ts.map +1 -0
  43. package/dist/batch-map.js +406 -0
  44. package/dist/batch-map.js.map +1 -0
  45. package/dist/batch-queue.d.ts +273 -0
  46. package/dist/batch-queue.d.ts.map +1 -0
  47. package/dist/batch-queue.js +271 -0
  48. package/dist/batch-queue.js.map +1 -0
  49. package/dist/context.d.ts +133 -0
  50. package/dist/context.d.ts.map +1 -0
  51. package/dist/context.js +267 -0
  52. package/dist/context.js.map +1 -0
  53. package/dist/embeddings.d.ts +123 -0
  54. package/dist/embeddings.d.ts.map +1 -0
  55. package/dist/embeddings.js +170 -0
  56. package/dist/embeddings.js.map +1 -0
  57. package/dist/eval/index.d.ts +8 -0
  58. package/dist/eval/index.d.ts.map +1 -0
  59. package/dist/eval/index.js +8 -0
  60. package/dist/eval/index.js.map +1 -0
  61. package/dist/eval/models.d.ts +66 -0
  62. package/dist/eval/models.d.ts.map +1 -0
  63. package/dist/eval/models.js +120 -0
  64. package/dist/eval/models.js.map +1 -0
  65. package/dist/eval/runner.d.ts +64 -0
  66. package/dist/eval/runner.d.ts.map +1 -0
  67. package/dist/eval/runner.js +148 -0
  68. package/dist/eval/runner.js.map +1 -0
  69. package/dist/generate.d.ts +168 -0
  70. package/dist/generate.d.ts.map +1 -0
  71. package/dist/generate.js +174 -0
  72. package/dist/generate.js.map +1 -0
  73. package/dist/index.d.ts +29 -4
  74. package/dist/index.d.ts.map +1 -1
  75. package/dist/index.js +53 -52
  76. package/dist/index.js.map +1 -1
  77. package/dist/primitives.d.ts +292 -0
  78. package/dist/primitives.d.ts.map +1 -0
  79. package/dist/primitives.js +471 -0
  80. package/dist/primitives.js.map +1 -0
  81. package/dist/providers/cloudflare.d.ts +9 -0
  82. package/dist/providers/cloudflare.d.ts.map +1 -0
  83. package/dist/providers/cloudflare.js +9 -0
  84. package/dist/providers/cloudflare.js.map +1 -0
  85. package/dist/providers/index.d.ts +9 -0
  86. package/dist/providers/index.d.ts.map +1 -0
  87. package/dist/providers/index.js +9 -0
  88. package/dist/providers/index.js.map +1 -0
  89. package/dist/schema.d.ts +54 -0
  90. package/dist/schema.d.ts.map +1 -0
  91. package/dist/schema.js +109 -0
  92. package/dist/schema.js.map +1 -0
  93. package/dist/template.d.ts +73 -0
  94. package/dist/template.d.ts.map +1 -0
  95. package/dist/template.js +129 -0
  96. package/dist/template.js.map +1 -0
  97. package/dist/types.d.ts +474 -106
  98. package/dist/types.d.ts.map +1 -1
  99. package/dist/types.js +4 -8
  100. package/dist/types.js.map +1 -1
  101. package/evalite.config.ts +19 -0
  102. package/evals/README.md +212 -0
  103. package/evals/classification.eval.ts +108 -0
  104. package/evals/marketing.eval.ts +370 -0
  105. package/evals/math.eval.ts +94 -0
  106. package/evals/run-evals.ts +166 -0
  107. package/evals/structured-output.eval.ts +143 -0
  108. package/evals/writing.eval.ts +117 -0
  109. package/examples/batch-blog-posts.ts +160 -0
  110. package/package.json +57 -57
  111. package/src/ai-promise.ts +784 -0
  112. package/src/ai.ts +1183 -0
  113. package/src/batch/anthropic.ts +375 -0
  114. package/src/batch/bedrock.ts +801 -0
  115. package/src/batch/cloudflare.ts +421 -0
  116. package/src/batch/google.ts +491 -0
  117. package/src/batch/index.ts +31 -0
  118. package/src/batch/memory.ts +253 -0
  119. package/src/batch/openai.ts +557 -0
  120. package/src/batch-map.ts +534 -0
  121. package/src/batch-queue.ts +493 -0
  122. package/src/context.ts +332 -0
  123. package/src/embeddings.ts +244 -0
  124. package/src/eval/index.ts +8 -0
  125. package/src/eval/models.ts +158 -0
  126. package/src/eval/runner.ts +217 -0
  127. package/src/generate.ts +245 -0
  128. package/src/index.ts +154 -0
  129. package/src/primitives.ts +612 -0
  130. package/src/providers/cloudflare.ts +15 -0
  131. package/src/providers/index.ts +14 -0
  132. package/src/schema.ts +147 -0
  133. package/src/template.ts +209 -0
  134. package/src/types.ts +540 -0
  135. package/test/README.md +105 -0
  136. package/test/ai-proxy.test.ts +192 -0
  137. package/test/async-iterators.test.ts +327 -0
  138. package/test/batch-background.test.ts +482 -0
  139. package/test/batch-blog-posts.test.ts +387 -0
  140. package/test/blog-generation.test.ts +510 -0
  141. package/test/browse-read.test.ts +611 -0
  142. package/test/core-functions.test.ts +694 -0
  143. package/test/decide.test.ts +393 -0
  144. package/test/define.test.ts +274 -0
  145. package/test/e2e-bedrock-manual.ts +163 -0
  146. package/test/e2e-bedrock.test.ts +191 -0
  147. package/test/e2e-flex-gateway.ts +157 -0
  148. package/test/e2e-flex-manual.ts +183 -0
  149. package/test/e2e-flex.test.ts +209 -0
  150. package/test/e2e-google-manual.ts +178 -0
  151. package/test/e2e-google.test.ts +216 -0
  152. package/test/embeddings.test.ts +284 -0
  153. package/test/evals/define-function.eval.test.ts +379 -0
  154. package/test/evals/primitives.eval.test.ts +384 -0
  155. package/test/function-types.test.ts +492 -0
  156. package/test/generate-core.test.ts +319 -0
  157. package/test/generate.test.ts +163 -0
  158. package/test/implicit-batch.test.ts +422 -0
  159. package/test/schema.test.ts +109 -0
  160. package/test/tagged-templates.test.ts +302 -0
  161. package/tsconfig.json +10 -0
  162. package/vitest.config.ts +42 -0
  163. package/LICENSE +0 -21
  164. package/bin/cli.js +0 -5
  165. package/dist/cli/index.d.ts +0 -10
  166. package/dist/cli/index.d.ts.map +0 -1
  167. package/dist/cli/index.js +0 -38
  168. package/dist/cli/index.js.map +0 -1
  169. package/dist/cli/index.test.d.ts +0 -2
  170. package/dist/cli/index.test.d.ts.map +0 -1
  171. package/dist/cli/index.test.js +0 -35
  172. package/dist/cli/index.test.js.map +0 -1
  173. package/dist/constants/models.d.ts +0 -10
  174. package/dist/constants/models.d.ts.map +0 -1
  175. package/dist/constants/models.js +0 -12
  176. package/dist/constants/models.js.map +0 -1
  177. package/dist/converters/index.d.ts +0 -3
  178. package/dist/converters/index.d.ts.map +0 -1
  179. package/dist/converters/index.js +0 -3
  180. package/dist/converters/index.js.map +0 -1
  181. package/dist/converters/model.d.ts +0 -4
  182. package/dist/converters/model.d.ts.map +0 -1
  183. package/dist/converters/model.js +0 -19
  184. package/dist/converters/model.js.map +0 -1
  185. package/dist/converters/schema.d.ts +0 -4
  186. package/dist/converters/schema.d.ts.map +0 -1
  187. package/dist/converters/schema.js +0 -25
  188. package/dist/converters/schema.js.map +0 -1
  189. package/dist/core/responses.d.ts +0 -5
  190. package/dist/core/responses.d.ts.map +0 -1
  191. package/dist/core/responses.js +0 -16
  192. package/dist/core/responses.js.map +0 -1
  193. package/dist/core/responses.test.d.ts +0 -2
  194. package/dist/core/responses.test.d.ts.map +0 -1
  195. package/dist/core/responses.test.js +0 -31
  196. package/dist/core/responses.test.js.map +0 -1
  197. package/dist/errors.d.ts +0 -6
  198. package/dist/errors.d.ts.map +0 -1
  199. package/dist/errors.js +0 -9
  200. package/dist/errors.js.map +0 -1
  201. package/dist/examples/streaming.test.d.ts +0 -2
  202. package/dist/examples/streaming.test.d.ts.map +0 -1
  203. package/dist/examples/streaming.test.js +0 -176
  204. package/dist/examples/streaming.test.js.map +0 -1
  205. package/dist/factory/__tests__/index.test.d.ts +0 -2
  206. package/dist/factory/__tests__/index.test.d.ts.map +0 -1
  207. package/dist/factory/__tests__/index.test.js +0 -430
  208. package/dist/factory/__tests__/index.test.js.map +0 -1
  209. package/dist/factory/__tests__/list.test.d.ts +0 -2
  210. package/dist/factory/__tests__/list.test.d.ts.map +0 -1
  211. package/dist/factory/__tests__/list.test.js +0 -92
  212. package/dist/factory/__tests__/list.test.js.map +0 -1
  213. package/dist/factory/index.d.ts +0 -20
  214. package/dist/factory/index.d.ts.map +0 -1
  215. package/dist/factory/index.js +0 -287
  216. package/dist/factory/index.js.map +0 -1
  217. package/dist/factory/index.test.d.ts +0 -2
  218. package/dist/factory/index.test.d.ts.map +0 -1
  219. package/dist/factory/index.test.js +0 -287
  220. package/dist/factory/index.test.js.map +0 -1
  221. package/dist/factory/list.d.ts +0 -3
  222. package/dist/factory/list.d.ts.map +0 -1
  223. package/dist/factory/list.js +0 -221
  224. package/dist/factory/list.js.map +0 -1
  225. package/dist/factory/list.test.d.ts +0 -2
  226. package/dist/factory/list.test.d.ts.map +0 -1
  227. package/dist/factory/list.test.js +0 -84
  228. package/dist/factory/list.test.js.map +0 -1
  229. package/dist/generate/index.d.ts +0 -5
  230. package/dist/generate/index.d.ts.map +0 -1
  231. package/dist/generate/index.js +0 -17
  232. package/dist/generate/index.js.map +0 -1
  233. package/dist/index.test.d.ts +0 -2
  234. package/dist/index.test.d.ts.map +0 -1
  235. package/dist/index.test.js +0 -59
  236. package/dist/index.test.js.map +0 -1
  237. package/dist/list/await.d.ts +0 -3
  238. package/dist/list/await.d.ts.map +0 -1
  239. package/dist/list/await.js +0 -28
  240. package/dist/list/await.js.map +0 -1
  241. package/dist/list/constants.d.ts +0 -4
  242. package/dist/list/constants.d.ts.map +0 -1
  243. package/dist/list/constants.js +0 -5
  244. package/dist/list/constants.js.map +0 -1
  245. package/dist/list/create-function.d.ts +0 -3
  246. package/dist/list/create-function.d.ts.map +0 -1
  247. package/dist/list/create-function.js +0 -11
  248. package/dist/list/create-function.js.map +0 -1
  249. package/dist/list/index.d.ts +0 -4
  250. package/dist/list/index.d.ts.map +0 -1
  251. package/dist/list/index.js +0 -5
  252. package/dist/list/index.js.map +0 -1
  253. package/dist/list/prompt.d.ts +0 -3
  254. package/dist/list/prompt.d.ts.map +0 -1
  255. package/dist/list/prompt.js +0 -6
  256. package/dist/list/prompt.js.map +0 -1
  257. package/dist/list/schemas.d.ts +0 -4
  258. package/dist/list/schemas.d.ts.map +0 -1
  259. package/dist/list/schemas.js +0 -8
  260. package/dist/list/schemas.js.map +0 -1
  261. package/dist/list/stream.d.ts +0 -3
  262. package/dist/list/stream.d.ts.map +0 -1
  263. package/dist/list/stream.js +0 -33
  264. package/dist/list/stream.js.map +0 -1
  265. package/dist/list/types.d.ts +0 -11
  266. package/dist/list/types.d.ts.map +0 -1
  267. package/dist/list/types.js +0 -2
  268. package/dist/list/types.js.map +0 -1
  269. package/dist/list/validation.d.ts +0 -3
  270. package/dist/list/validation.d.ts.map +0 -1
  271. package/dist/list/validation.js +0 -12
  272. package/dist/list/validation.js.map +0 -1
  273. package/dist/providers/config.d.ts +0 -4
  274. package/dist/providers/config.d.ts.map +0 -1
  275. package/dist/providers/config.js +0 -21
  276. package/dist/providers/config.js.map +0 -1
  277. package/dist/providers/config.test.d.ts +0 -2
  278. package/dist/providers/config.test.d.ts.map +0 -1
  279. package/dist/providers/config.test.js +0 -37
  280. package/dist/providers/config.test.js.map +0 -1
  281. package/dist/proxy/constants.d.ts +0 -4
  282. package/dist/proxy/constants.d.ts.map +0 -1
  283. package/dist/proxy/constants.js +0 -5
  284. package/dist/proxy/constants.js.map +0 -1
  285. package/dist/proxy/create-function.d.ts +0 -4
  286. package/dist/proxy/create-function.d.ts.map +0 -1
  287. package/dist/proxy/create-function.js +0 -24
  288. package/dist/proxy/create-function.js.map +0 -1
  289. package/dist/proxy/create-proxy.d.ts +0 -2
  290. package/dist/proxy/create-proxy.d.ts.map +0 -1
  291. package/dist/proxy/create-proxy.js +0 -11
  292. package/dist/proxy/create-proxy.js.map +0 -1
  293. package/dist/proxy/function-generator.d.ts +0 -9
  294. package/dist/proxy/function-generator.d.ts.map +0 -1
  295. package/dist/proxy/function-generator.js +0 -29
  296. package/dist/proxy/function-generator.js.map +0 -1
  297. package/dist/proxy/index.d.ts +0 -4
  298. package/dist/proxy/index.d.ts.map +0 -1
  299. package/dist/proxy/index.js +0 -4
  300. package/dist/proxy/index.js.map +0 -1
  301. package/dist/proxy/prompt.d.ts +0 -2
  302. package/dist/proxy/prompt.d.ts.map +0 -1
  303. package/dist/proxy/prompt.js +0 -6
  304. package/dist/proxy/prompt.js.map +0 -1
  305. package/dist/proxy/types.d.ts +0 -7
  306. package/dist/proxy/types.d.ts.map +0 -1
  307. package/dist/proxy/types.js +0 -2
  308. package/dist/proxy/types.js.map +0 -1
  309. package/dist/queue/manager.d.ts +0 -5
  310. package/dist/queue/manager.d.ts.map +0 -1
  311. package/dist/queue/manager.js +0 -37
  312. package/dist/queue/manager.js.map +0 -1
  313. package/dist/queue/manager.test.d.ts +0 -2
  314. package/dist/queue/manager.test.d.ts.map +0 -1
  315. package/dist/queue/manager.test.js +0 -52
  316. package/dist/queue/manager.test.js.map +0 -1
  317. package/dist/schema-converter.d.ts +0 -4
  318. package/dist/schema-converter.d.ts.map +0 -1
  319. package/dist/schema-converter.js +0 -30
  320. package/dist/schema-converter.js.map +0 -1
  321. package/dist/stream/index.d.ts +0 -7
  322. package/dist/stream/index.d.ts.map +0 -1
  323. package/dist/stream/index.js +0 -23
  324. package/dist/stream/index.js.map +0 -1
  325. package/dist/streaming/utils.d.ts +0 -4
  326. package/dist/streaming/utils.d.ts.map +0 -1
  327. package/dist/streaming/utils.js +0 -131
  328. package/dist/streaming/utils.js.map +0 -1
  329. package/dist/streaming/utils.test.d.ts +0 -2
  330. package/dist/streaming/utils.test.d.ts.map +0 -1
  331. package/dist/streaming/utils.test.js +0 -84
  332. package/dist/streaming/utils.test.js.map +0 -1
  333. package/dist/templates/result.d.ts +0 -7
  334. package/dist/templates/result.d.ts.map +0 -1
  335. package/dist/templates/result.js +0 -40
  336. package/dist/templates/result.js.map +0 -1
  337. package/dist/templates/result.test.d.ts +0 -2
  338. package/dist/templates/result.test.d.ts.map +0 -1
  339. package/dist/templates/result.test.js +0 -75
  340. package/dist/templates/result.test.js.map +0 -1
  341. package/dist/test/setup.d.ts +0 -2
  342. package/dist/test/setup.d.ts.map +0 -1
  343. package/dist/test/setup.js +0 -21
  344. package/dist/test/setup.js.map +0 -1
  345. package/dist/test-types.d.ts +0 -13
  346. package/dist/test-types.d.ts.map +0 -1
  347. package/dist/test-types.js +0 -55
  348. package/dist/test-types.js.map +0 -1
  349. package/dist/types/index.d.ts +0 -4
  350. package/dist/types/index.d.ts.map +0 -1
  351. package/dist/types/index.js +0 -4
  352. package/dist/types/index.js.map +0 -1
  353. package/dist/types/list.d.ts +0 -10
  354. package/dist/types/list.d.ts.map +0 -1
  355. package/dist/types/list.js +0 -2
  356. package/dist/types/list.js.map +0 -1
  357. package/dist/types/model.d.ts +0 -7
  358. package/dist/types/model.d.ts.map +0 -1
  359. package/dist/types/model.js +0 -2
  360. package/dist/types/model.js.map +0 -1
  361. package/dist/types/options.d.ts +0 -25
  362. package/dist/types/options.d.ts.map +0 -1
  363. package/dist/types/options.js +0 -2
  364. package/dist/types/options.js.map +0 -1
  365. package/dist/types/schema.d.ts +0 -5
  366. package/dist/types/schema.d.ts.map +0 -1
  367. package/dist/types/schema.js +0 -2
  368. package/dist/types/schema.js.map +0 -1
  369. package/dist/utils/__tests__/request-handler.test.d.ts +0 -2
  370. package/dist/utils/__tests__/request-handler.test.d.ts.map +0 -1
  371. package/dist/utils/__tests__/request-handler.test.js +0 -134
  372. package/dist/utils/__tests__/request-handler.test.js.map +0 -1
  373. package/dist/utils/__tests__/schema.test.d.ts +0 -2
  374. package/dist/utils/__tests__/schema.test.d.ts.map +0 -1
  375. package/dist/utils/__tests__/schema.test.js +0 -49
  376. package/dist/utils/__tests__/schema.test.js.map +0 -1
  377. package/dist/utils/__tests__/stream-progress.test.d.ts +0 -2
  378. package/dist/utils/__tests__/stream-progress.test.d.ts.map +0 -1
  379. package/dist/utils/__tests__/stream-progress.test.js +0 -85
  380. package/dist/utils/__tests__/stream-progress.test.js.map +0 -1
  381. package/dist/utils/index.d.ts +0 -2
  382. package/dist/utils/index.d.ts.map +0 -1
  383. package/dist/utils/index.js +0 -2
  384. package/dist/utils/index.js.map +0 -1
  385. package/dist/utils/request-handler.d.ts +0 -17
  386. package/dist/utils/request-handler.d.ts.map +0 -1
  387. package/dist/utils/request-handler.js +0 -105
  388. package/dist/utils/request-handler.js.map +0 -1
  389. package/dist/utils/schema.d.ts +0 -11
  390. package/dist/utils/schema.d.ts.map +0 -1
  391. package/dist/utils/schema.js +0 -51
  392. package/dist/utils/schema.js.map +0 -1
  393. package/dist/utils/stream-progress.d.ts +0 -17
  394. package/dist/utils/stream-progress.d.ts.map +0 -1
  395. package/dist/utils/stream-progress.js +0 -86
  396. package/dist/utils/stream-progress.js.map +0 -1
  397. package/dist/utils/validation.d.ts +0 -3
  398. package/dist/utils/validation.d.ts.map +0 -1
  399. package/dist/utils/validation.js +0 -30
  400. package/dist/utils/validation.js.map +0 -1
@@ -0,0 +1,375 @@
1
+ /**
2
+ * Anthropic Message Batches API Adapter
3
+ *
4
+ * Implements batch processing using Anthropic's Message Batches API:
5
+ * - 50% cost discount
6
+ * - 24-hour turnaround
7
+ * - Up to 10,000 requests per batch
8
+ *
9
+ * @see https://docs.anthropic.com/en/docs/build-with-claude/message-batches
10
+ *
11
+ * @packageDocumentation
12
+ */
13
+
14
+ import {
15
+ registerBatchAdapter,
16
+ type BatchAdapter,
17
+ type BatchItem,
18
+ type BatchJob,
19
+ type BatchQueueOptions,
20
+ type BatchResult,
21
+ type BatchSubmitResult,
22
+ type BatchStatus,
23
+ } from '../batch-queue.js'
24
+ import { schema as convertSchema } from '../schema.js'
25
+
26
+ // ============================================================================
27
+ // Types
28
+ // ============================================================================
29
+
30
+ interface AnthropicBatchRequest {
31
+ custom_id: string
32
+ params: {
33
+ model: string
34
+ max_tokens: number
35
+ messages: Array<{ role: string; content: string }>
36
+ system?: string
37
+ temperature?: number
38
+ tool_choice?: { type: 'tool'; name: string }
39
+ tools?: Array<{
40
+ name: string
41
+ description: string
42
+ input_schema: Record<string, unknown>
43
+ }>
44
+ }
45
+ }
46
+
47
+ interface AnthropicBatchResult {
48
+ custom_id: string
49
+ result: {
50
+ type: 'succeeded' | 'errored' | 'canceled' | 'expired'
51
+ message?: {
52
+ id: string
53
+ content: Array<{
54
+ type: 'text' | 'tool_use'
55
+ text?: string
56
+ name?: string
57
+ input?: unknown
58
+ }>
59
+ usage: {
60
+ input_tokens: number
61
+ output_tokens: number
62
+ }
63
+ }
64
+ error?: {
65
+ type: string
66
+ message: string
67
+ }
68
+ }
69
+ }
70
+
71
+ interface AnthropicBatch {
72
+ id: string
73
+ type: 'message_batch'
74
+ processing_status: 'in_progress' | 'ended'
75
+ request_counts: {
76
+ processing: number
77
+ succeeded: number
78
+ errored: number
79
+ canceled: number
80
+ expired: number
81
+ }
82
+ ended_at: string | null
83
+ created_at: string
84
+ expires_at: string
85
+ cancel_initiated_at: string | null
86
+ results_url: string | null
87
+ }
88
+
89
+ // ============================================================================
90
+ // Anthropic Client
91
+ // ============================================================================
92
+
93
+ let anthropicApiKey: string | undefined
94
+ let anthropicBaseUrl = 'https://api.anthropic.com/v1'
95
+ const ANTHROPIC_VERSION = '2023-06-01'
96
+ const ANTHROPIC_BETA = 'message-batches-2024-09-24'
97
+
98
+ /**
99
+ * Configure the Anthropic client
100
+ */
101
+ export function configureAnthropic(options: { apiKey?: string; baseUrl?: string }): void {
102
+ if (options.apiKey) anthropicApiKey = options.apiKey
103
+ if (options.baseUrl) anthropicBaseUrl = options.baseUrl
104
+ }
105
+
106
+ function getApiKey(): string {
107
+ const key = anthropicApiKey || process.env.ANTHROPIC_API_KEY
108
+ if (!key) {
109
+ throw new Error('Anthropic API key not configured. Set ANTHROPIC_API_KEY or call configureAnthropic()')
110
+ }
111
+ return key
112
+ }
113
+
114
+ async function anthropicRequest<T>(
115
+ method: 'GET' | 'POST',
116
+ path: string,
117
+ body?: unknown
118
+ ): Promise<T> {
119
+ const url = `${anthropicBaseUrl}${path}`
120
+ const response = await fetch(url, {
121
+ method,
122
+ headers: {
123
+ 'x-api-key': getApiKey(),
124
+ 'anthropic-version': ANTHROPIC_VERSION,
125
+ 'anthropic-beta': ANTHROPIC_BETA,
126
+ 'Content-Type': 'application/json',
127
+ },
128
+ body: body ? JSON.stringify(body) : undefined,
129
+ })
130
+
131
+ if (!response.ok) {
132
+ const error = await response.text()
133
+ throw new Error(`Anthropic API error: ${response.status} ${error}`)
134
+ }
135
+
136
+ return response.json()
137
+ }
138
+
139
+ // ============================================================================
140
+ // Status Mapping
141
+ // ============================================================================
142
+
143
+ function mapStatus(batch: AnthropicBatch): BatchStatus {
144
+ if (batch.cancel_initiated_at) {
145
+ return batch.processing_status === 'ended' ? 'cancelled' : 'cancelling'
146
+ }
147
+ if (batch.processing_status === 'ended') {
148
+ return 'completed'
149
+ }
150
+ return 'in_progress'
151
+ }
152
+
153
+ // ============================================================================
154
+ // Anthropic Batch Adapter
155
+ // ============================================================================
156
+
157
+ const anthropicAdapter: BatchAdapter = {
158
+ async submit(items: BatchItem[], options: BatchQueueOptions): Promise<BatchSubmitResult> {
159
+ const model = options.model || 'claude-sonnet-4-20250514'
160
+ const maxTokens = 4096
161
+
162
+ // Build batch requests
163
+ const requests: AnthropicBatchRequest[] = items.map((item) => {
164
+ const request: AnthropicBatchRequest = {
165
+ custom_id: item.id,
166
+ params: {
167
+ model,
168
+ max_tokens: item.options?.maxTokens || maxTokens,
169
+ messages: [{ role: 'user', content: item.prompt }],
170
+ system: item.options?.system,
171
+ temperature: item.options?.temperature,
172
+ },
173
+ }
174
+
175
+ // Add JSON schema as a tool if provided
176
+ if (item.schema) {
177
+ const zodSchema = convertSchema(item.schema)
178
+ const jsonSchema = zodToJsonSchema(zodSchema)
179
+
180
+ request.params.tools = [
181
+ {
182
+ name: 'structured_response',
183
+ description: 'Generate a structured response matching the schema',
184
+ input_schema: jsonSchema,
185
+ },
186
+ ]
187
+ request.params.tool_choice = { type: 'tool', name: 'structured_response' }
188
+ }
189
+
190
+ return request
191
+ })
192
+
193
+ // Create the batch
194
+ const batch = await anthropicRequest<AnthropicBatch>('POST', '/messages/batches', {
195
+ requests,
196
+ })
197
+
198
+ const job: BatchJob = {
199
+ id: batch.id,
200
+ provider: 'anthropic',
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,
208
+ }
209
+
210
+ // Create completion promise
211
+ const completion = this.waitForCompletion(batch.id)
212
+
213
+ return { job, completion }
214
+ },
215
+
216
+ async getStatus(batchId: string): Promise<BatchJob> {
217
+ 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
+ }
235
+ },
236
+
237
+ async cancel(batchId: string): Promise<void> {
238
+ await anthropicRequest('POST', `/messages/batches/${batchId}/cancel`)
239
+ },
240
+
241
+ async getResults(batchId: string): Promise<BatchResult[]> {
242
+ const status = await this.getStatus(batchId)
243
+
244
+ if (status.status !== 'completed' && status.status !== 'cancelled') {
245
+ throw new Error(`Batch not complete. Status: ${status.status}`)
246
+ }
247
+
248
+ // Fetch results (Anthropic returns them directly via the API)
249
+ const batch = await anthropicRequest<AnthropicBatch>('GET', `/messages/batches/${batchId}`)
250
+
251
+ if (!batch.results_url) {
252
+ throw new Error('No results URL available')
253
+ }
254
+
255
+ // Download results from the URL
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
+
264
+ if (!response.ok) {
265
+ throw new Error(`Failed to fetch results: ${response.status}`)
266
+ }
267
+
268
+ const content = await response.text()
269
+ const lines = content.trim().split('\n')
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
316
+ },
317
+
318
+ async waitForCompletion(batchId: string, pollInterval = 5000): Promise<BatchResult[]> {
319
+ while (true) {
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
+ }
328
+ },
329
+ }
330
+
331
+ // ============================================================================
332
+ // Helpers
333
+ // ============================================================================
334
+
335
+ /**
336
+ * Simple Zod to JSON Schema converter
337
+ */
338
+ function zodToJsonSchema(zodSchema: unknown): Record<string, unknown> {
339
+ const schema = zodSchema as { _def?: { typeName?: string; shape?: unknown } }
340
+
341
+ if (!schema._def) {
342
+ return { type: 'object' }
343
+ }
344
+
345
+ const typeName = schema._def.typeName
346
+
347
+ switch (typeName) {
348
+ case 'ZodString':
349
+ return { type: 'string' }
350
+ case 'ZodNumber':
351
+ return { type: 'number' }
352
+ case 'ZodBoolean':
353
+ return { type: 'boolean' }
354
+ case 'ZodArray':
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) }
363
+ }
364
+ default:
365
+ return { type: 'object' }
366
+ }
367
+ }
368
+
369
+ // ============================================================================
370
+ // Register Adapter
371
+ // ============================================================================
372
+
373
+ registerBatchAdapter('anthropic', anthropicAdapter)
374
+
375
+ export { anthropicAdapter }