@amitdeshmukh/ax-crew 3.6.1 → 3.7.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/.env.example +9 -0
- package/CHANGELOG.md +19 -0
- package/README.md +122 -12
- package/dist/agents/agentConfig.d.ts +17 -47
- package/dist/agents/agentConfig.js +85 -30
- package/dist/agents/agentUseCosts.d.ts +1 -53
- package/dist/agents/index.d.ts +13 -11
- package/dist/agents/index.js +127 -14
- package/dist/functions/index.d.ts +3 -11
- package/dist/index.d.ts +4 -5
- package/dist/index.js +1 -1
- package/dist/state/index.d.ts +1 -17
- package/dist/types.d.ts +146 -0
- package/dist/types.js +1 -0
- package/examples/README.md +38 -1
- package/examples/basic-researcher-writer.ts +8 -5
- package/examples/mcp-agent.ts +104 -0
- package/examples/solve-math-problem.ts +6 -7
- package/examples/streaming.ts +90 -0
- package/examples/write-post-and-publish-to-wordpress.ts +3 -3
- package/package.json +12 -4
- package/src/agents/agentConfig.ts +102 -71
- package/src/agents/agentUseCosts.ts +9 -59
- package/src/agents/index.ts +172 -23
- package/src/functions/index.ts +1 -7
- package/src/index.ts +13 -7
- package/src/state/index.ts +2 -19
- package/src/types.ts +168 -0
- package/tests/AxCrew.test.ts +142 -0
- package/vitest.config.ts +19 -0
- package/axllm.txt +0 -11633
package/.env.example
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
# API Keys (only set the ones you need)
|
|
2
|
+
OPENAI_API_KEY=sk-******************BlLB
|
|
3
|
+
ANTHROPIC_API_KEY=sk-ant-api********cQAA
|
|
4
|
+
GEMINI_API_KEY=sk-gemini-api********cQAA
|
|
5
|
+
COHERE_API_KEY=sk-cohere-api********cQAA
|
|
6
|
+
MISTRAL_API_KEY=sk-mistral-api********cQAA
|
|
7
|
+
GROK_API_KEY=sk-grok-api********cQAA
|
|
8
|
+
TOGETHER_API_KEY=sk-together-api********cQAA
|
|
9
|
+
HUGGINGFACE_API_KEY=sk-huggingface-api********cQAA
|
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,25 @@ This Changelog format is based on [Keep a Changelog]
|
|
|
5
5
|
adheres to [Semantic Versioning](https://semver.org/spec/
|
|
6
6
|
v2.0.0.html).
|
|
7
7
|
|
|
8
|
+
## [3.7.1] - 2025-03-27
|
|
9
|
+
|
|
10
|
+
### Fixed
|
|
11
|
+
- Enhanced error reporting for unsupported transport types with proper JSON stringification
|
|
12
|
+
|
|
13
|
+
## [3.7.0] - 2025-03-25
|
|
14
|
+
|
|
15
|
+
### Added
|
|
16
|
+
- New TypeScript type exports in src/index.ts for better type accessibility
|
|
17
|
+
- Enhanced type definitions for metrics and cost tracking interfaces
|
|
18
|
+
- Improved type documentation for core configuration interfaces
|
|
19
|
+
- Support for Model Context Protocol (MCP)
|
|
20
|
+
- Added `addAllAgents` method to add all agents to the crew
|
|
21
|
+
- Support for streaming responses from agents
|
|
22
|
+
|
|
23
|
+
### Changed
|
|
24
|
+
- Reorganized type exports in src/index.ts for better code organization
|
|
25
|
+
- Updated TypeScript interfaces for better type inference and documentation
|
|
26
|
+
|
|
8
27
|
## [3.6.1] - 2025-03-22
|
|
9
28
|
|
|
10
29
|
### Changed
|
package/README.md
CHANGED
|
@@ -8,6 +8,8 @@ This repo simplifies development of [AxLLM](https://axllm.dev) AI Agents by usin
|
|
|
8
8
|
- **Crew Configuration**: Define a crew of agents in a JSON file. (see [agentConfig.json](agentConfig.json) as an example)
|
|
9
9
|
- **State Management**: Share state across agents in a crew, as well as with functions used by those agents.
|
|
10
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.
|
|
11
13
|
|
|
12
14
|
## Getting Started
|
|
13
15
|
|
|
@@ -240,26 +242,91 @@ const crew = new AxCrew(configFilePath, myFunctions);
|
|
|
240
242
|
```
|
|
241
243
|
|
|
242
244
|
### Adding Agents to the Crew
|
|
243
|
-
|
|
245
|
+
There are three ways to add agents to your crew, each offering different levels of control:
|
|
244
246
|
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
- agents added in the right order (an error will be thrown if an agent is added before its dependent agents).
|
|
247
|
+
#### Method 1: Add All Agents Automatically
|
|
248
|
+
This is the simplest method that automatically handles all dependencies:
|
|
248
249
|
|
|
249
|
-
|
|
250
|
+
```javascript
|
|
251
|
+
// Initialize all agents defined in the config
|
|
252
|
+
await crew.addAllAgents();
|
|
253
|
+
|
|
254
|
+
// Get agent instances
|
|
255
|
+
const planner = crew.agents?.get("Planner");
|
|
256
|
+
const manager = crew.agents?.get("Manager");
|
|
257
|
+
```
|
|
258
|
+
|
|
259
|
+
This method:
|
|
260
|
+
- Reads all agents from your configuration
|
|
261
|
+
- Automatically determines the correct initialization order based on dependencies
|
|
262
|
+
- Initializes all agents in the proper sequence
|
|
263
|
+
- Throws an error if there are circular dependencies
|
|
250
264
|
|
|
251
|
-
|
|
265
|
+
#### Method 2: Add Multiple Agents with Dependencies
|
|
266
|
+
This method allows you to initialize a subset of agents while still handling dependencies automatically:
|
|
252
267
|
|
|
253
268
|
```javascript
|
|
254
|
-
// Add agents
|
|
255
|
-
|
|
256
|
-
const agents = crew.addAgentsToCrew(agentNames);
|
|
269
|
+
// Add multiple agents - dependencies will be handled automatically
|
|
270
|
+
await crew.addAgentsToCrew(['Manager', 'Planner', 'Calculator']);
|
|
257
271
|
|
|
258
|
-
//
|
|
259
|
-
|
|
260
|
-
|
|
272
|
+
// Or add them in multiple steps - order doesn't matter as dependencies are handled
|
|
273
|
+
await crew.addAgentsToCrew(['Calculator']); // Will be initialized first
|
|
274
|
+
await crew.addAgentsToCrew(['Manager']); // Will initialize Planner first if it's a dependency
|
|
261
275
|
```
|
|
262
276
|
|
|
277
|
+
This method:
|
|
278
|
+
- Takes an array of agent names you want to initialize
|
|
279
|
+
- Automatically handles dependencies even if not explicitly included
|
|
280
|
+
- Initializes agents in the correct order regardless of the order specified
|
|
281
|
+
- Throws an error if required dependencies are missing or if there are circular dependencies
|
|
282
|
+
|
|
283
|
+
#### Method 3: Add Individual Agents
|
|
284
|
+
This method gives you the most control but requires manual dependency management:
|
|
285
|
+
|
|
286
|
+
```javascript
|
|
287
|
+
// Add agents one by one - you must handle dependencies manually
|
|
288
|
+
await crew.addAgent('Calculator'); // Add base agent first
|
|
289
|
+
await crew.addAgent('Planner'); // Then its dependent
|
|
290
|
+
await crew.addAgent('Manager'); // Then agents that depend on both
|
|
291
|
+
```
|
|
292
|
+
|
|
293
|
+
This method:
|
|
294
|
+
- Gives you full control over the initialization process
|
|
295
|
+
- Requires you to handle dependencies manually
|
|
296
|
+
- Throws an error if you try to initialize an agent before its dependencies
|
|
297
|
+
|
|
298
|
+
#### Dependency Handling
|
|
299
|
+
The crew system automatically handles agent dependencies in the following ways:
|
|
300
|
+
|
|
301
|
+
1. **Explicit Dependencies**: Defined in the agent config using the `agents` field:
|
|
302
|
+
```javascript
|
|
303
|
+
{
|
|
304
|
+
name: "Manager",
|
|
305
|
+
// ... other config ...
|
|
306
|
+
agents: ["Planner", "Calculator"] // Manager depends on these agents
|
|
307
|
+
}
|
|
308
|
+
```
|
|
309
|
+
|
|
310
|
+
2. **Initialization Order**:
|
|
311
|
+
- Base agents (no dependencies) are initialized first
|
|
312
|
+
- Dependent agents are initialized only after their dependencies
|
|
313
|
+
- Circular dependencies are detected and reported
|
|
314
|
+
|
|
315
|
+
3. **Error Handling**:
|
|
316
|
+
- Missing dependencies are reported with clear error messages
|
|
317
|
+
- Circular dependencies are detected and reported
|
|
318
|
+
- Invalid agent names or configurations are caught early
|
|
319
|
+
|
|
320
|
+
4. **State Management**:
|
|
321
|
+
- All initialized agents within a crew share the same state
|
|
322
|
+
- Dependencies can access and modify shared state
|
|
323
|
+
- State persists across all initialization methods
|
|
324
|
+
|
|
325
|
+
Choose the method that best fits your needs:
|
|
326
|
+
- Use `addAllAgents()` for simple cases where you want all agents
|
|
327
|
+
- Use `addAgentsToCrew()` when you need a subset of agents with automatic dependency handling
|
|
328
|
+
- Use `addAgent()` when you need fine-grained control over the initialization process
|
|
329
|
+
|
|
263
330
|
### State Management
|
|
264
331
|
|
|
265
332
|
The `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/
|
|
@@ -314,6 +381,49 @@ console.log(`\n\nPlan: ${plan}`);
|
|
|
314
381
|
console.log(`\n\nAnswer: ${answer}`);
|
|
315
382
|
```
|
|
316
383
|
|
|
384
|
+
### Streaming Responses
|
|
385
|
+
|
|
386
|
+
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.
|
|
387
|
+
|
|
388
|
+
```javascript
|
|
389
|
+
import { AxCrew, AxCrewFunctions } from '@amitdeshmukh/ax-crew';
|
|
390
|
+
|
|
391
|
+
// Create and initialize crew as shown above
|
|
392
|
+
const crew = new AxCrew('./agentConfig.json', AxCrewFunctions);
|
|
393
|
+
await crew.addAgentsToCrew(['Planner']);
|
|
394
|
+
|
|
395
|
+
const planner = crew.agents.get("Planner");
|
|
396
|
+
|
|
397
|
+
// Stream responses using the forward method
|
|
398
|
+
await planner.forward(
|
|
399
|
+
{ task: "Create a detailed plan for a website" },
|
|
400
|
+
{
|
|
401
|
+
onStream: (chunk) => {
|
|
402
|
+
// Process each chunk of the response as it arrives
|
|
403
|
+
console.log('Received chunk:', chunk);
|
|
404
|
+
}
|
|
405
|
+
}
|
|
406
|
+
);
|
|
407
|
+
|
|
408
|
+
// You can also use streaming with sub-agents
|
|
409
|
+
await planner.forward(
|
|
410
|
+
ai,
|
|
411
|
+
{ task: "Create a detailed plan for a website" },
|
|
412
|
+
{
|
|
413
|
+
onStream: (chunk) => {
|
|
414
|
+
process.stdout.write(chunk);
|
|
415
|
+
}
|
|
416
|
+
}
|
|
417
|
+
);
|
|
418
|
+
```
|
|
419
|
+
|
|
420
|
+
Key streaming features:
|
|
421
|
+
- Real-time response processing
|
|
422
|
+
- Support for both direct and sub-agent usage
|
|
423
|
+
- Customizable stream handling through callbacks
|
|
424
|
+
- Compatible with all agent types and configurations
|
|
425
|
+
- Maintains cost tracking and state management functionality
|
|
426
|
+
|
|
317
427
|
### Tracking Usage Costs
|
|
318
428
|
|
|
319
429
|
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.
|
|
@@ -1,67 +1,37 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
import { FunctionRegistryType } from '../
|
|
1
|
+
import type { AxFunction } from '@ax-llm/ax';
|
|
2
|
+
import type { AgentConfig, CrewConfigInput, FunctionRegistryType, MCPTransportConfig, MCPStdioTransportConfig, MCPHTTPTransportConfig } from '../types.js';
|
|
3
3
|
declare const AIConstructors: Record<string, any>;
|
|
4
4
|
export type Provider = keyof typeof AIConstructors;
|
|
5
|
+
export declare function isStdioTransport(config: MCPTransportConfig): config is MCPStdioTransportConfig;
|
|
6
|
+
export declare function isHTTPTransport(config: MCPTransportConfig): config is MCPHTTPTransportConfig;
|
|
5
7
|
/**
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
* @
|
|
9
|
-
* @
|
|
10
|
-
* @property {string | AxSignature} signature - The signature for the agent in DSPy format.
|
|
11
|
-
* @property {Provider} provider - LLM provider name.
|
|
12
|
-
* @property {string} providerKeyName - The name of the provider key (read from environment variables).
|
|
13
|
-
* @property {AxModelConfig & { model: string }} ai - The AI model configuration to be passed to the agent.
|
|
14
|
-
* @property {boolean} debug - Whether to enable debug mode.
|
|
15
|
-
* @property {string} apiURL - Set this if you are using a custom API URL e.g. ollama on localhost.
|
|
16
|
-
* @property {Record<string, any>} options - Agent options. Refer to the Ax documentation for more details.
|
|
17
|
-
* @property {string[]} functions - Function names to be used by the agent.
|
|
18
|
-
* @property {string[]} agents - Sub-agent available to the agent.
|
|
19
|
-
* @property {Record<string, any>[]} examples - DSPy examples for the agent to learn from.
|
|
20
|
-
*/
|
|
21
|
-
export interface AgentConfig {
|
|
22
|
-
name: string;
|
|
23
|
-
description: string;
|
|
24
|
-
signature: string | AxSignature;
|
|
25
|
-
provider: Provider;
|
|
26
|
-
providerKeyName?: string;
|
|
27
|
-
ai: AxModelConfig & {
|
|
28
|
-
model: string;
|
|
29
|
-
};
|
|
30
|
-
debug?: boolean;
|
|
31
|
-
apiURL?: string;
|
|
32
|
-
options?: Record<string, any>;
|
|
33
|
-
functions?: string[];
|
|
34
|
-
agents?: string[];
|
|
35
|
-
examples?: Array<Record<string, any>>;
|
|
36
|
-
}
|
|
37
|
-
/**
|
|
38
|
-
* The input type for the agent config. This can be a path to a JSON file or a JSON object.
|
|
8
|
+
* Parses and returns the AxCrew config from either a JSON config file or a direct JSON object.
|
|
9
|
+
* @param {CrewConfigInput} input - Either a path to the agent config json file or a JSON object with crew configuration.
|
|
10
|
+
* @returns {Object} The parsed crew config.
|
|
11
|
+
* @throws Will throw an error if reading/parsing fails.
|
|
39
12
|
*/
|
|
40
|
-
|
|
13
|
+
declare const parseCrewConfig: (input: CrewConfigInput) => {
|
|
41
14
|
crew: AgentConfig[];
|
|
42
15
|
};
|
|
43
16
|
/**
|
|
44
|
-
*
|
|
45
|
-
*
|
|
46
|
-
* and creates an instance of the AI agent with the appropriate settings.
|
|
17
|
+
* Parses the agent's configuration, validates the presence of the necessary API key,
|
|
18
|
+
* and creates an instance of the Agent with the appropriate settings.
|
|
47
19
|
*
|
|
48
20
|
* @param {string} agentName - The identifier for the AI agent to be initialized.
|
|
49
|
-
* @param {
|
|
21
|
+
* @param {CrewConfigInput} crewConfig - Either a file path to the JSON configuration or a JSON object with crew configuration.
|
|
50
22
|
* @param {FunctionRegistryType} functions - The functions available to the agent.
|
|
51
23
|
* @param {Object} state - The state object for the agent.
|
|
52
24
|
* @returns {Object} An object containing the Agents AI instance, its name, description, signature, functions and subAgentList.
|
|
53
25
|
* @throws {Error} Throws an error if the agent configuration is missing, the provider is unsupported,
|
|
54
26
|
* the API key is not found, or the provider key name is not specified in the configuration.
|
|
55
27
|
*/
|
|
56
|
-
declare const
|
|
28
|
+
declare const parseAgentConfig: (agentName: string, crewConfig: CrewConfigInput, functions: FunctionRegistryType, state: Record<string, any>) => Promise<{
|
|
57
29
|
ai: any;
|
|
58
30
|
name: string;
|
|
59
31
|
description: string;
|
|
60
|
-
signature: string | AxSignature;
|
|
61
|
-
functions:
|
|
62
|
-
toFunction: () => AxFunction;
|
|
63
|
-
}) | undefined)[];
|
|
32
|
+
signature: string | import("@ax-llm/ax").AxSignature;
|
|
33
|
+
functions: AxFunction[];
|
|
64
34
|
subAgentNames: string[];
|
|
65
35
|
examples: Record<string, any>[];
|
|
66
|
-
}
|
|
67
|
-
export {
|
|
36
|
+
}>;
|
|
37
|
+
export { parseAgentConfig, parseCrewConfig };
|
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
import fs from 'fs';
|
|
2
|
+
// Import all the providers
|
|
2
3
|
import { AxAIAnthropic, AxAIOpenAI, AxAIAzureOpenAI, AxAICohere, AxAIDeepSeek, AxAIGoogleGemini, AxAIGroq, AxAIHuggingFace, AxAIMistral, AxAIOllama, AxAITogether } from '@ax-llm/ax';
|
|
4
|
+
// Import the MCP client and transports
|
|
5
|
+
import { AxMCPClient, AxMCPStdioTransport, AxMCPHTTPTransport } from '@ax-llm/ax';
|
|
3
6
|
import { PROVIDER_API_KEYS } from '../config/index.js';
|
|
4
7
|
// Define a mapping from provider names to their respective constructors
|
|
5
8
|
const AIConstructors = {
|
|
@@ -15,6 +18,14 @@ const AIConstructors = {
|
|
|
15
18
|
'openai': AxAIOpenAI,
|
|
16
19
|
'together': AxAITogether
|
|
17
20
|
};
|
|
21
|
+
// Type guard to check if config is stdio transport
|
|
22
|
+
export function isStdioTransport(config) {
|
|
23
|
+
return 'command' in config;
|
|
24
|
+
}
|
|
25
|
+
// Type guard to check if config is http transport
|
|
26
|
+
export function isHTTPTransport(config) {
|
|
27
|
+
return 'sseUrl' in config;
|
|
28
|
+
}
|
|
18
29
|
/**
|
|
19
30
|
* Type guard to check if a value is a constructor function for a type T.
|
|
20
31
|
*
|
|
@@ -67,19 +78,55 @@ Original error: ${error.message}`;
|
|
|
67
78
|
}
|
|
68
79
|
return `Error parsing agent configuration: ${error.message}`;
|
|
69
80
|
};
|
|
81
|
+
const initializeMCPServers = async (agentConfigData) => {
|
|
82
|
+
const mcpServers = agentConfigData.mcpServers;
|
|
83
|
+
if (!mcpServers || Object.keys(mcpServers).length === 0) {
|
|
84
|
+
return [];
|
|
85
|
+
}
|
|
86
|
+
let initializedClients = [];
|
|
87
|
+
const functions = [];
|
|
88
|
+
try {
|
|
89
|
+
for (const [mcpServerName, mcpServerConfig] of Object.entries(mcpServers)) {
|
|
90
|
+
let transport;
|
|
91
|
+
if (isStdioTransport(mcpServerConfig)) {
|
|
92
|
+
transport = new AxMCPStdioTransport({
|
|
93
|
+
command: mcpServerConfig.command,
|
|
94
|
+
args: mcpServerConfig.args,
|
|
95
|
+
env: mcpServerConfig.env
|
|
96
|
+
});
|
|
97
|
+
}
|
|
98
|
+
else if (isHTTPTransport(mcpServerConfig)) {
|
|
99
|
+
transport = new AxMCPHTTPTransport(mcpServerConfig.sseUrl);
|
|
100
|
+
}
|
|
101
|
+
else {
|
|
102
|
+
throw new Error(`Unsupported transport type: ${JSON.stringify(mcpServerConfig)}`);
|
|
103
|
+
}
|
|
104
|
+
const mcpClient = new AxMCPClient(transport, { debug: agentConfigData.debug || false });
|
|
105
|
+
await mcpClient.init();
|
|
106
|
+
initializedClients.push(mcpClient);
|
|
107
|
+
functions.push(...mcpClient.toFunction());
|
|
108
|
+
}
|
|
109
|
+
return functions;
|
|
110
|
+
}
|
|
111
|
+
catch (error) {
|
|
112
|
+
initializedClients = [];
|
|
113
|
+
console.error(`Error during MCP client setup: ${error}`);
|
|
114
|
+
throw error;
|
|
115
|
+
}
|
|
116
|
+
};
|
|
70
117
|
/**
|
|
71
|
-
*
|
|
72
|
-
* @param {
|
|
73
|
-
* @returns {Object} The parsed
|
|
118
|
+
* Parses and returns the AxCrew config from either a JSON config file or a direct JSON object.
|
|
119
|
+
* @param {CrewConfigInput} input - Either a path to the agent config json file or a JSON object with crew configuration.
|
|
120
|
+
* @returns {Object} The parsed crew config.
|
|
74
121
|
* @throws Will throw an error if reading/parsing fails.
|
|
75
122
|
*/
|
|
76
|
-
const
|
|
123
|
+
const parseCrewConfig = (input) => {
|
|
77
124
|
try {
|
|
78
125
|
if (typeof input === 'string') {
|
|
79
126
|
// Handle file path input
|
|
80
127
|
const fileContents = fs.readFileSync(input, 'utf8');
|
|
81
|
-
const
|
|
82
|
-
return
|
|
128
|
+
const parsedConfig = JSON.parse(fileContents);
|
|
129
|
+
return parsedConfig;
|
|
83
130
|
}
|
|
84
131
|
else {
|
|
85
132
|
// Handle direct JSON object input
|
|
@@ -98,22 +145,21 @@ const parseAgentConfig = (input) => {
|
|
|
98
145
|
}
|
|
99
146
|
};
|
|
100
147
|
/**
|
|
101
|
-
*
|
|
102
|
-
*
|
|
103
|
-
* and creates an instance of the AI agent with the appropriate settings.
|
|
148
|
+
* Parses the agent's configuration, validates the presence of the necessary API key,
|
|
149
|
+
* and creates an instance of the Agent with the appropriate settings.
|
|
104
150
|
*
|
|
105
151
|
* @param {string} agentName - The identifier for the AI agent to be initialized.
|
|
106
|
-
* @param {
|
|
152
|
+
* @param {CrewConfigInput} crewConfig - Either a file path to the JSON configuration or a JSON object with crew configuration.
|
|
107
153
|
* @param {FunctionRegistryType} functions - The functions available to the agent.
|
|
108
154
|
* @param {Object} state - The state object for the agent.
|
|
109
155
|
* @returns {Object} An object containing the Agents AI instance, its name, description, signature, functions and subAgentList.
|
|
110
156
|
* @throws {Error} Throws an error if the agent configuration is missing, the provider is unsupported,
|
|
111
157
|
* the API key is not found, or the provider key name is not specified in the configuration.
|
|
112
158
|
*/
|
|
113
|
-
const
|
|
159
|
+
const parseAgentConfig = async (agentName, crewConfig, functions, state) => {
|
|
114
160
|
try {
|
|
115
161
|
// Retrieve the parameters for the specified AI agent from config
|
|
116
|
-
const agentConfigData =
|
|
162
|
+
const agentConfigData = parseCrewConfig(crewConfig).crew.find(agent => agent.name === agentName);
|
|
117
163
|
if (!agentConfigData) {
|
|
118
164
|
throw new Error(`AI agent with name ${agentName} is not configured`);
|
|
119
165
|
}
|
|
@@ -144,24 +190,33 @@ const getAgentConfigParams = (agentName, agentConfig, functions, state) => {
|
|
|
144
190
|
});
|
|
145
191
|
// If an apiURL is provided in the agent config, set it in the AI agent
|
|
146
192
|
if (agentConfigData.apiURL) {
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
.map(funcName => {
|
|
152
|
-
const func = functions[funcName];
|
|
153
|
-
if (!func) {
|
|
154
|
-
console.warn(`Warning: Function ${funcName} not found.`);
|
|
155
|
-
return;
|
|
193
|
+
try {
|
|
194
|
+
// Validate apiURL format
|
|
195
|
+
new URL(agentConfigData.apiURL);
|
|
196
|
+
ai.setAPIURL(agentConfigData.apiURL);
|
|
156
197
|
}
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
return new func(state).toFunction();
|
|
198
|
+
catch (error) {
|
|
199
|
+
throw new Error(`Invalid apiURL provided: ${agentConfigData.apiURL}`);
|
|
160
200
|
}
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
201
|
+
}
|
|
202
|
+
// If an mcpServers config is provided in the agent config, convert to functions
|
|
203
|
+
const mcpFunctions = await initializeMCPServers(agentConfigData);
|
|
204
|
+
// Prepare functions for the AI agent
|
|
205
|
+
const agentFunctions = [
|
|
206
|
+
// Add custom functions
|
|
207
|
+
...(agentConfigData.functions || [])
|
|
208
|
+
.map(funcName => {
|
|
209
|
+
const func = functions[funcName];
|
|
210
|
+
if (!func) {
|
|
211
|
+
console.warn(`Warning: Function ${funcName} not found.`);
|
|
212
|
+
return;
|
|
213
|
+
}
|
|
214
|
+
return func;
|
|
215
|
+
})
|
|
216
|
+
.filter((func) => func !== null),
|
|
217
|
+
// Add MCP functions to functions
|
|
218
|
+
...mcpFunctions
|
|
219
|
+
];
|
|
165
220
|
// Return AI instance and Agent parameters
|
|
166
221
|
return {
|
|
167
222
|
ai,
|
|
@@ -170,7 +225,7 @@ const getAgentConfigParams = (agentName, agentConfig, functions, state) => {
|
|
|
170
225
|
signature: agentConfigData.signature,
|
|
171
226
|
functions: agentFunctions,
|
|
172
227
|
subAgentNames: agentConfigData.agents || [],
|
|
173
|
-
examples: agentConfigData.examples || []
|
|
228
|
+
examples: agentConfigData.examples || [],
|
|
174
229
|
};
|
|
175
230
|
}
|
|
176
231
|
catch (error) {
|
|
@@ -180,4 +235,4 @@ const getAgentConfigParams = (agentName, agentConfig, functions, state) => {
|
|
|
180
235
|
throw new Error(`Error setting up AI agent: ${error}`);
|
|
181
236
|
}
|
|
182
237
|
};
|
|
183
|
-
export {
|
|
238
|
+
export { parseAgentConfig, parseCrewConfig };
|
|
@@ -1,56 +1,4 @@
|
|
|
1
|
-
import type { StateInstance } from '../
|
|
2
|
-
/**
|
|
3
|
-
* The usage metrics of the model.
|
|
4
|
-
* promptTokens: number;
|
|
5
|
-
* completionTokens: number;
|
|
6
|
-
*/
|
|
7
|
-
export interface ModelUsage {
|
|
8
|
-
promptTokens: number;
|
|
9
|
-
completionTokens: number;
|
|
10
|
-
}
|
|
11
|
-
/**
|
|
12
|
-
* The published cost for using the model.
|
|
13
|
-
* promptTokenCostPer1M: number;
|
|
14
|
-
* completionTokenCostPer1M: number;
|
|
15
|
-
*/
|
|
16
|
-
export interface ModelInfo {
|
|
17
|
-
promptTokenCostPer1M: number;
|
|
18
|
-
completionTokenCostPer1M: number;
|
|
19
|
-
}
|
|
20
|
-
/**
|
|
21
|
-
* The cost incurred for using the model.
|
|
22
|
-
*
|
|
23
|
-
*/
|
|
24
|
-
export interface UsageCost {
|
|
25
|
-
promptCost: string;
|
|
26
|
-
completionCost: string;
|
|
27
|
-
totalCost: string;
|
|
28
|
-
tokenMetrics: {
|
|
29
|
-
promptTokens: number;
|
|
30
|
-
completionTokens: number;
|
|
31
|
-
totalTokens: number;
|
|
32
|
-
};
|
|
33
|
-
}
|
|
34
|
-
/**
|
|
35
|
-
* Aggregated metrics from all agent and sub-agent invocations.
|
|
36
|
-
*
|
|
37
|
-
*/
|
|
38
|
-
export interface AggregatedMetrics {
|
|
39
|
-
promptTokens: number;
|
|
40
|
-
completionTokens: number;
|
|
41
|
-
totalTokens: number;
|
|
42
|
-
promptCost: string;
|
|
43
|
-
completionCost: string;
|
|
44
|
-
}
|
|
45
|
-
/**
|
|
46
|
-
* The incurred costs from all agent and sub-agent invocations.
|
|
47
|
-
*
|
|
48
|
-
*/
|
|
49
|
-
export interface AggregatedCosts {
|
|
50
|
-
totalCost: string;
|
|
51
|
-
byAgent: Record<string, UsageCost>;
|
|
52
|
-
aggregatedMetrics: AggregatedMetrics;
|
|
53
|
-
}
|
|
1
|
+
import type { StateInstance, ModelUsage, ModelInfo, UsageCost, AggregatedCosts } from '../types.js';
|
|
54
2
|
/**
|
|
55
3
|
* Utility class to handle usage related functionality.
|
|
56
4
|
*
|
package/dist/agents/index.d.ts
CHANGED
|
@@ -1,9 +1,7 @@
|
|
|
1
1
|
import { AxAgent, AxAI } from "@ax-llm/ax";
|
|
2
|
-
import type { AxSignature, AxAgentic, AxFunction, AxProgramForwardOptions } from "@ax-llm/ax";
|
|
3
|
-
import type {
|
|
4
|
-
import {
|
|
5
|
-
import { StateInstance } from "../state/index.js";
|
|
6
|
-
import { StateFulAxAgentUsage, UsageCost } from "./agentUseCosts.js";
|
|
2
|
+
import type { AxSignature, AxAgentic, AxFunction, AxProgramForwardOptions, AxProgramStreamingForwardOptions, AxGenStreamingOut } from "@ax-llm/ax";
|
|
3
|
+
import type { StateInstance, FunctionRegistryType, UsageCost, CrewConfigInput, MCPTransportConfig } from "../types.js";
|
|
4
|
+
import { StateFulAxAgentUsage } from "./agentUseCosts.js";
|
|
7
5
|
declare class StatefulAxAgent extends AxAgent<any, any> {
|
|
8
6
|
state: StateInstance;
|
|
9
7
|
axai: any;
|
|
@@ -15,9 +13,12 @@ declare class StatefulAxAgent extends AxAgent<any, any> {
|
|
|
15
13
|
agents?: AxAgentic[] | undefined;
|
|
16
14
|
functions?: (AxFunction | (() => AxFunction))[] | undefined;
|
|
17
15
|
examples?: Array<Record<string, any>> | undefined;
|
|
16
|
+
mcpServers?: Record<string, MCPTransportConfig> | undefined;
|
|
18
17
|
}>, state: StateInstance);
|
|
19
18
|
forward(values: Record<string, any>, options?: Readonly<AxProgramForwardOptions>): Promise<Record<string, any>>;
|
|
20
19
|
forward(ai: AxAI, values: Record<string, any>, options?: Readonly<AxProgramForwardOptions>): Promise<Record<string, any>>;
|
|
20
|
+
streamingForward(values: Record<string, any>, options?: Readonly<AxProgramStreamingForwardOptions>): AxGenStreamingOut<any>;
|
|
21
|
+
streamingForward(ai: AxAI, values: Record<string, any>, options?: Readonly<AxProgramStreamingForwardOptions>): AxGenStreamingOut<any>;
|
|
21
22
|
getLastUsageCost(): UsageCost | null;
|
|
22
23
|
getAccumulatedCosts(): UsageCost | null;
|
|
23
24
|
}
|
|
@@ -25,30 +26,30 @@ declare class StatefulAxAgent extends AxAgent<any, any> {
|
|
|
25
26
|
* Represents a crew of agents with shared state functionality.
|
|
26
27
|
*/
|
|
27
28
|
declare class AxCrew {
|
|
28
|
-
private
|
|
29
|
+
private crewConfig;
|
|
29
30
|
functionsRegistry: FunctionRegistryType;
|
|
30
31
|
crewId: string;
|
|
31
32
|
agents: Map<string, StatefulAxAgent> | null;
|
|
32
33
|
state: StateInstance;
|
|
33
34
|
/**
|
|
34
35
|
* Creates an instance of AxCrew.
|
|
35
|
-
* @param {
|
|
36
|
+
* @param {CrewConfigInput} crewConfig - Either a path to the agent config file or a JSON object with crew configuration.
|
|
36
37
|
* @param {FunctionRegistryType} [functionsRegistry={}] - The registry of functions to use in the crew.
|
|
37
38
|
* @param {string} [crewId=uuidv4()] - The unique identifier for the crew.
|
|
38
39
|
*/
|
|
39
|
-
constructor(
|
|
40
|
+
constructor(crewConfig: CrewConfigInput, functionsRegistry?: FunctionRegistryType, crewId?: string);
|
|
40
41
|
/**
|
|
41
42
|
* Factory function for creating an agent.
|
|
42
43
|
* @param {string} agentName - The name of the agent to create.
|
|
43
44
|
* @returns {StatefulAxAgent} The created StatefulAxAgent instance.
|
|
44
45
|
* @throws Will throw an error if the agent creation fails.
|
|
45
46
|
*/
|
|
46
|
-
createAgent: (agentName: string) => StatefulAxAgent
|
|
47
|
+
createAgent: (agentName: string) => Promise<StatefulAxAgent>;
|
|
47
48
|
/**
|
|
48
49
|
* Adds an agent to the crew by name.
|
|
49
50
|
* @param {string} agentName - The name of the agent to add.
|
|
50
51
|
*/
|
|
51
|
-
addAgent(agentName: string): void
|
|
52
|
+
addAgent(agentName: string): Promise<void>;
|
|
52
53
|
/**
|
|
53
54
|
* Sets up agents in the crew by name.
|
|
54
55
|
* For an array of Agent names provided, it adds
|
|
@@ -56,7 +57,8 @@ declare class AxCrew {
|
|
|
56
57
|
* @param {string[]} agentNames - An array of agent names to configure.
|
|
57
58
|
* @returns {Map<string, StatefulAxAgent> | null} A map of agent names to their corresponding instances.
|
|
58
59
|
*/
|
|
59
|
-
addAgentsToCrew(agentNames: string[]): Map<string, StatefulAxAgent> | null
|
|
60
|
+
addAgentsToCrew(agentNames: string[]): Promise<Map<string, StatefulAxAgent> | null>;
|
|
61
|
+
addAllAgents(): Promise<Map<string, StatefulAxAgent> | null>;
|
|
60
62
|
/**
|
|
61
63
|
* Cleans up the crew by dereferencing agents and resetting the state.
|
|
62
64
|
*/
|