ai-functions 2.1.3 → 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.
Files changed (277) hide show
  1. package/.turbo/turbo-build.log +1 -1
  2. package/CHANGELOG.md +55 -1
  3. package/README.md +38 -0
  4. package/dist/ai-promise.d.ts +3 -3
  5. package/dist/ai-promise.d.ts.map +1 -1
  6. package/dist/ai-promise.js +135 -64
  7. package/dist/ai-promise.js.map +1 -1
  8. package/dist/ai-schemas.d.ts +56 -0
  9. package/dist/ai-schemas.d.ts.map +1 -0
  10. package/dist/ai-schemas.js +53 -0
  11. package/dist/ai-schemas.js.map +1 -0
  12. package/dist/ai.d.ts +16 -242
  13. package/dist/ai.d.ts.map +1 -1
  14. package/dist/ai.js +51 -858
  15. package/dist/ai.js.map +1 -1
  16. package/dist/batch/anthropic.d.ts +6 -4
  17. package/dist/batch/anthropic.d.ts.map +1 -1
  18. package/dist/batch/anthropic.js +83 -145
  19. package/dist/batch/anthropic.js.map +1 -1
  20. package/dist/batch/bedrock.d.ts +8 -30
  21. package/dist/batch/bedrock.d.ts.map +1 -1
  22. package/dist/batch/bedrock.js +155 -338
  23. package/dist/batch/bedrock.js.map +1 -1
  24. package/dist/batch/cloudflare.d.ts +8 -20
  25. package/dist/batch/cloudflare.d.ts.map +1 -1
  26. package/dist/batch/cloudflare.js +68 -189
  27. package/dist/batch/cloudflare.js.map +1 -1
  28. package/dist/batch/google.d.ts +6 -20
  29. package/dist/batch/google.d.ts.map +1 -1
  30. package/dist/batch/google.js +70 -238
  31. package/dist/batch/google.js.map +1 -1
  32. package/dist/batch/index.d.ts +4 -1
  33. package/dist/batch/index.d.ts.map +1 -1
  34. package/dist/batch/index.js +4 -1
  35. package/dist/batch/index.js.map +1 -1
  36. package/dist/batch/memory.d.ts +1 -1
  37. package/dist/batch/memory.d.ts.map +1 -1
  38. package/dist/batch/memory.js +14 -10
  39. package/dist/batch/memory.js.map +1 -1
  40. package/dist/batch/openai.d.ts +11 -14
  41. package/dist/batch/openai.d.ts.map +1 -1
  42. package/dist/batch/openai.js +52 -156
  43. package/dist/batch/openai.js.map +1 -1
  44. package/dist/batch/provider.d.ts +111 -0
  45. package/dist/batch/provider.d.ts.map +1 -0
  46. package/dist/batch/provider.js +233 -0
  47. package/dist/batch/provider.js.map +1 -0
  48. package/dist/batch-map.d.ts.map +1 -1
  49. package/dist/batch-map.js +23 -17
  50. package/dist/batch-map.js.map +1 -1
  51. package/dist/batch-queue.d.ts +65 -0
  52. package/dist/batch-queue.d.ts.map +1 -1
  53. package/dist/batch-queue.js +169 -14
  54. package/dist/batch-queue.js.map +1 -1
  55. package/dist/budget.d.ts.map +1 -1
  56. package/dist/budget.js +27 -14
  57. package/dist/budget.js.map +1 -1
  58. package/dist/cache.d.ts +23 -0
  59. package/dist/cache.d.ts.map +1 -1
  60. package/dist/cache.js +36 -15
  61. package/dist/cache.js.map +1 -1
  62. package/dist/context.d.ts +26 -8
  63. package/dist/context.d.ts.map +1 -1
  64. package/dist/context.js +64 -62
  65. package/dist/context.js.map +1 -1
  66. package/dist/digital-objects-registry.d.ts +229 -0
  67. package/dist/digital-objects-registry.d.ts.map +1 -0
  68. package/dist/digital-objects-registry.js +617 -0
  69. package/dist/digital-objects-registry.js.map +1 -0
  70. package/dist/embeddings.d.ts +2 -2
  71. package/dist/embeddings.d.ts.map +1 -1
  72. package/dist/errors.d.ts +22 -0
  73. package/dist/errors.d.ts.map +1 -0
  74. package/dist/errors.js +35 -0
  75. package/dist/errors.js.map +1 -0
  76. package/dist/eval/runner.d.ts +8 -0
  77. package/dist/eval/runner.d.ts.map +1 -1
  78. package/dist/eval/runner.js +41 -35
  79. package/dist/eval/runner.js.map +1 -1
  80. package/dist/eval-log/in-memory.d.ts +34 -0
  81. package/dist/eval-log/in-memory.d.ts.map +1 -0
  82. package/dist/eval-log/in-memory.js +84 -0
  83. package/dist/eval-log/in-memory.js.map +1 -0
  84. package/dist/eval-log/index.d.ts +29 -0
  85. package/dist/eval-log/index.d.ts.map +1 -0
  86. package/dist/eval-log/index.js +39 -0
  87. package/dist/eval-log/index.js.map +1 -0
  88. package/dist/eval-log/types.d.ts +101 -0
  89. package/dist/eval-log/types.d.ts.map +1 -0
  90. package/dist/eval-log/types.js +16 -0
  91. package/dist/eval-log/types.js.map +1 -0
  92. package/dist/function-registry.d.ts +116 -0
  93. package/dist/function-registry.d.ts.map +1 -0
  94. package/dist/function-registry.js +546 -0
  95. package/dist/function-registry.js.map +1 -0
  96. package/dist/generate.d.ts +9 -3
  97. package/dist/generate.d.ts.map +1 -1
  98. package/dist/generate.js +18 -18
  99. package/dist/generate.js.map +1 -1
  100. package/dist/index.d.ts +18 -11
  101. package/dist/index.d.ts.map +1 -1
  102. package/dist/index.js +35 -18
  103. package/dist/index.js.map +1 -1
  104. package/dist/logger.d.ts +118 -0
  105. package/dist/logger.d.ts.map +1 -0
  106. package/dist/logger.js +187 -0
  107. package/dist/logger.js.map +1 -0
  108. package/dist/middleware/budget.d.ts +84 -0
  109. package/dist/middleware/budget.d.ts.map +1 -0
  110. package/dist/middleware/budget.js +110 -0
  111. package/dist/middleware/budget.js.map +1 -0
  112. package/dist/middleware/cache.d.ts +103 -0
  113. package/dist/middleware/cache.d.ts.map +1 -0
  114. package/dist/middleware/cache.js +228 -0
  115. package/dist/middleware/cache.js.map +1 -0
  116. package/dist/middleware/embed-cache.d.ts +99 -0
  117. package/dist/middleware/embed-cache.d.ts.map +1 -0
  118. package/dist/middleware/embed-cache.js +128 -0
  119. package/dist/middleware/embed-cache.js.map +1 -0
  120. package/dist/middleware/index.d.ts +11 -0
  121. package/dist/middleware/index.d.ts.map +1 -0
  122. package/dist/middleware/index.js +11 -0
  123. package/dist/middleware/index.js.map +1 -0
  124. package/dist/middleware/trace.d.ts +103 -0
  125. package/dist/middleware/trace.d.ts.map +1 -0
  126. package/dist/middleware/trace.js +176 -0
  127. package/dist/middleware/trace.js.map +1 -0
  128. package/dist/primitives.d.ts +120 -1
  129. package/dist/primitives.d.ts.map +1 -1
  130. package/dist/primitives.js +398 -26
  131. package/dist/primitives.js.map +1 -1
  132. package/dist/retry.d.ts +66 -1
  133. package/dist/retry.d.ts.map +1 -1
  134. package/dist/retry.js +115 -8
  135. package/dist/retry.js.map +1 -1
  136. package/dist/schema.js +2 -2
  137. package/dist/schema.js.map +1 -1
  138. package/dist/telemetry.d.ts +128 -0
  139. package/dist/telemetry.d.ts.map +1 -0
  140. package/dist/telemetry.js +285 -0
  141. package/dist/telemetry.js.map +1 -0
  142. package/dist/template.d.ts.map +1 -1
  143. package/dist/template.js +6 -1
  144. package/dist/template.js.map +1 -1
  145. package/dist/tool-orchestration.d.ts +66 -4
  146. package/dist/tool-orchestration.d.ts.map +1 -1
  147. package/dist/tool-orchestration.js +123 -23
  148. package/dist/tool-orchestration.js.map +1 -1
  149. package/dist/type-guards.d.ts +28 -0
  150. package/dist/type-guards.d.ts.map +1 -0
  151. package/dist/type-guards.js +29 -0
  152. package/dist/type-guards.js.map +1 -0
  153. package/dist/types.d.ts +135 -17
  154. package/dist/types.d.ts.map +1 -1
  155. package/dist/types.js +36 -1
  156. package/dist/types.js.map +1 -1
  157. package/dist/wrap-for-v3.d.ts +80 -0
  158. package/dist/wrap-for-v3.d.ts.map +1 -0
  159. package/dist/wrap-for-v3.js +89 -0
  160. package/dist/wrap-for-v3.js.map +1 -0
  161. package/examples/00-quickstart.ts +232 -0
  162. package/examples/01-rag-chatbot.ts +212 -0
  163. package/examples/02-multi-agent-research.ts +290 -0
  164. package/examples/03-email-classification.ts +379 -0
  165. package/examples/04-content-moderation.ts +400 -0
  166. package/examples/05-document-extraction.ts +455 -0
  167. package/examples/06-streaming-chat-nextjs.ts +437 -0
  168. package/examples/07-cloudflare-worker.ts +483 -0
  169. package/examples/08-batch-processing.ts +491 -0
  170. package/examples/09-budget-constrained.ts +527 -0
  171. package/examples/10-tool-orchestration.ts +565 -0
  172. package/examples/11-retry-resilience.ts +403 -0
  173. package/examples/12-caching-strategies.ts +422 -0
  174. package/examples/README.md +145 -0
  175. package/package.json +28 -25
  176. package/src/ai-promise.ts +226 -140
  177. package/src/ai-schemas.ts +122 -0
  178. package/src/ai.ts +69 -1176
  179. package/src/batch/anthropic.ts +96 -161
  180. package/src/batch/bedrock.ts +203 -454
  181. package/src/batch/cloudflare.ts +99 -282
  182. package/src/batch/google.ts +91 -297
  183. package/src/batch/index.ts +4 -1
  184. package/src/batch/memory.ts +15 -10
  185. package/src/batch/openai.ts +65 -193
  186. package/src/batch/provider.ts +336 -0
  187. package/src/batch-map.ts +29 -24
  188. package/src/batch-queue.ts +200 -11
  189. package/src/budget.ts +31 -18
  190. package/src/cache.ts +45 -17
  191. package/src/context.ts +106 -77
  192. package/src/digital-objects-registry.ts +750 -0
  193. package/src/errors.ts +37 -0
  194. package/src/eval/runner.ts +60 -36
  195. package/src/eval-log/in-memory.ts +90 -0
  196. package/src/eval-log/index.ts +46 -0
  197. package/src/eval-log/types.ts +110 -0
  198. package/src/function-registry.ts +671 -0
  199. package/src/generate.ts +33 -28
  200. package/src/index.ts +119 -21
  201. package/src/logger.ts +232 -0
  202. package/src/middleware/budget.ts +171 -0
  203. package/src/middleware/cache.ts +299 -0
  204. package/src/middleware/embed-cache.ts +195 -0
  205. package/src/middleware/index.ts +23 -0
  206. package/src/middleware/trace.ts +248 -0
  207. package/src/primitives.ts +589 -62
  208. package/src/retry.ts +144 -18
  209. package/src/schema.ts +8 -8
  210. package/src/telemetry.ts +403 -0
  211. package/src/template.ts +8 -4
  212. package/src/tool-orchestration.ts +213 -48
  213. package/src/type-guards.ts +31 -0
  214. package/src/types.ts +164 -25
  215. package/src/wrap-for-v3.ts +105 -0
  216. package/test/ai-promise.test.ts +1080 -0
  217. package/test/ai-proxy.test.ts +1 -1
  218. package/test/batch-autosubmit-errors.test.ts +49 -37
  219. package/test/batch-blog-posts.test.ts +87 -129
  220. package/test/core-functions.test.ts +183 -579
  221. package/test/decide.test.ts +154 -322
  222. package/test/define.test.ts +211 -8
  223. package/test/digital-objects-registry.test.ts +760 -0
  224. package/test/embedding-cache-middleware.test.ts +140 -0
  225. package/test/generate-core.test.ts +140 -229
  226. package/test/implicit-batch.test.ts +22 -65
  227. package/test/retry-policy-integration.test.ts +117 -0
  228. package/test/schema.test.ts +55 -19
  229. package/test/template.test.ts +1164 -0
  230. package/test/tool-orchestration.test.ts +270 -0
  231. package/test/wrap-for-v3.test.ts +612 -0
  232. package/vitest.config.js +6 -0
  233. package/vitest.config.ts +20 -0
  234. package/LICENSE +0 -21
  235. package/dist/rpc/auth.d.ts +0 -69
  236. package/dist/rpc/auth.d.ts.map +0 -1
  237. package/dist/rpc/auth.js +0 -136
  238. package/dist/rpc/auth.js.map +0 -1
  239. package/dist/rpc/client.d.ts +0 -62
  240. package/dist/rpc/client.d.ts.map +0 -1
  241. package/dist/rpc/client.js +0 -103
  242. package/dist/rpc/client.js.map +0 -1
  243. package/dist/rpc/deferred.d.ts +0 -60
  244. package/dist/rpc/deferred.d.ts.map +0 -1
  245. package/dist/rpc/deferred.js +0 -96
  246. package/dist/rpc/deferred.js.map +0 -1
  247. package/dist/rpc/index.d.ts +0 -22
  248. package/dist/rpc/index.d.ts.map +0 -1
  249. package/dist/rpc/index.js +0 -38
  250. package/dist/rpc/index.js.map +0 -1
  251. package/dist/rpc/local.d.ts +0 -42
  252. package/dist/rpc/local.d.ts.map +0 -1
  253. package/dist/rpc/local.js +0 -50
  254. package/dist/rpc/local.js.map +0 -1
  255. package/dist/rpc/server.d.ts +0 -165
  256. package/dist/rpc/server.d.ts.map +0 -1
  257. package/dist/rpc/server.js +0 -405
  258. package/dist/rpc/server.js.map +0 -1
  259. package/dist/rpc/session.d.ts +0 -32
  260. package/dist/rpc/session.d.ts.map +0 -1
  261. package/dist/rpc/session.js +0 -43
  262. package/dist/rpc/session.js.map +0 -1
  263. package/dist/rpc/transport.d.ts +0 -306
  264. package/dist/rpc/transport.d.ts.map +0 -1
  265. package/dist/rpc/transport.js +0 -731
  266. package/dist/rpc/transport.js.map +0 -1
  267. package/src/batch/anthropic.js +0 -256
  268. package/src/batch/bedrock.js +0 -584
  269. package/src/batch/cloudflare.js +0 -287
  270. package/src/batch/google.js +0 -359
  271. package/src/batch/index.js +0 -30
  272. package/src/batch/memory.js +0 -187
  273. package/src/batch/openai.js +0 -402
  274. package/src/eval/index.js +0 -7
  275. package/src/eval/models.js +0 -119
  276. package/src/eval/runner.js +0 -147
  277. package/test/schema.test.js +0 -96
