@ax-llm/ax 19.0.44 → 20.0.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.
@@ -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.44"
4
+ version: "20.0.0"
5
5
  ---
6
6
 
7
7
  # Ax Signature Reference
@@ -37,7 +37,7 @@ version: "19.0.44"
37
37
  'problem:string -> reasoning!:string, solution:string' // internal with !
38
38
  ```
39
39
 
40
- ## Three Ways to Create Signatures
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. Hybrid
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
- - [Fluent Signature](https://raw.githubusercontent.com/ax-llm/ax/refs/heads/main/src/examples/fluent-signature-example.ts) — fluent f() API
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