@amitdeshmukh/ax-crew 9.0.0 → 9.0.1

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/CHANGELOG.md CHANGED
@@ -1,5 +1,11 @@
1
1
  # Changelog
2
2
 
3
+ ## [9.0.1] - 2026-03-29
4
+
5
+ ### Fixed
6
+ - **Agent-level forward options now respected**: Config options like `maxSteps`, `showThoughts`, and `thinkingTokenBudget` defined in agent config `options` were parsed but never passed to `AxGen.forward()`. They are now merged as defaults under caller-supplied options.
7
+ - **Removed hardcoded `contextCache` breakpoint**: The `cacheBreakpoint: 'after-examples'` setting on AxGen is removed, as it is no longer needed after prompt caching changes in 9.0.0.
8
+
3
9
  ## [9.0.0] - 2026-03-25
4
10
 
5
11
  ### Breaking Changes
@@ -40,5 +40,6 @@ declare const parseAgentConfig: (agentName: string, crewConfig: AxCrewConfig, fu
40
40
  tracker: AxDefaultCostTracker;
41
41
  deferredTools: any;
42
42
  debug: any;
43
+ forwardOptions: any;
43
44
  }>;
44
45
  export { parseAgentConfig, parseCrewConfig };
@@ -201,6 +201,7 @@ const parseAgentConfig = async (agentName, crewConfig, functions, state, options
201
201
  tracker: costTracker,
202
202
  deferredTools: agentConfigData.deferredTools,
203
203
  debug: agentConfigData.options?.debug ?? agentConfigData.debug ?? false,
204
+ forwardOptions: agentConfigData.options,
204
205
  };
205
206
  }
