ai-functions 2.1.1 → 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 -4
- package/CHANGELOG.md +68 -1
- package/README.md +397 -157
- package/dist/ai-promise.d.ts +50 -3
- package/dist/ai-promise.d.ts.map +1 -1
- package/dist/ai-promise.js +410 -51
- 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 +54 -837
- 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 +272 -0
- package/dist/budget.d.ts.map +1 -0
- package/dist/budget.js +513 -0
- package/dist/budget.js.map +1 -0
- package/dist/cache.d.ts +295 -0
- package/dist/cache.d.ts.map +1 -0
- package/dist/cache.js +433 -0
- package/dist/cache.js.map +1 -0
- package/dist/context.d.ts +42 -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 +10 -1
- 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 -22
- package/dist/generate.js.map +1 -1
- package/dist/index.d.ts +35 -20
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +89 -42
- 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 +368 -0
- package/dist/retry.d.ts.map +1 -0
- package/dist/retry.js +646 -0
- package/dist/retry.js.map +1 -0
- package/dist/schema.d.ts.map +1 -1
- package/dist/schema.js +2 -10
- 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 +453 -0
- package/dist/tool-orchestration.d.ts.map +1 -0
- package/dist/tool-orchestration.js +763 -0
- package/dist/tool-orchestration.js.map +1 -0
- 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 +10 -6
- package/src/ai-promise.ts +528 -99
- package/src/ai-schemas.ts +122 -0
- package/src/ai.ts +69 -1153
- 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 +740 -0
- package/src/cache.ts +681 -0
- package/src/context.ts +122 -76
- package/src/digital-objects-registry.ts +750 -0
- package/src/errors.ts +37 -0
- package/src/eval/runner.ts +63 -38
- 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 -33
- package/src/index.ts +325 -49
- 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 +902 -0
- package/src/schema.ts +8 -17
- package/src/telemetry.ts +403 -0
- package/src/template.ts +8 -4
- package/src/tool-orchestration.ts +1173 -0
- 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/backward-compat.test.ts +147 -0
- package/test/batch-autosubmit-errors.test.ts +610 -0
- package/test/batch-blog-posts.test.ts +87 -129
- 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.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/evals/deterministic.eval.test.ts +376 -0
- package/test/generate-core.test.ts +140 -229
- package/test/implicit-batch.test.ts +22 -65
- package/test/json-parse-error-handling.test.ts +463 -0
- package/test/retry-policy-integration.test.ts +117 -0
- package/test/retry.test.ts +1016 -0
- package/test/schema.test.ts +55 -19
- package/test/streaming.test.ts +316 -0
- package/test/template.test.ts +1164 -0
- package/test/tool-orchestration.test.ts +1040 -0
- package/test/wrap-for-v3.test.ts +612 -0
- package/vitest.config.js +6 -0
- package/vitest.config.ts +20 -0
- 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
|
@@ -0,0 +1,232 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Quickstart Example
|
|
3
|
+
*
|
|
4
|
+
* This example demonstrates the core primitives of ai-functions in a simple,
|
|
5
|
+
* easy-to-follow format. It covers:
|
|
6
|
+
* - Basic text generation with `write`
|
|
7
|
+
* - List generation with `list`
|
|
8
|
+
* - Boolean checks with `is`
|
|
9
|
+
* - Structured output with `ai`
|
|
10
|
+
* - Configuration options
|
|
11
|
+
*
|
|
12
|
+
* @example
|
|
13
|
+
* ```bash
|
|
14
|
+
* ANTHROPIC_API_KEY=sk-... npx tsx examples/00-quickstart.ts
|
|
15
|
+
* ```
|
|
16
|
+
*/
|
|
17
|
+
|
|
18
|
+
import { ai, write, list, is, extract, configure, withContext } from '../src/index.js'
|
|
19
|
+
|
|
20
|
+
// ============================================================================
|
|
21
|
+
// Setup
|
|
22
|
+
// ============================================================================
|
|
23
|
+
|
|
24
|
+
// Configure the AI provider (optional - will use env vars by default)
|
|
25
|
+
configure({
|
|
26
|
+
model: 'sonnet', // or 'gpt-4o', 'claude-3-5-haiku-latest', etc.
|
|
27
|
+
provider: 'anthropic', // or 'openai'
|
|
28
|
+
})
|
|
29
|
+
|
|
30
|
+
// ============================================================================
|
|
31
|
+
// Text Generation
|
|
32
|
+
// ============================================================================
|
|
33
|
+
|
|
34
|
+
async function textGenerationExamples() {
|
|
35
|
+
console.log('\n=== Text Generation ===\n')
|
|
36
|
+
|
|
37
|
+
// Simple text generation
|
|
38
|
+
const haiku = await write`a haiku about TypeScript`
|
|
39
|
+
console.log('Haiku:', haiku)
|
|
40
|
+
|
|
41
|
+
// With more context
|
|
42
|
+
const email = await write`a professional email declining a meeting invitation.
|
|
43
|
+
Keep it brief and polite.`
|
|
44
|
+
console.log('\nEmail:', email)
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
// ============================================================================
|
|
48
|
+
// List Generation
|
|
49
|
+
// ============================================================================
|
|
50
|
+
|
|
51
|
+
async function listGenerationExamples() {
|
|
52
|
+
console.log('\n=== List Generation ===\n')
|
|
53
|
+
|
|
54
|
+
// Generate a simple list
|
|
55
|
+
const ideas = await list`5 startup ideas in the AI space`
|
|
56
|
+
console.log('Startup Ideas:')
|
|
57
|
+
ideas.forEach((idea, i) => console.log(` ${i + 1}. ${idea}`))
|
|
58
|
+
|
|
59
|
+
// Using map for processing (batched automatically)
|
|
60
|
+
console.log('\nProcessing ideas with map...')
|
|
61
|
+
const evaluated = await Promise.all(
|
|
62
|
+
ideas.slice(0, 3).map(async (idea) => ({
|
|
63
|
+
idea,
|
|
64
|
+
feasible: await is`"${idea}" is technically feasible with current technology`,
|
|
65
|
+
}))
|
|
66
|
+
)
|
|
67
|
+
|
|
68
|
+
console.log('\nFeasibility Check:')
|
|
69
|
+
evaluated.forEach((e) => {
|
|
70
|
+
console.log(` ${e.feasible ? '✓' : '✗'} ${e.idea}`)
|
|
71
|
+
})
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
// ============================================================================
|
|
75
|
+
// Boolean Checks
|
|
76
|
+
// ============================================================================
|
|
77
|
+
|
|
78
|
+
async function booleanCheckExamples() {
|
|
79
|
+
console.log('\n=== Boolean Checks ===\n')
|
|
80
|
+
|
|
81
|
+
// Simple true/false questions
|
|
82
|
+
const checks = [
|
|
83
|
+
await is`"TypeScript" is a programming language`,
|
|
84
|
+
await is`42 is a prime number`,
|
|
85
|
+
await is`Paris is the capital of France`,
|
|
86
|
+
await is`HTML is a programming language`,
|
|
87
|
+
]
|
|
88
|
+
|
|
89
|
+
console.log('Boolean Checks:')
|
|
90
|
+
console.log(` TypeScript is a programming language: ${checks[0]}`)
|
|
91
|
+
console.log(` 42 is a prime number: ${checks[1]}`)
|
|
92
|
+
console.log(` Paris is capital of France: ${checks[2]}`)
|
|
93
|
+
console.log(` HTML is a programming language: ${checks[3]}`)
|
|
94
|
+
|
|
95
|
+
// Content validation example
|
|
96
|
+
const userInput = 'Buy our amazing product at discount.com!!!'
|
|
97
|
+
const isSpam = await is`This text is spam or promotional: "${userInput}"`
|
|
98
|
+
console.log(`\n "${userInput}" is spam: ${isSpam}`)
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
// ============================================================================
|
|
102
|
+
// Structured Output
|
|
103
|
+
// ============================================================================
|
|
104
|
+
|
|
105
|
+
async function structuredOutputExamples() {
|
|
106
|
+
console.log('\n=== Structured Output ===\n')
|
|
107
|
+
|
|
108
|
+
// Extract structured data from text
|
|
109
|
+
const article = `
|
|
110
|
+
Apple Inc. announced today that CEO Tim Cook will be presenting
|
|
111
|
+
the new iPhone 16 at the September 2024 event in Cupertino, California.
|
|
112
|
+
The device is expected to feature AI capabilities and cost around $999.
|
|
113
|
+
`
|
|
114
|
+
|
|
115
|
+
// Using destructuring to define the schema
|
|
116
|
+
const { company, product, person, location, price, date } = await ai`
|
|
117
|
+
Extract key information from this article:
|
|
118
|
+
${article}
|
|
119
|
+
|
|
120
|
+
Provide:
|
|
121
|
+
- company: company name
|
|
122
|
+
- product: product mentioned
|
|
123
|
+
- person: person mentioned
|
|
124
|
+
- location: location mentioned
|
|
125
|
+
- price: price if mentioned
|
|
126
|
+
- date: date or time mentioned
|
|
127
|
+
`
|
|
128
|
+
|
|
129
|
+
console.log('Extracted Information:')
|
|
130
|
+
console.log(` Company: ${company}`)
|
|
131
|
+
console.log(` Product: ${product}`)
|
|
132
|
+
console.log(` Person: ${person}`)
|
|
133
|
+
console.log(` Location: ${location}`)
|
|
134
|
+
console.log(` Price: ${price}`)
|
|
135
|
+
console.log(` Date: ${date}`)
|
|
136
|
+
|
|
137
|
+
// Generate structured content
|
|
138
|
+
const { title, description, tags } = await ai`
|
|
139
|
+
Create a blog post metadata for a post about "Getting Started with AI Functions":
|
|
140
|
+
- title: engaging blog post title
|
|
141
|
+
- description: SEO description (under 160 chars)
|
|
142
|
+
- tags: array of 5 relevant tags
|
|
143
|
+
`
|
|
144
|
+
|
|
145
|
+
console.log('\nGenerated Blog Metadata:')
|
|
146
|
+
console.log(` Title: ${title}`)
|
|
147
|
+
console.log(` Description: ${description}`)
|
|
148
|
+
console.log(` Tags: ${(tags as string[]).join(', ')}`)
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
// ============================================================================
|
|
152
|
+
// Data Extraction
|
|
153
|
+
// ============================================================================
|
|
154
|
+
|
|
155
|
+
async function extractionExamples() {
|
|
156
|
+
console.log('\n=== Data Extraction ===\n')
|
|
157
|
+
|
|
158
|
+
const text = `
|
|
159
|
+
Contact us at support@example.com or sales@company.io.
|
|
160
|
+
Call John at 555-123-4567 or reach Sarah at 555-987-6543.
|
|
161
|
+
Meeting scheduled for March 15, 2024 and follow-up on April 1st.
|
|
162
|
+
`
|
|
163
|
+
|
|
164
|
+
const emails = await extract`all email addresses from: ${text}`
|
|
165
|
+
console.log('Emails:', emails)
|
|
166
|
+
|
|
167
|
+
const phones = await extract`all phone numbers from: ${text}`
|
|
168
|
+
console.log('Phone Numbers:', phones)
|
|
169
|
+
|
|
170
|
+
const dates = await extract`all dates from: ${text}`
|
|
171
|
+
console.log('Dates:', dates)
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
// ============================================================================
|
|
175
|
+
// Scoped Configuration
|
|
176
|
+
// ============================================================================
|
|
177
|
+
|
|
178
|
+
async function scopedConfigExamples() {
|
|
179
|
+
console.log('\n=== Scoped Configuration ===\n')
|
|
180
|
+
|
|
181
|
+
// Use different settings for specific operations
|
|
182
|
+
const result = await withContext(
|
|
183
|
+
{
|
|
184
|
+
model: 'claude-3-5-haiku-latest', // Use faster model
|
|
185
|
+
temperature: 0.1, // More deterministic
|
|
186
|
+
},
|
|
187
|
+
async () => {
|
|
188
|
+
console.log(' Using Haiku model with low temperature...')
|
|
189
|
+
return write`What is 2+2? Answer with just the number.`
|
|
190
|
+
}
|
|
191
|
+
)
|
|
192
|
+
|
|
193
|
+
console.log(` Result: ${result}`)
|
|
194
|
+
|
|
195
|
+
// Back to default configuration
|
|
196
|
+
const creative = await write`Give a creative name for a cat`
|
|
197
|
+
console.log(` Creative cat name: ${creative}`)
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
// ============================================================================
|
|
201
|
+
// Main
|
|
202
|
+
// ============================================================================
|
|
203
|
+
|
|
204
|
+
async function main() {
|
|
205
|
+
console.log('\n========================================')
|
|
206
|
+
console.log(' ai-functions Quickstart')
|
|
207
|
+
console.log('========================================')
|
|
208
|
+
|
|
209
|
+
await textGenerationExamples()
|
|
210
|
+
await listGenerationExamples()
|
|
211
|
+
await booleanCheckExamples()
|
|
212
|
+
await structuredOutputExamples()
|
|
213
|
+
await extractionExamples()
|
|
214
|
+
await scopedConfigExamples()
|
|
215
|
+
|
|
216
|
+
console.log('\n========================================')
|
|
217
|
+
console.log(' Quickstart Complete!')
|
|
218
|
+
console.log('========================================')
|
|
219
|
+
console.log(`
|
|
220
|
+
Next steps:
|
|
221
|
+
- Try the other examples in this directory
|
|
222
|
+
- Read the README.md for the full API reference
|
|
223
|
+
- Check out test/ for more usage patterns
|
|
224
|
+
`)
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
main()
|
|
228
|
+
.then(() => process.exit(0))
|
|
229
|
+
.catch((error) => {
|
|
230
|
+
console.error('\nError:', error.message)
|
|
231
|
+
process.exit(1)
|
|
232
|
+
})
|
|
@@ -0,0 +1,212 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* RAG Chatbot Example
|
|
3
|
+
*
|
|
4
|
+
* This example demonstrates building a Retrieval-Augmented Generation (RAG) chatbot
|
|
5
|
+
* using ai-functions. It shows how to:
|
|
6
|
+
* - Generate embeddings for documents
|
|
7
|
+
* - Perform semantic search
|
|
8
|
+
* - Generate context-aware responses
|
|
9
|
+
*
|
|
10
|
+
* @example
|
|
11
|
+
* ```bash
|
|
12
|
+
* ANTHROPIC_API_KEY=sk-... npx tsx examples/01-rag-chatbot.ts
|
|
13
|
+
* ```
|
|
14
|
+
*/
|
|
15
|
+
|
|
16
|
+
import {
|
|
17
|
+
write,
|
|
18
|
+
list,
|
|
19
|
+
configure,
|
|
20
|
+
EmbeddingCache,
|
|
21
|
+
MemoryCache,
|
|
22
|
+
GenerationCache,
|
|
23
|
+
withRetry,
|
|
24
|
+
} from '../src/index.js'
|
|
25
|
+
|
|
26
|
+
// ============================================================================
|
|
27
|
+
// Document Store (In-memory for this example)
|
|
28
|
+
// ============================================================================
|
|
29
|
+
|
|
30
|
+
interface Document {
|
|
31
|
+
id: string
|
|
32
|
+
content: string
|
|
33
|
+
embedding?: number[]
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
const documents: Document[] = [
|
|
37
|
+
{
|
|
38
|
+
id: 'doc-1',
|
|
39
|
+
content:
|
|
40
|
+
'ai-functions is a TypeScript library that simplifies AI integration. It provides template literals for natural AI calls like `const poem = await write`a haiku about TypeScript``.',
|
|
41
|
+
},
|
|
42
|
+
{
|
|
43
|
+
id: 'doc-2',
|
|
44
|
+
content:
|
|
45
|
+
'The library supports batch processing with 50% cost savings through provider batch APIs. Use createBatch() to process large workloads efficiently.',
|
|
46
|
+
},
|
|
47
|
+
{
|
|
48
|
+
id: 'doc-3',
|
|
49
|
+
content:
|
|
50
|
+
'Built-in retry logic with exponential backoff handles rate limits automatically. Use withRetry() or RetryPolicy for custom retry behavior.',
|
|
51
|
+
},
|
|
52
|
+
{
|
|
53
|
+
id: 'doc-4',
|
|
54
|
+
content:
|
|
55
|
+
'Budget tracking monitors token usage and costs. BudgetTracker supports alerts at configurable thresholds and enforces spending limits.',
|
|
56
|
+
},
|
|
57
|
+
{
|
|
58
|
+
id: 'doc-5',
|
|
59
|
+
content:
|
|
60
|
+
'The list primitive generates arrays with automatic batching. Use list`5 ideas`.map() to process each item in parallel.',
|
|
61
|
+
},
|
|
62
|
+
]
|
|
63
|
+
|
|
64
|
+
// ============================================================================
|
|
65
|
+
// Simple Embedding Simulation (replace with real embeddings in production)
|
|
66
|
+
// ============================================================================
|
|
67
|
+
|
|
68
|
+
function simulateEmbedding(text: string): number[] {
|
|
69
|
+
// Simple word-based embedding simulation
|
|
70
|
+
// In production, use a real embedding model
|
|
71
|
+
const words = text.toLowerCase().split(/\s+/)
|
|
72
|
+
const embedding = new Array(128).fill(0)
|
|
73
|
+
|
|
74
|
+
for (const word of words) {
|
|
75
|
+
const hash = word.split('').reduce((acc, char) => acc + char.charCodeAt(0), 0)
|
|
76
|
+
embedding[hash % 128] += 1
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
// Normalize
|
|
80
|
+
const magnitude = Math.sqrt(embedding.reduce((acc, val) => acc + val * val, 0))
|
|
81
|
+
return embedding.map((val) => (magnitude > 0 ? val / magnitude : 0))
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
function cosineSimilarity(a: number[], b: number[]): number {
|
|
85
|
+
let dotProduct = 0
|
|
86
|
+
for (let i = 0; i < a.length; i++) {
|
|
87
|
+
dotProduct += a[i] * b[i]
|
|
88
|
+
}
|
|
89
|
+
return dotProduct
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
// ============================================================================
|
|
93
|
+
// RAG Chatbot Implementation
|
|
94
|
+
// ============================================================================
|
|
95
|
+
|
|
96
|
+
class RAGChatbot {
|
|
97
|
+
private documents: Document[]
|
|
98
|
+
private responseCache: GenerationCache
|
|
99
|
+
|
|
100
|
+
constructor(documents: Document[]) {
|
|
101
|
+
this.documents = documents
|
|
102
|
+
this.responseCache = new GenerationCache({
|
|
103
|
+
defaultTTL: 3600000, // 1 hour cache
|
|
104
|
+
})
|
|
105
|
+
|
|
106
|
+
// Generate embeddings for all documents
|
|
107
|
+
for (const doc of this.documents) {
|
|
108
|
+
doc.embedding = simulateEmbedding(doc.content)
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
/**
|
|
113
|
+
* Find the most relevant documents for a query
|
|
114
|
+
*/
|
|
115
|
+
private findRelevantDocs(query: string, topK: number = 3): Document[] {
|
|
116
|
+
const queryEmbedding = simulateEmbedding(query)
|
|
117
|
+
|
|
118
|
+
const scored = this.documents.map((doc) => ({
|
|
119
|
+
doc,
|
|
120
|
+
score: cosineSimilarity(queryEmbedding, doc.embedding!),
|
|
121
|
+
}))
|
|
122
|
+
|
|
123
|
+
return scored
|
|
124
|
+
.sort((a, b) => b.score - a.score)
|
|
125
|
+
.slice(0, topK)
|
|
126
|
+
.map(({ doc }) => doc)
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
/**
|
|
130
|
+
* Generate a response using RAG
|
|
131
|
+
*/
|
|
132
|
+
async chat(userMessage: string): Promise<string> {
|
|
133
|
+
console.log(`\nUser: ${userMessage}`)
|
|
134
|
+
console.log('---')
|
|
135
|
+
|
|
136
|
+
// Step 1: Retrieve relevant documents
|
|
137
|
+
const relevantDocs = this.findRelevantDocs(userMessage)
|
|
138
|
+
console.log(`Found ${relevantDocs.length} relevant documents`)
|
|
139
|
+
|
|
140
|
+
// Step 2: Build context from retrieved documents
|
|
141
|
+
const context = relevantDocs.map((doc, i) => `[Source ${i + 1}]: ${doc.content}`).join('\n\n')
|
|
142
|
+
|
|
143
|
+
// Step 3: Generate response with context
|
|
144
|
+
const response =
|
|
145
|
+
await write`You are a helpful assistant that answers questions about ai-functions library.
|
|
146
|
+
|
|
147
|
+
Context from documentation:
|
|
148
|
+
${context}
|
|
149
|
+
|
|
150
|
+
User Question: ${userMessage}
|
|
151
|
+
|
|
152
|
+
Please provide a helpful, accurate response based on the context above. If the context doesn't contain enough information, say so.`
|
|
153
|
+
|
|
154
|
+
console.log(`Assistant: ${response}`)
|
|
155
|
+
return response
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
/**
|
|
159
|
+
* Generate follow-up questions
|
|
160
|
+
*/
|
|
161
|
+
async suggestFollowUps(topic: string): Promise<string[]> {
|
|
162
|
+
const suggestions =
|
|
163
|
+
await list`3 follow-up questions someone might ask about ${topic} related to ai-functions library`
|
|
164
|
+
return suggestions
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
// ============================================================================
|
|
169
|
+
// Main Example
|
|
170
|
+
// ============================================================================
|
|
171
|
+
|
|
172
|
+
async function main() {
|
|
173
|
+
console.log('\n=== RAG Chatbot Example ===\n')
|
|
174
|
+
|
|
175
|
+
// Configure the AI provider
|
|
176
|
+
configure({
|
|
177
|
+
model: 'sonnet',
|
|
178
|
+
provider: 'anthropic',
|
|
179
|
+
})
|
|
180
|
+
|
|
181
|
+
// Initialize the chatbot with our documents
|
|
182
|
+
const chatbot = new RAGChatbot(documents)
|
|
183
|
+
|
|
184
|
+
// Example conversation
|
|
185
|
+
const questions = [
|
|
186
|
+
'How do I generate a list of items?',
|
|
187
|
+
'What are the cost savings for batch processing?',
|
|
188
|
+
'How does retry handling work?',
|
|
189
|
+
]
|
|
190
|
+
|
|
191
|
+
for (const question of questions) {
|
|
192
|
+
await chatbot.chat(question)
|
|
193
|
+
console.log('')
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
// Generate follow-up suggestions
|
|
197
|
+
console.log('\n--- Suggested follow-up questions ---')
|
|
198
|
+
const followUps = await chatbot.suggestFollowUps('batch processing')
|
|
199
|
+
for (const suggestion of followUps) {
|
|
200
|
+
console.log(`- ${suggestion}`)
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
main()
|
|
205
|
+
.then(() => {
|
|
206
|
+
console.log('\n=== Example Complete ===\n')
|
|
207
|
+
process.exit(0)
|
|
208
|
+
})
|
|
209
|
+
.catch((error) => {
|
|
210
|
+
console.error('\nError:', error.message)
|
|
211
|
+
process.exit(1)
|
|
212
|
+
})
|