@ax-llm/ax 18.0.0 → 18.0.2
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/cli/index.mjs +85 -37
- package/index.cjs +54 -54
- package/index.cjs.map +1 -1
- package/index.d.cts +23 -3
- package/index.d.ts +23 -3
- package/index.global.js +57 -57
- package/index.global.js.map +1 -1
- package/index.js +59 -59
- package/index.js.map +1 -1
- package/package.json +1 -1
- package/scripts/postinstall.mjs +38 -6
- package/skills/ax-agent.md +286 -111
- package/skills/ax-llm.md +479 -244
package/skills/ax-llm.md
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
|
-
name: ax
|
|
2
|
+
name: ax
|
|
3
3
|
description: This skill helps with using the @ax-llm/ax TypeScript library for building LLM applications. Use when the user asks about ax(), ai(), f(), s(), agent(), flow(), AxGen, AxAgent, AxFlow, signatures, streaming, or mentions @ax-llm/ax.
|
|
4
|
-
version: "18.0.
|
|
4
|
+
version: "18.0.2"
|
|
5
5
|
---
|
|
6
6
|
|
|
7
7
|
# Ax Library (@ax-llm/ax) Usage Guide
|
|
@@ -11,24 +11,20 @@ Ax is a TypeScript library for building LLM-powered applications with type-safe
|
|
|
11
11
|
## Quick Reference
|
|
12
12
|
|
|
13
13
|
```typescript
|
|
14
|
-
import { ax, ai,
|
|
14
|
+
import { ax, ai, f, agent, flow, AxGen, AxAgent, AxFlow } from '@ax-llm/ax';
|
|
15
15
|
|
|
16
16
|
// Create AI provider
|
|
17
17
|
const llm = ai({ name: 'openai', apiKey: process.env.OPENAI_API_KEY });
|
|
18
18
|
|
|
19
|
-
// Create typed generator
|
|
20
|
-
const gen = ax(
|
|
19
|
+
// Create typed generator using f() fluent API
|
|
20
|
+
const gen = ax(
|
|
21
|
+
f()
|
|
22
|
+
.input('question', f.string('User question'))
|
|
23
|
+
.output('answer', f.string('AI response'))
|
|
24
|
+
.build()
|
|
25
|
+
);
|
|
21
26
|
const result = await gen.forward(llm, { question: 'What is 2+2?' });
|
|
22
27
|
// result.answer is typed as string
|
|
23
|
-
|
|
24
|
-
// Create signature separately
|
|
25
|
-
const sig = s('text:string -> summary:string');
|
|
26
|
-
|
|
27
|
-
// Field builders for programmatic signatures
|
|
28
|
-
const customSig = f()
|
|
29
|
-
.input('text', f.string('Input text'))
|
|
30
|
-
.output('summary', f.string('Summary output'))
|
|
31
|
-
.build();
|
|
32
28
|
```
|
|
33
29
|
|
|
34
30
|
## 1. AI Provider Setup
|
|
@@ -89,7 +85,7 @@ const grok = ai({ name: 'grok', apiKey: 'your-key' });
|
|
|
89
85
|
### Full Provider Example
|
|
90
86
|
|
|
91
87
|
```typescript
|
|
92
|
-
import { ai, ax } from '@ax-llm/ax';
|
|
88
|
+
import { ai, ax, f } from '@ax-llm/ax';
|
|
93
89
|
|
|
94
90
|
// Create provider with options
|
|
95
91
|
const llm = ai({
|
|
@@ -103,117 +99,34 @@ const llm = ai({
|
|
|
103
99
|
});
|
|
104
100
|
|
|
105
101
|
// Use with generator
|
|
106
|
-
const gen = ax(
|
|
102
|
+
const gen = ax(
|
|
103
|
+
f()
|
|
104
|
+
.input('topic', f.string())
|
|
105
|
+
.output('essay', f.string('A short essay'))
|
|
106
|
+
.build()
|
|
107
|
+
);
|
|
107
108
|
const result = await gen.forward(llm, { topic: 'Climate change' });
|
|
108
109
|
console.log(result.essay);
|
|
109
110
|
```
|
|
110
111
|
|
|
111
112
|
## 2. Signatures & Generators
|
|
112
113
|
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
```
|
|
116
|
-
[description] inputField:type ["field desc"], ... -> outputField:type ["field desc"], ...
|
|
117
|
-
```
|
|
118
|
-
|
|
119
|
-
**Types:** `string`, `number`, `boolean`, `json`, `class`, `date`, `datetime`, `image`, `audio`, `file`, `code`, `url`
|
|
114
|
+
Use the `f()` fluent builder to create type-safe signatures with validation, descriptions, and constraints.
|
|
120
115
|
|
|
121
|
-
|
|
122
|
-
- `field?:type` - Optional field
|
|
123
|
-
- `field:type[]` - Array type
|
|
124
|
-
- `field:class "opt1, opt2, opt3"` - Enum/classification
|
|
125
|
-
|
|
126
|
-
### Signature Examples
|
|
116
|
+
### Basic Signature
|
|
127
117
|
|
|
128
118
|
```typescript
|
|
129
|
-
import { ax,
|
|
130
|
-
|
|
131
|
-
// Basic signature
|
|
132
|
-
const gen1 = ax('question:string -> answer:string');
|
|
133
|
-
|
|
134
|
-
// With descriptions
|
|
135
|
-
const gen2 = ax('question:string "User question" -> answer:string "AI response"');
|
|
119
|
+
import { ax, f } from '@ax-llm/ax';
|
|
136
120
|
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
// Classification (enum)
|
|
144
|
-
const gen5 = ax('review:string -> sentiment:class "positive, negative, neutral"');
|
|
145
|
-
|
|
146
|
-
// Multiple outputs
|
|
147
|
-
const gen6 = ax('article:string -> title:string, summary:string, tags:string[]');
|
|
148
|
-
|
|
149
|
-
// Numbers and booleans
|
|
150
|
-
const gen7 = ax('text:string -> wordCount:number, isQuestion:boolean');
|
|
151
|
-
|
|
152
|
-
// JSON output
|
|
153
|
-
const gen8 = ax('data:string -> parsed:json');
|
|
154
|
-
|
|
155
|
-
// Dates
|
|
156
|
-
const gen9 = ax('text:string -> extractedDate:date');
|
|
157
|
-
|
|
158
|
-
// Code blocks
|
|
159
|
-
const gen10 = ax('task:string -> code:code "python"');
|
|
160
|
-
|
|
161
|
-
// Signature description
|
|
162
|
-
const gen11 = ax('"Translate text to French" text:string -> translation:string');
|
|
163
|
-
|
|
164
|
-
// Using s() for signature only
|
|
165
|
-
const sig = s('input:string -> output:string');
|
|
166
|
-
```
|
|
167
|
-
|
|
168
|
-
### Complete Generator Example
|
|
169
|
-
|
|
170
|
-
```typescript
|
|
171
|
-
import { ai, ax } from '@ax-llm/ax';
|
|
172
|
-
|
|
173
|
-
const llm = ai({ name: 'openai', apiKey: process.env.OPENAI_API_KEY! });
|
|
174
|
-
|
|
175
|
-
// Create generator with options
|
|
176
|
-
const summarizer = ax('article:string -> summary:string, keyPoints:string[]', {
|
|
177
|
-
description: 'Summarize articles and extract key points',
|
|
178
|
-
maxRetries: 3,
|
|
179
|
-
maxSteps: 5
|
|
180
|
-
});
|
|
181
|
-
|
|
182
|
-
// Forward (non-streaming)
|
|
183
|
-
const result = await summarizer.forward(llm, {
|
|
184
|
-
article: 'Long article text here...'
|
|
185
|
-
});
|
|
186
|
-
|
|
187
|
-
console.log(result.summary); // string
|
|
188
|
-
console.log(result.keyPoints); // string[]
|
|
189
|
-
|
|
190
|
-
// With model override
|
|
191
|
-
const result2 = await summarizer.forward(llm, { article: 'text' }, {
|
|
192
|
-
model: 'gpt-4o-mini'
|
|
193
|
-
});
|
|
194
|
-
```
|
|
195
|
-
|
|
196
|
-
## 3. Field Builders (f.xxx())
|
|
197
|
-
|
|
198
|
-
Use field builders for programmatic signature creation with full type safety.
|
|
199
|
-
|
|
200
|
-
### Basic Field Types
|
|
201
|
-
|
|
202
|
-
```typescript
|
|
203
|
-
import { f } from '@ax-llm/ax';
|
|
204
|
-
|
|
205
|
-
// Start a signature builder
|
|
206
|
-
const sig = f()
|
|
207
|
-
.input('userQuery', f.string('The user question'))
|
|
208
|
-
.input('context', f.string('Background context').optional())
|
|
209
|
-
.output('response', f.string('AI response'))
|
|
210
|
-
.output('confidence', f.number('Confidence score 0-1'))
|
|
211
|
-
.output('isComplete', f.boolean('Whether response is complete'))
|
|
212
|
-
.description('Answer questions with confidence scoring')
|
|
213
|
-
.build();
|
|
121
|
+
const gen = ax(
|
|
122
|
+
f()
|
|
123
|
+
.input('question', f.string('User question'))
|
|
124
|
+
.output('answer', f.string('AI response'))
|
|
125
|
+
.build()
|
|
126
|
+
);
|
|
214
127
|
```
|
|
215
128
|
|
|
216
|
-
###
|
|
129
|
+
### Field Types
|
|
217
130
|
|
|
218
131
|
```typescript
|
|
219
132
|
import { f } from '@ax-llm/ax';
|
|
@@ -270,51 +183,186 @@ f.string().internal() // Internal (not shown to LLM)
|
|
|
270
183
|
f.string().cache() // Enable caching
|
|
271
184
|
```
|
|
272
185
|
|
|
273
|
-
###
|
|
186
|
+
### Signature Examples
|
|
187
|
+
|
|
188
|
+
```typescript
|
|
189
|
+
import { ax, f } from '@ax-llm/ax';
|
|
190
|
+
|
|
191
|
+
// Basic Q&A
|
|
192
|
+
const gen1 = ax(
|
|
193
|
+
f()
|
|
194
|
+
.input('question', f.string())
|
|
195
|
+
.output('answer', f.string())
|
|
196
|
+
.build()
|
|
197
|
+
);
|
|
198
|
+
|
|
199
|
+
// With descriptions
|
|
200
|
+
const gen2 = ax(
|
|
201
|
+
f()
|
|
202
|
+
.input('question', f.string('User question'))
|
|
203
|
+
.output('answer', f.string('AI response'))
|
|
204
|
+
.build()
|
|
205
|
+
);
|
|
206
|
+
|
|
207
|
+
// Optional fields
|
|
208
|
+
const gen3 = ax(
|
|
209
|
+
f()
|
|
210
|
+
.input('query', f.string())
|
|
211
|
+
.input('context', f.string('Background context').optional())
|
|
212
|
+
.output('response', f.string())
|
|
213
|
+
.build()
|
|
214
|
+
);
|
|
215
|
+
|
|
216
|
+
// Arrays
|
|
217
|
+
const gen4 = ax(
|
|
218
|
+
f()
|
|
219
|
+
.input('text', f.string())
|
|
220
|
+
.output('keywords', f.string().array())
|
|
221
|
+
.build()
|
|
222
|
+
);
|
|
223
|
+
|
|
224
|
+
// Classification (enum)
|
|
225
|
+
const gen5 = ax(
|
|
226
|
+
f()
|
|
227
|
+
.input('review', f.string())
|
|
228
|
+
.output('sentiment', f.class(['positive', 'negative', 'neutral']))
|
|
229
|
+
.build()
|
|
230
|
+
);
|
|
231
|
+
|
|
232
|
+
// Multiple outputs
|
|
233
|
+
const gen6 = ax(
|
|
234
|
+
f()
|
|
235
|
+
.input('article', f.string())
|
|
236
|
+
.output('title', f.string())
|
|
237
|
+
.output('summary', f.string())
|
|
238
|
+
.output('tags', f.string().array())
|
|
239
|
+
.build()
|
|
240
|
+
);
|
|
241
|
+
|
|
242
|
+
// Numbers and booleans
|
|
243
|
+
const gen7 = ax(
|
|
244
|
+
f()
|
|
245
|
+
.input('text', f.string())
|
|
246
|
+
.output('wordCount', f.number())
|
|
247
|
+
.output('isQuestion', f.boolean())
|
|
248
|
+
.build()
|
|
249
|
+
);
|
|
250
|
+
|
|
251
|
+
// JSON output
|
|
252
|
+
const gen8 = ax(
|
|
253
|
+
f()
|
|
254
|
+
.input('data', f.string())
|
|
255
|
+
.output('parsed', f.json())
|
|
256
|
+
.build()
|
|
257
|
+
);
|
|
258
|
+
|
|
259
|
+
// Dates
|
|
260
|
+
const gen9 = ax(
|
|
261
|
+
f()
|
|
262
|
+
.input('text', f.string())
|
|
263
|
+
.output('extractedDate', f.date())
|
|
264
|
+
.build()
|
|
265
|
+
);
|
|
266
|
+
|
|
267
|
+
// Code blocks
|
|
268
|
+
const gen10 = ax(
|
|
269
|
+
f()
|
|
270
|
+
.input('task', f.string())
|
|
271
|
+
.output('code', f.code('python'))
|
|
272
|
+
.build()
|
|
273
|
+
);
|
|
274
|
+
|
|
275
|
+
// Signature description
|
|
276
|
+
const gen11 = ax(
|
|
277
|
+
f()
|
|
278
|
+
.input('text', f.string())
|
|
279
|
+
.output('translation', f.string())
|
|
280
|
+
.description('Translate text to French')
|
|
281
|
+
.build()
|
|
282
|
+
);
|
|
283
|
+
|
|
284
|
+
// Nested objects
|
|
285
|
+
const gen12 = ax(
|
|
286
|
+
f()
|
|
287
|
+
.input('document', f.string('Document to analyze'))
|
|
288
|
+
.input('analysisType', f.class(['sentiment', 'entities', 'summary']))
|
|
289
|
+
.output('result', f.object({
|
|
290
|
+
score: f.number().min(0).max(1),
|
|
291
|
+
label: f.string(),
|
|
292
|
+
details: f.string().optional()
|
|
293
|
+
}))
|
|
294
|
+
.output('entities', f.object({
|
|
295
|
+
name: f.string(),
|
|
296
|
+
type: f.class(['person', 'org', 'location'])
|
|
297
|
+
}).array().optional())
|
|
298
|
+
.description('Analyze documents')
|
|
299
|
+
.build()
|
|
300
|
+
);
|
|
301
|
+
```
|
|
302
|
+
|
|
303
|
+
### Complete Generator Example
|
|
274
304
|
|
|
275
305
|
```typescript
|
|
276
306
|
import { ai, ax, f } from '@ax-llm/ax';
|
|
277
307
|
|
|
278
|
-
|
|
279
|
-
const analysisSig = f()
|
|
280
|
-
.input('document', f.string('Document to analyze'))
|
|
281
|
-
.input('analysisType', f.class(['sentiment', 'entities', 'summary']))
|
|
282
|
-
.output('result', f.object({
|
|
283
|
-
score: f.number().min(0).max(1),
|
|
284
|
-
label: f.string(),
|
|
285
|
-
details: f.string().optional()
|
|
286
|
-
}))
|
|
287
|
-
.output('entities', f.object({
|
|
288
|
-
name: f.string(),
|
|
289
|
-
type: f.class(['person', 'org', 'location'])
|
|
290
|
-
}).array().optional())
|
|
291
|
-
.description('Analyze documents')
|
|
292
|
-
.build();
|
|
308
|
+
const llm = ai({ name: 'openai', apiKey: process.env.OPENAI_API_KEY! });
|
|
293
309
|
|
|
294
|
-
// Create generator
|
|
295
|
-
const
|
|
310
|
+
// Create generator with options
|
|
311
|
+
const summarizer = ax(
|
|
312
|
+
f()
|
|
313
|
+
.input('article', f.string('Article to summarize'))
|
|
314
|
+
.output('summary', f.string('Concise summary'))
|
|
315
|
+
.output('keyPoints', f.string('Key point').array())
|
|
316
|
+
.build(),
|
|
317
|
+
{
|
|
318
|
+
description: 'Summarize articles and extract key points',
|
|
319
|
+
maxRetries: 3,
|
|
320
|
+
maxSteps: 5
|
|
321
|
+
}
|
|
322
|
+
);
|
|
296
323
|
|
|
297
|
-
|
|
324
|
+
// Forward (non-streaming)
|
|
325
|
+
const result = await summarizer.forward(llm, {
|
|
326
|
+
article: 'Long article text here...'
|
|
327
|
+
});
|
|
328
|
+
|
|
329
|
+
console.log(result.summary); // string
|
|
330
|
+
console.log(result.keyPoints); // string[]
|
|
298
331
|
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
332
|
+
// With model override
|
|
333
|
+
const result2 = await summarizer.forward(llm, { article: 'text' }, {
|
|
334
|
+
model: 'gpt-4o-mini'
|
|
302
335
|
});
|
|
336
|
+
```
|
|
337
|
+
|
|
338
|
+
### String Shorthand
|
|
339
|
+
|
|
340
|
+
For simple cases, you can also use string syntax:
|
|
341
|
+
|
|
342
|
+
```typescript
|
|
343
|
+
import { ax } from '@ax-llm/ax';
|
|
303
344
|
|
|
304
|
-
//
|
|
305
|
-
|
|
306
|
-
|
|
345
|
+
// String shorthand: 'inputField:type -> outputField:type'
|
|
346
|
+
const gen = ax('question:string -> answer:string');
|
|
347
|
+
|
|
348
|
+
// Types: string, number, boolean, json, class, date, datetime, image, audio, file, code, url
|
|
349
|
+
// Modifiers: field?:type (optional), field:type[] (array), field:class "opt1, opt2" (enum)
|
|
307
350
|
```
|
|
308
351
|
|
|
309
|
-
##
|
|
352
|
+
## 3. Streaming
|
|
310
353
|
|
|
311
354
|
### Basic Streaming
|
|
312
355
|
|
|
313
356
|
```typescript
|
|
314
|
-
import { ai, ax } from '@ax-llm/ax';
|
|
357
|
+
import { ai, ax, f } from '@ax-llm/ax';
|
|
315
358
|
|
|
316
359
|
const llm = ai({ name: 'openai', apiKey: process.env.OPENAI_API_KEY! });
|
|
317
|
-
const gen = ax(
|
|
360
|
+
const gen = ax(
|
|
361
|
+
f()
|
|
362
|
+
.input('topic', f.string())
|
|
363
|
+
.output('content', f.string())
|
|
364
|
+
.build()
|
|
365
|
+
);
|
|
318
366
|
|
|
319
367
|
// Stream responses
|
|
320
368
|
for await (const chunk of gen.streamingForward(llm, { topic: 'AI' })) {
|
|
@@ -328,11 +376,17 @@ for await (const chunk of gen.streamingForward(llm, { topic: 'AI' })) {
|
|
|
328
376
|
### Complete Streaming Example
|
|
329
377
|
|
|
330
378
|
```typescript
|
|
331
|
-
import { ai, ax } from '@ax-llm/ax';
|
|
379
|
+
import { ai, ax, f } from '@ax-llm/ax';
|
|
332
380
|
|
|
333
381
|
const llm = ai({ name: 'openai', apiKey: process.env.OPENAI_API_KEY! });
|
|
334
382
|
|
|
335
|
-
const writer = ax(
|
|
383
|
+
const writer = ax(
|
|
384
|
+
f()
|
|
385
|
+
.input('prompt', f.string())
|
|
386
|
+
.output('story', f.string())
|
|
387
|
+
.output('title', f.string())
|
|
388
|
+
.build()
|
|
389
|
+
);
|
|
336
390
|
|
|
337
391
|
async function streamStory() {
|
|
338
392
|
let fullStory = '';
|
|
@@ -365,11 +419,16 @@ await streamStory();
|
|
|
365
419
|
### Streaming with Field Processors
|
|
366
420
|
|
|
367
421
|
```typescript
|
|
368
|
-
import { ai, ax } from '@ax-llm/ax';
|
|
422
|
+
import { ai, ax, f } from '@ax-llm/ax';
|
|
369
423
|
|
|
370
424
|
const llm = ai({ name: 'openai', apiKey: process.env.OPENAI_API_KEY! });
|
|
371
425
|
|
|
372
|
-
const gen = ax(
|
|
426
|
+
const gen = ax(
|
|
427
|
+
f()
|
|
428
|
+
.input('query', f.string())
|
|
429
|
+
.output('response', f.string())
|
|
430
|
+
.build()
|
|
431
|
+
);
|
|
373
432
|
|
|
374
433
|
// Add streaming field processor
|
|
375
434
|
gen.addStreamingFieldProcessor('response', (chunk, context) => {
|
|
@@ -381,7 +440,7 @@ gen.addStreamingFieldProcessor('response', (chunk, context) => {
|
|
|
381
440
|
await gen.forward(llm, { query: 'Hello' }, { stream: true });
|
|
382
441
|
```
|
|
383
442
|
|
|
384
|
-
##
|
|
443
|
+
## 4. Agents with Tools
|
|
385
444
|
|
|
386
445
|
Agents can use functions (tools) to perform actions.
|
|
387
446
|
|
|
@@ -412,17 +471,23 @@ const getCurrentWeather = {
|
|
|
412
471
|
### Creating Agents
|
|
413
472
|
|
|
414
473
|
```typescript
|
|
415
|
-
import { ai, agent } from '@ax-llm/ax';
|
|
474
|
+
import { ai, agent, f } from '@ax-llm/ax';
|
|
416
475
|
|
|
417
476
|
const llm = ai({ name: 'openai', apiKey: process.env.OPENAI_API_KEY! });
|
|
418
477
|
|
|
419
478
|
// Create agent with functions
|
|
420
|
-
const weatherAgent = agent(
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
479
|
+
const weatherAgent = agent(
|
|
480
|
+
f()
|
|
481
|
+
.input('query', f.string())
|
|
482
|
+
.output('response', f.string())
|
|
483
|
+
.build(),
|
|
484
|
+
{
|
|
485
|
+
name: 'weatherAssistant',
|
|
486
|
+
description: 'An assistant that helps with weather queries',
|
|
487
|
+
definition: 'You are a helpful weather assistant. Use the getCurrentWeather function to get weather data and provide friendly responses.',
|
|
488
|
+
functions: [getCurrentWeather]
|
|
489
|
+
}
|
|
490
|
+
);
|
|
426
491
|
|
|
427
492
|
const result = await weatherAgent.forward(llm, {
|
|
428
493
|
query: 'What is the weather in Tokyo?'
|
|
@@ -434,7 +499,7 @@ console.log(result.response);
|
|
|
434
499
|
### Complete Agent Example
|
|
435
500
|
|
|
436
501
|
```typescript
|
|
437
|
-
import { ai, agent } from '@ax-llm/ax';
|
|
502
|
+
import { ai, agent, f } from '@ax-llm/ax';
|
|
438
503
|
|
|
439
504
|
// Define tools
|
|
440
505
|
const searchDatabase = {
|
|
@@ -480,7 +545,11 @@ const getProductDetails = {
|
|
|
480
545
|
|
|
481
546
|
// Create agent
|
|
482
547
|
const shopAssistant = agent(
|
|
483
|
-
|
|
548
|
+
f()
|
|
549
|
+
.input('userQuery', f.string())
|
|
550
|
+
.output('response', f.string())
|
|
551
|
+
.output('recommendations', f.string().array())
|
|
552
|
+
.build(),
|
|
484
553
|
{
|
|
485
554
|
name: 'shoppingAssistant',
|
|
486
555
|
description: 'An AI assistant that helps users find and learn about products',
|
|
@@ -507,20 +576,32 @@ console.log('Recommendations:', result.recommendations);
|
|
|
507
576
|
### Nested Agents
|
|
508
577
|
|
|
509
578
|
```typescript
|
|
510
|
-
import { ai, agent } from '@ax-llm/ax';
|
|
579
|
+
import { ai, agent, f } from '@ax-llm/ax';
|
|
511
580
|
|
|
512
581
|
// Child agent
|
|
513
|
-
const researcher = agent(
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
582
|
+
const researcher = agent(
|
|
583
|
+
f()
|
|
584
|
+
.input('topic', f.string())
|
|
585
|
+
.output('findings', f.string())
|
|
586
|
+
.build(),
|
|
587
|
+
{
|
|
588
|
+
name: 'researchAgent',
|
|
589
|
+
description: 'Researches topics and provides detailed findings'
|
|
590
|
+
}
|
|
591
|
+
);
|
|
517
592
|
|
|
518
593
|
// Parent agent that can use child agent
|
|
519
|
-
const writer = agent(
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
594
|
+
const writer = agent(
|
|
595
|
+
f()
|
|
596
|
+
.input('topic', f.string())
|
|
597
|
+
.output('article', f.string())
|
|
598
|
+
.build(),
|
|
599
|
+
{
|
|
600
|
+
name: 'writerAgent',
|
|
601
|
+
description: 'Writes articles using research from the research agent',
|
|
602
|
+
agents: [researcher]
|
|
603
|
+
}
|
|
604
|
+
);
|
|
524
605
|
|
|
525
606
|
const llm = ai({ name: 'openai', apiKey: process.env.OPENAI_API_KEY! });
|
|
526
607
|
|
|
@@ -529,20 +610,30 @@ const result = await writer.forward(llm, {
|
|
|
529
610
|
});
|
|
530
611
|
```
|
|
531
612
|
|
|
532
|
-
##
|
|
613
|
+
## 5. Workflows (AxFlow)
|
|
533
614
|
|
|
534
615
|
AxFlow enables building complex, multi-step AI workflows with type safety.
|
|
535
616
|
|
|
536
617
|
### Basic Flow
|
|
537
618
|
|
|
538
619
|
```typescript
|
|
539
|
-
import { ai, flow } from '@ax-llm/ax';
|
|
620
|
+
import { ai, flow, f } from '@ax-llm/ax';
|
|
540
621
|
|
|
541
622
|
const llm = ai({ name: 'openai', apiKey: process.env.OPENAI_API_KEY! });
|
|
542
623
|
|
|
624
|
+
const summarizerSig = f()
|
|
625
|
+
.input('text', f.string())
|
|
626
|
+
.output('summary', f.string())
|
|
627
|
+
.build();
|
|
628
|
+
|
|
629
|
+
const translatorSig = f()
|
|
630
|
+
.input('text', f.string())
|
|
631
|
+
.output('translation', f.string())
|
|
632
|
+
.build();
|
|
633
|
+
|
|
543
634
|
const pipeline = flow<{ text: string }, { result: string }>()
|
|
544
|
-
.node('summarizer',
|
|
545
|
-
.node('translator',
|
|
635
|
+
.node('summarizer', summarizerSig)
|
|
636
|
+
.node('translator', translatorSig)
|
|
546
637
|
.execute('summarizer', (state) => ({ text: state.text }))
|
|
547
638
|
.execute('translator', (state) => ({ text: state.summarizerResult.summary }))
|
|
548
639
|
.map((state) => ({ result: state.translatorResult.translation }));
|
|
@@ -554,13 +645,23 @@ console.log(result.result);
|
|
|
554
645
|
### Flow with Branching
|
|
555
646
|
|
|
556
647
|
```typescript
|
|
557
|
-
import { ai, flow } from '@ax-llm/ax';
|
|
648
|
+
import { ai, flow, f } from '@ax-llm/ax';
|
|
558
649
|
|
|
559
650
|
const llm = ai({ name: 'openai', apiKey: process.env.OPENAI_API_KEY! });
|
|
560
651
|
|
|
652
|
+
const technicalSig = f()
|
|
653
|
+
.input('query', f.string())
|
|
654
|
+
.output('answer', f.string())
|
|
655
|
+
.build();
|
|
656
|
+
|
|
657
|
+
const creativeSig = f()
|
|
658
|
+
.input('query', f.string())
|
|
659
|
+
.output('answer', f.string())
|
|
660
|
+
.build();
|
|
661
|
+
|
|
561
662
|
const workflow = flow<{ query: string; type: string }, { output: string }>()
|
|
562
|
-
.node('technical',
|
|
563
|
-
.node('creative',
|
|
663
|
+
.node('technical', technicalSig)
|
|
664
|
+
.node('creative', creativeSig)
|
|
564
665
|
.branch(
|
|
565
666
|
(state) => state.type === 'technical',
|
|
566
667
|
(branch) => branch.execute('technical', (s) => ({ query: s.query })),
|
|
@@ -579,14 +680,30 @@ const result = await workflow.forward(llm, {
|
|
|
579
680
|
### Flow with Parallel Execution
|
|
580
681
|
|
|
581
682
|
```typescript
|
|
582
|
-
import { ai, flow } from '@ax-llm/ax';
|
|
683
|
+
import { ai, flow, f } from '@ax-llm/ax';
|
|
583
684
|
|
|
584
685
|
const llm = ai({ name: 'openai', apiKey: process.env.OPENAI_API_KEY! });
|
|
585
686
|
|
|
687
|
+
const prosSig = f()
|
|
688
|
+
.input('topic', f.string())
|
|
689
|
+
.output('arguments', f.string())
|
|
690
|
+
.build();
|
|
691
|
+
|
|
692
|
+
const consSig = f()
|
|
693
|
+
.input('topic', f.string())
|
|
694
|
+
.output('arguments', f.string())
|
|
695
|
+
.build();
|
|
696
|
+
|
|
697
|
+
const summarySig = f()
|
|
698
|
+
.input('prosArgs', f.string())
|
|
699
|
+
.input('consArgs', f.string())
|
|
700
|
+
.output('summary', f.string())
|
|
701
|
+
.build();
|
|
702
|
+
|
|
586
703
|
const parallelFlow = flow<{ topic: string }, { combined: string }>()
|
|
587
|
-
.node('pros',
|
|
588
|
-
.node('cons',
|
|
589
|
-
.node('summary',
|
|
704
|
+
.node('pros', prosSig)
|
|
705
|
+
.node('cons', consSig)
|
|
706
|
+
.node('summary', summarySig)
|
|
590
707
|
.parallel([
|
|
591
708
|
{ branch: (b) => b.execute('pros', (s) => ({ topic: s.topic })) },
|
|
592
709
|
{ branch: (b) => b.execute('cons', (s) => ({ topic: s.topic })) }
|
|
@@ -666,15 +783,19 @@ console.log('Article:', result.article);
|
|
|
666
783
|
console.log('Word count:', result.wordCount);
|
|
667
784
|
```
|
|
668
785
|
|
|
669
|
-
##
|
|
786
|
+
## 6. Common Patterns
|
|
670
787
|
|
|
671
788
|
### Classification
|
|
672
789
|
|
|
673
790
|
```typescript
|
|
674
|
-
import { ai, ax } from '@ax-llm/ax';
|
|
791
|
+
import { ai, ax, f } from '@ax-llm/ax';
|
|
675
792
|
|
|
676
793
|
const classifier = ax(
|
|
677
|
-
|
|
794
|
+
f()
|
|
795
|
+
.input('text', f.string())
|
|
796
|
+
.output('category', f.class(['spam', 'ham', 'uncertain']))
|
|
797
|
+
.output('confidence', f.number().min(0).max(1))
|
|
798
|
+
.build()
|
|
678
799
|
);
|
|
679
800
|
|
|
680
801
|
const llm = ai({ name: 'openai', apiKey: process.env.OPENAI_API_KEY! });
|
|
@@ -692,17 +813,7 @@ console.log(result.confidence); // 0.95
|
|
|
692
813
|
```typescript
|
|
693
814
|
import { ai, ax, f } from '@ax-llm/ax';
|
|
694
815
|
|
|
695
|
-
|
|
696
|
-
const extractor = ax(`
|
|
697
|
-
text:string ->
|
|
698
|
-
people:string[],
|
|
699
|
-
organizations:string[],
|
|
700
|
-
locations:string[],
|
|
701
|
-
dates:date[]
|
|
702
|
-
`);
|
|
703
|
-
|
|
704
|
-
// Or with field builders for structured output
|
|
705
|
-
const structuredExtractor = ax(
|
|
816
|
+
const extractor = ax(
|
|
706
817
|
f()
|
|
707
818
|
.input('text', f.string())
|
|
708
819
|
.output('entities', f.object({
|
|
@@ -719,9 +830,9 @@ const result = await extractor.forward(llm, {
|
|
|
719
830
|
text: 'Tim Cook announced that Apple will open a new store in Paris on January 15th.'
|
|
720
831
|
});
|
|
721
832
|
|
|
722
|
-
console.log(result.people); // ['Tim Cook']
|
|
723
|
-
console.log(result.organizations); // ['Apple']
|
|
724
|
-
console.log(result.locations); // ['Paris']
|
|
833
|
+
console.log(result.entities.people); // ['Tim Cook']
|
|
834
|
+
console.log(result.entities.organizations); // ['Apple']
|
|
835
|
+
console.log(result.entities.locations); // ['Paris']
|
|
725
836
|
```
|
|
726
837
|
|
|
727
838
|
### Multi-modal (Images)
|
|
@@ -757,14 +868,34 @@ const result2 = await imageAnalyzer.forward(llm, {
|
|
|
757
868
|
### Chaining Generators
|
|
758
869
|
|
|
759
870
|
```typescript
|
|
760
|
-
import { ai, ax } from '@ax-llm/ax';
|
|
871
|
+
import { ai, ax, f } from '@ax-llm/ax';
|
|
761
872
|
|
|
762
873
|
const llm = ai({ name: 'openai', apiKey: process.env.OPENAI_API_KEY! });
|
|
763
874
|
|
|
764
875
|
// Define generators
|
|
765
|
-
const researcher = ax(
|
|
766
|
-
|
|
767
|
-
|
|
876
|
+
const researcher = ax(
|
|
877
|
+
f()
|
|
878
|
+
.input('topic', f.string())
|
|
879
|
+
.output('research', f.string())
|
|
880
|
+
.output('keyFacts', f.string().array())
|
|
881
|
+
.build()
|
|
882
|
+
);
|
|
883
|
+
|
|
884
|
+
const writer = ax(
|
|
885
|
+
f()
|
|
886
|
+
.input('research', f.string())
|
|
887
|
+
.input('keyFacts', f.string().array())
|
|
888
|
+
.output('article', f.string())
|
|
889
|
+
.build()
|
|
890
|
+
);
|
|
891
|
+
|
|
892
|
+
const editor = ax(
|
|
893
|
+
f()
|
|
894
|
+
.input('article', f.string())
|
|
895
|
+
.output('editedArticle', f.string())
|
|
896
|
+
.output('suggestions', f.string().array())
|
|
897
|
+
.build()
|
|
898
|
+
);
|
|
768
899
|
|
|
769
900
|
// Chain them
|
|
770
901
|
async function createArticle(topic: string) {
|
|
@@ -789,9 +920,14 @@ console.log(result.editedArticle);
|
|
|
789
920
|
### Error Handling
|
|
790
921
|
|
|
791
922
|
```typescript
|
|
792
|
-
import { ai, ax, AxGenerateError, AxAIServiceError } from '@ax-llm/ax';
|
|
923
|
+
import { ai, ax, f, AxGenerateError, AxAIServiceError } from '@ax-llm/ax';
|
|
793
924
|
|
|
794
|
-
const gen = ax(
|
|
925
|
+
const gen = ax(
|
|
926
|
+
f()
|
|
927
|
+
.input('input', f.string())
|
|
928
|
+
.output('output', f.string())
|
|
929
|
+
.build()
|
|
930
|
+
);
|
|
795
931
|
const llm = ai({ name: 'openai', apiKey: process.env.OPENAI_API_KEY! });
|
|
796
932
|
|
|
797
933
|
try {
|
|
@@ -812,9 +948,14 @@ try {
|
|
|
812
948
|
### Examples and Few-Shot Learning
|
|
813
949
|
|
|
814
950
|
```typescript
|
|
815
|
-
import { ai, ax } from '@ax-llm/ax';
|
|
951
|
+
import { ai, ax, f } from '@ax-llm/ax';
|
|
816
952
|
|
|
817
|
-
const classifier = ax(
|
|
953
|
+
const classifier = ax(
|
|
954
|
+
f()
|
|
955
|
+
.input('text', f.string())
|
|
956
|
+
.output('sentiment', f.class(['positive', 'negative', 'neutral']))
|
|
957
|
+
.build()
|
|
958
|
+
);
|
|
818
959
|
|
|
819
960
|
// Set examples for few-shot learning
|
|
820
961
|
classifier.setExamples([
|
|
@@ -833,9 +974,14 @@ const result = await classifier.forward(llm, {
|
|
|
833
974
|
### Assertions and Validation
|
|
834
975
|
|
|
835
976
|
```typescript
|
|
836
|
-
import { ai, ax } from '@ax-llm/ax';
|
|
977
|
+
import { ai, ax, f } from '@ax-llm/ax';
|
|
837
978
|
|
|
838
|
-
const gen = ax(
|
|
979
|
+
const gen = ax(
|
|
980
|
+
f()
|
|
981
|
+
.input('number', f.number())
|
|
982
|
+
.output('doubled', f.number())
|
|
983
|
+
.build()
|
|
984
|
+
);
|
|
839
985
|
|
|
840
986
|
// Add assertion
|
|
841
987
|
gen.addAssert(
|
|
@@ -852,9 +998,14 @@ const result = await gen.forward(llm, { number: 5 }, { maxRetries: 3 });
|
|
|
852
998
|
### Memory and Context
|
|
853
999
|
|
|
854
1000
|
```typescript
|
|
855
|
-
import { ai, ax, AxMemory } from '@ax-llm/ax';
|
|
1001
|
+
import { ai, ax, f, AxMemory } from '@ax-llm/ax';
|
|
856
1002
|
|
|
857
|
-
const chatbot = ax(
|
|
1003
|
+
const chatbot = ax(
|
|
1004
|
+
f()
|
|
1005
|
+
.input('userMessage', f.string())
|
|
1006
|
+
.output('response', f.string())
|
|
1007
|
+
.build()
|
|
1008
|
+
);
|
|
858
1009
|
const llm = ai({ name: 'openai', apiKey: process.env.OPENAI_API_KEY! });
|
|
859
1010
|
|
|
860
1011
|
// Create shared memory
|
|
@@ -866,15 +1017,20 @@ const response = await chatbot.forward(llm, { userMessage: 'What is my name?' },
|
|
|
866
1017
|
// response.response will reference "Alice"
|
|
867
1018
|
```
|
|
868
1019
|
|
|
869
|
-
##
|
|
1020
|
+
## 7. Advanced Configuration
|
|
870
1021
|
|
|
871
1022
|
### Model Configuration
|
|
872
1023
|
|
|
873
1024
|
```typescript
|
|
874
|
-
import { ai, ax } from '@ax-llm/ax';
|
|
1025
|
+
import { ai, ax, f } from '@ax-llm/ax';
|
|
875
1026
|
|
|
876
1027
|
const llm = ai({ name: 'openai', apiKey: process.env.OPENAI_API_KEY! });
|
|
877
|
-
const gen = ax(
|
|
1028
|
+
const gen = ax(
|
|
1029
|
+
f()
|
|
1030
|
+
.input('input', f.string())
|
|
1031
|
+
.output('output', f.string())
|
|
1032
|
+
.build()
|
|
1033
|
+
);
|
|
878
1034
|
|
|
879
1035
|
const result = await gen.forward(llm, { input: 'test' }, {
|
|
880
1036
|
model: 'gpt-4o',
|
|
@@ -889,10 +1045,15 @@ const result = await gen.forward(llm, { input: 'test' }, {
|
|
|
889
1045
|
### Debugging
|
|
890
1046
|
|
|
891
1047
|
```typescript
|
|
892
|
-
import { ai, ax, axCreateDefaultColorLogger } from '@ax-llm/ax';
|
|
1048
|
+
import { ai, ax, f, axCreateDefaultColorLogger } from '@ax-llm/ax';
|
|
893
1049
|
|
|
894
1050
|
const llm = ai({ name: 'openai', apiKey: process.env.OPENAI_API_KEY! });
|
|
895
|
-
const gen = ax(
|
|
1051
|
+
const gen = ax(
|
|
1052
|
+
f()
|
|
1053
|
+
.input('input', f.string())
|
|
1054
|
+
.output('output', f.string())
|
|
1055
|
+
.build()
|
|
1056
|
+
);
|
|
896
1057
|
|
|
897
1058
|
// Enable debug logging
|
|
898
1059
|
const result = await gen.forward(llm, { input: 'test' }, {
|
|
@@ -904,9 +1065,15 @@ const result = await gen.forward(llm, { input: 'test' }, {
|
|
|
904
1065
|
### Context Caching
|
|
905
1066
|
|
|
906
1067
|
```typescript
|
|
907
|
-
import { ai, ax } from '@ax-llm/ax';
|
|
1068
|
+
import { ai, ax, f } from '@ax-llm/ax';
|
|
908
1069
|
|
|
909
|
-
const gen = ax(
|
|
1070
|
+
const gen = ax(
|
|
1071
|
+
f()
|
|
1072
|
+
.input('document', f.string())
|
|
1073
|
+
.input('question', f.string())
|
|
1074
|
+
.output('answer', f.string())
|
|
1075
|
+
.build()
|
|
1076
|
+
);
|
|
910
1077
|
const llm = ai({ name: 'anthropic', apiKey: process.env.ANTHROPIC_API_KEY! });
|
|
911
1078
|
|
|
912
1079
|
// Enable context caching for long documents
|
|
@@ -920,7 +1087,7 @@ const result = await gen.forward(llm, {
|
|
|
920
1087
|
});
|
|
921
1088
|
```
|
|
922
1089
|
|
|
923
|
-
##
|
|
1090
|
+
## 8. Forward & AI Options
|
|
924
1091
|
|
|
925
1092
|
### Quick Reference Table
|
|
926
1093
|
|
|
@@ -940,10 +1107,15 @@ const result = await gen.forward(llm, {
|
|
|
940
1107
|
### Execution Control Options
|
|
941
1108
|
|
|
942
1109
|
```typescript
|
|
943
|
-
import { ai, ax } from '@ax-llm/ax';
|
|
1110
|
+
import { ai, ax, f } from '@ax-llm/ax';
|
|
944
1111
|
|
|
945
1112
|
const llm = ai({ name: 'openai', apiKey: process.env.OPENAI_API_KEY! });
|
|
946
|
-
const gen = ax(
|
|
1113
|
+
const gen = ax(
|
|
1114
|
+
f()
|
|
1115
|
+
.input('input', f.string())
|
|
1116
|
+
.output('output', f.string())
|
|
1117
|
+
.build()
|
|
1118
|
+
);
|
|
947
1119
|
|
|
948
1120
|
const result = await gen.forward(llm, { input: 'test' }, {
|
|
949
1121
|
// Retry failed generations (validation failures, API errors)
|
|
@@ -960,10 +1132,15 @@ const result = await gen.forward(llm, { input: 'test' }, {
|
|
|
960
1132
|
### Model Configuration
|
|
961
1133
|
|
|
962
1134
|
```typescript
|
|
963
|
-
import { ai, ax } from '@ax-llm/ax';
|
|
1135
|
+
import { ai, ax, f } from '@ax-llm/ax';
|
|
964
1136
|
|
|
965
1137
|
const llm = ai({ name: 'openai', apiKey: process.env.OPENAI_API_KEY! });
|
|
966
|
-
const gen = ax(
|
|
1138
|
+
const gen = ax(
|
|
1139
|
+
f()
|
|
1140
|
+
.input('input', f.string())
|
|
1141
|
+
.output('output', f.string())
|
|
1142
|
+
.build()
|
|
1143
|
+
);
|
|
967
1144
|
|
|
968
1145
|
const result = await gen.forward(llm, { input: 'test' }, {
|
|
969
1146
|
// Override the model for this request
|
|
@@ -1006,10 +1183,16 @@ const result = await gen.forward(llm, { input: 'test' }, {
|
|
|
1006
1183
|
Context caching saves costs when repeatedly querying with the same large context (documents, system prompts, examples).
|
|
1007
1184
|
|
|
1008
1185
|
```typescript
|
|
1009
|
-
import { ai, ax } from '@ax-llm/ax';
|
|
1186
|
+
import { ai, ax, f } from '@ax-llm/ax';
|
|
1010
1187
|
|
|
1011
1188
|
const llm = ai({ name: 'anthropic', apiKey: process.env.ANTHROPIC_API_KEY! });
|
|
1012
|
-
const gen = ax(
|
|
1189
|
+
const gen = ax(
|
|
1190
|
+
f()
|
|
1191
|
+
.input('document', f.string())
|
|
1192
|
+
.input('question', f.string())
|
|
1193
|
+
.output('answer', f.string())
|
|
1194
|
+
.build()
|
|
1195
|
+
);
|
|
1013
1196
|
|
|
1014
1197
|
const longDocument = '... very long document ...';
|
|
1015
1198
|
|
|
@@ -1047,10 +1230,15 @@ for (const question of questions) {
|
|
|
1047
1230
|
For reasoning models that support extended thinking:
|
|
1048
1231
|
|
|
1049
1232
|
```typescript
|
|
1050
|
-
import { ai, ax } from '@ax-llm/ax';
|
|
1233
|
+
import { ai, ax, f } from '@ax-llm/ax';
|
|
1051
1234
|
|
|
1052
1235
|
const llm = ai({ name: 'openai', apiKey: process.env.OPENAI_API_KEY! });
|
|
1053
|
-
const gen = ax(
|
|
1236
|
+
const gen = ax(
|
|
1237
|
+
f()
|
|
1238
|
+
.input('problem', f.string())
|
|
1239
|
+
.output('solution', f.string())
|
|
1240
|
+
.build()
|
|
1241
|
+
);
|
|
1054
1242
|
|
|
1055
1243
|
const result = await gen.forward(llm, { problem: 'Complex math problem' }, {
|
|
1056
1244
|
model: 'o1',
|
|
@@ -1071,10 +1259,16 @@ const result = await gen.forward(llm, { problem: 'Complex math problem' }, {
|
|
|
1071
1259
|
Generate multiple samples and pick the best one:
|
|
1072
1260
|
|
|
1073
1261
|
```typescript
|
|
1074
|
-
import { ai, ax } from '@ax-llm/ax';
|
|
1262
|
+
import { ai, ax, f } from '@ax-llm/ax';
|
|
1075
1263
|
|
|
1076
1264
|
const llm = ai({ name: 'openai', apiKey: process.env.OPENAI_API_KEY! });
|
|
1077
|
-
const gen = ax(
|
|
1265
|
+
const gen = ax(
|
|
1266
|
+
f()
|
|
1267
|
+
.input('input', f.string())
|
|
1268
|
+
.output('output', f.string())
|
|
1269
|
+
.output('confidence', f.number())
|
|
1270
|
+
.build()
|
|
1271
|
+
);
|
|
1078
1272
|
|
|
1079
1273
|
const result = await gen.forward(llm, { input: 'test' }, {
|
|
1080
1274
|
// Generate multiple samples
|
|
@@ -1095,13 +1289,21 @@ const result = await gen.forward(llm, { input: 'test' }, {
|
|
|
1095
1289
|
Control how agents use tools/functions:
|
|
1096
1290
|
|
|
1097
1291
|
```typescript
|
|
1098
|
-
import { ai, agent } from '@ax-llm/ax';
|
|
1292
|
+
import { ai, agent, f } from '@ax-llm/ax';
|
|
1099
1293
|
|
|
1100
1294
|
const llm = ai({ name: 'openai', apiKey: process.env.OPENAI_API_KEY! });
|
|
1101
1295
|
|
|
1102
|
-
const myAgent = agent(
|
|
1103
|
-
|
|
1104
|
-
|
|
1296
|
+
const myAgent = agent(
|
|
1297
|
+
f()
|
|
1298
|
+
.input('query', f.string())
|
|
1299
|
+
.output('answer', f.string())
|
|
1300
|
+
.build(),
|
|
1301
|
+
{
|
|
1302
|
+
name: 'toolAgent',
|
|
1303
|
+
description: 'An agent that uses tools to answer queries',
|
|
1304
|
+
functions: [searchTool, calculatorTool]
|
|
1305
|
+
}
|
|
1306
|
+
);
|
|
1105
1307
|
|
|
1106
1308
|
const result = await myAgent.forward(llm, { query: 'test' }, {
|
|
1107
1309
|
// Function calling mode:
|
|
@@ -1130,10 +1332,15 @@ const result = await myAgent.forward(llm, { query: 'test' }, {
|
|
|
1130
1332
|
### Debugging & Observability
|
|
1131
1333
|
|
|
1132
1334
|
```typescript
|
|
1133
|
-
import { ai, ax, axCreateDefaultColorLogger } from '@ax-llm/ax';
|
|
1335
|
+
import { ai, ax, f, axCreateDefaultColorLogger } from '@ax-llm/ax';
|
|
1134
1336
|
|
|
1135
1337
|
const llm = ai({ name: 'openai', apiKey: process.env.OPENAI_API_KEY! });
|
|
1136
|
-
const gen = ax(
|
|
1338
|
+
const gen = ax(
|
|
1339
|
+
f()
|
|
1340
|
+
.input('input', f.string())
|
|
1341
|
+
.output('output', f.string())
|
|
1342
|
+
.build()
|
|
1343
|
+
);
|
|
1137
1344
|
|
|
1138
1345
|
const result = await gen.forward(llm, { input: 'test' }, {
|
|
1139
1346
|
// Enable debug logging
|
|
@@ -1168,7 +1375,7 @@ const result = await gen.forward(llm, { input: 'test' }, {
|
|
|
1168
1375
|
### Retry & Error Handling
|
|
1169
1376
|
|
|
1170
1377
|
```typescript
|
|
1171
|
-
import { ai, ax } from '@ax-llm/ax';
|
|
1378
|
+
import { ai, ax, f } from '@ax-llm/ax';
|
|
1172
1379
|
|
|
1173
1380
|
const llm = ai({
|
|
1174
1381
|
name: 'openai',
|
|
@@ -1207,10 +1414,15 @@ const llm = ai({
|
|
|
1207
1414
|
### Request Control
|
|
1208
1415
|
|
|
1209
1416
|
```typescript
|
|
1210
|
-
import { ai, ax } from '@ax-llm/ax';
|
|
1417
|
+
import { ai, ax, f } from '@ax-llm/ax';
|
|
1211
1418
|
|
|
1212
1419
|
const llm = ai({ name: 'openai', apiKey: process.env.OPENAI_API_KEY! });
|
|
1213
|
-
const gen = ax(
|
|
1420
|
+
const gen = ax(
|
|
1421
|
+
f()
|
|
1422
|
+
.input('input', f.string())
|
|
1423
|
+
.output('output', f.string())
|
|
1424
|
+
.build()
|
|
1425
|
+
);
|
|
1214
1426
|
|
|
1215
1427
|
// Create abort controller
|
|
1216
1428
|
const controller = new AbortController();
|
|
@@ -1242,10 +1454,15 @@ try {
|
|
|
1242
1454
|
### Memory Configuration
|
|
1243
1455
|
|
|
1244
1456
|
```typescript
|
|
1245
|
-
import { ai, ax, AxMemory } from '@ax-llm/ax';
|
|
1457
|
+
import { ai, ax, f, AxMemory } from '@ax-llm/ax';
|
|
1246
1458
|
|
|
1247
1459
|
const llm = ai({ name: 'openai', apiKey: process.env.OPENAI_API_KEY! });
|
|
1248
|
-
const gen = ax(
|
|
1460
|
+
const gen = ax(
|
|
1461
|
+
f()
|
|
1462
|
+
.input('message', f.string())
|
|
1463
|
+
.output('response', f.string())
|
|
1464
|
+
.build()
|
|
1465
|
+
);
|
|
1249
1466
|
|
|
1250
1467
|
const memory = new AxMemory();
|
|
1251
1468
|
|
|
@@ -1261,10 +1478,15 @@ const result = await gen.forward(llm, { message: 'Hello' }, {
|
|
|
1261
1478
|
### Validation Options
|
|
1262
1479
|
|
|
1263
1480
|
```typescript
|
|
1264
|
-
import { ai, ax } from '@ax-llm/ax';
|
|
1481
|
+
import { ai, ax, f } from '@ax-llm/ax';
|
|
1265
1482
|
|
|
1266
1483
|
const llm = ai({ name: 'openai', apiKey: process.env.OPENAI_API_KEY! });
|
|
1267
|
-
const gen = ax(
|
|
1484
|
+
const gen = ax(
|
|
1485
|
+
f()
|
|
1486
|
+
.input('input', f.string())
|
|
1487
|
+
.output('output', f.string())
|
|
1488
|
+
.build()
|
|
1489
|
+
);
|
|
1268
1490
|
|
|
1269
1491
|
const result = await gen.forward(llm, { input: 'test' }, {
|
|
1270
1492
|
// Strict mode: fail on any validation error
|
|
@@ -1288,7 +1510,7 @@ const result = await gen.forward(llm, { input: 'test' }, {
|
|
|
1288
1510
|
});
|
|
1289
1511
|
```
|
|
1290
1512
|
|
|
1291
|
-
##
|
|
1513
|
+
## 9. MCP Integration
|
|
1292
1514
|
|
|
1293
1515
|
MCP (Model Context Protocol) enables AxAgent to use external tools from MCP-compliant servers. This allows your agents to interact with databases, file systems, APIs, and other services through a standardized protocol.
|
|
1294
1516
|
|
|
@@ -1312,7 +1534,10 @@ await mcpClient.init();
|
|
|
1312
1534
|
const agent = new AxAgent({
|
|
1313
1535
|
name: 'MyAssistant',
|
|
1314
1536
|
description: 'An assistant with MCP capabilities',
|
|
1315
|
-
signature:
|
|
1537
|
+
signature: f()
|
|
1538
|
+
.input('userMessage', f.string())
|
|
1539
|
+
.output('response', f.string())
|
|
1540
|
+
.build(),
|
|
1316
1541
|
functions: [mcpClient], // Pass client directly
|
|
1317
1542
|
});
|
|
1318
1543
|
|
|
@@ -1364,7 +1589,7 @@ const transport = new AxMCPStreambleHTTPTransport(
|
|
|
1364
1589
|
Pass the MCP client directly to the agent's `functions` array:
|
|
1365
1590
|
|
|
1366
1591
|
```typescript
|
|
1367
|
-
import { AxAgent, AxAI, AxMCPClient } from '@ax-llm/ax';
|
|
1592
|
+
import { AxAgent, AxAI, AxMCPClient, f } from '@ax-llm/ax';
|
|
1368
1593
|
import { AxMCPStdioTransport } from '@ax-llm/ax-tools';
|
|
1369
1594
|
|
|
1370
1595
|
const transport = new AxMCPStdioTransport({
|
|
@@ -1381,7 +1606,11 @@ const memoryAgent = new AxAgent<
|
|
|
1381
1606
|
>({
|
|
1382
1607
|
name: 'MemoryAssistant',
|
|
1383
1608
|
description: 'An assistant that remembers past conversations. Use the database functions to manage, search, and add memories.',
|
|
1384
|
-
signature:
|
|
1609
|
+
signature: f()
|
|
1610
|
+
.input('userMessage', f.string())
|
|
1611
|
+
.input('userId', f.string())
|
|
1612
|
+
.output('assistantResponse', f.string())
|
|
1613
|
+
.build(),
|
|
1385
1614
|
functions: [mcpClient],
|
|
1386
1615
|
});
|
|
1387
1616
|
|
|
@@ -1470,7 +1699,10 @@ const functions = mcpClient.toFunction();
|
|
|
1470
1699
|
// Use with agent
|
|
1471
1700
|
const agent = new AxAgent({
|
|
1472
1701
|
name: 'MyAgent',
|
|
1473
|
-
signature:
|
|
1702
|
+
signature: f()
|
|
1703
|
+
.input('query', f.string())
|
|
1704
|
+
.output('answer', f.string())
|
|
1705
|
+
.build(),
|
|
1474
1706
|
functions: functions, // Or spread: [...functions, otherFunction]
|
|
1475
1707
|
});
|
|
1476
1708
|
```
|
|
@@ -1478,7 +1710,7 @@ const agent = new AxAgent({
|
|
|
1478
1710
|
### Complete Example: Remote HTTP MCP Server
|
|
1479
1711
|
|
|
1480
1712
|
```typescript
|
|
1481
|
-
import { AxAgent, AxAI, AxMCPClient } from '@ax-llm/ax';
|
|
1713
|
+
import { AxAgent, AxAI, AxMCPClient, f } from '@ax-llm/ax';
|
|
1482
1714
|
import { AxMCPStreambleHTTPTransport } from '@ax-llm/ax/mcp/transports/httpStreamTransport.js';
|
|
1483
1715
|
import { createBackendClient } from '@pipedream/sdk/server';
|
|
1484
1716
|
|
|
@@ -1522,7 +1754,10 @@ const notionAgent = new AxAgent<
|
|
|
1522
1754
|
>({
|
|
1523
1755
|
name: 'NotionAssistant',
|
|
1524
1756
|
description: 'An assistant that can interact with Notion documents. Use the provided functions to read, search, and analyze Notion content.',
|
|
1525
|
-
signature:
|
|
1757
|
+
signature: f()
|
|
1758
|
+
.input('userRequest', f.string())
|
|
1759
|
+
.output('assistantResponse', f.string())
|
|
1760
|
+
.build(),
|
|
1526
1761
|
functions: [mcpClient],
|
|
1527
1762
|
});
|
|
1528
1763
|
|