@amitdeshmukh/ax-crew 4.0.1 → 4.1.2

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,4 +1,23 @@
1
1
  # Changelog
2
+ ## [4.1.2] - 2025-10-14
3
+
4
+ ### Added
5
+ - Azure OpenAI provider key support via `AZURE_OPENAI_API_KEY`.
6
+ - Documentation: README Environment now lists Azure and includes a minimal Azure config example (`provider: "azure-openai"` + `apiURL`).
7
+
8
+ ### Changed
9
+ - TypeScript config now includes Node types (`types: ["node"]`) to resolve `process` usage in `src/config/index.ts`.
10
+
11
+ ## [4.1.0] - 2025-08-25
12
+
13
+ ### Added
14
+ - Agent persona support via `definition` with validation (>= 100 chars).
15
+ - `prompt` alias for persona; `definition` takes precedence when both provided.
16
+
17
+ ### Changed
18
+ - README updated to document `definition`/`prompt` usage with example.
19
+ - Example `examples/mcp-agent.ts` demonstrates `prompt` in agent config.
20
+
2
21
  ## [4.0.1] - 2025-08-24
3
22
 
4
23
  ### Added
package/README.md CHANGED
@@ -1,20 +1,18 @@
1
1
  ![image](axcrew.png)
2
2
 
3
- # AxCrew - A Crew of AI Agents (built with AxLLM)
3
+ ### AxCrew build a crew of AI agents with shared state (powered by AxLLM)
4
4
 
