@amitdeshmukh/ax-crew 8.0.3 → 8.1.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,8 @@
1
1
  {
2
2
  "permissions": {
3
3
  "allow": [
4
- "Bash(npm test:*)"
4
+ "Bash(npm test:*)",
5
+ "Bash(git push:*)"
5
6
  ]
6
7
  }
7
8
  }
package/CHANGELOG.md CHANGED
@@ -1,5 +1,29 @@
1
1
  # Changelog
2
2
 
3
+ ## [8.1.0] - 2026-03-04
4
+
5
+ ### Added
6
+ - Per-agent execution engine selection via `executionMode: "axagent" | "axgen"` with internal routing.
7
+ - `axAgentOptions` support to configure modern AxAgent RLM capabilities from AxCrew.
8
+ - RLM examples:
9
+ - `examples/rlm-long-task.ts` (long task + context management + cost output)
10
+ - `examples/rlm-shared-fields.ts` (shared fields + sub-agent propagation + cost output)
11
+ - New test coverage for execution-mode metrics parity: `tests/execution-mode-metrics.test.ts`.
12
+
13
+ ### Changed
14
+ - Preserved external invocation API (`forward` / `streamingForward`) while routing internally by `executionMode`.
15
+ - Updated peer dependency minimums to `@ax-llm/ax@^19.0.11` and `@ax-llm/ax-tools@^19.0.11`.
16
+ - Updated README and docs to explain:
17
+ - why AxAgent changed (RLM split architecture),
18
+ - mandatory RLM options (`axAgentOptions.runtime`, `axAgentOptions.contextFields`),
19
+ - metrics-first cost reporting terminology.
20
+
21
+ ### Fixed
22
+ - `examples/graphjin-database-agent.ts` now:
23
+ - initializes agents inside `main()` for proper error handling,
24
+ - always calls `crew.destroy()` in `finally`,
25
+ - uses `answer` output consistently for `ManagerAgent`.
26
+
3
27
  ## [8.0.0] - 2025-01-17
4
28
 
5
29
  ### Added
@@ -320,4 +344,3 @@ v2.0.0.html).
320
344
 
321
345
  ### Fixed
322
346
  - Updates to [dateTime.ts](src/dateTime.ts) to enable use in Gemini models
