ai-functions 2.0.2 → 2.1.3
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 +4 -5
- package/CHANGELOG.md +38 -0
- package/LICENSE +21 -0
- package/README.md +361 -159
- package/dist/ai-promise.d.ts +47 -0
- package/dist/ai-promise.d.ts.map +1 -1
- package/dist/ai-promise.js +291 -3
- package/dist/ai-promise.js.map +1 -1
- package/dist/ai.d.ts +17 -18
- package/dist/ai.d.ts.map +1 -1
- package/dist/ai.js +93 -39
- package/dist/ai.js.map +1 -1
- package/dist/batch-map.d.ts +46 -4
- package/dist/batch-map.d.ts.map +1 -1
- package/dist/batch-map.js +35 -2
- package/dist/batch-map.js.map +1 -1
- package/dist/batch-queue.d.ts +116 -12
- package/dist/batch-queue.d.ts.map +1 -1
- package/dist/batch-queue.js +47 -2
- package/dist/batch-queue.js.map +1 -1
- package/dist/budget.d.ts +272 -0
- package/dist/budget.d.ts.map +1 -0
- package/dist/budget.js +500 -0
- package/dist/budget.js.map +1 -0
- package/dist/cache.d.ts +272 -0
- package/dist/cache.d.ts.map +1 -0
- package/dist/cache.js +412 -0
- package/dist/cache.js.map +1 -0
- package/dist/context.d.ts +32 -1
- package/dist/context.d.ts.map +1 -1
- package/dist/context.js +16 -1
- package/dist/context.js.map +1 -1
- package/dist/eval/runner.d.ts +2 -1
- package/dist/eval/runner.d.ts.map +1 -1
- package/dist/eval/runner.js.map +1 -1
- package/dist/generate.d.ts.map +1 -1
- package/dist/generate.js +6 -10
- package/dist/generate.js.map +1 -1
- package/dist/index.d.ts +27 -20
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +72 -42
- package/dist/index.js.map +1 -1
- package/dist/primitives.d.ts +17 -0
- package/dist/primitives.d.ts.map +1 -1
- package/dist/primitives.js +19 -1
- package/dist/primitives.js.map +1 -1
- package/dist/retry.d.ts +303 -0
- package/dist/retry.d.ts.map +1 -0
- package/dist/retry.js +539 -0
- package/dist/retry.js.map +1 -0
- package/dist/schema.d.ts.map +1 -1
- package/dist/schema.js +1 -9
- package/dist/schema.js.map +1 -1
- package/dist/tool-orchestration.d.ts +391 -0
- package/dist/tool-orchestration.d.ts.map +1 -0
- package/dist/tool-orchestration.js +663 -0
- package/dist/tool-orchestration.js.map +1 -0
- package/dist/types.d.ts +50 -33
- package/dist/types.d.ts.map +1 -1
- package/evalite.config.js +14 -0
- package/evals/classification.eval.js +97 -0
- package/evals/marketing.eval.js +289 -0
- package/evals/math.eval.js +83 -0
- package/evals/run-evals.js +151 -0
- package/evals/structured-output.eval.js +131 -0
- package/evals/writing.eval.js +105 -0
- package/examples/batch-blog-posts.js +128 -0
- package/package.json +26 -26
- package/src/ai-promise.ts +359 -3
- package/src/ai.ts +155 -110
- package/src/batch/anthropic.js +256 -0
- package/src/batch/bedrock.js +584 -0
- package/src/batch/cloudflare.js +287 -0
- package/src/batch/google.js +359 -0
- package/src/batch/index.js +30 -0
- package/src/batch/memory.js +187 -0
- package/src/batch/openai.js +402 -0
- package/src/batch-map.ts +46 -4
- package/src/batch-queue.ts +116 -12
- package/src/budget.ts +727 -0
- package/src/cache.ts +653 -0
- package/src/context.ts +33 -1
- package/src/eval/index.js +7 -0
- package/src/eval/models.js +119 -0
- package/src/eval/runner.js +147 -0
- package/src/eval/runner.ts +3 -2
- package/src/generate.ts +7 -12
- package/src/index.ts +231 -53
- package/src/primitives.ts +19 -1
- package/src/retry.ts +776 -0
- package/src/schema.ts +1 -10
- package/src/tool-orchestration.ts +1008 -0
- package/src/types.ts +59 -41
- package/test/ai-proxy.test.js +157 -0
- package/test/async-iterators.test.js +261 -0
- package/test/backward-compat.test.ts +147 -0
- package/test/batch-autosubmit-errors.test.ts +598 -0
- package/test/batch-background.test.js +352 -0
- package/test/batch-blog-posts.test.js +293 -0
- package/test/blog-generation.test.js +390 -0
- package/test/browse-read.test.js +480 -0
- package/test/budget-tracking.test.ts +800 -0
- package/test/cache.test.ts +712 -0
- package/test/context-isolation.test.ts +687 -0
- package/test/core-functions.test.js +490 -0
- package/test/decide.test.js +260 -0
- package/test/define.test.js +232 -0
- package/test/e2e-bedrock-manual.js +136 -0
- package/test/e2e-bedrock.test.js +164 -0
- package/test/e2e-flex-gateway.js +131 -0
- package/test/e2e-flex-manual.js +156 -0
- package/test/e2e-flex.test.js +174 -0
- package/test/e2e-google-manual.js +150 -0
- package/test/e2e-google.test.js +181 -0
- package/test/embeddings.test.js +220 -0
- package/test/evals/define-function.eval.test.js +309 -0
- package/test/evals/deterministic.eval.test.ts +376 -0
- package/test/evals/primitives.eval.test.js +360 -0
- package/test/function-types.test.js +407 -0
- package/test/generate-core.test.js +213 -0
- package/test/generate.test.js +143 -0
- package/test/generic-order.test.ts +342 -0
- package/test/implicit-batch.test.js +326 -0
- package/test/json-parse-error-handling.test.ts +463 -0
- package/test/retry.test.ts +1016 -0
- package/test/schema.test.js +96 -0
- package/test/streaming.test.ts +316 -0
- package/test/tagged-templates.test.js +240 -0
- package/test/tool-orchestration.test.ts +770 -0
- package/vitest.config.js +39 -0
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Model Registry for AI Functions Eval Suite
|
|
3
|
+
*
|
|
4
|
+
* Simple model list for running evals across providers.
|
|
5
|
+
* Uses ai-providers/language-models for resolution and pricing.
|
|
6
|
+
*
|
|
7
|
+
* @packageDocumentation
|
|
8
|
+
*/
|
|
9
|
+
import { resolve, get } from 'language-models';
|
|
10
|
+
// ============================================================================
|
|
11
|
+
// Models to evaluate - using aliases from language-models
|
|
12
|
+
// ============================================================================
|
|
13
|
+
/**
|
|
14
|
+
* Core models to test - one per tier per major provider
|
|
15
|
+
* These resolve via ai-providers to OpenRouter or direct SDKs
|
|
16
|
+
*
|
|
17
|
+
* Updated: December 2025
|
|
18
|
+
*
|
|
19
|
+
* Note: Some models use OpenRouter format (provider/model) to avoid
|
|
20
|
+
* resolution issues with provider_model_id mismatches.
|
|
21
|
+
*/
|
|
22
|
+
export const EVAL_MODELS = [
|
|
23
|
+
// Anthropic Claude 4.5 - via AWS Bedrock (uses AWS credits with bearer token auth)
|
|
24
|
+
// All Claude models should be 4.5 - older versions are deprecated
|
|
25
|
+
{ id: 'bedrock:us.anthropic.claude-opus-4-5-20251101-v1:0', name: 'Claude Opus 4.5', provider: 'anthropic', tier: 'best', notes: 'Bedrock' },
|
|
26
|
+
{ id: 'bedrock:us.anthropic.claude-sonnet-4-5-20250929-v1:0', name: 'Claude Sonnet 4.5', provider: 'anthropic', tier: 'fast', notes: 'Bedrock' },
|
|
27
|
+
{ id: 'bedrock:us.anthropic.claude-haiku-4-5-20251001-v1:0', name: 'Claude Haiku 4.5', provider: 'anthropic', tier: 'cheap', notes: 'Bedrock' },
|
|
28
|
+
// OpenAI - GPT-5.1 variants + GPT-oss (open source)
|
|
29
|
+
{ id: 'openai/o3', name: 'o3', provider: 'openai', tier: 'best' },
|
|
30
|
+
{ id: 'openai/gpt-5.1', name: 'GPT-5.1', provider: 'openai', tier: 'best' },
|
|
31
|
+
{ id: 'openai/gpt-5-mini', name: 'GPT-5 Mini', provider: 'openai', tier: 'fast' },
|
|
32
|
+
{ id: 'openai/gpt-5-nano', name: 'GPT-5 Nano', provider: 'openai', tier: 'cheap' },
|
|
33
|
+
// GPT-oss 120B removed - times out frequently
|
|
34
|
+
{ id: 'openai/gpt-oss-20b', name: 'GPT-oss 20B', provider: 'openai', tier: 'fast', notes: 'Open source' },
|
|
35
|
+
// Google - Gemini 3 (November 2025)
|
|
36
|
+
{ id: 'google/gemini-3-pro-preview', name: 'Gemini 3 Pro', provider: 'google', tier: 'best', notes: '1M context, #1 LMArena' },
|
|
37
|
+
// Gemini 2.5 Pro removed - times out frequently
|
|
38
|
+
{ id: 'flash', name: 'Gemini 2.5 Flash', provider: 'google', tier: 'fast' },
|
|
39
|
+
// Meta (via OpenRouter)
|
|
40
|
+
{ id: 'meta-llama/llama-4-maverick', name: 'Llama 4 Maverick', provider: 'meta-llama', tier: 'best' },
|
|
41
|
+
{ id: 'meta-llama/llama-3.3-70b-instruct', name: 'Llama 3.3 70B', provider: 'meta-llama', tier: 'fast' },
|
|
42
|
+
// DeepSeek - V3.2 (December 2025)
|
|
43
|
+
{ id: 'deepseek/deepseek-v3.2', name: 'DeepSeek V3.2', provider: 'deepseek', tier: 'best', notes: 'GPT-5 class reasoning' },
|
|
44
|
+
// DeepSeek V3.2 Speciale removed - no tool use support on OpenRouter
|
|
45
|
+
{ id: 'deepseek/deepseek-chat', name: 'DeepSeek Chat', provider: 'deepseek', tier: 'fast' },
|
|
46
|
+
// Mistral - Mistral 3 family (December 2025)
|
|
47
|
+
{ id: 'mistralai/mistral-large-2512', name: 'Mistral Large 3', provider: 'mistralai', tier: 'best', notes: '675B MoE, 41B active' },
|
|
48
|
+
{ id: 'mistralai/mistral-medium-3.1', name: 'Mistral Medium 3.1', provider: 'mistralai', tier: 'fast' },
|
|
49
|
+
// Ministral 3 14B removed - often fails structured output
|
|
50
|
+
// Qwen - Qwen3 family (2025)
|
|
51
|
+
{ id: 'qwen/qwen3-coder', name: 'Qwen3 Coder 480B', provider: 'qwen', tier: 'best', notes: 'Agentic coding' },
|
|
52
|
+
{ id: 'qwen/qwen3-30b-a3b', name: 'Qwen3 30B', provider: 'qwen', tier: 'fast', notes: 'MoE 30B/3B active' },
|
|
53
|
+
{ id: 'qwen/qwen3-next-80b-a3b-instruct', name: 'Qwen3 Next 80B', provider: 'qwen', tier: 'best', notes: 'Ultra-long context' },
|
|
54
|
+
// xAI - Grok 4 family (December 2025)
|
|
55
|
+
{ id: 'x-ai/grok-4', name: 'Grok 4', provider: 'x-ai', tier: 'best', notes: '256K context, reasoning' },
|
|
56
|
+
{ id: 'x-ai/grok-4.1-fast', name: 'Grok 4.1 Fast', provider: 'x-ai', tier: 'fast', notes: '2M context, agentic' },
|
|
57
|
+
{ id: 'x-ai/grok-4-fast', name: 'Grok 4 Fast', provider: 'x-ai', tier: 'fast', notes: '2M context' },
|
|
58
|
+
];
|
|
59
|
+
/**
|
|
60
|
+
* Get models by tier
|
|
61
|
+
*/
|
|
62
|
+
export function getModelsByTier(tier) {
|
|
63
|
+
return EVAL_MODELS.filter(m => m.tier === tier);
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Get models by provider
|
|
67
|
+
*/
|
|
68
|
+
export function getModelsByProvider(provider) {
|
|
69
|
+
return EVAL_MODELS.filter(m => m.provider === provider);
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Get model info from language-models package (includes pricing)
|
|
73
|
+
*/
|
|
74
|
+
export function getModelInfo(id) {
|
|
75
|
+
const resolved = resolve(id);
|
|
76
|
+
return get(resolved);
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Get pricing for a model (from OpenRouter data)
|
|
80
|
+
*/
|
|
81
|
+
export function getModelPricing(id) {
|
|
82
|
+
const info = getModelInfo(id);
|
|
83
|
+
if (!info?.pricing)
|
|
84
|
+
return undefined;
|
|
85
|
+
return {
|
|
86
|
+
prompt: parseFloat(info.pricing.prompt) * 1_000_000, // Convert to per-million
|
|
87
|
+
completion: parseFloat(info.pricing.completion) * 1_000_000,
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* Create evalite variants for model testing
|
|
92
|
+
*/
|
|
93
|
+
export function createModelVariants(opts) {
|
|
94
|
+
let models = EVAL_MODELS;
|
|
95
|
+
if (opts?.tiers) {
|
|
96
|
+
models = models.filter(m => opts.tiers.includes(m.tier));
|
|
97
|
+
}
|
|
98
|
+
if (opts?.providers) {
|
|
99
|
+
models = models.filter(m => opts.providers.includes(m.provider));
|
|
100
|
+
}
|
|
101
|
+
return models.map(model => ({
|
|
102
|
+
name: `${model.provider}/${model.name}`,
|
|
103
|
+
input: model,
|
|
104
|
+
}));
|
|
105
|
+
}
|
|
106
|
+
/**
|
|
107
|
+
* Get a representative model from each provider for a given tier
|
|
108
|
+
*/
|
|
109
|
+
export function getRepresentativeModels(tier) {
|
|
110
|
+
const seen = new Set();
|
|
111
|
+
const result = [];
|
|
112
|
+
for (const model of EVAL_MODELS) {
|
|
113
|
+
if (model.tier === tier && !seen.has(model.provider)) {
|
|
114
|
+
seen.add(model.provider);
|
|
115
|
+
result.push(model);
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
return result;
|
|
119
|
+
}
|
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Simple eval runner for AI Functions
|
|
3
|
+
*
|
|
4
|
+
* Runs evals across multiple models and collects results.
|
|
5
|
+
* Does not depend on evalite - uses our own infrastructure.
|
|
6
|
+
*/
|
|
7
|
+
import { generateObject, generateText } from '../generate.js';
|
|
8
|
+
import { schema } from '../schema.js';
|
|
9
|
+
import { createModelVariants, getModelPricing } from './models.js';
|
|
10
|
+
/**
|
|
11
|
+
* Run an eval suite across models
|
|
12
|
+
*/
|
|
13
|
+
export async function runEval(options) {
|
|
14
|
+
const { name, cases, task, scorers, concurrency = 3 } = options;
|
|
15
|
+
// Get models to test
|
|
16
|
+
const models = options.models ?? createModelVariants({
|
|
17
|
+
tiers: options.tiers,
|
|
18
|
+
providers: options.providers,
|
|
19
|
+
}).map(v => v.input);
|
|
20
|
+
const results = [];
|
|
21
|
+
const startTime = Date.now();
|
|
22
|
+
console.log(`\n🧪 Running eval: ${name}`);
|
|
23
|
+
console.log(` Models: ${models.map(m => m.name).join(', ')}`);
|
|
24
|
+
console.log(` Cases: ${cases.length}`);
|
|
25
|
+
console.log('');
|
|
26
|
+
// Run all model/case combinations
|
|
27
|
+
const jobs = [];
|
|
28
|
+
for (const model of models) {
|
|
29
|
+
for (const evalCase of cases) {
|
|
30
|
+
jobs.push({ model, case: evalCase });
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
// Process in batches with concurrency limit
|
|
34
|
+
for (let i = 0; i < jobs.length; i += concurrency) {
|
|
35
|
+
const batch = jobs.slice(i, i + concurrency);
|
|
36
|
+
const batchResults = await Promise.all(batch.map(async (job) => {
|
|
37
|
+
const caseStart = Date.now();
|
|
38
|
+
try {
|
|
39
|
+
// Run the task
|
|
40
|
+
const output = await task(job.case.input, job.model);
|
|
41
|
+
const latencyMs = Date.now() - caseStart;
|
|
42
|
+
// Run scorers
|
|
43
|
+
const scores = [];
|
|
44
|
+
for (const s of scorers) {
|
|
45
|
+
try {
|
|
46
|
+
const score = await s.scorer({
|
|
47
|
+
input: job.case.input,
|
|
48
|
+
output,
|
|
49
|
+
expected: job.case.expected,
|
|
50
|
+
});
|
|
51
|
+
scores.push({
|
|
52
|
+
name: s.name,
|
|
53
|
+
score: Math.max(0, Math.min(1, score)),
|
|
54
|
+
description: s.description,
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
catch (err) {
|
|
58
|
+
scores.push({
|
|
59
|
+
name: s.name,
|
|
60
|
+
score: 0,
|
|
61
|
+
description: s.description,
|
|
62
|
+
metadata: { error: String(err) },
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
// Calculate cost
|
|
67
|
+
const pricing = getModelPricing(job.model.id);
|
|
68
|
+
// Estimate tokens - rough approximation
|
|
69
|
+
const estimatedPromptTokens = 100;
|
|
70
|
+
const estimatedCompletionTokens = 200;
|
|
71
|
+
const cost = pricing
|
|
72
|
+
? (estimatedPromptTokens * pricing.prompt + estimatedCompletionTokens * pricing.completion) / 1_000_000
|
|
73
|
+
: 0;
|
|
74
|
+
const avgScore = scores.length > 0
|
|
75
|
+
? scores.reduce((sum, s) => sum + s.score, 0) / scores.length
|
|
76
|
+
: 0;
|
|
77
|
+
const symbol = avgScore >= 0.8 ? '✓' : avgScore >= 0.5 ? '~' : '✗';
|
|
78
|
+
console.log(` ${symbol} ${job.model.name} | ${job.case.name} | ${(avgScore * 100).toFixed(0)}% | ${latencyMs}ms`);
|
|
79
|
+
return {
|
|
80
|
+
model: job.model,
|
|
81
|
+
case: job.case,
|
|
82
|
+
output,
|
|
83
|
+
scores,
|
|
84
|
+
latencyMs,
|
|
85
|
+
cost,
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
catch (err) {
|
|
89
|
+
console.log(` ✗ ${job.model.name} | ${job.case.name} | ERROR: ${err}`);
|
|
90
|
+
return {
|
|
91
|
+
model: job.model,
|
|
92
|
+
case: job.case,
|
|
93
|
+
output: null,
|
|
94
|
+
scores: scorers.map(s => ({ name: s.name, score: 0 })),
|
|
95
|
+
latencyMs: Date.now() - caseStart,
|
|
96
|
+
cost: 0,
|
|
97
|
+
error: String(err),
|
|
98
|
+
};
|
|
99
|
+
}
|
|
100
|
+
}));
|
|
101
|
+
results.push(...batchResults);
|
|
102
|
+
}
|
|
103
|
+
// Calculate summary
|
|
104
|
+
const totalTime = Date.now() - startTime;
|
|
105
|
+
const totalCost = results.reduce((sum, r) => sum + r.cost, 0);
|
|
106
|
+
const allScores = results.flatMap(r => r.scores.map(s => s.score));
|
|
107
|
+
const avgScore = allScores.length > 0
|
|
108
|
+
? allScores.reduce((a, b) => a + b, 0) / allScores.length
|
|
109
|
+
: 0;
|
|
110
|
+
// Group by model
|
|
111
|
+
const byModel = {};
|
|
112
|
+
for (const result of results) {
|
|
113
|
+
const modelKey = result.model.id;
|
|
114
|
+
if (!byModel[modelKey]) {
|
|
115
|
+
byModel[modelKey] = { avgScore: 0, count: 0 };
|
|
116
|
+
}
|
|
117
|
+
const resultAvg = result.scores.reduce((sum, s) => sum + s.score, 0) / result.scores.length;
|
|
118
|
+
byModel[modelKey].avgScore += resultAvg;
|
|
119
|
+
byModel[modelKey].count++;
|
|
120
|
+
}
|
|
121
|
+
for (const key of Object.keys(byModel)) {
|
|
122
|
+
const entry = byModel[key];
|
|
123
|
+
if (entry) {
|
|
124
|
+
entry.avgScore /= entry.count;
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
console.log('');
|
|
128
|
+
console.log(`📊 Results:`);
|
|
129
|
+
console.log(` Overall: ${(avgScore * 100).toFixed(1)}%`);
|
|
130
|
+
console.log(` Time: ${(totalTime / 1000).toFixed(1)}s`);
|
|
131
|
+
console.log(` Cost: $${totalCost.toFixed(4)}`);
|
|
132
|
+
console.log('');
|
|
133
|
+
console.log(' By Model:');
|
|
134
|
+
for (const [modelId, stats] of Object.entries(byModel)) {
|
|
135
|
+
console.log(` - ${modelId}: ${(stats.avgScore * 100).toFixed(1)}%`);
|
|
136
|
+
}
|
|
137
|
+
return {
|
|
138
|
+
name,
|
|
139
|
+
results,
|
|
140
|
+
avgScore,
|
|
141
|
+
byModel,
|
|
142
|
+
totalCost,
|
|
143
|
+
totalTime,
|
|
144
|
+
};
|
|
145
|
+
}
|
|
146
|
+
// Re-export helpers
|
|
147
|
+
export { generateObject, generateText, schema };
|
package/src/eval/runner.ts
CHANGED
|
@@ -25,7 +25,8 @@ export interface EvalScore {
|
|
|
25
25
|
export interface EvalResult<TOutput = unknown> {
|
|
26
26
|
model: EvalModel
|
|
27
27
|
case: EvalCase
|
|
28
|
-
output
|
|
28
|
+
/** The output from the task. Will be null if an error occurred. */
|
|
29
|
+
output: TOutput | null
|
|
29
30
|
scores: EvalScore[]
|
|
30
31
|
latencyMs: number
|
|
31
32
|
cost: number
|
|
@@ -153,7 +154,7 @@ export async function runEval<TInput, TOutput, TExpected>(
|
|
|
153
154
|
return {
|
|
154
155
|
model: job.model,
|
|
155
156
|
case: job.case,
|
|
156
|
-
output: null
|
|
157
|
+
output: null,
|
|
157
158
|
scores: scorers.map(s => ({ name: s.name, score: 0 })),
|
|
158
159
|
latencyMs: Date.now() - caseStart,
|
|
159
160
|
cost: 0,
|
package/src/generate.ts
CHANGED
|
@@ -21,6 +21,7 @@ import {
|
|
|
21
21
|
type LanguageModel
|
|
22
22
|
} from 'ai'
|
|
23
23
|
import { schema as convertSchema, type SimpleSchema } from './schema.js'
|
|
24
|
+
import { isZodSchema } from '@org.ai/core'
|
|
24
25
|
import type { ZodTypeAny } from 'zod'
|
|
25
26
|
|
|
26
27
|
type ModelArg = string | LanguageModel
|
|
@@ -82,16 +83,6 @@ async function resolveModel(modelArg: ModelArg): Promise<LanguageModel> {
|
|
|
82
83
|
return model(modelArg)
|
|
83
84
|
}
|
|
84
85
|
|
|
85
|
-
/**
|
|
86
|
-
* Check if value is a Zod schema
|
|
87
|
-
*/
|
|
88
|
-
function isZodSchema(value: unknown): value is ZodTypeAny {
|
|
89
|
-
return value !== null &&
|
|
90
|
-
typeof value === 'object' &&
|
|
91
|
-
'_def' in value &&
|
|
92
|
-
'parse' in value
|
|
93
|
-
}
|
|
94
|
-
|
|
95
86
|
/**
|
|
96
87
|
* Convert schema to Zod if needed
|
|
97
88
|
*/
|
|
@@ -208,13 +199,17 @@ export async function streamObject<T>(
|
|
|
208
199
|
): Promise<StreamObjectResult<T, T, never>> {
|
|
209
200
|
const model = await resolveModel(options.model)
|
|
210
201
|
const schema = resolveSchema(options.schema as SchemaArg)
|
|
211
|
-
//
|
|
202
|
+
// NOTE: Type assertion required due to AI SDK's complex conditional return types.
|
|
203
|
+
// The SDK uses different return types based on output mode ('object' | 'array' | 'enum' | 'no-schema')
|
|
204
|
+
// and schema definition presence. Our wrapper simplifies this to always use 'object' output mode.
|
|
205
|
+
// This cast is safe because we control the input parameters.
|
|
206
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
212
207
|
return sdkStreamObject({
|
|
213
208
|
...options,
|
|
214
209
|
model,
|
|
215
210
|
schema,
|
|
216
211
|
output: 'object'
|
|
217
|
-
} as any) as
|
|
212
|
+
} as any) as StreamObjectResult<T, T, never>
|
|
218
213
|
}
|
|
219
214
|
|
|
220
215
|
/**
|
package/src/index.ts
CHANGED
|
@@ -1,39 +1,67 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* ai-functions -
|
|
2
|
+
* ai-functions - Full-featured AI primitives for building intelligent applications
|
|
3
3
|
*
|
|
4
|
-
* This
|
|
5
|
-
*
|
|
6
|
-
* -
|
|
7
|
-
* -
|
|
8
|
-
* -
|
|
9
|
-
* -
|
|
10
|
-
* -
|
|
11
|
-
* -
|
|
12
|
-
* -
|
|
4
|
+
* This package provides the complete feature set including:
|
|
5
|
+
* - Core primitives from ai-core (generate, AIPromise, templates, context)
|
|
6
|
+
* - Batch processing (BatchQueue, BatchMapPromise)
|
|
7
|
+
* - Retry/resilience patterns (RetryPolicy, CircuitBreaker, FallbackChain)
|
|
8
|
+
* - Budget tracking (BudgetTracker, TokenCounter)
|
|
9
|
+
* - Caching (MemoryCache, EmbeddingCache, GenerationCache)
|
|
10
|
+
* - Tool orchestration (AgenticLoop, ToolRouter)
|
|
11
|
+
* - Embeddings
|
|
12
|
+
* - Provider integrations
|
|
13
|
+
*
|
|
14
|
+
* For lightweight usage with just core primitives, use ai-core directly.
|
|
13
15
|
*
|
|
14
16
|
* @packageDocumentation
|
|
15
17
|
*/
|
|
16
18
|
|
|
17
|
-
//
|
|
18
|
-
export
|
|
19
|
-
|
|
20
|
-
// Export AI function types and interfaces
|
|
21
|
-
export * from './types.js'
|
|
22
|
-
export * from './ai.js'
|
|
23
|
-
|
|
24
|
-
// Export embedding utilities
|
|
25
|
-
export * from './embeddings.js'
|
|
26
|
-
|
|
27
|
-
// Export generation functions with smart model routing
|
|
28
|
-
export { generateObject, generateText, streamObject, streamText } from './generate.js'
|
|
19
|
+
// ============================================================================
|
|
20
|
+
// Re-export core primitives from ai-core for backward compatibility
|
|
21
|
+
// ============================================================================
|
|
29
22
|
|
|
30
|
-
//
|
|
31
|
-
export
|
|
23
|
+
// Types from ai-core
|
|
24
|
+
export type {
|
|
25
|
+
AIFunctionDefinition,
|
|
26
|
+
JSONSchema,
|
|
27
|
+
AIGenerateOptions,
|
|
28
|
+
AIGenerateResult,
|
|
29
|
+
AIFunctionCall,
|
|
30
|
+
AIClient,
|
|
31
|
+
ImageOptions,
|
|
32
|
+
ImageResult,
|
|
33
|
+
VideoOptions,
|
|
34
|
+
VideoResult,
|
|
35
|
+
WriteOptions,
|
|
36
|
+
TemplateFunction as CoreTemplateFunction,
|
|
37
|
+
ListItem,
|
|
38
|
+
ListResult,
|
|
39
|
+
NamedList,
|
|
40
|
+
ListsResult,
|
|
41
|
+
CodeLanguage,
|
|
42
|
+
GenerativeOutputType,
|
|
43
|
+
HumanChannel,
|
|
44
|
+
LegacyHumanChannel,
|
|
45
|
+
SchemaLimitations,
|
|
46
|
+
BaseFunctionDefinition,
|
|
47
|
+
CodeFunctionDefinition,
|
|
48
|
+
CodeFunctionResult,
|
|
49
|
+
GenerativeFunctionDefinition,
|
|
50
|
+
GenerativeFunctionResult,
|
|
51
|
+
AgenticFunctionDefinition,
|
|
52
|
+
AgenticExecutionState,
|
|
53
|
+
HumanFunctionDefinition,
|
|
54
|
+
HumanFunctionResult,
|
|
55
|
+
FunctionDefinition,
|
|
56
|
+
DefinedFunction,
|
|
57
|
+
FunctionRegistry,
|
|
58
|
+
AutoDefineResult,
|
|
59
|
+
} from '@org.ai/core'
|
|
32
60
|
|
|
33
|
-
//
|
|
34
|
-
export
|
|
61
|
+
// Schema exports from ai-core
|
|
62
|
+
export { schema, type SimpleSchema } from '@org.ai/core'
|
|
35
63
|
|
|
36
|
-
//
|
|
64
|
+
// Template exports from ai-core
|
|
37
65
|
export {
|
|
38
66
|
parseTemplate,
|
|
39
67
|
createTemplateFunction,
|
|
@@ -45,9 +73,9 @@ export {
|
|
|
45
73
|
type BatchableFunction,
|
|
46
74
|
type StreamableList,
|
|
47
75
|
type ChainablePromise,
|
|
48
|
-
} from '
|
|
76
|
+
} from '@org.ai/core'
|
|
49
77
|
|
|
50
|
-
//
|
|
78
|
+
// AIPromise exports from ai-core
|
|
51
79
|
export {
|
|
52
80
|
AIPromise,
|
|
53
81
|
isAIPromise,
|
|
@@ -63,17 +91,19 @@ export {
|
|
|
63
91
|
AI_PROMISE_SYMBOL,
|
|
64
92
|
RAW_PROMISE_SYMBOL,
|
|
65
93
|
type AIPromiseOptions,
|
|
66
|
-
|
|
94
|
+
type StreamingAIPromise,
|
|
95
|
+
type StreamOptions,
|
|
96
|
+
} from '@org.ai/core'
|
|
67
97
|
|
|
68
|
-
//
|
|
98
|
+
// Generation exports from ai-core
|
|
99
|
+
export { generateObject, generateText, streamObject, streamText } from '@org.ai/core'
|
|
100
|
+
|
|
101
|
+
// Primitives from ai-core
|
|
69
102
|
export {
|
|
70
|
-
// Core generate primitive
|
|
71
103
|
generate,
|
|
72
104
|
type GenerateType,
|
|
73
105
|
type GenerateOptions,
|
|
74
|
-
|
|
75
|
-
// Generative functions
|
|
76
|
-
ai as aiPrompt, // Renamed to avoid conflict with AIProxy from ai.ts
|
|
106
|
+
ai,
|
|
77
107
|
write,
|
|
78
108
|
code,
|
|
79
109
|
list,
|
|
@@ -85,25 +115,52 @@ export {
|
|
|
85
115
|
slides,
|
|
86
116
|
image,
|
|
87
117
|
video,
|
|
88
|
-
|
|
89
|
-
// Agentic functions
|
|
90
118
|
do,
|
|
91
119
|
research,
|
|
92
|
-
|
|
93
|
-
// Web functions
|
|
94
120
|
read,
|
|
95
121
|
browse,
|
|
96
|
-
|
|
97
|
-
// Decision functions
|
|
98
122
|
decide,
|
|
99
|
-
|
|
100
|
-
// Human-in-the-loop functions
|
|
101
123
|
ask,
|
|
102
124
|
approve,
|
|
103
125
|
review,
|
|
104
126
|
type HumanOptions,
|
|
105
127
|
type HumanResult,
|
|
106
|
-
} from '
|
|
128
|
+
} from '@org.ai/core'
|
|
129
|
+
|
|
130
|
+
// Context exports from ai-core (basic version)
|
|
131
|
+
export {
|
|
132
|
+
configure,
|
|
133
|
+
getContext,
|
|
134
|
+
withContext,
|
|
135
|
+
getGlobalContext,
|
|
136
|
+
resetContext,
|
|
137
|
+
getModel,
|
|
138
|
+
getProvider,
|
|
139
|
+
type ExecutionContext,
|
|
140
|
+
} from '@org.ai/core'
|
|
141
|
+
|
|
142
|
+
// Type guards from ai-core
|
|
143
|
+
export { isZodSchema } from '@org.ai/core'
|
|
144
|
+
|
|
145
|
+
// ============================================================================
|
|
146
|
+
// Export AI Proxy (the AI class/proxy from ai.ts)
|
|
147
|
+
// This is separate from the core 'ai' template function
|
|
148
|
+
// ============================================================================
|
|
149
|
+
|
|
150
|
+
export { AI, define, defineFunction, type AIProxy } from './ai.js'
|
|
151
|
+
|
|
152
|
+
// Also export 'ai' primitive as 'aiPrompt' to avoid conflict with AIProxy
|
|
153
|
+
export { ai as aiPrompt } from '@org.ai/core'
|
|
154
|
+
|
|
155
|
+
// Export embedding utilities (not in ai-core)
|
|
156
|
+
export * from './embeddings.js'
|
|
157
|
+
|
|
158
|
+
// Export providers (not in ai-core)
|
|
159
|
+
export * from './providers/index.js'
|
|
160
|
+
|
|
161
|
+
// ============================================================================
|
|
162
|
+
// Extended exports (NOT in ai-core)
|
|
163
|
+
// ============================================================================
|
|
107
164
|
|
|
108
165
|
// Export batch processing
|
|
109
166
|
export {
|
|
@@ -137,18 +194,139 @@ export {
|
|
|
137
194
|
type BatchMapOptions,
|
|
138
195
|
} from './batch-map.js'
|
|
139
196
|
|
|
140
|
-
// Export execution context
|
|
197
|
+
// Export additional execution context features (full version with batch/budget)
|
|
141
198
|
export {
|
|
142
|
-
configure,
|
|
143
|
-
getContext,
|
|
144
|
-
withContext,
|
|
145
|
-
getGlobalContext,
|
|
146
|
-
resetContext,
|
|
147
|
-
getModel,
|
|
148
|
-
getProvider,
|
|
149
199
|
getBatchMode,
|
|
150
200
|
getBatchThreshold,
|
|
151
201
|
shouldUseBatchAPI,
|
|
152
|
-
|
|
202
|
+
getFlexThreshold,
|
|
203
|
+
getExecutionTier,
|
|
204
|
+
isFlexAvailable,
|
|
153
205
|
type BatchMode,
|
|
206
|
+
type ContextBudgetConfig,
|
|
207
|
+
type ExecutionTier,
|
|
154
208
|
} from './context.js'
|
|
209
|
+
|
|
210
|
+
// Export budget tracking and request tracing
|
|
211
|
+
export {
|
|
212
|
+
BudgetTracker,
|
|
213
|
+
TokenCounter,
|
|
214
|
+
RequestContext,
|
|
215
|
+
BudgetExceededError,
|
|
216
|
+
createRequestContext,
|
|
217
|
+
withBudget,
|
|
218
|
+
type BudgetConfig,
|
|
219
|
+
type BudgetAlert,
|
|
220
|
+
type BudgetSnapshot,
|
|
221
|
+
type TokenUsage,
|
|
222
|
+
type RequestInfo,
|
|
223
|
+
type RequestContextOptions,
|
|
224
|
+
type ModelPricing,
|
|
225
|
+
type WithBudgetOptions,
|
|
226
|
+
type RemainingBudget,
|
|
227
|
+
type CheckBudgetOptions,
|
|
228
|
+
} from './budget.js'
|
|
229
|
+
|
|
230
|
+
// Export agentic tool orchestration
|
|
231
|
+
export {
|
|
232
|
+
// Core classes
|
|
233
|
+
AgenticLoop,
|
|
234
|
+
ToolRouter,
|
|
235
|
+
ToolValidator,
|
|
236
|
+
|
|
237
|
+
// Tool composition utilities
|
|
238
|
+
createTool,
|
|
239
|
+
createToolset,
|
|
240
|
+
wrapTool,
|
|
241
|
+
cachedTool,
|
|
242
|
+
rateLimitedTool,
|
|
243
|
+
timeoutTool,
|
|
244
|
+
createAgenticLoop,
|
|
245
|
+
|
|
246
|
+
// Types
|
|
247
|
+
type Tool,
|
|
248
|
+
type ToolCall,
|
|
249
|
+
type ToolResult,
|
|
250
|
+
type FormattedToolResult,
|
|
251
|
+
type ValidationResult,
|
|
252
|
+
type ModelResponse,
|
|
253
|
+
type Message,
|
|
254
|
+
type StepInfo,
|
|
255
|
+
type LoopOptions,
|
|
256
|
+
type RunOptions,
|
|
257
|
+
type ToolCallResult,
|
|
258
|
+
type SDKToolResult,
|
|
259
|
+
type LoopResult,
|
|
260
|
+
type LoopStreamEvent,
|
|
261
|
+
} from './tool-orchestration.js'
|
|
262
|
+
|
|
263
|
+
// Export caching layer for embeddings and generations
|
|
264
|
+
export {
|
|
265
|
+
// Core cache storage
|
|
266
|
+
MemoryCache,
|
|
267
|
+
|
|
268
|
+
// Specialized caches
|
|
269
|
+
EmbeddingCache,
|
|
270
|
+
GenerationCache,
|
|
271
|
+
|
|
272
|
+
// Cache wrapper
|
|
273
|
+
withCache,
|
|
274
|
+
|
|
275
|
+
// Utilities
|
|
276
|
+
hashKey,
|
|
277
|
+
createCacheKey,
|
|
278
|
+
|
|
279
|
+
// Types
|
|
280
|
+
type CacheStorage,
|
|
281
|
+
type CacheEntry,
|
|
282
|
+
type CacheOptions,
|
|
283
|
+
type CacheStats,
|
|
284
|
+
type MemoryCacheOptions,
|
|
285
|
+
type CacheKeyType,
|
|
286
|
+
type EmbeddingCacheOptions,
|
|
287
|
+
type BatchEmbeddingResult,
|
|
288
|
+
type GenerationParams,
|
|
289
|
+
type GenerationCacheGetOptions,
|
|
290
|
+
type WithCacheOptions,
|
|
291
|
+
type CachedFunction,
|
|
292
|
+
} from './cache.js'
|
|
293
|
+
|
|
294
|
+
// Export retry/fallback patterns with exponential backoff
|
|
295
|
+
export {
|
|
296
|
+
// Error types and classification
|
|
297
|
+
RetryableError,
|
|
298
|
+
NonRetryableError,
|
|
299
|
+
NetworkError,
|
|
300
|
+
RateLimitError,
|
|
301
|
+
CircuitOpenError,
|
|
302
|
+
ErrorCategory,
|
|
303
|
+
classifyError,
|
|
304
|
+
|
|
305
|
+
// Backoff calculation
|
|
306
|
+
calculateBackoff,
|
|
307
|
+
|
|
308
|
+
// Retry policy
|
|
309
|
+
RetryPolicy,
|
|
310
|
+
|
|
311
|
+
// Circuit breaker
|
|
312
|
+
CircuitBreaker,
|
|
313
|
+
|
|
314
|
+
// Fallback chain
|
|
315
|
+
FallbackChain,
|
|
316
|
+
|
|
317
|
+
// Convenience helper
|
|
318
|
+
withRetry,
|
|
319
|
+
|
|
320
|
+
// Types
|
|
321
|
+
type JitterStrategy,
|
|
322
|
+
type BackoffOptions,
|
|
323
|
+
type RetryOptions,
|
|
324
|
+
type RetryInfo,
|
|
325
|
+
type BatchItemResult,
|
|
326
|
+
type CircuitState,
|
|
327
|
+
type CircuitBreakerOptions,
|
|
328
|
+
type CircuitBreakerMetrics,
|
|
329
|
+
type FallbackModel,
|
|
330
|
+
type FallbackOptions,
|
|
331
|
+
type FallbackMetrics,
|
|
332
|
+
} from './retry.js'
|