
Product
Introducing Socket Firewall Enterprise: Flexible, Configurable Protection for Modern Package Ecosystems
Socket Firewall Enterprise is now available with flexible deployment, configurable policies, and expanded language support.
@amitdeshmukh/ax-crew
Advanced tools
Build and launch a crew of AI agents with shared state. Built with axllm.dev

This repo simplifies development of AxLLM 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.
Install this package:
npm install @amitdeshmukh/ax-crew
AxLLM is a peer dependency, so you will need to install it separately.
npm install @ax-llm/ax
This package includes TypeScript declarations and provides full type safety. Here's how to use it with TypeScript:
import { AxCrew, AxCrewFunctions, FunctionRegistryType, StateInstance } from '@amitdeshmukh/ax-crew';
import type { AxFunction } from '@ax-llm/ax';
// Type-safe configuration
const config = {
crew: [{
name: "Planner",
description: "Creates a plan to complete a task",
signature: "task:string \"a task to be completed\" -> plan:string \"a plan to execute the task\"",
provider: "google-gemini",
providerKeyName: "GEMINI_API_KEY",
ai: {
model: "gemini-1.5-pro",
temperature: 0
}
}]
};
// Create custom functions with type safety
class MyCustomFunction {
constructor(private state: Record<string, any>) {}
toFunction(): AxFunction {
return {
name: 'MyCustomFunction',
description: 'Does something useful',
parameters: {
type: 'object',
properties: {
inputParam: { type: 'string', description: "input to the function" }
}
},
func: async ({ inputParam }) => {
// Implementation
return inputParam;
}
};
}
}
// Type-safe function registry
const myFunctions: FunctionRegistryType = {
MyCustomFunction
};
// Create crew with type checking
const crew = new AxCrew(config, myFunctions);
// Set and get state
crew.state.set('key', 'value');
const value: string = crew.state.get('key');
// Add agents to the crew
const agents = crew.addAgentsToCrew(['Planner']);
const planner = agents?.get('Planner');
if (planner) {
// Agent usage with function overloads
// Direct usage - AI config from agent construction is used
const response = await planner.forward({ task: "Plan something" });
// Sub-agent usage - when used by another agent (AI is ignored and agent's own config is used)
const subAgentResponse = await planner.forward(ai, { task: "Plan something" });
const cost = planner.getUsageCost();
if (cost) {
console.log(`Total cost: $${cost.totalCost}`);
console.log(`Total tokens: ${cost.tokenMetrics.totalTokens}`);
}
}
Key TypeScript features:
Refer to the .env.example file for the required environment variables. These will need to be set in the environment where the agents are run.
A Crew is a team of agents that work together to achieve a common goal. You can configure your crew in two ways:
See agentConfig.json for an example configuration file.
// Import the AxCrew class
import { AxCrew } from '@amitdeshmukh/ax-crew';
// Create a new instance of AxCrew using a config file
const configFilePath = './agentConfig.json';
const crew = new AxCrew(configFilePath);
You can also pass the configuration directly as a JSON object:
// Import the AxCrew class
import { AxCrew } from '@amitdeshmukh/ax-crew';
// Create the configuration object
const config = {
crew: [
{
name: "Planner",
description: "Creates a plan to complete a task",
signature: "task:string \"a task to be completed\" -> plan:string \"a plan to execute the task in 5 steps or less\"",
provider: "google-gemini",
providerKeyName: "GEMINI_API_KEY",
ai: {
model: "gemini-1.5-flash",
temperature: 0
},
options: {
debug: false
}
}
// ... more agents
]
};
// Create a new instance of AxCrew using the config object
const crew = new AxCrew(config);
Both methods support the same configuration structure and options. Choose the one that best fits your use case:
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.
{
"name": "MathTeacher",
"description": "Solves math problems with step by step explanations",
"signature": "problem:string \"a math problem to solve\" -> solution:string \"step by step solution with final answer\"",
"provider": "google-gemini",
"providerKeyName": "GEMINI_API_KEY",
"ai": {
"model": "gemini-1.5-pro",
"temperature": 0
},
"examples": [
{
"problem": "what is the square root of 144?",
"solution": "Let's solve this step by step:\n1. The square root of a number is a value that, when multiplied by itself, gives the original number\n2. For 144, we need to find a number that when multiplied by itself equals 144\n3. 12 Ă— 12 = 144\nTherefore, the square root of 144 is 12"
},
{
"problem": "what is the cube root of 27?",
"solution": "Let's solve this step by step:\n1. The cube root of a number is a value that, when multiplied by itself twice, gives the original number\n2. For 27, we need to find a number that when cubed equals 27\n3. 3 Ă— 3 Ă— 3 = 27\nTherefore, the cube root of 27 is 3"
}
]
}
The examples should:
Examples are particularly useful for:
Functions (aka Tools) are the building blocks of agents. They are used to perform specific tasks, such as calling external APIs, databases, or other services.
The FunctionRegistry is a central place where all the functions that agents can use are registered. This allows for easy access and management of functions across different agents in the crew.
To use the FunctionRegistry, you need to either:
@amitdeshmukh/ax-crew package, orAxCrew.Here's an example of how to set up the FunctionRegistry with built-in functions:
import { AxCrewFunctions } from '@amitdeshmukh/ax-crew';
const crew = new AxCrew(configFilePath, AxCrewFunctions);
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.
import { FunctionRegistryType } from '@amitdeshmukh/ax-crew';
const myFunctions: FunctionRegistryType = {
GoogleSearch: googleSearchInstance.toFunction()
};
const crew = new AxCrew(configFilePath, myFunctions);
There are three ways to add agents to your crew, each offering different levels of control:
This is the simplest method that automatically handles all dependencies:
// Initialize all agents defined in the config
await crew.addAllAgents();
// Get agent instances
const planner = crew.agents?.get("Planner");
const manager = crew.agents?.get("Manager");
This method:
This method allows you to initialize a subset of agents while still handling dependencies automatically:
// Add multiple agents - dependencies will be handled automatically
await crew.addAgentsToCrew(['Manager', 'Planner', 'Calculator']);
// Or add them in multiple steps - order doesn't matter as dependencies are handled
await crew.addAgentsToCrew(['Calculator']); // Will be initialized first
await crew.addAgentsToCrew(['Manager']); // Will initialize Planner first if it's a dependency
This method:
This method gives you the most control but requires manual dependency management:
// Add agents one by one - you must handle dependencies manually
await crew.addAgent('Calculator'); // Add base agent first
await crew.addAgent('Planner'); // Then its dependent
await crew.addAgent('Manager'); // Then agents that depend on both
This method:
The crew system automatically handles agent dependencies in the following ways:
agents field:{
name: "Manager",
// ... other config ...
agents: ["Planner", "Calculator"] // Manager depends on these agents
}
Initialization Order:
Error Handling:
State Management:
Choose the method that best fits your needs:
addAllAgents() for simple cases where you want all agentsaddAgentsToCrew() when you need a subset of agents with automatic dependency handlingaddAgent() when you need fine-grained control over the initialization processThe StatefulAxAgent class in src/agents/index.js allows for shared state functionality across agents. Sub-agents can be added to an agent to create complex behaviors. All agents in the crew have access to the shared state. State can also be shared with functions that are passed to the agents. To do this, pass the state object as an argument to the function class as shown here https://axllm.dev/guides/functions-1/
// Set some state (key/value) for this crew
crew.state.set('name', 'Crew1');
crew.state.set('location', 'Earth');
// Get the state for the crew
crew.state.get('name'); // 'Crew1'
crew.state.getAll(); // { name: 'Crew1', location: 'Earth' }
State can also be set/get by individual agents in the crew. This state is shared with all agents. It is also passed to any functions expressed as a class in FunctionsRegistry.
Planner.state.set('plan', 'Fly to Mars');
console.log(Manager.state.getAll()); // { name: 'Crew1', location: 'Earth', plan: 'Fly to Mars' }
An example of how to complete a task using the agents is shown below. The Planner agent is used to plan the task, and the Manager agent is used to execute the task.
import { AxCrew, AxCrewFunctions } from '@amitdeshmukh/ax-crew';
// Create a new instance of AxCrew
const crew = new AxCrew('./agentConfig.json', AxCrewFunctions);
crew.addAgentsToCrew(['Planner', 'Calculator', 'Manager']);
// Get agent instances
const Planner = crew.agents.get("Planner");
const Manager = crew.agents.get("Manager");
// User query
const userQuery = "whats the square root of the number of days between now and Christmas";
console.log(`\n\nQuestion: ${userQuery}`);
// Forward the user query to the agents
const planResponse = await Planner.forward({ task: userQuery });
const managerResponse = await Manager.forward({ question: userQuery, plan: planResponse.plan });
// Get and print the plan and answer from the agents
const plan = planResponse.plan;
const answer = managerResponse.answer;
console.log(`\n\nPlan: ${plan}`);
console.log(`\n\nAnswer: ${answer}`);
The package supports streaming responses from agents, allowing you to receive and process agent outputs in real-time. This is particularly useful for long-running tasks or when you want to provide immediate feedback to users.
import { AxCrew, AxCrewFunctions } from '@amitdeshmukh/ax-crew';
// Create and initialize crew as shown above
const crew = new AxCrew('./agentConfig.json', AxCrewFunctions);
await crew.addAgentsToCrew(['Planner']);
const planner = crew.agents.get("Planner");
// Stream responses using the forward method
await planner.forward(
{ task: "Create a detailed plan for a website" },
{
onStream: (chunk) => {
// Process each chunk of the response as it arrives
console.log('Received chunk:', chunk);
}
}
);
// You can also use streaming with sub-agents
await planner.forward(
ai,
{ task: "Create a detailed plan for a website" },
{
onStream: (chunk) => {
process.stdout.write(chunk);
}
}
);
Key streaming features:
The package provides precise cost tracking capabilities for monitoring API usage across individual agents and the entire crew. Costs are calculated using high-precision decimal arithmetic to ensure accuracy.
// After running an agent's forward method
const response = await Planner.forward({ task: userQuery });
// Get individual agent costs
const agentCost = Planner.getLastUsageCost();
console.log(agentCost);
/* Output example:
{
promptCost: "0.0003637500000",
completionCost: "0.0006100000000",
totalCost: "0.0009737500000",
tokenMetrics: {
promptTokens: 291,
completionTokens: 122,
totalTokens: 413
}
}
*/
// Get cumulative costs for the agent
const cumulativeCost = Planner.getAccumulatedCosts();
console.log(cumulativeCost);
/* Output example:
{
promptCost: "0.0003637500000",
completionCost: "0.0006100000000",
totalCost: "0.0009737500000",
tokenMetrics: {
promptTokens: 291,
completionTokens: 122,
totalTokens: 413
}
}
*/
// Get aggregated costs for all agents in the crew
const crewCosts = crew.getAggregatedCosts();
console.log(crewCosts);
/* Output example:
{
totalCost: "0.0025482500000",
byAgent: {
"Planner": { ... },
"Calculator": { ... },
"Manager": { ... }
},
aggregatedMetrics: {
promptTokens: 850,
completionTokens: 324,
totalTokens: 1174,
promptCost: "0.0010625000000",
completionCost: "0.0014857500000"
}
}
*/
// Reset cost tracking if needed
crew.resetCosts();
Cost tracking features:
See CHANGELOG.md for a list of changes and version updates.
[3.9.0] - 2025-05-28
ErrorOptions type compatibility issue with @ax-llm/ax packageFAQs
Build and launch a crew of AI agents with shared state. Built with axllm.dev
The npm package @amitdeshmukh/ax-crew receives a total of 232 weekly downloads. As such, @amitdeshmukh/ax-crew popularity was classified as not popular.
We found that @amitdeshmukh/ax-crew demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Product
Socket Firewall Enterprise is now available with flexible deployment, configurable policies, and expanded language support.

Security News
Open source dashboard CNAPulse tracks CVE Numbering Authorities’ publishing activity, highlighting trends and transparency across the CVE ecosystem.

Product
Detect malware, unsafe data flows, and license issues in GitHub Actions with Socket’s new workflow scanning support.