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/.turbo/turbo-build.log
CHANGED
package/CHANGELOG.md
CHANGED
|
@@ -1,10 +1,62 @@
|
|
|
1
1
|
# ai-functions
|
|
2
2
|
|
|
3
|
+
## 2.3.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- 9e2779a: Make `kind: 'code'` deterministic.
|
|
8
|
+
|
|
9
|
+
Previously `defineFunction({ type: 'code' })` LLM-**generated** code at call time. A `CodeFunctionDefinition` now carries a deterministic `handler: (input) => output` (or an inline `code` string body), and `executeCodeFunction` runs it with **no model in the call path**. This aligns `Code` with the documented "Code = deterministic" contract (a fetch/transform/rule handler), keeping `Generative` / `Agentic` / `Human` semantics intact.
|
|
10
|
+
|
|
11
|
+
The code-**authoring** behavior (have a model write code) is preserved but moved to an explicit, opt-in path so the change is not silent:
|
|
12
|
+
|
|
13
|
+
- New `generateCode(definition, args)` export — returns generated source as a string.
|
|
14
|
+
- New `CodeGenerationDefinition` type for that path.
|
|
15
|
+
- `define.code(...)` now defines a deterministic handler function.
|
|
16
|
+
- Auto-define (`define(name, args)`) authors a self-contained body once at define time and carries it as an inline `code` body, so the resulting function is deterministic on every call.
|
|
17
|
+
- The `generate('code', prompt)` primitive is unchanged (a string-prompt code-authoring helper, distinct from the `FunctionDefinition` union).
|
|
18
|
+
|
|
19
|
+
`CodeFunctionDefinition` drops `includeTests` / `includeExamples` (relocated to `CodeGenerationDefinition`). The four `*FunctionDefinition` shapes and the `FunctionDefinition` union remain source-compatible for consumers binding to the type surface.
|
|
20
|
+
|
|
21
|
+
### Patch Changes
|
|
22
|
+
|
|
23
|
+
- Updated dependencies [2787830]
|
|
24
|
+
- language-models@2.3.0
|
|
25
|
+
- ai-providers@2.3.0
|
|
26
|
+
- @org.ai/types@2.3.0
|
|
27
|
+
|
|
28
|
+
## 2.2.0
|
|
29
|
+
|
|
30
|
+
### Minor Changes
|
|
31
|
+
|
|
32
|
+
- Make `kind: 'code'` deterministic. A `CodeFunctionDefinition` now carries a
|
|
33
|
+
deterministic `handler: (input) => output` (or an inline `code` string body)
|
|
34
|
+
and `executeCodeFunction` runs it with **no model in the call path** — the
|
|
35
|
+
documented "Code = deterministic" contract. The previous call-time code
|
|
36
|
+
_generation_ behavior is preserved but moved to an explicit opt-in path: the
|
|
37
|
+
new `generateCode()` export (+ `CodeGenerationDefinition` type). `define.code`
|
|
38
|
+
now defines a handler; auto-define authors a body once at define time and
|
|
39
|
+
carries it as inline `code`. `Generative` / `Agentic` / `Human` semantics are
|
|
40
|
+
unchanged; the `generate('code', prompt)` primitive is unchanged.
|
|
41
|
+
`CodeFunctionDefinition` drops `includeTests` / `includeExamples` (relocated
|
|
42
|
+
to `CodeGenerationDefinition`).
|
|
43
|
+
- Deepen `language-models` with per-model resilience and tier policy data
|
|
44
|
+
(aip-70mk). The `ModelPolicy` MDXLD type (`$type: 'ModelPolicy'`) and
|
|
45
|
+
`policyFor()` derivation layer now live in `language-models`. The runtime
|
|
46
|
+
machinery in `ai-functions` (`RetryPolicy`, `CircuitBreaker`,
|
|
47
|
+
`FallbackChain`) gains `forModel(alias)` factories that read policy from
|
|
48
|
+
the catalog. Default behaviour is preserved when no alias is provided.
|
|
49
|
+
- New helpers: `tiersForModel(alias)`, `modelSupportsTier(alias, tier)`,
|
|
50
|
+
re-exported `modelPolicyFor` (alias for `policyFor`).
|
|
51
|
+
- New types re-exported: `ModelPolicy`, `BatchTier`, `RetryPolicyData`,
|
|
52
|
+
`CircuitBreakerPolicyData`, `ErrorCategoryName`, `FlexAdapter`.
|
|
53
|
+
|
|
3
54
|
## 2.1.3
|
|
4
55
|
|
|
5
56
|
### Patch Changes
|
|
6
57
|
|
|
7
58
|
- Documentation and testing improvements
|
|
59
|
+
|
|
8
60
|
- Add deterministic AI testing suite with self-validating patterns
|
|
9
61
|
- Apply StoryBrand narrative to all package READMEs
|
|
10
62
|
- Update TESTING.md with four principles of deterministic AI testing
|
|
@@ -20,12 +72,14 @@
|
|
|
20
72
|
### Patch Changes
|
|
21
73
|
|
|
22
74
|
- 6beb531: Add TDD RED phase tests for type system unification
|
|
75
|
+
|
|
23
76
|
- ai-functions: Add tests for AIFunction<Output, Input> generic order flip
|
|
24
77
|
- ai-workflows: Add tests for EventHandler<TOutput, TInput> order and OnProxy/EveryProxy autocomplete
|
|
25
78
|
- ai-database: Existing package - no changes in this release
|
|
26
|
-
- @
|
|
79
|
+
- @org.ai/types: New shared types package with failing tests for RED phase
|
|
27
80
|
|
|
28
81
|
These tests document the expected behavior for the GREEN phase implementation where generic type parameters will be reordered to put Output first (matching Promise<T> convention).
|
|
82
|
+
|
|
29
83
|
- ai-providers@2.1.1
|
|
30
84
|
- language-models@2.1.1
|
|
31
85
|
|
package/README.md
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
# ai-functions
|
|
2
2
|
|
|
3
|
+