5
- This repo simplifies development of [AxLLM](https://axllm.dev) AI Agents by using config to instantiate agents. This means you can write a library of functions, and quickly invoke AI agents to use them using a simple configuration file.
5
+ AxCrew lets you define a team of AI agents in config and run them together with shared state, tools, streaming, MCP, and built‑in metrics/cost tracking. Bring your own functions or use the provided registry.
6
6
 
7
- ## Features
8
- - **Crew Configuration**: Define a crew of agents in a JSON file. (see [agentConfig.json](agentConfig.json) as an example)
9
- - **State Management**: Share state across agents in a crew, as well as with functions used by those agents.
10
- - **Task Execution**: Plan and execute tasks using agents in the crew.
11
- - **Streaming Support**: Stream agent responses in real-time for better user experience and faster feedback.
12
- - **Model Context Protocol (MCP)**: Support for MCP to allow agents to use MCP servers.
13
- - **Metrics and Cost Tracking**: Built-in per-agent and per-crew metrics, including token usage and estimated USD costs (5-decimal rounding).
7
+ ### Why AxCrew
8
+ - **Config-first crews**: Declare agents once; instantiate on demand.
9
+ - **Shared state**: Simple key/value state all agents can read/write.
10
+ - **Sub‑agents and tools**: Compose agents and functions cleanly.
11
+ - **Streaming**: Real‑time token streaming for responsive UX.
12
+ - **MCP**: Connect agents to MCP servers (STDIO, HTTP SSE, Streamable HTTP).
13
+ - **Metrics & costs**: Per‑agent and crew snapshots, with estimated USD.
14
14
 
15
- ## Getting Started
16
-
17
- ### Installation
15
+ ### Install
18
16
  Install this package:
19
17
  ```bash
20
18
  npm install @amitdeshmukh/ax-crew
@@ -22,11 +20,41 @@ npm install @amitdeshmukh/ax-crew
22
20
  AxLLM is a peer dependency, so you will need to install it separately.
23
21
 
24
22
  ```bash
25
- npm install @ax-llm/ax
23
+ npm install @ax-llm/ax @ax-llm/ax-tools
24
+ ```
25
+
26
+ Requirements: Node.js >= 21.
27
+
28
+ ### Environment
29
+ Set provider keys in your environment. Example `.env`:
30
+ ```bash
31
+ GEMINI_API_KEY=...
32
+ ANTHROPIC_API_KEY=...
33
+ OPENAI_API_KEY=...
34
+ AZURE_OPENAI_API_KEY=...
35
+ ```
36
+ In each agent config, set `providerKeyName` to the env var name.
37
+
38
+ #### Azure OpenAI
39
+ - Use provider `azure-openai`.
40
+ - Set `providerKeyName` to `AZURE_OPENAI_API_KEY`.
41
+ - Set `apiURL` to your Azure endpoint (e.g., `https://your-resource.openai.azure.com`).
42
+
43
+ Minimal example agent config:
44
+ ```json
45
+ {
46
+ "name": "Writer",
47
+ "description": "Writes concise summaries",
48
+ "signature": "topic:string -> summary:string",
49
+ "provider": "azure-openai",
50
+ "providerKeyName": "AZURE_OPENAI_API_KEY",
51
+ "ai": { "model": "gpt-4o-mini", "temperature": 0 },
52
+ "apiURL": "https://your-resource.openai.azure.com"
53
+ }
26
54
  ```
27
55
 
28
- ### TypeScript Support
29
- This package includes TypeScript declarations and provides full type safety. Here's how to use it with TypeScript:
56
+ ### Quickstart
57
+ This package includes TypeScript declarations and provides type safety.
30
58
 
31
59
  ```typescript
32
60
  import { AxCrew, AxCrewFunctions, FunctionRegistryType, StateInstance } from '@amitdeshmukh/ax-crew';
@@ -82,12 +110,10 @@ crew.state.set('key', 'value');
82
110
  const value: string = crew.state.get('key');
83
111
 
84
112
  // Add agents to the crew
85
- const agents = crew.addAgentsToCrew(['Planner']);
86
- const planner = agents?.get('Planner');
113
+ await crew.addAgentsToCrew(['Planner']);
114
+ const planner = crew.agents?.get('Planner');
87
115
 
88
116
  if (planner) {
89
- // Agent usage with function overloads
90
- // Direct usage - AI config from agent construction is used
91
117
  const response = await planner.forward({ task: "Plan something" });
92
118
 
93
119
  // Sub-agent usage - when used by another agent (AI is ignored and agent's own config is used)
@@ -109,8 +135,14 @@ Key TypeScript features:
109
135
  - Comprehensive type safety for agent operations and responses
110
136
  - Usage cost tracking with proper types
111
137
 
112
- ### Environment Setup
113
- Refer to the [.env.example](.env.example) file for the required environment variables. These will need to be set in the environment where the agents are run.
138
+ ### Concepts at a glance
139
+ - **Agent**: An LLM program with a `signature`, `provider`, `ai` model config, optional `examples`, and optional `mcpServers`.
140
+ - **Sub‑agents**: List other agent names in `agents` to compose behaviors.
141
+ - **Functions (tools)**: Register callable functions via a registry and reference by name in agent `functions`.
142
+ - **State**: `crew.state.set/get/getAll()` shared across all agents.
143
+ - **Persona**: Use `definition` (preferred) or `prompt` to set the system program. If both are present, `definition` wins.
144
+ - **Streaming**: Use `streamingForward()` for token streams.
145
+ - **Metrics**: Per‑agent `getMetrics()` + crew‑level `getCrewMetrics()` snapshots.
114
146
 
115
147
  ## Usage
116
148
 
@@ -174,6 +206,25 @@ Both methods support the same configuration structure and options. Choose the on
174
206
  - Modify configurations at runtime
175
207
  - Keep everything in one file for simpler projects
176
208
 
209
+ ### Agent Persona: definition and prompt
210
+
211
+ - **definition**: Detailed persona/program description used as the system prompt. Recommended for precise control. Must be at least 100 characters.
212
+ - **prompt**: An alias for `definition`. If both are provided, **definition** takes precedence.
213
+
214
+ Add either field to any agent config. The chosen value becomes the Ax agent's underlying program description (system prompt).
215
+
216
+ ```json
217
+ {
218
+ "name": "Planner",
219
+ "description": "Creates a plan to complete a task",
220
+ "prompt": "You are a meticulous planning assistant. Produce concise, executable step-by-step plans with clear justifications, constraints, and assumptions. Prefer brevity, avoid fluff, and ask for missing critical details before proceeding when necessary.",
221
+ "signature": "task:string -> plan:string",
222
+ "provider": "google-gemini",
223
+ "providerKeyName": "GEMINI_API_KEY",
224
+ "ai": { "model": "gemini-1.5-flash", "temperature": 0 }
225
+ }
226
+ ```
227
+
177
228
  ### Agent Examples
178
229
  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.
179
230
 
@@ -29,6 +29,7 @@ declare const parseAgentConfig: (agentName: string, crewConfig: CrewConfigInput,
29
29
  ai: import("@ax-llm/ax").AxAI<string>;
30
30
  name: string;
31
31
  description: string;
32
+ definition: any;
32
33
  signature: string | import("@ax-llm/ax").AxSignature<Record<string, any>, Record<string, any>>;
33
34
  functions: AxFunction[];
34
35
  subAgentNames: string[];
@@ -192,7 +192,7 @@ const parseAgentConfig = async (agentName, crewConfig, functions, state) => {
192
192
  throw new Error(`Provider key name is missing in the agent configuration`);
193
193
  }
194
194
  // Create a cost tracker instance and pass to ai()
195
- const costTracker = new AxDefaultCostTracker();
195
+ const costTracker = new AxDefaultCostTracker((agentConfigData.options?.costTracking) || undefined);
196
196
  // Create an instance of the AI agent via factory
197
197
  const aiArgs = {
198
198
  name: provider,
@@ -238,6 +238,7 @@ const parseAgentConfig = async (agentName, crewConfig, functions, state) => {
238
238
  ai: aiInstance,
239
239
  name: agentName,
240
240
  description: agentConfigData.description,
241
+ definition: agentConfigData.definition ?? agentConfigData.prompt,
241
242
  signature: agentConfigData.signature,
242
243
  functions: agentFunctions,
243
244
  subAgentNames: agentConfigData.agents || [],
@@ -12,6 +12,7 @@ declare class StatefulAxAgent extends AxAgent<any, any> {
12
12
  constructor(ai: AxAI, options: Readonly<{
13
13
  name: string;
14
14
  description: string;
15
+ definition?: string;
15
16
  signature: string | AxSignature;
16
17
  agents?: AxAgentic<any, any>[] | undefined;
17
18
  functions?: (AxFunction | (() => AxFunction))[] | undefined;
@@ -244,6 +244,7 @@ class AxCrew {
244
244
  const agent = new StatefulAxAgent(ai, {
245
245
  name,
246
246
  description,
247
+ definition: agentConfig.definition,
247
248
  signature,
248
249
  functions: uniqueFunctions,
249
250
  agents: uniqueSubAgents,
@@ -3,6 +3,7 @@ dotenv.config();
3
3
  // AI API keys
4
4
  const ANTHROPIC_API_KEY = process.env.ANTHROPIC_API_KEY;
5
5
  const OPENAI_API_KEY = process.env.OPENAI_API_KEY;
6
+ const AZURE_OPENAI_API_KEY = process.env.AZURE_OPENAI_API_KEY;
6
7
  const COHERE_API_KEY = process.env.COHERE_API_KEY;
7
8
  const DEEPSEEK_API_KEY = process.env.DEEPSEEK_API_KEY;
8
9
  const GEMINI_API_KEY = process.env.GEMINI_API_KEY;
@@ -16,6 +17,7 @@ const PROVIDER_API_KEYS = {
16
17
  COHERE_API_KEY,
17
18
  GEMINI_API_KEY,
18
19
  OPENAI_API_KEY,
20
+ AZURE_OPENAI_API_KEY,
19
21
  ANTHROPIC_API_KEY,
20
22
  DEEPSEEK_API_KEY,
21
23
  GROQ_API_KEY,
package/dist/types.d.ts CHANGED
@@ -147,6 +147,16 @@ type MCPTransportConfig = MCPStdioTransportConfig | MCPHTTPSSETransportConfig |
147
147
  interface AgentConfig {
148
148
  name: string;
149
149
  description: string;
150
+ /**
151
+ * Optional detailed persona/program definition. If provided, becomes the system prompt.
152
+ * Must be at least 100 characters per Ax semantics.
153
+ */
154
+ definition?: string;
155
+ /**
156
+ * Optional alias for definition for clarity. If provided and definition is omitted,
157
+ * this will be used as the program definition/system prompt.
158
+ */
159
+ prompt?: string;
150
160
  signature: string | AxSignature;
151
161
  provider: Provider;
152
162
  providerKeyName?: string;
@@ -1,15 +1,15 @@
1
- import { AxCrew } from "../dist/index.js";
2
- import type { AxCrewConfig } from "../dist/index.js";
1
+ import { AxCrew, AxCrewConfig } from "../dist/index.js";
3
2
 
4
3
  import dotenv from "dotenv";
5
4
  dotenv.config();
6
5
 
7
6
  // Define the crew configuration
8
- const config: AxCrewConfig = {
7
+ const config = {
9
8
  crew: [
10
9
  {
11
10
  name: "MapsAgent",
12
11
  description: "A specialized agent with access to Google Maps APIs that can: geocode addresses to coordinates and vice versa, search for and get details about places, calculate travel distances and times between multiple locations, provide elevation data, and generate navigation directions between points.",
12
+ prompt: "You are a precise geospatial assistant with expert knowledge of Google Maps APIs. Answer user queries by combining place search, geocoding, distance matrix, elevation, and directions. Provide concise, actionable answers, include travel mode assumptions, and cite uncertainties. When location is ambiguous, ask a brief clarifying question before proceeding.",
13
13
  signature: 'userQuery:string "a question to be answered" -> answer:string "the answer to the question"',
14
14
  provider: "anthropic",
15
15
  providerKeyName: "ANTHROPIC_API_KEY",
@@ -38,6 +38,7 @@ const config: AxCrewConfig = {
38
38
  {
39
39
  name: "ManagerAgent",
40
40
  description: "Completes a user specified task",
41
+ prompt: "You are a manager agent that orchestrates tools and sub-agents. Read the user's objective, optionally produce a short plan, then call the MapsAgent when geospatial knowledge is needed. Keep answers direct and avoid extraneous commentary.",
41
42
  signature:
42
43
  'question:string "a question to be answered" -> answer:string "the answer to the question"',
43
44
  provider: "openai",
@@ -73,7 +74,7 @@ const config: AxCrewConfig = {
73
74
  };
74
75
 
75
76
  // Create a new instance of AxCrew with the config
76
- const crew = new AxCrew(config);
77
+ const crew = new AxCrew(config as AxCrewConfig);
77
78
 
78
79
  // Add the agents to the crew
79
80
  await crew.addAllAgents();
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "type": "module",
3
3
  "name": "@amitdeshmukh/ax-crew",
4
- "version": "4.0.1",
4
+ "version": "4.1.2",
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",
@@ -30,7 +30,7 @@
30
30
  "devDependencies": {
31
31
  "@testing-library/jest-dom": "^6.6.3",
32
32
  "@types/big.js": "^6.2.2",
33
- "@types/node": "^20.14.9",
33
+ "@types/node": "^20.19.21",
34
34
  "@types/uuid": "^10.0.0",
35
35
  "@vitest/coverage-v8": "^3.0.9",
36
36
  "@vitest/ui": "^3.0.9",
@@ -224,7 +224,7 @@ const parseAgentConfig = async (
224
224
  }
225
225
 
226
226
  // Create a cost tracker instance and pass to ai()
227
- const costTracker = new AxDefaultCostTracker();
227
+ const costTracker = new AxDefaultCostTracker(((agentConfigData as any).options?.costTracking) || undefined);
228
228
 
229
229
  // Create an instance of the AI agent via factory
230
230
  const aiArgs: any = {
@@ -273,6 +273,7 @@ const parseAgentConfig = async (
273
273
  ai: aiInstance,
274
274
  name: agentName,
275
275
  description: agentConfigData.description,
276
+ definition: (agentConfigData as any).definition ?? (agentConfigData as any).prompt,
276
277
  signature: agentConfigData.signature,
277
278
  functions: agentFunctions,
278
279
  subAgentNames: agentConfigData.agents || [],
@@ -27,6 +27,7 @@ interface ParsedAgentConfig {
27
27
  ai: AxAI;
28
28
  name: string;
29
29
  description: string;
30
+ definition?: string;
30
31
  signature: string | AxSignature;
31
32
  functions: (
32
33
  | AxFunction
@@ -58,6 +59,7 @@ class StatefulAxAgent extends AxAgent<any, any> {
58
59
  options: Readonly<{
59
60
  name: string;
60
61
  description: string;
62
+ definition?: string;
61
63
  signature: string | AxSignature;
62
64
  agents?: AxAgentic<any, any>[] | undefined;
63
65
  functions?: (AxFunction | (() => AxFunction))[] | undefined;
@@ -347,6 +349,7 @@ class AxCrew {
347
349
  {
348
350
  name,
349
351
  description,
352
+ definition: (agentConfig as any).definition,
350
353
  signature,
351
354
  functions: uniqueFunctions,
352
355
  agents: uniqueSubAgents,
@@ -4,6 +4,7 @@ dotenv.config();
4
4
  // AI API keys
5
5
  const ANTHROPIC_API_KEY: string | undefined = process.env.ANTHROPIC_API_KEY;
6
6
  const OPENAI_API_KEY: string | undefined = process.env.OPENAI_API_KEY;
7
+ const AZURE_OPENAI_API_KEY: string | undefined = process.env.AZURE_OPENAI_API_KEY;
7
8
  const COHERE_API_KEY: string | undefined = process.env.COHERE_API_KEY;
8
9
  const DEEPSEEK_API_KEY: string | undefined = process.env.DEEPSEEK_API_KEY;
9
10
  const GEMINI_API_KEY: string | undefined = process.env.GEMINI_API_KEY;
@@ -23,6 +24,7 @@ const PROVIDER_API_KEYS: ProviderApiKeys = {
23
24
  COHERE_API_KEY,
24
25
  GEMINI_API_KEY,
25
26
  OPENAI_API_KEY,
27
+ AZURE_OPENAI_API_KEY,
26
28
  ANTHROPIC_API_KEY,
27
29
  DEEPSEEK_API_KEY,
28
30
  GROQ_API_KEY,
package/src/types.ts CHANGED
@@ -180,6 +180,16 @@ type MCPTransportConfig = MCPStdioTransportConfig | MCPHTTPSSETransportConfig |
180
180
  interface AgentConfig {
181
181
  name: string;
182
182
  description: string;
183
+ /**
184
+ * Optional detailed persona/program definition. If provided, becomes the system prompt.
185
+ * Must be at least 100 characters per Ax semantics.
186
+ */
187
+ definition?: string;
188
+ /**
189
+ * Optional alias for definition for clarity. If provided and definition is omitted,
190
+ * this will be used as the program definition/system prompt.
191
+ */
192
+ prompt?: string;
183
193
  signature: string | AxSignature;
184
194
  provider: Provider;
185
195
  providerKeyName?: string;
package/tsconfig.json CHANGED
@@ -13,7 +13,8 @@
13
13
  "rootDir": "./src",
14
14
  "allowJs": true,
15
15
  "resolveJsonModule": true,
16
- "typeRoots": ["./node_modules/@types", "./types"]
16
+ "typeRoots": ["./node_modules/@types", "./types"],
17
+ "types": ["node"]
17
18
  },
18
19
  "include": ["src/**/*"],
19
20
  "exclude": ["node_modules", "**/*.spec.ts"]