package/src/context.ts CHANGED
@@ -1,8 +1,8 @@
1
1
  /**
2
2
  * Execution Context for AI Functions
3
3
  *
4
- * Provides configuration without polluting function signatures.
5
- * Settings flow from environment global context local context.
4
+ * Standalone context module with batch processing and budget tracking features.
5
+ * Settings flow from environment -> global context -> local context.
6
6
  *
7
7
  * @example
8
8
  * ```ts
@@ -23,20 +23,41 @@
23
23
  * @packageDocumentation
24
24
  */
25
25
 
26
- import type { FunctionOptions } from './template.js'
27
26
  import type { BatchProvider } from './batch-queue.js'
28
- import type { BudgetConfig, RequestContext as IRequestContext, ModelPricing } from './budget.js'
27
+ import type { RequestContext as IRequestContext, ModelPricing } from './budget.js'
29
28
 
30
29
  // ============================================================================
31
- // Types
30
+ // Core Types (from template.ts equivalent)
31
+ // ============================================================================
32
+
33
+ /**
34
+ * Common options for all AI functions
35
+ */
36
+ export interface FunctionOptions {
37
+ /** Model to use (e.g., 'claude-opus-4-5', 'gpt-5-1', 'gemini-3-pro') */
38
+ model?: string
39
+ /** Thinking level: 'none', 'low', 'medium', 'high', or token budget number */
40
+ thinking?: 'none' | 'low' | 'medium' | 'high' | number
41
+ /** Temperature (0-2) */
42
+ temperature?: number
43
+ /** Maximum tokens to generate */
44
+ maxTokens?: number
45
+ /** System prompt */
46
+ system?: string
47
+ /** Processing mode */
48
+ mode?: 'default' | 'background'
49
+ }
50
+
51
+ // ============================================================================
52
+ // Extended Types for Batch Processing
32
53
  // ============================================================================