|
|
4
|
+
|
|
3
5
|
**Calling AI models shouldn't require 50 lines of boilerplate.**
|
|
4
6
|
|
|
5
7
|
You just want to get a response from Claude, GPT, or Gemini. Instead, you're drowning in SDK initialization, error handling, retry logic, JSON parsing, and type coercion. Every AI call becomes a small engineering project.
|
|
@@ -386,6 +388,42 @@ const trip = await planTrip.call({ destination: 'Paris', travelers: 4 })
|
|
|
386
388
|
const summary = await summarize.call({ text: longArticle, maxLength: 100 })
|
|
387
389
|
```
|
|
388
390
|
|
|
391
|
+
### The four Function kinds
|
|
392
|
+
|
|
393
|
+
`defineFunction` accepts a discriminated union (`FunctionDefinition`). Each `type` has a distinct execution contract:
|
|
394
|
+
|
|
395
|
+
| `type` | Meaning | At call time |
|
|
396
|
+
|--------|---------|--------------|
|
|
397
|
+
| `code` | **Deterministic handler** — a fetch/transform/rule | Runs your `handler` (or inline `code` body). **No model.** |
|
|
398
|
+
| `generative` | One-shot generation | `generateObject` / `generateText` |
|
|
399
|
+
| `agentic` | Plan-execute-observe tool loop | Iterative model + tool calls |
|
|
400
|
+
| `human` | Human/approval step | Generates channel UI, returns a pending result |
|
|
401
|
+
|
|
402
|
+
```typescript
|
|
403
|
+
// Code = deterministic. Supply a handler (or an inline `code` string).
|
|
404
|
+
const calculateTax = defineFunction({
|
|
405
|
+
type: 'code',
|
|
406
|
+
name: 'calculateTax',
|
|
407
|
+
args: { amount: 'Amount (number)', rate: 'Rate (number)' },
|
|
408
|
+
handler: ({ amount, rate }) => amount * rate, // runs every call, no LLM
|
|
409
|
+
})
|
|
410
|
+
await calculateTax.call({ amount: 100, rate: 0.2 }) // => 20
|
|
411
|
+
```
|
|
412
|
+
|
|
413
|
+
> **Migration (breaking, as of this release):** previously `type: 'code'` LLM-**generated** code at call time. `Code` is now **deterministic** — it requires a `handler` or inline `code` body and never calls a model. A `code` function with neither now throws.
|
|
414
|
+
>
|
|
415
|
+
> If you relied on the old behavior (have a model *author* code), use the new explicit `generateCode()` export, or a `generative` function whose output is source text:
|
|
416
|
+
>
|
|
417
|
+
> ```typescript
|
|
418
|
+
> import { generateCode } from 'ai-functions'
|
|
419
|
+
> const src = await generateCode(
|
|
420
|
+
> { name: 'fib', args: { n: '(number)' }, language: 'typescript' },
|
|
421
|
+
> { n: 10 }
|
|
422
|
+
> ) // => string of generated source
|
|
423
|
+
> ```
|
|
424
|
+
>
|
|
425
|
+
> The `generate('code', prompt)` primitive is unchanged — it is a string-prompt code-authoring helper, distinct from the `FunctionDefinition` union.
|
|
426
|
+
|
|
389
427
|
## API Reference
|
|
390
428
|
|
|
391
429
|
### Core Primitives
|
package/dist/ai-promise.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* AIPromise -
|
|
2
|
+
* AIPromise - Promise pipelining for AI functions
|
|
3
3
|
*
|
|
4
|
-
*
|
|
4
|
+
* This enables:
|
|
5
5
|
* - Property access tracking for dynamic schema inference
|
|
6
6
|
* - Promise pipelining without await
|
|
7
7
|
* - Magical .map() for batch processing
|
|
@@ -76,7 +76,7 @@ export interface AIPromiseOptions extends FunctionOptions {
|
|
|
76
76
|
propertyPath?: string[];
|
|
77
77
|
}
|
|
78
78
|
/**
|
|
79
|
-
* AIPromise -
|
|
79
|
+
* AIPromise - Promise wrapper for AI functions
|
|
80
80
|
*
|
|
81
81
|
* Acts as both a Promise AND a stub that:
|
|
82
82
|
* - Tracks property accesses for dynamic schema inference
|
package/dist/ai-promise.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ai-promise.d.ts","sourceRoot":"","sources":["../src/ai-promise.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AAGH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AAC/C,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,eAAe,CAAA;AACpD,OAAO,EAKL,eAAe,EAChB,MAAM,gBAAgB,CAAA;AAOvB;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,oCAAoC;IACpC,WAAW,CAAC,EAAE,WAAW,CAAA;CAC1B;AAED;;;GAGG;AACH,MAAM,WAAW,kBAAkB,CAAC,CAAC,
|
|
1
|
+
{"version":3,"file":"ai-promise.d.ts","sourceRoot":"","sources":["../src/ai-promise.ts"],"names":[],"mappings":"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"}
|
package/dist/ai-promise.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* AIPromise -
|
|
2
|
+
* AIPromise - Promise pipelining for AI functions
|
|
3
3
|
*
|
|
4
|
-
*
|
|
4
|
+
* This enables:
|
|
5
5
|
* - Property access tracking for dynamic schema inference
|
|
6
6
|
* - Promise pipelining without await
|
|
7
7
|
* - Magical .map() for batch processing
|
|
@@ -54,7 +54,7 @@ let resolutionScheduled = false;
|
|
|
54
54
|
// AIPromise Implementation
|
|
55
55
|
// ============================================================================
|
|
56
56
|
/**
|
|
57
|
-
* AIPromise -
|
|
57
|
+
* AIPromise - Promise wrapper for AI functions
|
|
58
58
|
*
|
|
59
59
|
* Acts as both a Promise AND a stub that:
|
|
60
60
|
* - Tracks property accesses for dynamic schema inference
|
|
@@ -150,19 +150,25 @@ export class AIPromise {
|
|
|
150
150
|
model: this._options.model || 'sonnet',
|
|
151
151
|
schema,
|
|
152
152
|
prompt: finalPrompt,
|
|
153
|
-
system: this._options.system,
|
|
154
|
-
temperature: this._options.temperature,
|
|
155
|
-
maxTokens: this._options.maxTokens,
|
|
153
|
+
...(this._options.system !== undefined && { system: this._options.system }),
|
|
154
|
+
...(this._options.temperature !== undefined && { temperature: this._options.temperature }),
|
|
155
|
+
...(this._options.maxTokens !== undefined && { maxTokens: this._options.maxTokens }),
|
|
156
156
|
});
|
|
157
157
|
// Extract the value based on type
|
|
158
158
|
// Type assertions here are safe because:
|
|
159
159
|
// 1. Runtime type checking validates the response structure
|
|
160
160
|
// 2. The type parameter T corresponds to the expected output type for each mode
|
|
161
161
|
let value = result.object;
|
|
162
|
-
if (this._options.type === 'text' &&
|
|
162
|
+
if (this._options.type === 'text' &&
|
|
163
|
+
typeof value === 'object' &&
|
|
164
|
+
value !== null &&
|
|
165
|
+
'text' in value) {
|
|
163
166
|
value = value.text;
|
|
164
167
|
}
|
|
165
|
-
else if (this._options.type === 'boolean' &&
|
|
168
|
+
else if (this._options.type === 'boolean' &&
|
|
169
|
+
typeof value === 'object' &&
|
|
170
|
+
value !== null &&
|
|
171
|
+
'answer' in value) {
|
|
166
172
|
const answer = value.answer;
|
|
167
173
|
// When type === 'boolean', T is constrained to boolean at the call site.
|
|
168
174
|
// TypeScript can't express this dependent relationship, so we use a simple cast.
|
|
@@ -170,7 +176,10 @@ export class AIPromise {
|
|
|
170
176
|
const booleanValue = answer === 'true' || answer === true;
|
|
171
177
|
value = booleanValue;
|
|
172
178
|
}
|
|
173
|
-
else if ((this._options.type === 'list' || this._options.type === 'extract') &&
|
|
179
|
+
else if ((this._options.type === 'list' || this._options.type === 'extract') &&
|
|
180
|
+
typeof value === 'object' &&
|
|
181
|
+
value !== null &&
|
|
182
|
+
'items' in value) {
|
|
174
183
|
value = value.items;
|
|
175
184
|
}
|
|
176
185
|
this._resolvedValue = value;
|
|
@@ -193,7 +202,11 @@ export class AIPromise {
|
|
|
193
202
|
case 'list':
|
|
194
203
|
return { items: ['List items'] };
|
|
195
204
|
case 'extract':
|
|
196
|
-
return {
|
|
205
|
+
return {
|
|
206
|
+
items: [
|
|
207
|
+
'Array of extracted items as strings - extract ALL matching items from the text',
|
|
208
|
+
],
|
|
209
|
+
};
|
|
197
210
|
case 'lists':
|
|
198
211
|
return { categories: ['Category names'], data: 'JSON object with categorized lists' };
|
|
199
212
|
case 'boolean':
|
|
@@ -268,17 +281,23 @@ export class AIPromise {
|
|
|
268
281
|
// Create a wrapper that resolves this promise first, then maps
|
|
269
282
|
const mapPromise = new BatchMapPromise([], [], {});
|
|
270
283
|
// Override the resolve to first get the list items
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
284
|
+
// Type assertion: BatchMapPromise.resolve is a public method that we're replacing
|
|
285
|
+
// with a compatible async function returning Promise<U[]>
|
|
286
|
+
const self = this;
|
|
287
|
+
Object.defineProperty(mapPromise, 'resolve', {
|
|
288
|
+
value: async function () {
|
|
289
|
+
// First, resolve the list
|
|
290
|
+
const items = await self.resolve();
|
|
291
|
+
if (!Array.isArray(items)) {
|
|
292
|
+
throw new Error('Cannot map over non-array result');
|
|
293
|
+
}
|
|
294
|
+
// Now create the actual batch map with the resolved items
|
|
295
|
+
const actualBatchMap = createBatchMap(items, callback);
|
|
296
|
+
return actualBatchMap.resolve();
|
|
297
|
+
},
|
|
298
|
+
writable: true,
|
|
299
|
+
configurable: true,
|
|
300
|
+
});
|
|
282
301
|
return mapPromise;
|
|
283
302
|
}
|
|
284
303
|
/**
|
|
@@ -295,26 +314,36 @@ export class AIPromise {
|
|
|
295
314
|
*/
|
|
296
315
|
mapImmediate(callback) {
|
|
297
316
|
const mapPromise = new BatchMapPromise([], [], { immediate: true });
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
317
|
+
const self = this;
|
|
318
|
+
Object.defineProperty(mapPromise, 'resolve', {
|
|
319
|
+
value: async function () {
|
|
320
|
+
const items = await self.resolve();
|
|
321
|
+
if (!Array.isArray(items)) {
|
|
322
|
+
throw new Error('Cannot map over non-array result');
|
|
323
|
+
}
|
|
324
|
+
const actualBatchMap = createBatchMap(items, callback, { immediate: true });
|
|
325
|
+
return actualBatchMap.resolve();
|
|
326
|
+
},
|
|
327
|
+
writable: true,
|
|
328
|
+
configurable: true,
|
|
329
|
+
});
|
|
306
330
|
return mapPromise;
|
|
307
331
|
}
|
|
308
332
|
mapDeferred(callback) {
|
|
309
333
|
const mapPromise = new BatchMapPromise([], [], { deferred: true });
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
334
|
+
const self = this;
|
|
335
|
+
Object.defineProperty(mapPromise, 'resolve', {
|
|
336
|
+
value: async function () {
|
|
337
|
+
const items = await self.resolve();
|
|
338
|
+
if (!Array.isArray(items)) {
|
|
339
|
+
throw new Error('Cannot map over non-array result');
|
|
340
|
+
}
|
|
341
|
+
const actualBatchMap = createBatchMap(items, callback, { deferred: true });
|
|
342
|
+
return actualBatchMap.resolve();
|
|
343
|
+
},
|
|
344
|
+
writable: true,
|
|
345
|
+
configurable: true,
|
|
346
|
+
});
|
|
318
347
|
return mapPromise;
|
|
319
348
|
}
|
|
320
349
|
/**
|
|
@@ -335,6 +364,7 @@ export class AIPromise {
|
|
|
335
364
|
}
|
|
336
365
|
}
|
|
337
366
|
else {
|
|
367
|
+
// When T is not an array, the conditional type T extends (infer I)[] ? I : T resolves to T
|
|
338
368
|
await callback(items, 0);
|
|
339
369
|
}
|
|
340
370
|
}
|
|
@@ -345,10 +375,12 @@ export class AIPromise {
|
|
|
345
375
|
const items = await this.resolve();
|
|
346
376
|
if (Array.isArray(items)) {
|
|
347
377
|
for (const item of items) {
|
|
378
|
+
// Each array item is the inferred element type I when T extends I[]
|
|
348
379
|
yield item;
|
|
349
380
|
}
|
|
350
381
|
}
|
|
351
382
|
else {
|
|
383
|
+
// When T is not an array, the item type is T itself
|
|
352
384
|
yield items;
|
|
353
385
|
}
|
|
354
386
|
}
|
|
@@ -423,7 +455,7 @@ export class AIPromise {
|
|
|
423
455
|
// Proxy Handlers
|
|
424
456
|
// ============================================================================
|
|
425
457
|
const PROXY_HANDLERS = {
|
|
426
|
-
get(target, prop,
|
|
458
|
+
get(target, prop, _receiver) {
|
|
427
459
|
// Handle symbols
|
|
428
460
|
if (typeof prop === 'symbol') {
|
|
429
461
|
if (prop === AI_PROMISE_SYMBOL)
|
|
@@ -436,14 +468,26 @@ const PROXY_HANDLERS = {
|
|
|
436
468
|
}
|
|
437
469
|
// Handle promise methods
|
|
438
470
|
if (prop === 'then' || prop === 'catch' || prop === 'finally') {
|
|
439
|
-
|
|
471
|
+
const method = target[prop];
|
|
472
|
+
return method?.bind(target);
|
|
440
473
|
}
|
|
441
474
|
// Handle AIPromise methods
|
|
442
|
-
if (prop === 'map' ||
|
|
443
|
-
|
|
475
|
+
if (prop === 'map' ||
|
|
476
|
+
prop === 'forEach' ||
|
|
477
|
+
prop === 'resolve' ||
|
|
478
|
+
prop === 'stream' ||
|
|
479
|
+
prop === 'addDependency' ||
|
|
480
|
+
prop === 'mapImmediate' ||
|
|
481
|
+
prop === 'mapDeferred') {
|
|
482
|
+
const method = target[prop];
|
|
483
|
+
return method?.bind(target);
|
|
444
484
|
}
|
|
445
485
|
// Handle internal properties
|
|
446
|
-
if (prop.startsWith('_') ||
|
|
486
|
+
if (prop.startsWith('_') ||
|
|
487
|
+
prop === 'prompt' ||
|
|
488
|
+
prop === 'path' ||
|
|
489
|
+
prop === 'isResolved' ||
|
|
490
|
+
prop === 'accessedProps') {
|
|
447
491
|
return target[prop];
|
|
448
492
|
}
|
|
449
493
|
// Track property access for schema inference
|
|
@@ -467,10 +511,11 @@ const PROXY_HANDLERS = {
|
|
|
467
511
|
throw new Error('AIPromise properties cannot be deleted');
|
|
468
512
|
},
|
|
469
513
|
// Handle function calls (for chained methods)
|
|
470
|
-
apply(target,
|
|
514
|
+
apply(target, _thisArg, args) {
|
|
471
515
|
// If the target is callable (e.g., from a template function), call it
|
|
472
|
-
|
|
473
|
-
|
|
516
|
+
const call = target['_call'];
|
|
517
|
+
if (typeof call === 'function') {
|
|
518
|
+
return call(...args);
|
|
474
519
|
}
|
|
475
520
|
throw new Error('AIPromise is not callable');
|
|
476
521
|
},
|
|
@@ -510,10 +555,12 @@ function analyzeRecordingResult(result, recording) {
|
|
|
510
555
|
const aiPromise = getRawPromise(value);
|
|
511
556
|
// Infer schema from the promise's accessed properties or type
|
|
512
557
|
if (aiPromise.accessedProps.size > 0) {
|
|
513
|
-
schema[key] = Object.fromEntries(Array.from(aiPromise.accessedProps).map(p => [p, `The ${p}`]));
|
|
558
|
+
schema[key] = Object.fromEntries(Array.from(aiPromise.accessedProps).map((p) => [p, `The ${p}`]));
|
|
514
559
|
}
|
|
515
560
|
else {
|
|
516
|
-
|
|
561
|
+
// Access private _options through type-safe assertion
|
|
562
|
+
const options = aiPromise._options;
|
|
563
|
+
const type = options?.type;
|
|
517
564
|
if (type === 'boolean') {
|
|
518
565
|
schema[key] = 'true | false';
|
|
519
566
|
}
|
|
@@ -549,10 +596,8 @@ export function isAIPromise(value) {
|
|
|
549
596
|
* Get the raw AIPromise from a proxied value
|
|
550
597
|
*/
|
|
551
598
|
export function getRawPromise(value) {
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
}
|
|
555
|
-
return value;
|
|
599
|
+
const raw = value[RAW_PROMISE_SYMBOL];
|
|
600
|
+
return raw ?? value;
|
|
556
601
|
}
|
|
557
602
|
// ============================================================================
|
|
558
603
|
// Factory Functions
|
|
@@ -644,16 +689,26 @@ export function createAITemplateFunction(type, baseOptions) {
|
|
|
644
689
|
}
|
|
645
690
|
// If we're in recording mode (inside a .map() callback), capture this operation
|
|
646
691
|
if (isInRecordingMode()) {
|
|
647
|
-
const batchType = type === 'text'
|
|
692
|
+
const batchType = type === 'text'
|
|
693
|
+
? 'text'
|
|
694
|
+
: type === 'boolean'
|
|
695
|
+
? 'boolean'
|
|
696
|
+
: type === 'list'
|
|
697
|
+
? 'list'
|
|
698
|
+
: 'object';
|
|
648
699
|
captureOperation(prompt, batchType, options.baseSchema, options.system);
|
|
649
700
|
}
|
|
650
|
-
const promise = new AIPromise(prompt, {
|
|
701
|
+
const promise = new AIPromise(prompt, {
|
|
702
|
+
...options,
|
|
703
|
+
...(type !== undefined && { type }),
|
|
704
|
+
});
|
|
651
705
|
// Add dependencies
|
|
652
706
|
for (const dep of dependencies) {
|
|
653
707
|
promise.addDependency(dep.promise, dep.path);
|
|
654
708
|
}
|
|
655
709
|
return promise;
|
|
656
710
|
}
|
|
711
|
+
// Return type matches the declared intersection type
|
|
657
712
|
return templateFn;
|
|
658
713
|
}
|
|
659
714
|
// ============================================================================
|
|
@@ -709,10 +764,16 @@ function createStreamingAIPromise(promise, options) {
|
|
|
709
764
|
// 2. The type parameter T corresponds to the expected output type for each mode
|
|
710
765
|
const extractFinalValue = (obj) => {
|
|
711
766
|
let value = obj;
|
|
712
|
-
if (promiseOptions.type === 'text' &&
|
|
767
|
+
if (promiseOptions.type === 'text' &&
|
|
768
|
+
typeof value === 'object' &&
|
|
769
|
+
value !== null &&
|
|
770
|
+
'text' in value) {
|
|
713
771
|
value = value.text;
|
|
714
772
|
}
|
|
715
|
-
else if (promiseOptions.type === 'boolean' &&
|
|
773
|
+
else if (promiseOptions.type === 'boolean' &&
|
|
774
|
+
typeof value === 'object' &&
|
|
775
|
+
value !== null &&
|
|
776
|
+
'answer' in value) {
|
|
716
777
|
const answer = value.answer;
|
|
717
778
|
// When type === 'boolean', T is constrained to boolean at the call site.
|
|
718
779
|
// TypeScript can't express this dependent relationship, so we use a simple cast.
|
|
@@ -720,7 +781,10 @@ function createStreamingAIPromise(promise, options) {
|
|
|
720
781
|
const booleanValue = answer === 'true' || answer === true;
|
|
721
782
|
value = booleanValue;
|
|
722
783
|
}
|
|
723
|
-
else if ((promiseOptions.type === 'list' || promiseOptions.type === 'extract') &&
|
|
784
|
+
else if ((promiseOptions.type === 'list' || promiseOptions.type === 'extract') &&
|
|
785
|
+
typeof value === 'object' &&
|
|
786
|
+
value !== null &&
|
|
787
|
+
'items' in value) {
|
|
724
788
|
value = value.items;
|
|
725
789
|
}
|
|
726
790
|
return value;
|
|
@@ -744,10 +808,12 @@ function createStreamingAIPromise(promise, options) {
|
|
|
744
808
|
const result = await streamText({
|
|
745
809
|
model: promiseOptions.model || 'sonnet',
|
|
746
810
|
prompt: finalPrompt,
|
|
747
|
-
system: promiseOptions.system,
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
811
|
+
...(promiseOptions.system !== undefined && { system: promiseOptions.system }),
|
|
812
|
+
...(promiseOptions.temperature !== undefined && {
|
|
813
|
+
temperature: promiseOptions.temperature,
|
|
814
|
+
}),
|
|
815
|
+
...(promiseOptions.maxTokens !== undefined && { maxTokens: promiseOptions.maxTokens }),
|
|
816
|
+
...(options?.abortSignal !== undefined && { abortSignal: options.abortSignal }),
|
|
751
817
|
});
|
|
752
818
|
let fullText = '';
|
|
753
819
|
for await (const chunk of result.textStream) {
|
|
@@ -785,10 +851,12 @@ function createStreamingAIPromise(promise, options) {
|
|
|
785
851
|
model: promiseOptions.model || 'sonnet',
|
|
786
852
|
schema,
|
|
787
853
|
prompt: finalPrompt,
|
|
788
|
-
system: promiseOptions.system,
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
854
|
+
...(promiseOptions.system !== undefined && { system: promiseOptions.system }),
|
|
855
|
+
...(promiseOptions.temperature !== undefined && {
|
|
856
|
+
temperature: promiseOptions.temperature,
|
|
857
|
+
}),
|
|
858
|
+
...(promiseOptions.maxTokens !== undefined && { maxTokens: promiseOptions.maxTokens }),
|
|
859
|
+
...(options?.abortSignal !== undefined && { abortSignal: options.abortSignal }),
|
|
792
860
|
});
|
|
793
861
|
let lastPartial = {};
|
|
794
862
|
for await (const partial of result.partialObjectStream) {
|
|
@@ -809,6 +877,7 @@ function createStreamingAIPromise(promise, options) {
|
|
|
809
877
|
async function* createMainStream() {
|
|
810
878
|
if (promiseOptions.type === 'text') {
|
|
811
879
|
for await (const chunk of createTextStream()) {
|
|
880
|
+
// When type is 'text', T is string, so the conditional type resolves to string
|
|
812
881
|
yield chunk;
|
|
813
882
|
}
|
|
814
883
|
}
|
|
@@ -818,6 +887,7 @@ function createStreamingAIPromise(promise, options) {
|
|
|
818
887
|
for await (const partial of createPartialObjectStream()) {
|
|
819
888
|
const items = partial.items || [];
|
|
820
889
|
for (let i = lastLength; i < items.length; i++) {
|
|
890
|
+
// List items are strings, cast to the conditional return type
|
|
821
891
|
yield items[i];
|
|
822
892
|
}
|
|
823
893
|
lastLength = items.length;
|
|
@@ -825,6 +895,7 @@ function createStreamingAIPromise(promise, options) {
|
|
|
825
895
|
}
|
|
826
896
|
else {
|
|
827
897
|
for await (const partial of createPartialObjectStream()) {
|
|
898
|
+
// For object types, T is not string, so conditional type resolves to Partial<T>
|
|
828
899
|
yield partial;
|
|
829
900
|
}
|
|
830
901
|
}
|