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.
- package/.turbo/turbo-build.log +1 -1
- package/CHANGELOG.md +55 -1
- package/README.md +38 -0
- package/dist/ai-promise.d.ts +3 -3
- package/dist/ai-promise.d.ts.map +1 -1
- package/dist/ai-promise.js +135 -64
- 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 +51 -858
- 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.map +1 -1
- package/dist/budget.js +27 -14
- package/dist/budget.js.map +1 -1
- package/dist/cache.d.ts +23 -0
- package/dist/cache.d.ts.map +1 -1
- package/dist/cache.js +36 -15
- package/dist/cache.js.map +1 -1
- package/dist/context.d.ts +26 -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 +8 -0
- 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 -18
- package/dist/generate.js.map +1 -1
- package/dist/index.d.ts +18 -11
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +35 -18
- 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 +66 -1
- package/dist/retry.d.ts.map +1 -1
- package/dist/retry.js +115 -8
- package/dist/retry.js.map +1 -1
- package/dist/schema.js +2 -2
- 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 +66 -4
- package/dist/tool-orchestration.d.ts.map +1 -1
- package/dist/tool-orchestration.js +123 -23
- package/dist/tool-orchestration.js.map +1 -1
- 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 +28 -25
- package/src/ai-promise.ts +226 -140
- package/src/ai-schemas.ts +122 -0
- package/src/ai.ts +69 -1176
- 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 +31 -18
- package/src/cache.ts +45 -17
- package/src/context.ts +106 -77
- package/src/digital-objects-registry.ts +750 -0
- package/src/errors.ts +37 -0
- package/src/eval/runner.ts +60 -36
- 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 -28
- package/src/index.ts +119 -21
- 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 +144 -18
- package/src/schema.ts +8 -8
- package/src/telemetry.ts +403 -0
- package/src/template.ts +8 -4
- package/src/tool-orchestration.ts +213 -48
- 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/batch-autosubmit-errors.test.ts +49 -37
- package/test/batch-blog-posts.test.ts +87 -129
- 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/generate-core.test.ts +140 -229
- package/test/implicit-batch.test.ts +22 -65
- package/test/retry-policy-integration.test.ts +117 -0
- package/test/schema.test.ts +55 -19
- package/test/template.test.ts +1164 -0
- package/test/tool-orchestration.test.ts +270 -0
- package/test/wrap-for-v3.test.ts +612 -0
- package/vitest.config.js +6 -0
- package/vitest.config.ts +20 -0
- package/LICENSE +0 -21
- 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/types.ts
CHANGED
|
@@ -2,16 +2,106 @@
|
|
|
2
2
|
* Core types for AI functions
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
|
+
// ============================================================================
|
|
6
|
+
// Human Function Pending Types
|
|
7
|
+
// ============================================================================
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Symbol used to identify pending human function results
|
|
11
|
+
*/
|
|
12
|
+
export const PENDING_HUMAN_RESULT_SYMBOL = Symbol.for('HumanFunctionPending')
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Human interaction channels
|
|
16
|
+
*
|
|
17
|
+
* - chat: Real-time messaging (WebSocket, in-app)
|
|
18
|
+
* - email: Async email communication
|
|
19
|
+
* - phone: Voice calls
|
|
20
|
+
* - sms: SMS text messages
|
|
21
|
+
* - workspace: Team collaboration platforms (Slack, Teams, Discord)
|
|
22
|
+
* - web: Web-based interface (browser, web app)
|
|
23
|
+
*/
|
|
24
|
+
export type HumanChannel = 'chat' | 'email' | 'phone' | 'sms' | 'workspace' | 'web'
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Pending human function result returned when human input is not yet available.
|
|
28
|
+
*
|
|
29
|
+
* This is returned by human functions that need actual human input but are running
|
|
30
|
+
* in a placeholder mode (e.g., during testing or when channel integrations are not configured).
|
|
31
|
+
*
|
|
32
|
+
* Use `isPendingHumanResult()` to check if a result is pending before using it.
|
|
33
|
+
*
|
|
34
|
+
* @example
|
|
35
|
+
* ```ts
|
|
36
|
+
* const result = await approveRefund({ amount: 500, reason: 'Duplicate charge' })
|
|
37
|
+
*
|
|
38
|
+
* if (isPendingHumanResult(result)) {
|
|
39
|
+
* console.log('Waiting for human approval via:', result.channel)
|
|
40
|
+
* // Handle pending state - queue for later, show UI, etc.
|
|
41
|
+
* } else {
|
|
42
|
+
* // result is the actual TOutput type
|
|
43
|
+
* console.log('Approved:', result.approved)
|
|
44
|
+
* }
|
|
45
|
+
* ```
|
|
46
|
+
*/
|
|
47
|
+
export interface HumanFunctionPending<TExpected = unknown> {
|
|
48
|
+
/** Symbol marker for type identification */
|
|
49
|
+
readonly [PENDING_HUMAN_RESULT_SYMBOL]: true
|
|
50
|
+
/** Indicates this is a pending placeholder, not actual human response */
|
|
51
|
+
readonly _pending: true
|
|
52
|
+
/** The channel where human input was requested */
|
|
53
|
+
readonly channel: HumanChannel
|
|
54
|
+
/** Generated UI/content artifacts for the channel */
|
|
55
|
+
readonly artifacts: unknown
|
|
56
|
+
/** The expected response type schema */
|
|
57
|
+
readonly expectedResponseType: TExpected
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* Type guard to check if a result is a pending human function result.
|
|
62
|
+
*
|
|
63
|
+
* Use this to safely handle cases where human input is not yet available.
|
|
64
|
+
*
|
|
65
|
+
* @param value - The value to check
|
|
66
|
+
* @returns True if the value is a HumanFunctionPending object
|
|
67
|
+
*
|
|
68
|
+
* @example
|
|
69
|
+
* ```ts
|
|
70
|
+
* const result = await reviewDocument({ docId: '123' })
|
|
71
|
+
*
|
|
72
|
+
* if (isPendingHumanResult(result)) {
|
|
73
|
+
* // result is HumanFunctionPending - human input needed
|
|
74
|
+
* console.warn('Human review pending:', result.channel)
|
|
75
|
+
* return { status: 'pending', channel: result.channel }
|
|
76
|
+
* }
|
|
77
|
+
*
|
|
78
|
+
* // result is ReviewResult - actual human response
|
|
79
|
+
* return { status: 'reviewed', approved: result.approved }
|
|
80
|
+
* ```
|
|
81
|
+
*/
|
|
82
|
+
export function isPendingHumanResult<T>(
|
|
83
|
+
value: T | HumanFunctionPending
|
|
84
|
+
): value is HumanFunctionPending {
|
|
85
|
+
return (
|
|
86
|
+
value !== null &&
|
|
87
|
+
typeof value === 'object' &&
|
|
88
|
+
'_pending' in value &&
|
|
89
|
+
value._pending === true &&
|
|
90
|
+
PENDING_HUMAN_RESULT_SYMBOL in value
|
|
91
|
+
)
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
// ============================================================================
|
|
95
|
+
// AI Function Types
|
|
96
|
+
// ============================================================================
|
|
97
|
+
|
|
5
98
|
/**
|
|
6
99
|
* A function definition that can be called by AI
|
|
7
100
|
*
|
|
8
101
|
* @typeParam TOutput - The return type of the function handler
|
|
9
102
|
* @typeParam TInput - The input type accepted by the function handler
|
|
10
103
|
*/
|
|
11
|
-
export interface AIFunctionDefinition<
|
|
12
|
-
TOutput = unknown,
|
|
13
|
-
TInput = unknown
|
|
14
|
-
> {
|
|
104
|
+
export interface AIFunctionDefinition<TOutput = unknown, TInput = unknown> {
|
|
15
105
|
/** Unique name for the function */
|
|
16
106
|
name: string
|
|
17
107
|
/** Human-readable description for the AI */
|
|
@@ -162,9 +252,11 @@ export interface WriteOptions {
|
|
|
162
252
|
/**
|
|
163
253
|
* Type for functions that support both regular calls and tagged template literals
|
|
164
254
|
*/
|
|
165
|
-
export type TemplateFunction<TArgs extends unknown[], TReturn> =
|
|
166
|
-
|
|
167
|
-
|
|
255
|
+
export type TemplateFunction<TArgs extends unknown[], TReturn> = ((
|
|
256
|
+
prompt: string,
|
|
257
|
+
...args: TArgs
|
|
258
|
+
) => TReturn) &
|
|
259
|
+
((strings: TemplateStringsArray, ...values: unknown[]) => TReturn)
|
|
168
260
|
|
|
169
261
|
/**
|
|
170
262
|
* A single item in a list
|
|
@@ -210,18 +302,6 @@ export type CodeLanguage = 'typescript' | 'javascript' | 'python' | 'go' | 'rust
|
|
|
210
302
|
*/
|
|
211
303
|
export type GenerativeOutputType = 'string' | 'object' | 'image' | 'video'
|
|
212
304
|
|
|
213
|
-
/**
|
|
214
|
-
* Human interaction channels
|
|
215
|
-
*
|
|
216
|
-
* - chat: Real-time messaging (WebSocket, in-app)
|
|
217
|
-
* - email: Async email communication
|
|
218
|
-
* - phone: Voice calls
|
|
219
|
-
* - sms: SMS text messages
|
|
220
|
-
* - workspace: Team collaboration platforms (Slack, Teams, Discord)
|
|
221
|
-
* - web: Web-based interface (browser, web app)
|
|
222
|
-
*/
|
|
223
|
-
export type HumanChannel = 'chat' | 'email' | 'phone' | 'sms' | 'workspace' | 'web'
|
|
224
|
-
|
|
225
305
|
/**
|
|
226
306
|
* Legacy channel type for backwards compatibility
|
|
227
307
|
* @deprecated Use HumanChannel instead
|
|
@@ -273,12 +353,24 @@ export interface BaseFunctionDefinition<TOutput = unknown, TInput = unknown> {
|
|
|
273
353
|
}
|
|
274
354
|
|
|
275
355
|
/**
|
|
276
|
-
* Code function -
|
|
356
|
+
* Code function - a **deterministic** handler.
|
|
357
|
+
*
|
|
358
|
+
* `Code` is the deterministic kind: a fetch/transform/rule handler that runs
|
|
359
|
+
* the **same logic every time** with no model in the execution path. When
|
|
360
|
+
* called, it invokes the supplied {@link CodeFunctionDefinition.handler}
|
|
361
|
+
* (or evaluates the inline {@link CodeFunctionDefinition.code} body) and
|
|
362
|
+
* returns the result directly — no LLM is consulted at call time.
|
|
363
|
+
*
|
|
364
|
+
* This is the contract consumers bind to (e.g. ADR-0033's
|
|
365
|
+
* "Code = deterministic"). If you want a model to *author* code, that is a
|
|
366
|
+
* generation task: use {@link generateCode} / the `generate('code', …)`
|
|
367
|
+
* primitive, or define a `Generative` function whose output is source text.
|
|
368
|
+
* See the migration note in the package README.
|
|
277
369
|
*
|
|
278
|
-
*
|
|
279
|
-
*
|
|
280
|
-
*
|
|
281
|
-
*
|
|
370
|
+
* Exactly one of `handler` or `code` should be supplied. `handler` is the
|
|
371
|
+
* canonical form (a native function reference); `code` is an inline source
|
|
372
|
+
* body, deterministically compiled by the consumer's runtime — never sent to
|
|
373
|
+
* a model.
|
|
282
374
|
*
|
|
283
375
|
* @example
|
|
284
376
|
* ```ts
|
|
@@ -290,7 +382,7 @@ export interface BaseFunctionDefinition<TOutput = unknown, TInput = unknown> {
|
|
|
290
382
|
* rate: 'Tax rate as decimal (number)',
|
|
291
383
|
* },
|
|
292
384
|
* returnType: 'The calculated tax amount (number)',
|
|
293
|
-
*
|
|
385
|
+
* handler: ({ amount, rate }) => amount * rate,
|
|
294
386
|
* })
|
|
295
387
|
* ```
|
|
296
388
|
*
|
|
@@ -300,6 +392,51 @@ export interface BaseFunctionDefinition<TOutput = unknown, TInput = unknown> {
|
|
|
300
392
|
export interface CodeFunctionDefinition<TOutput = unknown, TInput = unknown>
|
|
301
393
|
extends BaseFunctionDefinition<TOutput, TInput> {
|
|
302
394
|
type: 'code'
|
|
395
|
+
/**
|
|
396
|
+
* The deterministic handler invoked on every call. Receives the parsed
|
|
397
|
+
* `args` and returns (or resolves to) the result. No LLM is involved.
|
|
398
|
+
*
|
|
399
|
+
* Either `handler` or {@link CodeFunctionDefinition.code} must be provided;
|
|
400
|
+
* `handler` takes precedence when both are present.
|
|
401
|
+
*/
|
|
402
|
+
handler?: (input: TInput) => TOutput | Promise<TOutput>
|
|
403
|
+
/**
|
|
404
|
+
* Inline source body for the handler, as a string. Deterministically
|
|
405
|
+
* compiled by the consumer's runtime (it is **not** generated by a model).
|
|
406
|
+
* Used when a handler cannot be passed by reference (e.g. a definition
|
|
407
|
+
* loaded from storage). The body receives the `args` in scope and should
|
|
408
|
+
* `return` the result.
|
|
409
|
+
*
|
|
410
|
+
* Either `code` or {@link CodeFunctionDefinition.handler} must be provided.
|
|
411
|
+
*/
|
|
412
|
+
code?: string
|
|
413
|
+
/** Target programming language of `code` (default: `'typescript'`). Metadata only. */
|
|
414
|
+
language?: CodeLanguage
|
|
415
|
+
/** Optional human-readable note about what the handler does. Metadata only. */
|
|
416
|
+
instructions?: string
|
|
417
|
+
}
|
|
418
|
+
|
|
419
|
+
/**
|
|
420
|
+
* Definition for a code-**authoring** request — the explicit, opt-in path for
|
|
421
|
+
* having a model *write* code. This is the behavior `type: 'code'` used to
|
|
422
|
+
* have implicitly; it has been split out so that `Code` can mean
|
|
423
|
+
* "deterministic handler" without a silent change of meaning.
|
|
424
|
+
*
|
|
425
|
+
* This is **not** part of the {@link FunctionDefinition} union and never
|
|
426
|
+
* executes deterministically — calling it consults a model. Drive it via
|
|
427
|
+
* {@link generateCode}.
|
|
428
|
+
*
|
|
429
|
+
* @typeParam TInput - The arguments schema describing the code to author
|
|
430
|
+
*/
|
|
431
|
+
export interface CodeGenerationDefinition<TInput = unknown> {
|
|
432
|
+
/** Name of the function/query to author */
|
|
433
|
+
name: string
|
|
434
|
+
/** Human-readable description of what the code should do */
|
|
435
|
+
description?: string
|
|
436
|
+
/** Arguments/spec schema describing the code to generate */
|
|
437
|
+
args: TInput
|
|
438
|
+
/** Return type schema the authored code should produce (optional) */
|
|
439
|
+
returnType?: unknown
|
|
303
440
|
/** Target programming language */
|
|
304
441
|
language?: CodeLanguage
|
|
305
442
|
/** Additional context or requirements for code generation */
|
|
@@ -308,6 +445,8 @@ export interface CodeFunctionDefinition<TOutput = unknown, TInput = unknown>
|
|
|
308
445
|
includeTests?: boolean
|
|
309
446
|
/** Whether to include example usage (default: true) */
|
|
310
447
|
includeExamples?: boolean
|
|
448
|
+
/** Model to use for authoring (defaults to 'sonnet') */
|
|
449
|
+
model?: string
|
|
311
450
|
}
|
|
312
451
|
|
|
313
452
|
/**
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* wrapForV3 — convenience composer for the v3 cascade-walker / evaluator-panel
|
|
3
|
+
* use case.
|
|
4
|
+
*
|
|
5
|
+
* Composes `cacheMiddleware`, `budgetMiddleware`, and `traceMiddleware` in a
|
|
6
|
+
* single `wrapLanguageModel` call so callers in services-as-software (round
|
|
7
|
+
* 15+ swap) can replace their existing post-hoc duck-typing in
|
|
8
|
+
* `cost-estimate.ts` with a single wrap call:
|
|
9
|
+
*
|
|
10
|
+
* ```ts
|
|
11
|
+
* import { wrapForV3, BudgetTracker, getEvalLogStore } from 'ai-functions'
|
|
12
|
+
*
|
|
13
|
+
* const tracker = new BudgetTracker({ maxCost: 1.0 })
|
|
14
|
+
* const store = getEvalLogStore()
|
|
15
|
+
*
|
|
16
|
+
* const wrapped = wrapForV3(openai('gpt-4o'), {
|
|
17
|
+
* cache: { store: 'disk', ttlMs: 86_400_000 },
|
|
18
|
+
* budget: { tracker },
|
|
19
|
+
* trace: { emit: (e) => store.record({ ...e, costUsd: e.costUsd ?? 0 }) },
|
|
20
|
+
* })
|
|
21
|
+
* ```
|
|
22
|
+
*
|
|
23
|
+
* **Composition order:**
|
|
24
|
+
* 1. **cache** — first so cache hits skip budget+trace network cost. The
|
|
25
|
+
* cached payload's usage still flows downstream so budget records the
|
|
26
|
+
* cost on hits AND misses.
|
|
27
|
+
* 2. **budget** — second so it sees the wrapped result regardless of
|
|
28
|
+
* cache hit/miss; tracker.recordUsage fires either way.
|
|
29
|
+
* 3. **trace** — last so the event sees the final outcome (post-cache,
|
|
30
|
+
* post-budget). Errors from `emit` are swallowed.
|
|
31
|
+
*
|
|
32
|
+
* AI SDK 6 ordering semantics (per the wrapLanguageModel JSDoc): "the first
|
|
33
|
+
* middleware will transform the input first, and the last middleware will
|
|
34
|
+
* be wrapped directly around the model." So when we hand the array
|
|
35
|
+
* `[cache, budget, trace]`, the runtime call order is
|
|
36
|
+
* `cache → budget → trace → model` on the way in, and the reverse on the
|
|
37
|
+
* way out. Cache sees the call first; if it has a hit, downstream layers
|
|
38
|
+
* never run their `wrapGenerate` body for that call. Budget and trace each
|
|
39
|
+
* get their own post-completion hook on the result the layer below them
|
|
40
|
+
* returned — so on a cache hit, neither budget nor trace runs (because
|
|
41
|
+
* cache short-circuits via `return cached`). To get budget + trace on
|
|
42
|
+
* cache hits, the budgetMiddleware/traceMiddleware would need to wrap the
|
|
43
|
+
* cache middleware (i.e. install AFTER it in the chain). Per the spec
|
|
44
|
+
* above, "later in the array = closer to the model" → install order
|
|
45
|
+
* matters: callers who want cache-hit cost recording should pass
|
|
46
|
+
* `[budget, trace, cache]`. We use `[cache, budget, trace]` as the default
|
|
47
|
+
* because the eval-fixture use case wants the 5x verify-time win and is
|
|
48
|
+
* happy to skip the cost record on the hit path (the original miss already
|
|
49
|
+
* recorded it).
|
|
50
|
+
*
|
|
51
|
+
* @packageDocumentation
|
|
52
|
+
*/
|
|
53
|
+
|
|
54
|
+
import { wrapLanguageModel, type LanguageModel } from 'ai'
|
|
55
|
+
import type { LanguageModelV3, LanguageModelV3Middleware } from '@ai-sdk/provider'
|
|
56
|
+
import { cacheMiddleware, type CacheMiddlewareOptions } from './middleware/cache.js'
|
|
57
|
+
import { budgetMiddleware, type BudgetMiddlewareOptions } from './middleware/budget.js'
|
|
58
|
+
import { traceMiddleware, type TraceMiddlewareOptions } from './middleware/trace.js'
|
|
59
|
+
|
|
60
|
+
// ============================================================================
|
|
61
|
+
// Types
|
|
62
|
+
// ============================================================================
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* Options for {@link wrapForV3}. All three middleware sections are
|
|
66
|
+
* optional — pass only what you need.
|
|
67
|
+
*/
|
|
68
|
+
export interface WrapForV3Options {
|
|
69
|
+
/** Cache config (see {@link CacheMiddlewareOptions}). */
|
|
70
|
+
cache?: CacheMiddlewareOptions
|
|
71
|
+
/** Budget tracking config (see {@link BudgetMiddlewareOptions}). */
|
|
72
|
+
budget?: BudgetMiddlewareOptions
|
|
73
|
+
/** Trace emission config (see {@link TraceMiddlewareOptions}). */
|
|
74
|
+
trace?: TraceMiddlewareOptions
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
// ============================================================================
|
|
78
|
+
// Composer
|
|
79
|
+
// ============================================================================
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
* Wrap a {@link LanguageModel} with the v3-cascade middleware stack
|
|
83
|
+
* (cache → budget → trace, in install order).
|
|
84
|
+
*
|
|
85
|
+
* Returns the wrapped model with the same shape as the input; downstream
|
|
86
|
+
* `generateText` / `generateObject` / `streamText` calls treat it as a
|
|
87
|
+
* regular model.
|
|
88
|
+
*
|
|
89
|
+
* @see WrapForV3Options for partial-config behaviour
|
|
90
|
+
*/
|
|
91
|
+
export function wrapForV3(model: LanguageModel, opts: WrapForV3Options = {}): LanguageModel {
|
|
92
|
+
const middleware: LanguageModelV3Middleware[] = []
|
|
93
|
+
if (opts.cache) middleware.push(cacheMiddleware(opts.cache))
|
|
94
|
+
if (opts.budget) middleware.push(budgetMiddleware(opts.budget))
|
|
95
|
+
if (opts.trace) middleware.push(traceMiddleware(opts.trace))
|
|
96
|
+
if (middleware.length === 0) return model
|
|
97
|
+
// wrapLanguageModel currently accepts LanguageModelV3 — at the AI SDK 6
|
|
98
|
+
// surface, `LanguageModel` is the wider union. The runtime is V3
|
|
99
|
+
// everywhere in the published providers; the cast is the same one the
|
|
100
|
+
// wrapLanguageModel cookbook uses.
|
|
101
|
+
return wrapLanguageModel({
|
|
102
|
+
model: model as LanguageModelV3,
|
|
103
|
+
middleware,
|
|
104
|
+
}) as LanguageModel
|
|
105
|
+
}
|