@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.
- package/.claude/settings.local.json +3 -1
- package/.claude/skills/ax-crew/SKILL.md +466 -0
- package/CHANGELOG.md +13 -0
- package/LICENSE +21 -0
- package/README.md +7 -7
- package/examples/run-crew-workflow.ts +2 -2
- package/package.json +3 -1
- package/scripts/install-skills.mjs +59 -0
- package/scripts/uninstall-skills.mjs +25 -0
- package/src/skills/ax-crew-ace.md +165 -0
- package/src/skills/ax-crew-agent-config.md +181 -0
- package/src/skills/ax-crew-code-execution.md +166 -0
- package/src/skills/ax-crew-execution-modes.md +287 -0
- package/src/skills/ax-crew-few-shot.md +165 -0
- package/src/skills/ax-crew-functions.md +218 -0
- package/src/skills/ax-crew-mcp.md +221 -0
- package/src/skills/ax-crew-metrics.md +170 -0
- package/src/skills/ax-crew-patterns.md +286 -0
- package/src/skills/ax-crew-providers.md +204 -0
- package/src/skills/ax-crew-signatures.md +169 -0
- package/src/skills/ax-crew-state.md +168 -0
- package/src/skills/ax-crew-streaming.md +143 -0
- package/src/skills/ax-crew-sub-agents.md +203 -0
- package/src/skills/ax-crew-telemetry.md +161 -0
- package/src/skills/ax-crew.md +124 -0
- package/examples/run-manager.ts +0 -98
|
@@ -0,0 +1,203 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: ax-crew-sub-agents
|
|
3
|
+
description: AxCrew sub-agent composition via agents[] field. Covers agent delegation, dependency resolution, lazy agents (addLazyAgent), parent-child tool integration, and multi-agent orchestration patterns.
|
|
4
|
+
version: "__VERSION__"
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# AxCrew Sub-Agents
|
|
8
|
+
|
|
9
|
+
## Core Concept
|
|
10
|
+
|
|
11
|
+
The `agents[]` field in `AgentConfig` lists names of other agents that become available as tools to the parent agent. AxCrew resolves dependencies and initializes sub-agents before their parent.
|
|
12
|
+
|
|
13
|
+
## agents[] Field
|
|
14
|
+
|
|
15
|
+
```typescript
|
|
16
|
+
{
|
|
17
|
+
name: "ParentAgent",
|
|
18
|
+
description: "Orchestrates sub-agents",
|
|
19
|
+
signature: "query:string -> answer:string",
|
|
20
|
+
provider: "openai",
|
|
21
|
+
ai: { model: "gpt-4o" },
|
|
22
|
+
agents: ["SubAgentA", "SubAgentB"], // these become callable tools
|
|
23
|
+
}
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
The parent agent can call sub-agents as tools automatically. Each sub-agent's signature inputs become the tool's parameters, and its outputs are returned.
|
|
27
|
+
|
|
28
|
+
## Simple Delegation (Researcher-Writer)
|
|
29
|
+
|
|
30
|
+
```typescript
|
|
31
|
+
import { AxCrew } from 'ax-crew';
|
|
32
|
+
import type { AxCrewConfig } from 'ax-crew';
|
|
33
|
+
|
|
34
|
+
const config: AxCrewConfig = {
|
|
35
|
+
crew: [
|
|
36
|
+
{
|
|
37
|
+
name: "researcher",
|
|
38
|
+
description: "A research agent that finds information",
|
|
39
|
+
signature: "query:string -> research:string",
|
|
40
|
+
provider: "google-gemini",
|
|
41
|
+
providerKeyName: "GEMINI_API_KEY",
|
|
42
|
+
ai: { model: "gemini-2.5-flash-lite", maxTokens: 4000 },
|
|
43
|
+
},
|
|
44
|
+
{
|
|
45
|
+
name: "writer",
|
|
46
|
+
description: "A writing agent that creates content",
|
|
47
|
+
signature: "topic:string -> article:string",
|
|
48
|
+
provider: "google-gemini",
|
|
49
|
+
providerKeyName: "GEMINI_API_KEY",
|
|
50
|
+
ai: { model: "gemini-2.5-flash-lite", maxTokens: 4000 },
|
|
51
|
+
agents: ["researcher"], // writer delegates research to researcher
|
|
52
|
+
},
|
|
53
|
+
],
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
async function main() {
|
|
57
|
+
const crew = new AxCrew(config);
|
|
58
|
+
// addAllAgents resolves dependency order automatically
|
|
59
|
+
await crew.addAllAgents();
|
|
60
|
+
|
|
61
|
+
const writer = crew.agents?.get("writer");
|
|
62
|
+
const { article } = await writer!.forward({
|
|
63
|
+
topic: "Quantum Computing Benefits",
|
|
64
|
+
});
|
|
65
|
+
console.log(article);
|
|
66
|
+
crew.destroy();
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
main().catch(console.error);
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
## Multi-Agent Orchestration (Customer Support)
|
|
73
|
+
|
|
74
|
+
```typescript
|
|
75
|
+
import { AxJSRuntime, AxJSRuntimePermission } from '@ax-llm/ax';
|
|
76
|
+
import { AxCrew } from 'ax-crew';
|
|
77
|
+
import type { AxCrewConfig } from 'ax-crew';
|
|
78
|
+
|
|
79
|
+
const runtime = new AxJSRuntime({
|
|
80
|
+
permissions: [AxJSRuntimePermission.TIMING],
|
|
81
|
+
});
|
|
82
|
+
|
|
83
|
+
const config: AxCrewConfig = {
|
|
84
|
+
crew: [
|
|
85
|
+
{
|
|
86
|
+
name: "PolicyLookupAgent",
|
|
87
|
+
description: "Looks up policy details in the provided knowledge base.",
|
|
88
|
+
executionMode: "axagent",
|
|
89
|
+
signature:
|
|
90
|
+
'question:string -> answer:string "Looks up company policies and returns a concise answer"',
|
|
91
|
+
provider: "google-gemini",
|
|
92
|
+
providerKeyName: "GEMINI_API_KEY",
|
|
93
|
+
ai: { model: "gemini-2.5-flash", temperature: 0 },
|
|
94
|
+
axAgentOptions: { contextFields: [], runtime },
|
|
95
|
+
},
|
|
96
|
+
{
|
|
97
|
+
name: "BillingHelperAgent",
|
|
98
|
+
description: "Answers billing and account questions.",
|
|
99
|
+
executionMode: "axagent",
|
|
100
|
+
signature:
|
|
101
|
+
'question:string -> answer:string "Resolves billing and account questions"',
|
|
102
|
+
provider: "google-gemini",
|
|
103
|
+
providerKeyName: "GEMINI_API_KEY",
|
|
104
|
+
ai: { model: "gemini-2.5-flash", temperature: 0 },
|
|
105
|
+
axAgentOptions: { contextFields: [], runtime },
|
|
106
|
+
},
|
|
107
|
+
{
|
|
108
|
+
name: "SentimentClassifierAgent",
|
|
109
|
+
description: "Classifies customer message sentiment.",
|
|
110
|
+
executionMode: "axagent",
|
|
111
|
+
signature: 'question:string -> sentiment:string "positive, negative, or neutral"',
|
|
112
|
+
provider: "google-gemini",
|
|
113
|
+
providerKeyName: "GEMINI_API_KEY",
|
|
114
|
+
ai: { model: "gemini-2.5-flash", temperature: 0 },
|
|
115
|
+
axAgentOptions: {
|
|
116
|
+
contextFields: [],
|
|
117
|
+
fields: { excluded: ["knowledgeBase", "userId"] },
|
|
118
|
+
runtime,
|
|
119
|
+
},
|
|
120
|
+
},
|
|
121
|
+
{
|
|
122
|
+
name: "CustomerSupportAgent",
|
|
123
|
+
description: "Routes queries to specialists and returns a final answer.",
|
|
124
|
+
executionMode: "axagent",
|
|
125
|
+
signature: "query:string, knowledgeBase:string, userId:string -> answer:string",
|
|
126
|
+
provider: "google-gemini",
|
|
127
|
+
providerKeyName: "GEMINI_API_KEY",
|
|
128
|
+
ai: { model: "gemini-2.5-flash", temperature: 0 },
|
|
129
|
+
agents: [
|
|
130
|
+
"PolicyLookupAgent",
|
|
131
|
+
"BillingHelperAgent",
|
|
132
|
+
"SentimentClassifierAgent",
|
|
133
|
+
],
|
|
134
|
+
axAgentOptions: {
|
|
135
|
+
contextFields: ["knowledgeBase"],
|
|
136
|
+
fields: { shared: ["knowledgeBase", "userId"] },
|
|
137
|
+
runtime,
|
|
138
|
+
},
|
|
139
|
+
},
|
|
140
|
+
],
|
|
141
|
+
};
|
|
142
|
+
|
|
143
|
+
async function main() {
|
|
144
|
+
const crew = new AxCrew(config);
|
|
145
|
+
await crew.addAllAgents();
|
|
146
|
+
|
|
147
|
+
const support = crew.agents?.get("CustomerSupportAgent");
|
|
148
|
+
const result = await support!.forward({
|
|
149
|
+
query: "What is your refund policy?",
|
|
150
|
+
knowledgeBase: "Full refund within 30 days...",
|
|
151
|
+
userId: "cust-42",
|
|
152
|
+
});
|
|
153
|
+
console.log(result.answer);
|
|
154
|
+
crew.destroy();
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
main().catch(console.error);
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
## Dependency Resolution
|
|
161
|
+
|
|
162
|
+
`addAllAgents()` and `addAgentsToCrew()` resolve dependencies automatically:
|
|
163
|
+
|
|
164
|
+
```typescript
|
|
165
|
+
// All agents initialized in dependency order
|
|
166
|
+
await crew.addAllAgents();
|
|
167
|
+
|
|
168
|
+
// Or add specific agents -- dependencies must be included or already added
|
|
169
|
+
await crew.addAgentsToCrew(["researcher"]); // add leaf first
|
|
170
|
+
await crew.addAgentsToCrew(["writer"]); // then parent
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
Dependencies are checked: if agent A lists agent B in `agents[]`, B must be initialized first. `addAllAgents()` handles this automatically via topological ordering.
|
|
174
|
+
|
|
175
|
+
## Lazy Agents (addLazyAgent)
|
|
176
|
+
|
|
177
|
+
Defers expensive initialization (MCP servers, AI client) until the agent is first called. Useful for sub-agents that may not be needed on every request.
|
|
178
|
+
|
|
179
|
+
```typescript
|
|
180
|
+
const crew = new AxCrew(config);
|
|
181
|
+
|
|
182
|
+
// Eager: initialize immediately
|
|
183
|
+
await crew.addAgentsToCrew(["MainAgent"]);
|
|
184
|
+
|
|
185
|
+
// Lazy: tool schema is registered immediately, but actual agent
|
|
186
|
+
// initialization (MCP server startup, etc.) is deferred until first call
|
|
187
|
+
crew.addLazyAgent("RarelyUsedAgent");
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
The lazy agent exposes the same `getFunction()` interface. When the parent agent delegates to it, the real agent is created on-demand.
|
|
191
|
+
|
|
192
|
+
## Do Not Generate
|
|
193
|
+
|
|
194
|
+
- Do NOT list an agent in `agents[]` that is not defined in the crew config
|
|
195
|
+
- Do NOT manually wire sub-agent tool calls -- AxCrew does this automatically from the `agents[]` field
|
|
196
|
+
- Do NOT assume sub-agents share parent state by default -- use `axAgentOptions.fields.shared` for shared fields
|
|
197
|
+
- Do NOT add sub-agents after their parent without using `addAllAgents()` or correct ordering in `addAgentsToCrew()`
|
|
198
|
+
- Do NOT use `addLazyAgent()` for agents that are always needed -- it adds latency on first call
|
|
199
|
+
|
|
200
|
+
## References
|
|
201
|
+
|
|
202
|
+
- [basic-researcher-writer.ts](../examples/basic-researcher-writer.ts) -- simple delegation
|
|
203
|
+
- [rlm-shared-fields.ts](../examples/rlm-shared-fields.ts) -- multi-agent with shared fields
|
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: ax-crew-telemetry
|
|
3
|
+
version: __VERSION__
|
|
4
|
+
description: "AxCrew telemetry: OpenTelemetry tracing, metrics, observability with tracer and meter injection."
|
|
5
|
+
tags: [telemetry, opentelemetry, tracing, metrics, observability, tracer, meter]
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# Telemetry
|
|
9
|
+
|
|
10
|
+
AxCrew accepts OpenTelemetry `tracer` and `meter` instances via the `AxCrewOptions.telemetry` object. When provided, all agent `forward()` and `streamingForward()` calls emit spans and record token/cost metrics automatically.
|
|
11
|
+
|
|
12
|
+
## AxCrewOptions.telemetry
|
|
13
|
+
|
|
14
|
+
```ts
|
|
15
|
+
interface AxCrewOptions {
|
|
16
|
+
debug?: boolean;
|
|
17
|
+
telemetry?: {
|
|
18
|
+
tracer?: any; // OpenTelemetry Tracer instance
|
|
19
|
+
meter?: any; // OpenTelemetry Meter instance
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
## Setup
|
|
25
|
+
|
|
26
|
+
```ts
|
|
27
|
+
// Required packages:
|
|
28
|
+
// npm install @opentelemetry/api @opentelemetry/sdk-trace-node @opentelemetry/sdk-metrics
|
|
29
|
+
|
|
30
|
+
import { metrics, trace } from "@opentelemetry/api";
|
|
31
|
+
import { ConsoleSpanExporter, SimpleSpanProcessor } from "@opentelemetry/sdk-trace-base";
|
|
32
|
+
import { NodeTracerProvider } from "@opentelemetry/sdk-trace-node";
|
|
33
|
+
import { ConsoleMetricExporter, MeterProvider, PeriodicExportingMetricReader } from "@opentelemetry/sdk-metrics";
|
|
34
|
+
|
|
35
|
+
// Tracing
|
|
36
|
+
const tracerProvider = new NodeTracerProvider({
|
|
37
|
+
spanProcessors: [new SimpleSpanProcessor(new ConsoleSpanExporter())],
|
|
38
|
+
});
|
|
39
|
+
tracerProvider.register();
|
|
40
|
+
|
|
41
|
+
// Metrics
|
|
42
|
+
const meterProvider = new MeterProvider({
|
|
43
|
+
readers: [
|
|
44
|
+
new PeriodicExportingMetricReader({
|
|
45
|
+
exporter: new ConsoleMetricExporter(),
|
|
46
|
+
exportIntervalMillis: 5000,
|
|
47
|
+
}),
|
|
48
|
+
],
|
|
49
|
+
});
|
|
50
|
+
metrics.setGlobalMeterProvider(meterProvider);
|
|
51
|
+
|
|
52
|
+
// Get instances
|
|
53
|
+
const tracer = trace.getTracer("ax-crew-example");
|
|
54
|
+
const meter = metrics.getMeter("ax-crew-example");
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
## Passing to AxCrew
|
|
58
|
+
|
|
59
|
+
```ts
|
|
60
|
+
const crew = new AxCrew(crewConfig, functionsRegistry, {
|
|
61
|
+
telemetry: { tracer, meter },
|
|
62
|
+
});
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
The third argument to `AxCrew` is `AxCrewOptions`. Telemetry is optional -- omit it and no spans or metrics are emitted.
|
|
66
|
+
|
|
67
|
+
## Canonical Pattern
|
|
68
|
+
|
|
69
|
+
Full working example from `examples/telemetry-demo.ts`:
|
|
70
|
+
|
|
71
|
+
```ts
|
|
72
|
+
import { AxCrew } from "ax-crew";
|
|
73
|
+
import { AxCrewFunctions } from "ax-crew/functions";
|
|
74
|
+
import type { AxCrewConfig, Provider } from "ax-crew";
|
|
75
|
+
import { metrics, trace } from "@opentelemetry/api";
|
|
76
|
+
import { ConsoleSpanExporter, SimpleSpanProcessor } from "@opentelemetry/sdk-trace-base";
|
|
77
|
+
import { NodeTracerProvider } from "@opentelemetry/sdk-trace-node";
|
|
78
|
+
import { ConsoleMetricExporter, MeterProvider, PeriodicExportingMetricReader } from "@opentelemetry/sdk-metrics";
|
|
79
|
+
|
|
80
|
+
// Setup OpenTelemetry
|
|
81
|
+
const tracerProvider = new NodeTracerProvider({
|
|
82
|
+
spanProcessors: [new SimpleSpanProcessor(new ConsoleSpanExporter())],
|
|
83
|
+
});
|
|
84
|
+
tracerProvider.register();
|
|
85
|
+
|
|
86
|
+
const meterProvider = new MeterProvider({
|
|
87
|
+
readers: [
|
|
88
|
+
new PeriodicExportingMetricReader({
|
|
89
|
+
exporter: new ConsoleMetricExporter(),
|
|
90
|
+
exportIntervalMillis: 5000,
|
|
91
|
+
}),
|
|
92
|
+
],
|
|
93
|
+
});
|
|
94
|
+
metrics.setGlobalMeterProvider(meterProvider);
|
|
95
|
+
|
|
96
|
+
const tracer = trace.getTracer("my-app");
|
|
97
|
+
const meter = metrics.getMeter("my-app");
|
|
98
|
+
|
|
99
|
+
// Crew config
|
|
100
|
+
const crewConfig: AxCrewConfig = {
|
|
101
|
+
crew: [
|
|
102
|
+
{
|
|
103
|
+
name: "Researcher",
|
|
104
|
+
description: "Researches a topic and provides facts.",
|
|
105
|
+
signature: "topic:string -> facts:string[]",
|
|
106
|
+
provider: "openai" as Provider,
|
|
107
|
+
providerKeyName: "OPENAI_API_KEY",
|
|
108
|
+
ai: { model: "gpt-4o-mini", temperature: 0.7 },
|
|
109
|
+
functions: ["CurrentDateTime"],
|
|
110
|
+
},
|
|
111
|
+
{
|
|
112
|
+
name: "Writer",
|
|
113
|
+
description: "Writes a blog post from facts.",
|
|
114
|
+
signature: "facts:string[] -> blogPost:string",
|
|
115
|
+
provider: "google-gemini" as Provider,
|
|
116
|
+
providerKeyName: "GEMINI_API_KEY",
|
|
117
|
+
ai: { model: "gemini-flash-latest", temperature: 0.7 },
|
|
118
|
+
},
|
|
119
|
+
],
|
|
120
|
+
};
|
|
121
|
+
|
|
122
|
+
async function main() {
|
|
123
|
+
const crew = new AxCrew(crewConfig, AxCrewFunctions, {
|
|
124
|
+
telemetry: { tracer, meter },
|
|
125
|
+
});
|
|
126
|
+
|
|
127
|
+
await crew.addAgent("Researcher");
|
|
128
|
+
await crew.addAgent("Writer");
|
|
129
|
+
|
|
130
|
+
const researcher = crew.agents!.get("Researcher")!;
|
|
131
|
+
const writer = crew.agents!.get("Writer")!;
|
|
132
|
+
|
|
133
|
+
const researchResult = await researcher.forward({
|
|
134
|
+
topic: "The future of AI agents",
|
|
135
|
+
});
|
|
136
|
+
|
|
137
|
+
const writerResult = await writer.forward({
|
|
138
|
+
facts: researchResult.facts,
|
|
139
|
+
});
|
|
140
|
+
|
|
141
|
+
console.log(writerResult.blogPost);
|
|
142
|
+
|
|
143
|
+
// Wait for metric export flush
|
|
144
|
+
await new Promise((resolve) => setTimeout(resolve, 6000));
|
|
145
|
+
crew.destroy();
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
main().catch(console.error);
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
## Do Not Generate
|
|
152
|
+
|
|
153
|
+
- Do NOT import OpenTelemetry types from `ax-crew` -- import them from `@opentelemetry/api` and the SDK packages.
|
|
154
|
+
- Do NOT pass the `MeterProvider` or `NodeTracerProvider` directly -- pass the `tracer` and `meter` instances obtained via `trace.getTracer()` and `metrics.getMeter()`.
|
|
155
|
+
- Do NOT forget to call `tracerProvider.register()` before creating the crew -- spans will not be emitted otherwise.
|
|
156
|
+
- Do NOT expect telemetry to work without installing `@opentelemetry/api`, `@opentelemetry/sdk-trace-node`, and `@opentelemetry/sdk-metrics`.
|
|
157
|
+
|
|
158
|
+
## References
|
|
159
|
+
|
|
160
|
+
- [telemetry-demo.ts](https://github.com/amitdeshmukh/ax-crew/blob/main/examples/telemetry-demo.ts)
|
|
161
|
+
- [OpenTelemetry JS](https://opentelemetry.io/docs/languages/js/)
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: ax-crew
|
|
3
|
+
version: __VERSION__
|
|
4
|
+
description: "AxCrew - multi-agent orchestration: crew, agents, addAgent, addAllAgents, addAgentsToCrew, forward, streaming, sub-agents"
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# AxCrew
|
|
8
|
+
|
|
9
|
+
Multi-agent orchestration built on [ax-llm/ax](https://github.com/ax-llm/ax). Config-driven crew of agents sharing state, functions, and metrics.
|
|
10
|
+
|
|
11
|
+
## Use These Defaults
|
|
12
|
+
|
|
13
|
+
```ts
|
|
14
|
+
import { AxCrew, AxCrewFunctions } from '@amitdeshmukh/ax-crew';
|
|
15
|
+
import type { AxCrewConfig } from '@amitdeshmukh/ax-crew';
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
Always call `addAllAgents()` or `addAgentsToCrew([...names])` before using agents. Retrieve agents via `crew.agents.get("AgentName")`.
|
|
19
|
+
|
|
20
|
+
## Canonical Pattern
|
|
21
|
+
|
|
22
|
+
```ts
|
|
23
|
+
import { AxCrew, AxCrewFunctions } from '@amitdeshmukh/ax-crew';
|
|
24
|
+
import type { AxCrewConfig } from '@amitdeshmukh/ax-crew';
|
|
25
|
+
import dotenv from 'dotenv';
|
|
26
|
+
dotenv.config();
|
|
27
|
+
|
|
28
|
+
const config: AxCrewConfig = {
|
|
29
|
+
crew: [
|
|
30
|
+
{
|
|
31
|
+
name: "researcher",
|
|
32
|
+
description: "A research agent that finds information",
|
|
33
|
+
signature: "query:string -> research:string",
|
|
34
|
+
provider: "google-gemini",
|
|
35
|
+
providerKeyName: "GEMINI_API_KEY",
|
|
36
|
+
ai: { model: "gemini-2.5-flash-lite", maxTokens: 4000, stream: true },
|
|
37
|
+
options: { debug: true },
|
|
38
|
+
functions: ["CurrentDateTime"]
|
|
39
|
+
},
|
|
40
|
+
{
|
|
41
|
+
name: "writer",
|
|
42
|
+
description: "A writing agent that creates content",
|
|
43
|
+
signature: "topic:string -> article:string",
|
|
44
|
+
provider: "google-gemini",
|
|
45
|
+
providerKeyName: "GEMINI_API_KEY",
|
|
46
|
+
ai: { model: "gemini-2.5-flash-lite", maxTokens: 4000, stream: true },
|
|
47
|
+
options: { debug: true },
|
|
48
|
+
agents: ["researcher"] // sub-agent
|
|
49
|
+
}
|
|
50
|
+
]
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
async function main() {
|
|
54
|
+
const crew = new AxCrew(config, AxCrewFunctions);
|
|
55
|
+
|
|
56
|
+
// Add agents (resolves dependency order automatically)
|
|
57
|
+
await crew.addAllAgents();
|
|
58
|
+
|
|
59
|
+
const writer = crew.agents?.get("writer");
|
|
60
|
+
if (!writer) throw new Error("Failed to initialize writer");
|
|
61
|
+
|
|
62
|
+
try {
|
|
63
|
+
const { article } = await writer.forward({
|
|
64
|
+
topic: "Quantum Computing Benefits",
|
|
65
|
+
});
|
|
66
|
+
console.log("Article:", article);
|
|
67
|
+
|
|
68
|
+
// Metrics
|
|
69
|
+
console.log("Writer Metrics:", JSON.stringify(writer.getMetrics?.(), null, 2));
|
|
70
|
+
console.log("Crew Metrics:", JSON.stringify(crew.getCrewMetrics?.(), null, 2));
|
|
71
|
+
} finally {
|
|
72
|
+
crew.destroy();
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
main().catch(console.error);
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
## AxCrew Constructor
|
|
80
|
+
|
|
81
|
+
```ts
|
|
82
|
+
new AxCrew(crewConfig: AxCrewConfig, functionsRegistry?: FunctionRegistryType, options?: AxCrewOptions, crewId?: string)
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
- `crewConfig` -- `{ crew: AgentConfig[] }`. See skill `ax-crew-agent-config`.
|
|
86
|
+
- `functionsRegistry` -- map of function name to `AxFunction` or class-based function. See skill `ax-crew-functions`.
|
|
87
|
+
- `options` -- `{ debug?: boolean, telemetry?: { tracer?: any, meter?: any } }`.
|
|
88
|
+
- `crewId` -- auto-generated UUID if omitted.
|
|
89
|
+
|
|
90
|
+
## Agent Lifecycle
|
|
91
|
+
|
|
92
|
+
| Method | Description |
|
|
93
|
+
|---|---|
|
|
94
|
+
| `await crew.addAllAgents()` | Add all agents from config (resolves dependency order) |
|
|
95
|
+
| `await crew.addAgentsToCrew(["A", "B"])` | Add a subset by name |
|
|
96
|
+
| `await crew.addAgent("A")` | Add a single agent |
|
|
97
|
+
| `crew.addLazyAgent("A")` | Defer expensive init until first use |
|
|
98
|
+
| `crew.agents?.get("A")` | Retrieve a `StatefulAxAgent` |
|
|
99
|
+
| `await agent.forward({ key: "value" })` | Run the agent |
|
|
100
|
+
| `agent.streamingForward({ key: "value" })` | Stream output chunks |
|
|
101
|
+
| `crew.state` | Shared `StateInstance` across all agents |
|
|
102
|
+
| `crew.resetCosts()` | Reset usage/metrics for all agents |
|
|
103
|
+
| `crew.getCrewMetrics()` | Aggregate metrics snapshot |
|
|
104
|
+
| `crew.destroy()` | Clean up agents, state, execution history |
|
|
105
|
+
|
|
106
|
+
## Related Skills
|
|
107
|
+
|
|
108
|
+
- `ax-crew-agent-config` -- AgentConfig fields, provider setup, executionMode
|
|
109
|
+
- `ax-crew-functions` -- Function registry, custom tools, class-based functions
|
|
110
|
+
- `ax-crew-state` -- Shared state API, accessing state from functions
|
|
111
|
+
|
|
112
|
+
## Do Not Generate
|
|
113
|
+
|
|
114
|
+
- Do NOT instantiate `AxAgent` or `AxGen` directly; use `AxCrew` which wraps them as `StatefulAxAgent`.
|
|
115
|
+
- Do NOT call `agent.forward()` before calling `addAllAgents()` or `addAgentsToCrew()`.
|
|
116
|
+
- Do NOT import from `@ax-llm/ax` for crew orchestration; import from `@amitdeshmukh/ax-crew`.
|
|
117
|
+
- Do NOT use `crew.createAgent()` directly; use `addAgent()` or `addAllAgents()`.
|
|
118
|
+
- Do NOT forget to call `crew.destroy()` to clean up resources.
|
|
119
|
+
|
|
120
|
+
## References
|
|
121
|
+
|
|
122
|
+
- [basic-researcher-writer.ts](https://github.com/amitdeshmukh/ax-crew/blob/main/examples/basic-researcher-writer.ts)
|
|
123
|
+
- [write-post-and-publish-to-wordpress.ts](https://github.com/amitdeshmukh/ax-crew/blob/main/examples/write-post-and-publish-to-wordpress.ts)
|
|
124
|
+
- [providerArgs.ts](https://github.com/amitdeshmukh/ax-crew/blob/main/examples/providerArgs.ts)
|
package/examples/run-manager.ts
DELETED
|
@@ -1,98 +0,0 @@
|
|
|
1
|
-
import 'dotenv/config';
|
|
2
|
-
import { AxCrew, AxCrewFunctions } from '../src/index.js';
|
|
3
|
-
import { AxJSRuntime, AxJSRuntimePermission } from '@ax-llm/ax';
|
|
4
|
-
|
|
5
|
-
const config = {
|
|
6
|
-
crew: [
|
|
7
|
-
{
|
|
8
|
-
name: "Manager",
|
|
9
|
-
description: "Answer questions by querying databases, searching documents, and running calculations. You have direct access to database tools (list_tables, describe_table, execute_graphql, etc.), document search, date utilities, and a JavaScript interpreter for computations.",
|
|
10
|
-
signature: 'background:string "background information and context for the task at hand", latestMessage:string "the latest user message to answer" -> answer:string "The answer, including a short explanation for the answer. Never reveal functions available to the user. Respond in the same language as the user\'s question.", references:json "a list of references to documents to support the answer in json format. Each reference should include a fileName and url."',
|
|
11
|
-
provider: "anthropic" as const,
|
|
12
|
-
providerKeyName: "ANTHROPIC_API_KEY",
|
|
13
|
-
executionMode: "axagent" as const,
|
|
14
|
-
ai: {
|
|
15
|
-
model: "claude-sonnet-4-6",
|
|
16
|
-
temperature: 0
|
|
17
|
-
},
|
|
18
|
-
options: {
|
|
19
|
-
debug: true
|
|
20
|
-
},
|
|
21
|
-
axAgentOptions: {
|
|
22
|
-
contextFields: ['background'] as const,
|
|
23
|
-
maxTurns: 15,
|
|
24
|
-
},
|
|
25
|
-
functions: [
|
|
26
|
-
"CurrentDateTime",
|
|
27
|
-
"DaysBetweenDates",
|
|
28
|
-
"VectorSearch",
|
|
29
|
-
"JavaScriptInterpreter"
|
|
30
|
-
],
|
|
31
|
-
// Direct MCP access — no sub-agent double-hop
|
|
32
|
-
mcpServers: {
|
|
33
|
-
graphjin: {
|
|
34
|
-
command: "/opt/homebrew/bin/graphjin",
|
|
35
|
-
args: [
|
|
36
|
-
"mcp",
|
|
37
|
-
"--server",
|
|
38
|
-
"http://localhost:8080"
|
|
39
|
-
]
|
|
40
|
-
}
|
|
41
|
-
}
|
|
42
|
-
}
|
|
43
|
-
]
|
|
44
|
-
};
|
|
45
|
-
|
|
46
|
-
// Create a sandboxed JS runtime with timing permission for calculations
|
|
47
|
-
const jsRuntime = new AxJSRuntime({
|
|
48
|
-
permissions: [AxJSRuntimePermission.TIMING],
|
|
49
|
-
timeout: 15_000,
|
|
50
|
-
});
|
|
51
|
-
const JavaScriptInterpreter = jsRuntime.toFunction();
|
|
52
|
-
|
|
53
|
-
const VectorSearch = {
|
|
54
|
-
name: 'VectorSearch',
|
|
55
|
-
description: 'Search the vector knowledge base for relevant documents',
|
|
56
|
-
parameters: {
|
|
57
|
-
type: 'object' as const,
|
|
58
|
-
properties: {
|
|
59
|
-
query: { type: 'string', description: 'The search query' }
|
|
60
|
-
},
|
|
61
|
-
required: ['query']
|
|
62
|
-
},
|
|
63
|
-
func: async ({ query }: { query: string }) => {
|
|
64
|
-
console.log(`[VectorSearch] Searching for: ${query}`);
|
|
65
|
-
return `No documents found for: ${query}`;
|
|
66
|
-
}
|
|
67
|
-
};
|
|
68
|
-
|
|
69
|
-
async function main() {
|
|
70
|
-
const crew = new AxCrew(config, { ...AxCrewFunctions, VectorSearch, JavaScriptInterpreter });
|
|
71
|
-
|
|
72
|
-
await crew.addAllAgents();
|
|
73
|
-
|
|
74
|
-
const manager = crew.agents?.get('Manager');
|
|
75
|
-
if (!manager) {
|
|
76
|
-
throw new Error('Manager agent not found');
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
const query = "analyze all our orders to date, give me a table showing P&L";
|
|
80
|
-
console.log(`\nQuery: ${query}\n`);
|
|
81
|
-
|
|
82
|
-
const result = await manager.forward({
|
|
83
|
-
background: "User is querying the system about order information.",
|
|
84
|
-
latestMessage: query
|
|
85
|
-
});
|
|
86
|
-
|
|
87
|
-
console.log(`\nAnswer: ${result.answer}`);
|
|
88
|
-
console.log(`\nReferences:`, JSON.stringify(result.references, null, 2));
|
|
89
|
-
|
|
90
|
-
const crewMetrics = crew.getCrewMetrics();
|
|
91
|
-
console.log(`\nCrew Metrics:`, JSON.stringify(crewMetrics, null, 2));
|
|
92
|
-
|
|
93
|
-
crew.destroy();
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
main()
|
|
97
|
-
.catch(console.error)
|
|
98
|
-
.finally(() => process.exit(0));
|