@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 +6 -0
- package/dist/agents/agentConfig.d.ts +1 -0
- package/dist/agents/agentConfig.js +1 -0
- package/dist/agents/crew.js +2 -1
- package/dist/agents/statefulAgent.d.ts +4 -0
- package/dist/agents/statefulAgent.js +7 -2
- package/examples/graphjin-database-agent.ts +26 -16
- package/package.json +1 -1
- package/src/agents/agentConfig.ts +1 -0
- package/src/agents/crew.ts +2 -1
- package/src/agents/statefulAgent.ts +11 -2
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
|
|
@@ -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) {
|
package/dist/agents/crew.js
CHANGED
|
@@ -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
|
|
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
|
-
|
|
54
|
-
stream: false
|
|
53
|
+
stream: true
|
|
55
54
|
},
|
|
56
55
|
options: {
|
|
57
|
-
debug:
|
|
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: "
|
|
79
|
-
providerKeyName: "
|
|
77
|
+
provider: "google-gemini",
|
|
78
|
+
providerKeyName: "GEMINI_API_KEY",
|
|
80
79
|
ai: {
|
|
81
|
-
model: "
|
|
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 = "
|
|
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
|
|
111
|
-
|
|
112
|
-
|
|
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
|
|
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(`\
|
|
138
|
+
console.log(`\n\n--- Answer ---\n${answer}`);
|
|
129
139
|
|
|
130
140
|
// --- Timing & Metrics ---
|
|
131
141
|
console.log("\n--- Performance ---");
|
package/package.json
CHANGED
|
@@ -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) {
|
package/src/agents/crew.ts
CHANGED
|
@@ -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
|
|
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
|
}
|