206
207
  catch (error) {
@@ -56,7 +56,7 @@ class AxCrew {
56
56
  createAgent = async (agentName) => {
57
57
  try {
58
58
  const agentConfig = await parseAgentConfig(agentName, this.crewConfig, this.functionsRegistry, this.crewState, this.options);
59
- const { ai, name, executionMode, axAgentOptions, description, signature, functions, subAgentNames, examples, tracker } = agentConfig;
59
+ const { ai, name, executionMode, axAgentOptions, description, signature, functions, subAgentNames, examples, tracker, forwardOptions } = agentConfig;
60
60
  // Get subagents for the AI agent
61
61
  const subAgents = subAgentNames.map((subAgentName) => {
62
62
  if (!this.agents?.get(subAgentName)) {
@@ -128,6 +128,7 @@ class AxCrew {
128
128
  agents: uniqueSubAgents,
129
129
  examples,
130
130
  debug: agentConfig.debug,
131
+ forwardOptions,
131
132
  }, agentState);
132
133
  agent.costTracker = tracker;
133
134
  if (deferredManager.isActive) {
@@ -16,6 +16,8 @@ export interface ParsedAgentConfig {
16
16
  subAgentNames: string[];
17
17
  examples?: Array<Record<string, any>>;
18
18
  tracker?: any;
19
+ /** Agent-level forward options (maxSteps, showThoughts, thinkingTokenBudget, etc.) used as defaults when the caller doesn't supply them. */
20
+ forwardOptions?: Record<string, any>;
19
21
  }
20
22
  declare class StatefulAxAgent extends AxAgent<any, any> {
21
23
  crewState: StateInstance;
@@ -27,6 +29,7 @@ declare class StatefulAxAgent extends AxAgent<any, any> {
27
29
  private costTracker?;
28
30
  private debugEnabled;
29
31
  private deferredToolManager?;
32
+ private agentForwardOptions?;
30
33
  private static readonly modernAxAgentRuntime;
31
34
  private aceConfig?;
32
35
  private aceOptimizer?;
@@ -45,6 +48,7 @@ declare class StatefulAxAgent extends AxAgent<any, any> {
45
48
  examples?: Array<Record<string, any>> | undefined;
46
49
  mcpServers?: Record<string, MCPTransportConfig> | undefined;
47
50
  debug?: boolean;
51
+ forwardOptions?: Record<string, any>;
48
52
  }>, state: StateInstance);
49
53
  /**
50
54
  * @deprecated Use setExamplesCompat() to avoid Ax runtime version coupling.
@@ -11,6 +11,7 @@ class StatefulAxAgent extends AxAgent {
11
11
  costTracker;
12
12
  debugEnabled = false;
13
13
  deferredToolManager;
14
+ agentForwardOptions;
14
15
  static modernAxAgentRuntime = typeof AxAgent?.prototype?.getFunction === "function" &&
15
16
  typeof AxAgent?.prototype?.setExamples !== "function";
16
17
  // ACE-related optional state
@@ -88,6 +89,7 @@ class StatefulAxAgent extends AxAgent {
88
89
  this.agentDefinition = effectiveDefinition;
89
90
  this.executionMode = options.executionMode ?? "axgen";
90
91
  this.debugEnabled = debug ?? false;
92
+ this.agentForwardOptions = options.forwardOptions;
91
93
  // Convert sub-agents to callable functions so AxGen can invoke them as tools
92
94
  const subAgentFunctions = resolvedAgents
93
95
  .map(agent => {
@@ -102,7 +104,6 @@ class StatefulAxAgent extends AxAgent {
102
104
  this.axGenProgram = new AxGen(options.signature, {
103
105
  description: effectiveDefinition,
104
106
  functions: [...resolvedFunctions, ...subAgentFunctions],
105
- contextCache: { cacheBreakpoint: 'after-examples' },
106
107
  });
107
108
  for (const agent of resolvedAgents) {
108
109
  try {
@@ -177,7 +178,11 @@ class StatefulAxAgent extends AxAgent {
177
178
  throw new Error(`No AI instance is configured for agent "${this.agentName}"`);
178
179
  }
179
180
  const values = (calledWithAI ? second : first);
180
- const options = (calledWithAI ? third : second);
181
+ const callerOptions = (calledWithAI ? third : second);
182
+ // Merge agent-level forward options as defaults under caller-supplied options
183
+ const options = this.agentForwardOptions
184
+ ? { ...this.agentForwardOptions, ...callerOptions }
185
+ : callerOptions;
181
186
  return { ai, values, options, calledWithAI };
182
187
  }
183
188
  /** Merge deferred tool step hooks into forward options */
@@ -50,11 +50,10 @@ STRATEGY:
50
50
  providerKeyName: "ANTHROPIC_API_KEY",
51
51
  ai: {
52
52
  model: "claude-sonnet-4-6",
53
- temperature: 0,
54
- stream: false
53
+ stream: true
55
54
  },
56
55
  options: {
57
- debug: true
56
+ debug: false,
58
57
  },
59
58
  mcpServers: {
60
59
  "graphjin": {
@@ -75,10 +74,10 @@ Delegate each question to the most relevant agent in a SINGLE call — do not br
75
74
  The sub-agent will handle all the steps internally. Your job is to route and synthesize, not to decompose.
76
75
  If multiple agents are needed, call them and combine their answers.`,
77
76
  signature: 'question:string "a question to be answered" -> answer:string "the answer to the question"',
78
- provider: "anthropic",
79
- providerKeyName: "ANTHROPIC_API_KEY",
77
+ provider: "google-gemini",
78
+ providerKeyName: "GEMINI_API_KEY",
80
79
  ai: {
81
- model: "claude-sonnet-4-6",
80
+ model: "gemini-3-flash-preview",
82
81
  maxTokens: 2000,
83
82
  temperature: 0,
84
83
  stream: false
@@ -94,10 +93,11 @@ If multiple agents are needed, call them and combine their answers.`,
94
93
  // Create a new instance of AxCrew with the config
95
94
  const crew = new AxCrew(config as AxCrewConfig);
96
95
 
97
- const userQuery = "which products had the most refund requests and why?";
96
+ const userQuery = "what are the 10 products with the most number of refund requests and what are the top complaints against each of them";
98
97
 
99
98
  console.log(`\nQuestion: ${userQuery}`);
100
99
 
100
+
101
101
  const main = async (): Promise<void> => {
102
102
  const timers: Record<string, number> = {};
103
103
 
@@ -107,25 +107,35 @@ const main = async (): Promise<void> => {
107
107
  await crew.addAllAgents();
108
108
  timers["setup"] = performance.now() - t0;
109
109
 
110
- const managerAgent = crew.agents?.get("ManagerAgent");
111
-
112
- if (!managerAgent) {
113
- throw new Error("Failed to initialize ManagerAgent");
110
+ const dbAgent = crew.agents?.get("DatabaseAgent");
111
+ if (!dbAgent) {
112
+ throw new Error("Failed to initialize DatabaseAgent");
114
113
  }
115
114
 
116
- // --- Query phase ---
115
+ // --- Query phase with streaming thoughts ---
117
116
  console.log("\n--- Starting query ---\n");
118
117
  const t1 = performance.now();
119
118
 
120
- const managerResponse = await managerAgent.forward({
121
- question: userQuery,
122
- });
119
+ const stream = dbAgent.streamingForward(
120
+ { question: userQuery },
121
+ { showThoughts: true, thinkingTokenBudget: "low" }
122
+ );
123
+
124
+ let answer = '';
125
+ for await (const chunk of stream) {
126
+ if (chunk.delta && 'thought' in chunk.delta) {
127
+ process.stdout.write(chunk.delta.thought as string);
128
+ }
129
+ if (chunk.delta && 'answer' in chunk.delta) {
130
+ answer += chunk.delta.answer ?? '';
131
+ }
132
+ }
123
133
 
124
134
  timers["query"] = performance.now() - t1;
125
135
  timers["total"] = performance.now() - t0;
126
136
 
127
137
  // --- Results ---
128
- console.log(`\nAnswer: ${JSON.stringify(managerResponse?.answer, null, 2)}`);
138
+ console.log(`\n\n--- Answer ---\n${answer}`);
129
139
 
130
140
  // --- Timing & Metrics ---
131
141
  console.log("\n--- Performance ---");
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "type": "module",
3
3
  "name": "@amitdeshmukh/ax-crew",
4
- "version": "9.0.0",
4
+ "version": "9.0.1",
5
5
  "description": "Build and launch a crew of AI agents with shared state. Built with axllm.dev",
6
6
  "main": "dist/index.js",
7
7
  "types": "dist/index.d.ts",
@@ -237,6 +237,7 @@ const parseAgentConfig = async (
237
237
  tracker: costTracker,
238
238
  deferredTools: (agentConfigData as any).deferredTools,
239
239
  debug: (agentConfigData as any).options?.debug ?? (agentConfigData as any).debug ?? false,
240
+ forwardOptions: (agentConfigData as any).options,
240
241
  };
241
242
  } catch (error) {
242
243
  if (error instanceof Error) {
@@ -93,7 +93,7 @@ class AxCrew {
93
93
  this.options
94
94
  );
95
95
 
96
- const { ai, name, executionMode, axAgentOptions, description, signature, functions, subAgentNames, examples, tracker } = agentConfig;
96
+ const { ai, name, executionMode, axAgentOptions, description, signature, functions, subAgentNames, examples, tracker, forwardOptions } = agentConfig;
97
97
 
98
98
  // Get subagents for the AI agent
99
99
  const subAgents = subAgentNames.map((subAgentName: string) => {
@@ -182,6 +182,7 @@ class AxCrew {
182
182
  agents: uniqueSubAgents,
183
183
  examples,
184
184
  debug: (agentConfig as any).debug,
185
+ forwardOptions,
185
186
  },
186
187
  agentState as StateInstance
187
188
  );
@@ -42,6 +42,8 @@ export interface ParsedAgentConfig {
42
42
  subAgentNames: string[];
43
43
  examples?: Array<Record<string, any>>;
44
44
  tracker?: any;
45
+ /** Agent-level forward options (maxSteps, showThoughts, thinkingTokenBudget, etc.) used as defaults when the caller doesn't supply them. */
46
+ forwardOptions?: Record<string, any>;
45
47
  }
46
48
 
47
49
  // Extend the AxAgent class from ax-llm
@@ -55,6 +57,7 @@ class StatefulAxAgent extends AxAgent<any, any> {
55
57
  private costTracker?: any;
56
58
  private debugEnabled: boolean = false;
57
59
  private deferredToolManager?: DeferredToolManager;
60
+ private agentForwardOptions?: Record<string, any>;
58
61
  private static readonly modernAxAgentRuntime =
59
62
  typeof (AxAgent as any)?.prototype?.getFunction === "function" &&
60
63
  typeof (AxAgent as any)?.prototype?.setExamples !== "function";
@@ -82,6 +85,7 @@ class StatefulAxAgent extends AxAgent<any, any> {
82
85
  examples?: Array<Record<string, any>> | undefined;
83
86
  mcpServers?: Record<string, MCPTransportConfig> | undefined;
84
87
  debug?: boolean;
88
+ forwardOptions?: Record<string, any>;
85
89
  }>,
86
90
  state: StateInstance
87
91
  ) {
@@ -162,6 +166,7 @@ class StatefulAxAgent extends AxAgent<any, any> {
162
166
  this.agentDefinition = effectiveDefinition;
163
167
  this.executionMode = options.executionMode ?? "axgen";
164
168
  this.debugEnabled = debug ?? false;
169
+ this.agentForwardOptions = options.forwardOptions;
165
170
  // Convert sub-agents to callable functions so AxGen can invoke them as tools
166
171
  const subAgentFunctions: AxFunction[] = resolvedAgents
167
172
  .map(agent => {
@@ -173,7 +178,6 @@ class StatefulAxAgent extends AxAgent<any, any> {
173
178
  this.axGenProgram = new AxGen(options.signature as any, {
174
179
  description: effectiveDefinition,
175
180
  functions: [...resolvedFunctions, ...subAgentFunctions],
176
- contextCache: { cacheBreakpoint: 'after-examples' },
177
181
  } as any);
178
182
 
179
183
  for (const agent of resolvedAgents) {
@@ -270,7 +274,12 @@ class StatefulAxAgent extends AxAgent<any, any> {
270
274
  }
271
275
 
272
276
  const values = (calledWithAI ? second : first) as Record<string, any>;
273
- const options = (calledWithAI ? third : second) as Readonly<TOptions> | undefined;
277
+ const callerOptions = (calledWithAI ? third : second) as Readonly<TOptions> | undefined;
278
+
279
+ // Merge agent-level forward options as defaults under caller-supplied options
280
+ const options = this.agentForwardOptions
281
+ ? ({ ...this.agentForwardOptions, ...callerOptions } as Readonly<TOptions>)
282
+ : callerOptions;
274
283
 
275
284
  return { ai, values, options, calledWithAI };
276
285
  }