@amitdeshmukh/ax-crew 8.5.0 → 8.7.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.
@@ -0,0 +1,287 @@
1
+ ---
2
+ name: ax-crew-execution-modes
3
+ version: "__VERSION__"
4
+ description: "ax-crew execution modes: execution mode, axgen, axagent, RLM, runtime, contextFields, AxJSRuntime, contextManagement, fields, shared, globallyShared, excluded, maxTurns, maxSubAgentCalls"
5
+ argument-hint: [topic]
6
+ allowed-tools: Read, Grep, Glob
7
+ ---
8
+
9
+ # ax-crew Execution Modes
10
+
11
+ ## axgen (default)
12
+
13
+ Uses `AxGen` for structured generation. Single-pass, deterministic. Sub-agents become callable tool functions. Best for straightforward input-to-output tasks.
14
+
15
+ ```typescript
16
+ {
17
+ name: "SimpleAgent",
18
+ executionMode: "axgen", // default, can be omitted
19
+ signature: "query:string -> answer:string",
20
+ // ...
21
+ }
22
+ ```
23
+
24
+ ## axagent
25
+
26
+ Uses `AxAgent` with RLM (Runtime Language Model). Multi-step agentic reasoning loop. Supports context management, tombstoning, and state inspection.
27
+
28
+ ```typescript
29
+ {
30
+ name: "ReasoningAgent",
31
+ executionMode: "axagent",
32
+ signature: "context:string, query:string -> answer:string",
33
+ // ...
34
+ axAgentOptions: {
35
+ contextFields: ["context"], // required for axagent (can be empty [])
36
+ runtime: new AxJSRuntime({ permissions: [AxJSRuntimePermission.TIMING] }),
37
+ },
38
+ }
39
+ ```
40
+
41
+ Both modes use the same `forward()` / `streamingForward()` API.
42
+
43
+ ## axAgentOptions Full Reference
44
+
45
+ Type: `AxCrewAxAgentOptions` (extends `Partial<AxAgentOptions>`)
46
+
47
+ ```typescript
48
+ axAgentOptions: {
49
+ // Required: which input fields contain context for RLM processing
50
+ contextFields: string[],
51
+
52
+ // Runtime for code execution in RLM
53
+ runtime?: AxJSRuntime,
54
+
55
+ // Max reasoning turns before stopping
56
+ maxTurns?: number,
57
+
58
+ // Max sub-agent delegations
59
+ maxSubAgentCalls?: number,
60
+
61
+ // RLM mode
62
+ mode?: "simple" | "full",
63
+
64
+ // Context management strategies
65
+ contextManagement?: {
66
+ errorPruning?: boolean, // prune context on errors
67
+ hindsightEvaluation?: boolean, // evaluate context relevance
68
+ pruneRank?: number, // ranking threshold for pruning
69
+ tombstoning?: { // summarize pruned context
70
+ model: string,
71
+ modelConfig?: { maxTokens?: number },
72
+ },
73
+ stateInspection?: {
74
+ contextThreshold?: number, // token count threshold
75
+ },
76
+ },
77
+
78
+ // Sub-agents and functions (can also be set via top-level agents/functions)
79
+ agents?: AxAgentOptions['agents'],
80
+ functions?: AxAgentOptions['functions'],
81
+
82
+ // Field sharing between parent and sub-agents
83
+ fields?: {
84
+ shared?: string[], // fields shared with sub-agents
85
+ globallyShared?: string[], // fields shared with all descendants
86
+ excluded?: string[], // opt out of parent's shared fields
87
+ },
88
+ }
89
+ ```
90
+
91
+ ## fields: shared, globallyShared, excluded
92
+
93
+ Control how input/output fields propagate between parent and sub-agents in `axagent` mode.
94
+
95
+ ```typescript
96
+ // Parent agent shares knowledgeBase and userId with sub-agents
97
+ {
98
+ name: "CustomerSupportAgent",
99
+ executionMode: "axagent",
100
+ signature: "query:string, knowledgeBase:string, userId:string -> answer:string",
101
+ agents: ["PolicyLookupAgent", "BillingHelperAgent", "SentimentClassifierAgent"],
102
+ axAgentOptions: {
103
+ contextFields: ["knowledgeBase"],
104
+ fields: { shared: ["knowledgeBase", "userId"] },
105
+ runtime,
106
+ },
107
+ }
108
+
109
+ // Sub-agent that opts OUT of receiving shared fields
110
+ {
111
+ name: "SentimentClassifierAgent",
112
+ executionMode: "axagent",
113
+ signature: 'question:string -> sentiment:string "positive, negative, or neutral"',
114
+ axAgentOptions: {
115
+ contextFields: [],
116
+ fields: { excluded: ["knowledgeBase", "userId"] }, // won't receive these
117
+ runtime,
118
+ },
119
+ }
120
+ ```
121
+
122
+ ## Canonical Pattern: RLM with Context Management
123
+
124
+ From `rlm-long-task.ts`:
125
+
126
+ ```typescript
127
+ import { AxJSRuntime, AxJSRuntimePermission } from '@ax-llm/ax';
128
+ import { AxCrew } from '@amitdeshmukh/ax-crew';
129
+ import type { AxCrewConfig } from '@amitdeshmukh/ax-crew';
130
+
131
+ const runtime = new AxJSRuntime({
132
+ permissions: [AxJSRuntimePermission.TIMING],
133
+ });
134
+
135
+ const config: AxCrewConfig = {
136
+ crew: [
137
+ {
138
+ name: "Analyzer",
139
+ description: "Analyzes a large dataset with semantic context management.",
140
+ executionMode: "axagent",
141
+ signature:
142
+ 'context:string, query:string -> answer:string, keyFindings:string[] "Analyzes context and returns findings"',
143
+ provider: "google-gemini",
144
+ providerKeyName: "GEMINI_API_KEY",
145
+ ai: { model: "gemini-2.5-flash", temperature: 0 },
146
+ axAgentOptions: {
147
+ contextFields: ["context"],
148
+ runtime,
149
+ maxTurns: 20,
150
+ maxSubAgentCalls: 40,
151
+ mode: "simple",
152
+ contextManagement: {
153
+ errorPruning: true,
154
+ hindsightEvaluation: true,
155
+ pruneRank: 2,
156
+ tombstoning: {
157
+ model: "gemini-2.5-flash",
158
+ modelConfig: { maxTokens: 60 },
159
+ },
160
+ stateInspection: { contextThreshold: 3000 },
161
+ },
162
+ },
163
+ },
164
+ ],
165
+ };
166
+
167
+ async function main() {
168
+ const crew = new AxCrew(config);
169
+ try {
170
+ await crew.addAllAgents();
171
+
172
+ const analyzer = crew.agents?.get("Analyzer");
173
+ if (!analyzer) throw new Error("Failed to initialize Analyzer");
174
+
175
+ const result = await analyzer.forward({
176
+ context: "Region,Month,Product,Units,Revenue\nNorth,Jan,Widget-A,1200,48000\n...",
177
+ query: "Which region has the highest revenue growth from Jan to Mar?",
178
+ });
179
+
180
+ console.log("Answer:", result.answer);
181
+ console.log("Key Findings:", result.keyFindings);
182
+
183
+ console.log("Agent Metrics:", JSON.stringify(analyzer.getMetrics?.(), null, 2));
184
+ console.log("Crew Metrics:", JSON.stringify(crew.getCrewMetrics(), null, 2));
185
+ } finally {
186
+ crew.destroy();
187
+ }
188
+ }
189
+
190
+ main().catch(console.error);
191
+ ```
192
+
193
+ ## Canonical Pattern: Shared Fields Between Agents
194
+
195
+ From `rlm-shared-fields.ts`:
196
+
197
+ ```typescript
198
+ import { AxJSRuntime, AxJSRuntimePermission } from '@ax-llm/ax';
199
+ import { AxCrew } from '@amitdeshmukh/ax-crew';
200
+ import type { AxCrewConfig } from '@amitdeshmukh/ax-crew';
201
+
202
+ const runtime = new AxJSRuntime({
203
+ permissions: [AxJSRuntimePermission.TIMING],
204
+ });
205
+
206
+ const config: AxCrewConfig = {
207
+ crew: [
208
+ {
209
+ name: "PolicyLookupAgent",
210
+ description: "Looks up policy details in the provided knowledge base.",
211
+ executionMode: "axagent",
212
+ signature: 'question:string -> answer:string',
213
+ provider: "google-gemini",
214
+ providerKeyName: "GEMINI_API_KEY",
215
+ ai: { model: "gemini-2.5-flash", temperature: 0 },
216
+ axAgentOptions: { contextFields: [], runtime },
217
+ },
218
+ {
219
+ name: "SentimentClassifierAgent",
220
+ description: "Classifies customer message sentiment.",
221
+ executionMode: "axagent",
222
+ signature: 'question:string -> sentiment:string "positive, negative, or neutral"',
223
+ provider: "google-gemini",
224
+ providerKeyName: "GEMINI_API_KEY",
225
+ ai: { model: "gemini-2.5-flash", temperature: 0 },
226
+ axAgentOptions: {
227
+ contextFields: [],
228
+ fields: { excluded: ["knowledgeBase", "userId"] },
229
+ runtime,
230
+ },
231
+ },
232
+ {
233
+ name: "CustomerSupportAgent",
234
+ description: "Routes queries to specialists and returns a final answer.",
235
+ executionMode: "axagent",
236
+ signature: "query:string, knowledgeBase:string, userId:string -> answer:string",
237
+ provider: "google-gemini",
238
+ providerKeyName: "GEMINI_API_KEY",
239
+ ai: { model: "gemini-2.5-flash", temperature: 0 },
240
+ agents: ["PolicyLookupAgent", "SentimentClassifierAgent"],
241
+ axAgentOptions: {
242
+ contextFields: ["knowledgeBase"],
243
+ fields: { shared: ["knowledgeBase", "userId"] },
244
+ runtime,
245
+ },
246
+ },
247
+ ],
248
+ };
249
+
250
+ async function main() {
251
+ const crew = new AxCrew(config);
252
+ try {
253
+ await crew.addAllAgents();
254
+
255
+ const supportAgent = crew.agents?.get("CustomerSupportAgent");
256
+ if (!supportAgent) throw new Error("Failed to initialize");
257
+
258
+ const result = await supportAgent.forward({
259
+ query: "I want to return the Smart Lamp. Am I eligible for a full refund?",
260
+ knowledgeBase: "REFUND POLICY: Full refund within 30 days...",
261
+ userId: "cust-42",
262
+ });
263
+
264
+ console.log("Answer:", result.answer);
265
+ } finally {
266
+ crew.destroy();
267
+ }
268
+ }
269
+
270
+ main().catch(console.error);
271
+ ```
272
+
273
+ ## Do Not Generate
274
+
275
+ - Do NOT use `axAgentOptions` without setting `executionMode: "axagent"` -- it is ignored in `axgen` mode.
276
+ - Do NOT omit `contextFields` when using `axagent` mode -- it is required (use `[]` if no context fields).
277
+ - Do NOT omit `runtime` when using RLM features -- `AxJSRuntime` is required for code execution.
278
+ - Do NOT confuse `fields.shared` with `contextFields` -- `shared` controls field propagation to sub-agents, `contextFields` identifies which fields contain context for RLM processing.
279
+ - Do NOT set `fields.excluded` on a parent agent -- it is for sub-agents opting out of the parent's shared fields.
280
+ - Do NOT use `axAgentOptions.agents` or `axAgentOptions.functions` unless you need the AxAgent-native format -- prefer the top-level `agents` and `functions` config fields.
281
+
282
+ ## References
283
+
284
+ - [rlm-long-task.ts example](https://github.com/amitdeshmukh/ax-crew/blob/main/examples/rlm-long-task.ts)
285
+ - [rlm-shared-fields.ts example](https://github.com/amitdeshmukh/ax-crew/blob/main/examples/rlm-shared-fields.ts)
286
+ - [Source: AxCrewAxAgentOptions type](https://github.com/amitdeshmukh/ax-crew/blob/main/src/types.ts)
287
+ - [Source: StatefulAxAgent execution mode handling](https://github.com/amitdeshmukh/ax-crew/blob/main/src/agents/index.ts)
@@ -0,0 +1,165 @@
1
+ ---
2
+ name: ax-crew-few-shot
3
+ description: AxCrew few-shot examples via examples[] field in AgentConfig. Covers in-context learning, demonstration structure, input/output field matching, setExamplesCompat() for dynamic updates, and when to use examples vs definition/prompt.
4
+ version: "__VERSION__"
5
+ ---
6
+
7
+ # AxCrew Few-Shot Examples
8
+
9
+ The `examples[]` field in `AgentConfig` provides DSPy-style few-shot demonstrations. Each example contains input AND output field values matching the agent's signature.
10
+
11
+ ## Basic Structure
12
+
13
+ ```typescript
14
+ {
15
+ name: "Agent",
16
+ signature: "question:string -> answer:string",
17
+ // ...
18
+ examples: [
19
+ { question: "What is 2+2?", answer: "4" },
20
+ { question: "Capital of France?", answer: "Paris" },
21
+ ],
22
+ }
23
+ ```
24
+
25
+ Every key in the example object must match a field name from the signature (inputs and/or outputs).
26
+
27
+ ## Full Example
28
+
29
+ ```typescript
30
+ import { AxCrew } from 'ax-crew';
31
+ import type { AxCrewConfig } from 'ax-crew';
32
+
33
+ const config: AxCrewConfig = {
34
+ crew: [
35
+ {
36
+ name: "SupportAgent",
37
+ description: "Customer support agent that follows company tone",
38
+ signature:
39
+ "ticket:string, standardPolicies:string[] -> politeSupportResponse:string, decision:string, policyApplied:string",
40
+ provider: "google-gemini",
41
+ providerKeyName: "GEMINI_API_KEY",
42
+ ai: { model: "gemini-2.5-flash", temperature: 0.7 },
43
+ examples: [
44
+ {
45
+ ticket: "I want to return my laptop purchased 10 days ago.",
46
+ standardPolicies: ["Returns within 30 days only"],
47
+ politeSupportResponse:
48
+ "Of course! Your laptop is within our 30-day return window. I'll process that right away.",
49
+ decision: "approved",
50
+ policyApplied: "Returns within 30 days only",
51
+ },
52
+ {
53
+ ticket: "Refund my sale item please.",
54
+ standardPolicies: ["Sale items: no returns, no refunds"],
55
+ politeSupportResponse:
56
+ "I understand your frustration. Unfortunately, sale items are final sale per our policy. I'd be happy to help with an exchange instead.",
57
+ decision: "denied",
58
+ policyApplied: "Sale items: no returns, no refunds",
59
+ },
60
+ ],
61
+ },
62
+ ],
63
+ };
64
+
65
+ async function main() {
66
+ const crew = new AxCrew(config);
67
+ await crew.addAllAgents();
68
+
69
+ const agent = crew.agents?.get("SupportAgent");
70
+ const result = await agent!.forward({
71
+ ticket: "I bought headphones 15 days ago and they broke.",
72
+ standardPolicies: ["Returns within 30 days only", "Defective items replaced free"],
73
+ });
74
+
75
+ console.log(result.politeSupportResponse);
76
+ console.log(result.decision);
77
+ crew.destroy();
78
+ }
79
+
80
+ main().catch(console.error);
81
+ ```
82
+
83
+ ## Multi-Field Examples
84
+
85
+ ```typescript
86
+ {
87
+ name: "Planner",
88
+ description: "Creates execution plans",
89
+ signature: "task:string, context:string -> plan:string, steps:string[]",
90
+ provider: "openai",
91
+ ai: { model: "gpt-4o" },
92
+ examples: [
93
+ {
94
+ task: "Deploy new API version",
95
+ context: "Kubernetes cluster, 3 environments",
96
+ plan: "Blue-green deployment with canary rollout",
97
+ steps: [
98
+ "Run integration tests",
99
+ "Deploy to staging",
100
+ "Canary 10% traffic",
101
+ "Full rollout",
102
+ ],
103
+ },
104
+ {
105
+ task: "Migrate database",
106
+ context: "PostgreSQL 14 to 16, 500GB data",
107
+ plan: "Logical replication with minimal downtime",
108
+ steps: [
109
+ "Set up PG16 replica",
110
+ "Enable logical replication",
111
+ "Sync and verify",
112
+ "Switch over",
113
+ ],
114
+ },
115
+ ],
116
+ }
117
+ ```
118
+
119
+ ## Dynamic Example Updates (setExamplesCompat)
120
+
121
+ Update examples at runtime after agent initialization:
122
+
123
+ ```typescript
124
+ const crew = new AxCrew(config);
125
+ await crew.addAllAgents();
126
+
127
+ const agent = crew.agents?.get("SupportAgent");
128
+
129
+ // Update examples dynamically
130
+ (agent as any).setExamplesCompat([
131
+ {
132
+ ticket: "My order never arrived.",
133
+ standardPolicies: ["Reship if not delivered in 14 days"],
134
+ politeSupportResponse: "I'm sorry about that! Let me reship your order immediately.",
135
+ decision: "approved",
136
+ policyApplied: "Reship if not delivered in 14 days",
137
+ },
138
+ ]);
139
+ ```
140
+
141
+ `setExamplesCompat()` replaces all current examples. It is preferred over `setExamples()` (deprecated) for compatibility across Ax runtime versions.
142
+
143
+ ## When to Use examples[] vs definition/prompt
144
+
145
+ | Use `examples[]` | Use `definition` / `prompt` |
146
+ |---|---|
147
+ | Structured output consistency | System persona / role description |
148
+ | Demonstrate tone, format, style | Complex multi-paragraph instructions |
149
+ | Classification patterns | Domain context / background knowledge |
150
+ | Input-output mappings | Behavioral constraints |
151
+
152
+ Best practice: use `definition`/`prompt` for WHO the agent is, `examples[]` for HOW it should respond.
153
+
154
+ ## Do Not Generate
155
+
156
+ - Do NOT embed examples as text in `definition` or `prompt` -- use the `examples[]` field for structured few-shot learning
157
+ - Do NOT include fields in examples that are not in the signature -- keys must match signature field names
158
+ - Do NOT provide only input fields in examples -- include BOTH input and output fields to demonstrate expected behavior
159
+ - Do NOT use `setExamples()` directly -- use `setExamplesCompat()` for cross-version compatibility
160
+ - Do NOT add excessive examples (2-5 is typical) -- too many increase token usage without proportional quality gain
161
+
162
+ ## References
163
+
164
+ - [ace-customer-support.ts](../examples/ace-customer-support.ts) -- agent with structured examples and ACE feedback
165
+ - [basic-researcher-writer.ts](../examples/basic-researcher-writer.ts) -- simple agent config
@@ -0,0 +1,218 @@
1
+ ---
2
+ name: ax-crew-functions
3
+ version: __VERSION__
4
+ description: "Functions and tools: FunctionRegistryType, AxFunction, toFunction, custom functions, AxCrewFunctions, class-based functions with state"
5
+ ---
6
+
7
+ # Functions
8
+
9
+ Agents call tools via a `FunctionRegistryType` -- a map of function names to either plain `AxFunction` objects or class-based constructors that receive shared state.
10
+
11
+ ## Two Patterns
12
+
13
+ ### Object-based (plain AxFunction)
14
+
15
+ ```ts
16
+ import type { AxFunction } from '@ax-llm/ax';
17
+
18
+ const MyTool: AxFunction = {
19
+ name: 'MyTool',
20
+ description: 'Does something useful',
21
+ parameters: {
22
+ type: 'object',
23
+ properties: {
24
+ input: { type: 'string', description: 'The input value' }
25
+ },
26
+ required: ['input']
27
+ },
28
+ func: ({ input }: { input: string }) => {
29
+ return `Processed: ${input}`;
30
+ }
31
+ };
32
+ ```
33
+
34
+ ### Class-based (with state access)
35
+
36
+ Constructor receives shared state. Must implement `toFunction()` returning an `AxFunction`.
37
+
38
+ ```ts
39
+ import type { AxFunction } from '@ax-llm/ax';
40
+
41
+ class WordPressPost {
42
+ private state: Record<string, any>;
43
+
44
+ constructor(state: Record<string, any>) {
45
+ this.state = state;
46
+ }
47
+
48
+ toFunction(): AxFunction {
49
+ return {
50
+ name: 'WordPressPost',
51
+ description: 'Creates a post on WordPress',
52
+ parameters: {
53
+ type: 'object',
54
+ properties: {
55
+ title: { type: 'string', description: 'Post title' },
56
+ content: { type: 'string', description: 'Post content' },
57
+ status: { type: 'string', description: 'Post status (draft, publish, private)' }
58
+ },
59
+ required: ['title', 'content', 'status']
60
+ },
61
+ func: async ({ title, content, status }: { title: string; content: string; status: string }) => {
62
+ const env = this.state.env || {};
63
+ const url = env.WORDPRESS_URL;
64
+ const username = env.WORDPRESS_USERNAME;
65
+ const password = env.WORDPRESS_PASSWORD;
66
+ // ... make API call using credentials from state
67
+ return { id: 123, link: `${url}/?p=123` };
68
+ }
69
+ };
70
+ }
71
+ }
72
+ ```
73
+
74
+ ## FunctionRegistryType
75
+
76
+ ```ts
77
+ type FunctionRegistryType = {
78
+ [key: string]: AxFunction | { new(state: Record<string, any>): { toFunction: () => AxFunction } };
79
+ };
80
+ ```
81
+
82
+ The registry key must match the name used in `AgentConfig.functions[]`.
83
+
84
+ ## Built-in AxCrewFunctions
85
+
86
+ ```ts
87
+ import { AxCrewFunctions } from '@amitdeshmukh/ax-crew';
88
+ // Contains: { CurrentDateTime, DaysBetweenDates }
89
+ ```
90
+
91
+ **CurrentDateTime** -- returns current date/time in `iso`, `datetime`, or `date` format.
92
+
93
+ **DaysBetweenDates** -- calculates days between two ISO date strings. Parameters: `startDate`, `endDate`.
94
+
95
+ ## Merging Registries
96
+
97
+ ```ts
98
+ import { AxCrew, AxCrewFunctions } from '@amitdeshmukh/ax-crew';
99
+ import type { FunctionRegistryType } from '@amitdeshmukh/ax-crew';
100
+
101
+ const myFunctions: FunctionRegistryType = {
102
+ MyTool: MyTool,
103
+ WordPressPost: WordPressPost, // class-based
104
+ };
105
+
106
+ // Merge built-in + custom
107
+ const crew = new AxCrew(config, { ...AxCrewFunctions, ...myFunctions });
108
+ ```
109
+
110
+ Then reference by name in agent config:
111
+
112
+ ```ts
113
+ {
114
+ name: "poster",
115
+ functions: ["CurrentDateTime", "WordPressPost"],
116
+ // ...
117
+ }
118
+ ```
119
+
120
+ ## Canonical Pattern
121
+
122
+ Full runnable example adapted from the WordPress example:
123
+
124
+ ```ts
125
+ import { AxCrew } from '@amitdeshmukh/ax-crew';
126
+ import type { AxCrewConfig, FunctionRegistryType } from '@amitdeshmukh/ax-crew';
127
+ import type { AxFunction } from '@ax-llm/ax';
128
+ import dotenv from 'dotenv';
129
+ dotenv.config();
130
+
131
+ // Plain AxFunction
132
+ const Summarize: AxFunction = {
133
+ name: 'Summarize',
134
+ description: 'Summarize text to a given length',
135
+ parameters: {
136
+ type: 'object',
137
+ properties: {
138
+ text: { type: 'string', description: 'Text to summarize' },
139
+ maxWords: { type: 'number', description: 'Maximum words' }
140
+ },
141
+ required: ['text']
142
+ },
143
+ func: ({ text, maxWords }: { text: string; maxWords?: number }) => {
144
+ const limit = maxWords ?? 50;
145
+ return text.split(' ').slice(0, limit).join(' ') + '...';
146
+ }
147
+ };
148
+
149
+ // Class-based function with state access
150
+ class FetchFromAPI {
151
+ private state: Record<string, any>;
152
+ constructor(state: Record<string, any>) { this.state = state; }
153
+ toFunction(): AxFunction {
154
+ return {
155
+ name: 'FetchFromAPI',
156
+ description: 'Fetch data from a configured API endpoint',
157
+ parameters: {
158
+ type: 'object',
159
+ properties: {
160
+ endpoint: { type: 'string', description: 'API endpoint path' }
161
+ },
162
+ required: ['endpoint']
163
+ },
164
+ func: async ({ endpoint }: { endpoint: string }) => {
165
+ const baseUrl = this.state.env?.API_BASE_URL || 'https://api.example.com';
166
+ const resp = await fetch(`${baseUrl}${endpoint}`);
167
+ return await resp.json();
168
+ }
169
+ };
170
+ }
171
+ }
172
+
173
+ const config: AxCrewConfig = {
174
+ crew: [
175
+ {
176
+ name: "assistant",
177
+ description: "An assistant that can summarize text and fetch data",
178
+ signature: "request:string -> response:string",
179
+ provider: "openai",
180
+ providerKeyName: "OPENAI_API_KEY",
181
+ ai: { model: "gpt-4o-mini", temperature: 0.5 },
182
+ functions: ["Summarize", "FetchFromAPI"],
183
+ }
184
+ ]
185
+ };
186
+
187
+ async function main() {
188
+ const customFunctions: FunctionRegistryType = {
189
+ Summarize,
190
+ FetchFromAPI,
191
+ };
192
+ const crew = new AxCrew(config, customFunctions);
193
+
194
+ // Set state for class-based functions
195
+ crew.state.set("env", { API_BASE_URL: "https://api.example.com" });
196
+
197
+ await crew.addAllAgents();
198
+ const assistant = crew.agents?.get("assistant");
199
+ const result = await assistant?.forward({ request: "Summarize the latest news" });
200
+ console.log(result?.response);
201
+ crew.destroy();
202
+ }
203
+
204
+ main().catch(console.error);
205
+ ```
206
+
207
+ ## Do Not Generate
208
+
209
+ - Do NOT define functions inline in AgentConfig; always use a `FunctionRegistryType` registry passed to the `AxCrew` constructor.
210
+ - Do NOT forget that class-based function constructors receive `state: Record<string, any>`, not `StateInstance`. Access values directly (e.g. `this.state.env`), since the state object is a plain record populated via `crew.state.set()`.
211
+ - Do NOT use a registry key that differs from the function name used in `AgentConfig.functions[]` -- they must match.
212
+ - Do NOT import `AxCrewFunctions` from `@ax-llm/ax`; import from `@amitdeshmukh/ax-crew`.
213
+
214
+ ## References
215
+
216
+ - [write-post-and-publish-to-wordpress.ts](https://github.com/amitdeshmukh/ax-crew/blob/main/examples/write-post-and-publish-to-wordpress.ts)
217
+ - [src/functions/dateTime.ts](https://github.com/amitdeshmukh/ax-crew/blob/main/src/functions/dateTime.ts)
218
+ - [src/functions/index.ts](https://github.com/amitdeshmukh/ax-crew/blob/main/src/functions/index.ts)