33
54
 
34
55
  /** Batch execution mode */
35
56
  export type BatchMode =
36
- | 'auto' // Smart selection: immediate < flexThreshold, flex < batchThreshold, batch above
37
- | 'immediate' // Execute immediately (concurrent requests, full price)
38
- | 'flex' // Use flex processing (faster than batch, ~50% discount, minutes)
39
- | 'deferred' // Always use provider batch API (50% discount, up to 24hr)
57
+ | 'auto' // Smart selection: immediate < flexThreshold, flex < batchThreshold, batch above
58
+ | 'immediate' // Execute immediately (concurrent requests, full price)
59
+ | 'flex' // Use flex processing (faster than batch, ~50% discount, minutes)
60
+ | 'deferred' // Always use provider batch API (50% discount, up to 24hr)
40
61
 
41
62
  /** Budget configuration for context */
42
63
  export interface ContextBudgetConfig {
@@ -50,10 +71,12 @@ export interface ContextBudgetConfig {
50
71
  customPricing?: Record<string, ModelPricing>
51
72
  }
52
73
 
53
- /** Execution context configuration */
74
+ /**
75
+ * Execution context with batch processing and budget features.
76
+ */
54
77
  export interface ExecutionContext extends FunctionOptions {
55
- /** Batch provider to use */
56
- provider?: BatchProvider
78
+ /** Provider to use (for model resolution) */
79
+ provider?: BatchProvider | string
57
80
  /** Batch execution mode */
58
81
  batchMode?: BatchMode
59
82
  /** Minimum items to use flex processing (for 'auto' mode, default: 5) */
@@ -120,18 +143,6 @@ let asyncLocalStorage: {
120
143
  // Lazy initialization of AsyncLocalStorage
121
144
  let asyncLocalStorageInitialized = false
122
145
 
123
- async function initAsyncLocalStorage(): Promise<void> {
124
- if (asyncLocalStorageInitialized) return
125
- asyncLocalStorageInitialized = true
126
-
127
- try {
128
- const { AsyncLocalStorage } = await import('async_hooks')
129
- asyncLocalStorage = new AsyncLocalStorage<ExecutionContext>()
130
- } catch {
131
- // Not in Node.js environment, use global context only
132
- }
133
- }
134
-
135
146
  // Initialize synchronously if possible (for Node.js environments)
136
147
  if (typeof process !== 'undefined' && process.versions?.node) {
137
148
  import('async_hooks')
@@ -144,16 +155,80 @@ if (typeof process !== 'undefined' && process.versions?.node) {
144
155
  })
145
156
  }
146
157
 
158
+ // ============================================================================
159
+ // Environment Defaults
160
+ // ============================================================================
161
+
162
+ function getEnvContext(): ExecutionContext {
163
+ if (typeof process === 'undefined') return {}
164
+
165
+ const context: ExecutionContext = {}
166
+
167
+ // Model defaults
168
+ if (process.env['AI_MODEL']) {
169
+ context.model = process.env['AI_MODEL']
170
+ }
171
+
172
+ // Provider defaults
173
+ if (process.env['AI_PROVIDER']) {
174
+ context.provider = process.env['AI_PROVIDER']
175
+ } else if (process.env['ANTHROPIC_API_KEY'] && !process.env['OPENAI_API_KEY']) {
176
+ context.provider = 'anthropic'
177
+ } else if (process.env['OPENAI_API_KEY']) {
178
+ context.provider = 'openai'
179
+ } else if (process.env['CLOUDFLARE_API_TOKEN']) {
180
+ context.provider = 'cloudflare'
181
+ } else if (process.env['AWS_ACCESS_KEY_ID']) {
182
+ context.provider = 'bedrock'
183
+ }
184
+
185
+ return context
186
+ }
187
+
188
+ function getEnvBatchContext(): Partial<ExecutionContext> {
189
+ if (typeof process === 'undefined') return {}
190
+
191
+ const context: Partial<ExecutionContext> = {}
192
+
193
+ // Batch mode
194
+ if (process.env['AI_BATCH_MODE']) {
195
+ context.batchMode = process.env['AI_BATCH_MODE'] as BatchMode
196
+ }
197
+
198
+ // Flex threshold (when to start using flex processing)
199
+ if (process.env['AI_FLEX_THRESHOLD']) {
200
+ context.flexThreshold = parseInt(process.env['AI_FLEX_THRESHOLD'], 10)
201
+ }
202
+
203
+ // Batch threshold (when to switch from flex to full batch)
204
+ if (process.env['AI_BATCH_THRESHOLD']) {
205
+ context.batchThreshold = parseInt(process.env['AI_BATCH_THRESHOLD'], 10)
206
+ }
207
+
208
+ // Webhook URL
209
+ if (process.env['AI_BATCH_WEBHOOK_URL']) {
210
+ context.webhookUrl = process.env['AI_BATCH_WEBHOOK_URL']
211
+ }
212
+
213
+ return context
214
+ }
215
+
216
+ // ============================================================================
217
+ // Context Functions
218
+ // ============================================================================
219
+
147
220
  /**
148
221
  * Get the current execution context
149
- * Merges: environment defaults global context local context
222
+ * Merges: environment defaults -> global context -> local context
150
223
  */
151
224
  export function getContext(): ExecutionContext {
152
225
  const envContext = getEnvContext()
226
+ const envBatchContext = getEnvBatchContext()
153
227
  const localContext = asyncLocalStorage?.getStore()
154
228
 
155
229
  return {
156
230
  ...envContext,
231
+ ...envBatchContext,
157
232
  ...globalContext,
158
233
  ...localContext,
159
234
  }
@@ -190,56 +265,6 @@ export function withContext<T>(
190
265
  }
191
266
  }
192
267
 
193
- // ============================================================================
194
- // Environment Defaults
195
- // ============================================================================
196
-
197
- function getEnvContext(): ExecutionContext {
198
- if (typeof process === 'undefined') return {}
199
-
200
- const context: ExecutionContext = {}
201
-
202
- // Model defaults
203
- if (process.env.AI_MODEL) {
204
- context.model = process.env.AI_MODEL
205
- }
206
-
207
- // Provider defaults
208
- if (process.env.AI_PROVIDER) {
209
- context.provider = process.env.AI_PROVIDER as BatchProvider
210
- } else if (process.env.ANTHROPIC_API_KEY && !process.env.OPENAI_API_KEY) {
211
- context.provider = 'anthropic'
212
- } else if (process.env.OPENAI_API_KEY) {
213
- context.provider = 'openai'
214
- } else if (process.env.CLOUDFLARE_API_TOKEN) {
215
- context.provider = 'cloudflare'
216
- } else if (process.env.AWS_ACCESS_KEY_ID) {
217
- context.provider = 'bedrock'
218
- }
219
-
220
- // Batch mode
221
- if (process.env.AI_BATCH_MODE) {
222
- context.batchMode = process.env.AI_BATCH_MODE as BatchMode
223
- }
224
-
225
- // Flex threshold (when to start using flex processing)
226
- if (process.env.AI_FLEX_THRESHOLD) {
227
- context.flexThreshold = parseInt(process.env.AI_FLEX_THRESHOLD, 10)
228
- }
229
-
230
- // Batch threshold (when to switch from flex to full batch)
231
- if (process.env.AI_BATCH_THRESHOLD) {
232
- context.batchThreshold = parseInt(process.env.AI_BATCH_THRESHOLD, 10)
233
- }
234
-
235
- // Webhook URL
236
- if (process.env.AI_BATCH_WEBHOOK_URL) {
237
- context.webhookUrl = process.env.AI_BATCH_WEBHOOK_URL
238
- }
239
-
240
- return context
241
- }
242
-
243
268
  // ============================================================================
244
269
  // Context Helpers
245
270
  // ============================================================================
@@ -253,13 +278,17 @@ export function getModel(): string {
253
278
  }
254
279
 
255
280
  /**
256
- * Get the effective provider from context
281
+ * Get the effective provider from context (typed as BatchProvider)
257
282
  */
258
283
  export function getProvider(): BatchProvider {
259
284
  const ctx = getContext()
260
- return ctx.provider || 'openai'
285
+ return (ctx.provider || 'openai') as BatchProvider
261
286
  }
262
287
 
288
+ // ============================================================================
289
+ // Batch-Specific Context Helpers
290
+ // ============================================================================
291
+
263
292
  /**
264
293
  * Get the effective batch mode from context
265
294
  */