323
-
package/README.md CHANGED
@@ -50,6 +50,7 @@ const config = {
50
50
  crew: [{
51
51
  name: "Planner",
52
52
  description: "Creates a plan to complete a task",
53
+ executionMode: "axagent", // "axagent" | "axgen"
53
54
  signature: "task:string \"a task to be completed\" -> plan:string \"a plan to execute the task\"",
54
55
  provider: "google-gemini",
55
56
  providerKeyName: "GEMINI_API_KEY",
@@ -126,6 +127,7 @@ Key TypeScript features:
126
127
  - **Functions (tools)**: Register callable functions via a registry and reference by name in agent `functions`.
127
128
  - **State**: `crew.state.set/get/getAll()` shared across all agents.
128
129
  - **Persona**: Use `definition` (preferred) or `prompt` to set the system program. If both are present, `definition` wins.
130
+ - **Execution mode**: Set `executionMode` to `axagent` (default) or `axgen` per agent.
129
131
  - **Streaming**: Use `streamingForward()` for token streams.
130
132
  - **Metrics**: Per‑agent `getMetrics()` + crew‑level `getCrewMetrics()` snapshots.
131
133
 
@@ -184,6 +186,103 @@ Add either field to any agent config. The chosen value becomes the Ax agent's un
184
186
  }
185
187
  ```
186
188
 
189
+ ### Execution Modes (`axagent` | `axgen`)
190
+
191
+ Each agent can run in one of two execution modes supported by AxLLM:
192
+
193
+ - `axagent` (default): Uses AxAgent capabilities.
194
+ - `axgen`: Uses AxGen capabilities.
195
+
196
+ Set mode in config:
197
+
198
+ ```json
199
+ {
200
+ "name": "Planner",
201
+ "description": "Creates plans",
202
+ "executionMode": "axgen",
203
+ "signature": "task:string -> plan:string",
204
+ "provider": "google-gemini",
205
+ "providerKeyName": "GEMINI_API_KEY",
206
+ "ai": { "model": "gemini-1.5-flash", "temperature": 0 }
207
+ }
208
+ ```
209
+
210
+ Execution is routed internally by `executionMode` while you continue to call the same public APIs (`forward` / `streamingForward`).
211
+ There is no external API split and no caller-side branching for `axagent` vs `axgen`.
212
+
213
+ ### AxAgent RLM Support
214
+
215
+ `AxAgent` in newer Ax versions moved to an RLM split architecture (Actor/Responder + runtime loop).
216
+ AxCrew supports this directly so you can use modern AxAgent capabilities without changing the AxCrew call surface.
217
+
218
+ To configure those capabilities in AxCrew, use `axAgentOptions` on an agent (effective when `executionMode` is `axagent`):
219
+
220
+ ```typescript
221
+ const config = {
222
+ crew: [{
223
+ name: "Researcher",
224
+ description: "Deep research agent",
225
+ executionMode: "axagent",
226
+ signature: "query:string, context:string? -> answer:string",
227
+ provider: "google-gemini",
228
+ providerKeyName: "GEMINI_API_KEY",
229
+ ai: { model: "gemini-1.5-pro", temperature: 0 },
230
+ axAgentOptions: {
231
+ runtime,
232
+ contextFields: ["context"],
233
+ mode: "simple",
234
+ maxTurns: 12
235
+ }
236
+ }]
237
+ };
238
+ ```
239
+
240
+ RLM mode requirements:
241
+ - `axAgentOptions.runtime`: Provide an `AxJSRuntime` instance for runtime execution.
242
+ - `axAgentOptions.contextFields`: Required in RLM mode (can be an empty array when no context fields are needed).
243
+
244
+ Example runtime wiring:
245
+
246
+ ```typescript
247
+ import { AxJSRuntime, AxJSRuntimePermission } from '@ax-llm/ax';
248
+
249
+ const runtime = new AxJSRuntime({
250
+ permissions: [AxJSRuntimePermission.TIMING],
251
+ });
252
+
253
+ const config = {
254
+ crew: [{
255
+ name: "Analyzer",
256
+ executionMode: "axagent",
257
+ // ...
258
+ axAgentOptions: {
259
+ runtime,
260
+ contextFields: ["context"]
261
+ }
262
+ }]
263
+ };
264
+ ```
265
+
266
+ Why this exists:
267
+ - Upstream AxAgent changed to support richer RLM behaviors (runtime-backed decomposition, actor/responder separation, context management).
268
+ - AxCrew needs to preserve compatibility while exposing these capabilities.
269
+ - `executionMode` keeps this explicit per-agent and lets AxCrew route internally with zero external API change.
270
+
271
+ `forward()` and `streamingForward()` remain unchanged; AxCrew routes internally based on `executionMode`.
272
+
273
+ ### RLM Examples (with cost and tracing verification)
274
+
275
+ The following examples in this repo demonstrate equivalent RLM behavior in AxCrew and print accumulated costs at the end:
276
+
277
+ - [`examples/rlm-long-task.ts`](examples/rlm-long-task.ts): Long-task analysis with context management and RLM runtime.
278
+ - [`examples/rlm-shared-fields.ts`](examples/rlm-shared-fields.ts): Shared-field propagation with parent/child AxAgent setup.
279
+
280
+ Both examples:
281
+ - run through the same public `forward()` API
282
+ - use AxAgent RLM options through `axAgentOptions`
283
+ - print per-agent and crew metrics (`estimatedCostUSD`, token usage)
284
+ - are compatible with telemetry/tracing instrumentation
285
+
187
286
  ### Agent Examples
188
287
  You can provide examples to guide the behavior of your agents using the `examples` field in the agent configuration. Examples help the agent understand the expected input/output format and improve its responses.
189
288
 
@@ -236,7 +335,7 @@ Here's an example of how to set up the `FunctionRegistry` with built-in function
236
335
 
237
336
  ```javascript
238
337
  import { AxCrewFunctions } from '@amitdeshmukh/ax-crew';
239
- const crew = new AxCrew(configFilePath, AxCrewFunctions);
338
+ const crew = new AxCrew(config, AxCrewFunctions);
240
339
  ```
241
340
 
242
341
  if you want to bring your own functions, you can do so by creating a new instance of `FunctionRegistry` and passing it to the `AxCrew` constructor.
@@ -248,7 +347,7 @@ const myFunctions: FunctionRegistryType = {
248
347
  GoogleSearch: googleSearchInstance.toFunction()
249
348
  };
250
349
 
251
- const crew = new AxCrew(configFilePath, myFunctions);
350
+ const crew = new AxCrew(config, myFunctions);
252
351
  ```
253
352
 
254
353
  ### Adding Agents to the Crew
@@ -368,7 +467,7 @@ import { AxCrew, AxCrewFunctions } from '@amitdeshmukh/ax-crew';
368
467
 
369
468
  // Create a new instance of AxCrew
370
469
  const crew = new AxCrew(config, AxCrewFunctions);
371
- crew.addAgentsToCrew(['Planner', 'Calculator', 'Manager']);
470
+ await crew.addAgentsToCrew(['Planner', 'Calculator', 'Manager']);
372
471
 
373
472
  // Get agent instances
374
473
  const Planner = crew.agents.get("Planner");
@@ -714,7 +813,7 @@ crew.resetCosts();
714
813
  ```
715
814
 
716
815
  Notes:
717
- - Legacy cost APIs (`getLastUsageCost`, `getAccumulatedCosts`, `getAggregatedCosts`) are superseded by metrics methods.
816
+ - Legacy cost APIs (`getLastUsageCost`, `getAccumulatedCosts`, `getAggregatedCosts`) are superseded by metrics APIs.
718
817
  - Estimated cost values are numbers rounded to 5 decimal places.
719
818
 
720
819
  ### Telemetry Support (OpenTelemetry)
@@ -941,14 +1040,14 @@ console.log(playbook);
941
1040
  |----------|-------------|
942
1041
  | `"all"` | Apply feedback to all agents involved in the task |
943
1042
  | `"primary"` | Apply only to the primary (entry) agent |
944
- | `"leaf"` | Apply only to leaf agents (no sub-agents) |
1043
+ | `"weighted"` | Apply to all involved agents (reserved for weighted scoring flows) |
945
1044
 
946
1045
  #### Examples
947
1046
 
948
1047
  See the ACE examples for complete demonstrations:
949
1048
 
950
1049
  - [`ace-customer-support.ts`](examples/ace-customer-support.ts) - Learn edge-case handling beyond standard policies
951
- - [`ace-feedback-routing.ts`](examples/ace-feedback-routing.ts) - Flight assistant with preference learning
1050
+ - [`ace-flight-finder.ts`](examples/ace-flight-finder.ts) - Flight assistant with preference learning
952
1051
 
953
1052
  ```bash
954
1053
  # Run the customer support demo
@@ -957,4 +1056,4 @@ npx tsx examples/ace-customer-support.ts
957
1056
 
958
1057
  ## Changelog
959
1058
 
960
- See [CHANGELOG.md](CHANGELOG.md) for a list of changes and version updates.
1059
+ See [CHANGELOG.md](CHANGELOG.md) for a list of changes and version updates.
@@ -1,6 +1,6 @@
1
1
  import { AxDefaultCostTracker } from '@ax-llm/ax';
2
2
  import type { AxFunction } from '@ax-llm/ax';
3
- import type { AgentConfig, AxCrewConfig, AxCrewOptions, FunctionRegistryType, MCPTransportConfig, MCPStdioTransportConfig, MCPHTTPSSETransportConfig, MCPStreamableHTTPTransportConfig } from '../types.js';
3
+ import type { AgentConfig, AgentExecutionMode, AxCrewAxAgentOptions, AxCrewConfig, AxCrewOptions, FunctionRegistryType, MCPTransportConfig, MCPStdioTransportConfig, MCPHTTPSSETransportConfig, MCPStreamableHTTPTransportConfig } from '../types.js';
4
4
  export declare function isStdioTransport(config: MCPTransportConfig): config is MCPStdioTransportConfig;
5
5
  export declare function isHTTPSSETransport(config: MCPTransportConfig): config is MCPHTTPSSETransportConfig;
6
6
  export declare function isStreambleHTTPTransport(config: MCPTransportConfig): config is MCPStreamableHTTPTransportConfig;
@@ -28,6 +28,8 @@ declare const parseCrewConfig: (input: AxCrewConfig) => {
28
28
  declare const parseAgentConfig: (agentName: string, crewConfig: AxCrewConfig, functions: FunctionRegistryType, state: Record<string, any>, options?: AxCrewOptions) => Promise<{
29
29
  ai: import("@ax-llm/ax").AxAI<string>;
30
30
  name: string;
31
+ executionMode: AgentExecutionMode;
32
+ axAgentOptions: AxCrewAxAgentOptions;
31
33
  description: string;
32
34
  definition: any;
33
35
  signature: string | import("@ax-llm/ax").AxSignature<Record<string, any>, Record<string, any>>;
@@ -174,10 +174,13 @@ const parseAgentConfig = async (agentName, crewConfig, functions, state, options
174
174
  // Add MCP functions to functions
175
175
  ...mcpFunctions
176
176
  ];
177
+ const executionMode = agentConfigData.executionMode === 'axgen' ? 'axgen' : 'axagent';
177
178
  // Return AI instance and Agent parameters
178
179
  return {
179
180
  ai: aiInstance,
180
181
  name: agentName,
182
+ executionMode,
183
+ axAgentOptions: (agentConfigData.axAgentOptions ?? {}),
181
184
  description: agentConfigData.description,
182
185
  definition: agentConfigData.definition ?? agentConfigData.prompt,
183
186
  signature: agentConfigData.signature,
@@ -1,22 +1,26 @@
1
1
  import { AxAgent, AxAI } from "@ax-llm/ax";
2
2
  import type { AxSignature, AxAgentic, AxFunction, AxProgramForwardOptions, AxProgramStreamingForwardOptions, AxGenStreamingOut } from "@ax-llm/ax";
3
- import type { StateInstance, FunctionRegistryType, UsageCost, AxCrewConfig, AxCrewOptions, MCPTransportConfig, ACEConfig } from "../types.js";
3
+ import type { StateInstance, FunctionRegistryType, UsageCost, AxCrewConfig, AxCrewOptions, MCPTransportConfig, ACEConfig, AgentExecutionMode, AxCrewAxAgentOptions } from "../types.js";
4
4
  declare class StatefulAxAgent extends AxAgent<any, any> {
5
5
  state: StateInstance;
6
6
  axai: any;
7
7
  private agentName;
8
+ private agentDefinition;
9
+ private executionMode;
10
+ private axGenProgram;
8
11
  private costTracker?;
9
- private lastRecordedCostUSD;
10
12
  private debugEnabled;
13
+ private static readonly modernAxAgentRuntime;
11
14
  private aceConfig?;
12
15
  private aceOptimizer?;
13
16
  private acePlaybook?;
14
17
  private aceBaseInstruction?;
15
18
  private isAxAIService;
16
- private isAxAIInstance;
17
19
  constructor(ai: AxAI, options: Readonly<{
18
20
  name: string;
19
21
  description: string;
22
+ executionMode?: AgentExecutionMode;
23
+ axAgentOptions?: AxCrewAxAgentOptions;
20
24
  definition?: string;
21
25
  signature: string | AxSignature;
22
26
  agents?: AxAgentic<any, any>[] | undefined;
@@ -25,8 +29,28 @@ declare class StatefulAxAgent extends AxAgent<any, any> {
25
29
  mcpServers?: Record<string, MCPTransportConfig> | undefined;
26
30
  debug?: boolean;
27
31
  }>, state: StateInstance);
32
+ /**
33
+ * @deprecated Use setExamplesCompat() to avoid Ax runtime version coupling.
34
+ */
35
+ setExamples(examples: Readonly<Array<Record<string, any>>>): void;
36
+ setExamplesCompat(examples: Readonly<Array<Record<string, any>>>): void;
37
+ /**
38
+ * @deprecated Use setDescriptionCompat() to avoid Ax runtime version coupling.
39
+ */
40
+ setDescription(description: string): void;
41
+ setDescriptionCompat(description: string): void;
42
+ getUsage(): (import("@ax-llm/ax").AxModelUsage & {
43
+ ai: string;
44
+ model: string;
45
+ })[];
46
+ resetUsage(): void;
47
+ private resolveInvocationArgs;
48
+ private executeForwardByMode;
49
+ private recordUsageMetrics;
50
+ private runForwardInvocation;
28
51
  forward(values: Record<string, any>, options?: Readonly<AxProgramForwardOptions<any>>): Promise<Record<string, any>>;
29
52
  forward(ai: AxAI, values: Record<string, any>, options?: Readonly<AxProgramForwardOptions<any>>): Promise<Record<string, any>>;
53
+ private runStreamingInvocation;
30
54
  streamingForward(values: Record<string, any>, options?: Readonly<AxProgramStreamingForwardOptions<any>>): AxGenStreamingOut<any>;
31
55
  streamingForward(ai: AxAI, values: Record<string, any>, options?: Readonly<AxProgramStreamingForwardOptions<any>>): AxGenStreamingOut<any>;
32
56
  getLastUsageCost(): UsageCost | null;