@amitdeshmukh/ax-crew 3.3.0 → 3.3.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
@@ -5,7 +5,13 @@ 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.3.0] - 2024-12-11
8
+ ## [3.3.1] - 2024-12-11
9
+
10
+ ### Changed
11
+ - Fixed Websearch agent configuration in `agentConfig.json`
12
+ - Refactored agent configuration structure in `src/agents/agentConfig.ts` for better type safety and maintainability
13
+
14
+ ## [3.3.0] - 2024-12-10
9
15
 
10
16
  ### Added
11
17
  - Added `getUsageCost` method to track API usage costs and token metrics
package/agentConfig.json CHANGED
@@ -62,7 +62,11 @@
62
62
  },
63
63
  "options": {
64
64
  "debug": true,
65
- "googleSearchRetrieval": true
65
+ "googleSearchRetrieval": {
66
+ "dynamic_retrieval_config": {
67
+ "mode": "MODE_UNSPECIFIED"
68
+ }
69
+ }
66
70
  },
67
71
  "functions": ["CurrentDateTime", "DaysBetweenDates"]
68
72
  },
@@ -0,0 +1,47 @@
1
+ import type { AxModelConfig, AxFunction, AxSignature } from '@ax-llm/ax';
2
+ import { FunctionRegistryType } from '../functions/index.js';
3
+ type ExtendedAxModelConfig = AxModelConfig & {
4
+ model: string;
5
+ };
6
+ interface AgentConfig {
7
+ name: string;
8
+ description: string;
9
+ signature: AxSignature;
10
+ provider: string;
11
+ providerKeyName?: string;
12
+ ai: ExtendedAxModelConfig;
13
+ debug?: boolean;
14
+ apiURL?: string;
15
+ options?: Record<string, any>;
16
+ functions?: string[];
17
+ agents?: string[];
18
+ examples?: Array<Record<string, any>>;
19
+ }
20
+ type AgentConfigInput = string | {
21
+ crew: AgentConfig[];
22
+ };
23
+ /**
24
+ * Initializes the AI agent using the specified agent name and configuration.
25
+ * This function parses the agent's configuration, validates the presence of the necessary API key,
26
+ * and creates an instance of the AI agent with the appropriate settings.
27
+ *
28
+ * @param {string} agentName - The identifier for the AI agent to be initialized.
29
+ * @param {AgentConfigInput} agentConfig - Either a file path to the JSON configuration or a JSON object with crew configuration.
30
+ * @param {FunctionRegistryType} functions - The functions available to the agent.
31
+ * @param {Object} state - The state object for the agent.
32
+ * @returns {Object} An object containing the Agents AI instance, its name, description, signature, functions and subAgentList.
33
+ * @throws {Error} Throws an error if the agent configuration is missing, the provider is unsupported,
34
+ * the API key is not found, or the provider key name is not specified in the configuration.
35
+ */
36
+ declare const getAgentConfigParams: (agentName: string, agentConfig: AgentConfigInput, functions: FunctionRegistryType, state: Record<string, any>) => {
37
+ ai: any;
38
+ name: string;
39
+ description: string;
40
+ signature: AxSignature;
41
+ functions: (AxFunction | (new (state: Record<string, any>) => {
42
+ toFunction: () => AxFunction;
43
+ }) | undefined)[];
44
+ subAgentNames: string[];
45
+ examples: Record<string, any>[];
46
+ };
47
+ export { getAgentConfigParams, AgentConfigInput };
@@ -133,20 +133,19 @@ const getAgentConfigParams = (agentName, agentConfig, functions, state) => {
133
133
  else {
134
134
  throw new Error(`Provider key name is missing in the agent configuration`);
135
135
  }
136
- // Create an instance of the AI agent
136
+ // Create an instance of the AI agent and set options
137
137
  const ai = new AIConstructor({
138
138
  apiKey,
139
139
  config: agentConfigData.ai,
140
140
  options: {
141
- debug: agentConfigData.debug || false
141
+ debug: agentConfigData.debug || false,
142
+ ...agentConfigData.options
142
143
  }
143
144
  });
144
145
  // If an apiURL is provided in the agent config, set it in the AI agent
145
146
  if (agentConfigData.apiURL) {
146
147
  ai.setAPIURL(agentConfigData.apiURL);
147
148
  }
148
- // Set all options from the agent configuration
149
- ai.setOptions({ ...agentConfigData.options });
150
149
  // Prepare functions for the AI agent
151
150
  const agentFunctions = (agentConfigData.functions || [])
152
151
  .map(funcName => {
@@ -0,0 +1,21 @@
1
+ export interface ModelUsage {
2
+ promptTokens: number;
3
+ completionTokens: number;
4
+ }
5
+ export interface ModelInfo {
6
+ promptTokenCostPer1M: number;
7
+ completionTokenCostPer1M: number;
8
+ }
9
+ export interface UsageCost {
10
+ promptCost: number;
11
+ completionCost: number;
12
+ totalCost: number;
13
+ tokenMetrics: {
14
+ promptTokens: number;
15
+ completionTokens: number;
16
+ totalTokens: number;
17
+ };
18
+ }
19
+ export declare class StateFulAxAgentUsage {
20
+ static calculateCost(modelUsage: ModelUsage, modelInfo: ModelInfo): UsageCost;
21
+ }
@@ -0,0 +1,62 @@
1
+ import { AxAgent, AxAI } from "@ax-llm/ax";
2
+ import type { AxSignature, AxAgentic, AxFunction, AxProgramForwardOptions } from "@ax-llm/ax";
3
+ import type { AgentConfigInput } from "./agentConfig.js";
4
+ import { FunctionRegistryType } from "../functions/index.js";
5
+ import { StateInstance } from "../state/index.js";
6
+ import { UsageCost } from "./agentUseCosts.js";
7
+ declare class StatefulAxAgent extends AxAgent<any, any> {
8
+ state: StateInstance;
9
+ axai: any;
10
+ constructor(ai: AxAI, options: Readonly<{
11
+ name: string;
12
+ description: string;
13
+ signature: string | AxSignature;
14
+ agents?: AxAgentic[] | undefined;
15
+ functions?: (AxFunction | (() => AxFunction))[] | undefined;
16
+ examples?: Array<Record<string, any>> | undefined;
17
+ }>, state: StateInstance);
18
+ forward(input: Record<string, any>, options?: Readonly<AxProgramForwardOptions>): Promise<Record<string, any>>;
19
+ getUsageCost(): UsageCost | null;
20
+ }
21
+ /**
22
+ * Represents a crew of agents with shared state functionality.
23
+ */
24
+ declare class AxCrew {
25
+ private agentConfig;
26
+ functionsRegistry: FunctionRegistryType;
27
+ crewId: string;
28
+ agents: Map<string, StatefulAxAgent> | null;
29
+ state: StateInstance;
30
+ /**
31
+ * Creates an instance of AxCrew.
32
+ * @param {AgentConfigInput} agentConfig - Either a path to the agent config file or a JSON object with crew configuration.
33
+ * @param {FunctionRegistryType} [functionsRegistry={}] - The registry of functions to use in the crew.
34
+ * @param {string} [crewId=uuidv4()] - The unique identifier for the crew.
35
+ */
36
+ constructor(agentConfig: AgentConfigInput, functionsRegistry?: FunctionRegistryType, crewId?: string);
37
+ /**
38
+ * Factory function for creating an agent.
39
+ * @param {string} agentName - The name of the agent to create.
40
+ * @returns {StatefulAxAgent} The created StatefulAxAgent instance.
41
+ * @throws Will throw an error if the agent creation fails.
42
+ */
43
+ createAgent: (agentName: string) => StatefulAxAgent;
44
+ /**
45
+ * Adds an agent to the crew by name.
46
+ * @param {string} agentName - The name of the agent to add.
47
+ */
48
+ addAgent(agentName: string): void;
49
+ /**
50
+ * Sets up agents in the crew by name.
51
+ * For an array of Agent names provided, it adds
52
+ * the agent to the crew if not already present.
53
+ * @param {string[]} agentNames - An array of agent names to configure.
54
+ * @returns {Map<string, StatefulAxAgent> | null} A map of agent names to their corresponding instances.
55
+ */
56
+ addAgentsToCrew(agentNames: string[]): Map<string, StatefulAxAgent> | null;
57
+ /**
58
+ * Cleans up the crew by dereferencing agents and resetting the state.
59
+ */
60
+ destroy(): void;
61
+ }
62
+ export { AxCrew };
@@ -0,0 +1,5 @@
1
+ interface ProviderApiKeys {
2
+ [key: string]: string | undefined;
3
+ }
4
+ declare const PROVIDER_API_KEYS: ProviderApiKeys;
5
+ export { PROVIDER_API_KEYS, };
@@ -0,0 +1,3 @@
1
+ import type { AxFunction } from "@ax-llm/ax";
2
+ export declare const CurrentDateTime: AxFunction;
3
+ export declare const DaysBetweenDates: AxFunction;
@@ -0,0 +1,13 @@
1
+ import { AxFunction } from '@ax-llm/ax';
2
+ type FunctionRegistryType = {
3
+ [key: string]: AxFunction | {
4
+ new (state: Record<string, any>): {
5
+ toFunction: () => AxFunction;
6
+ };
7
+ };
8
+ };
9
+ declare const AxCrewFunctions: {
10
+ CurrentDateTime: AxFunction;
11
+ DaysBetweenDates: AxFunction;
12
+ };
13
+ export { AxCrewFunctions, FunctionRegistryType };
@@ -0,0 +1,3 @@
1
+ import { AxCrew } from './agents/index.js';
2
+ import { AxCrewFunctions, FunctionRegistryType } from './functions/index.js';
3
+ export { AxCrew, AxCrewFunctions, FunctionRegistryType };
@@ -0,0 +1,12 @@
1
+ interface StateInstance {
2
+ set: (key: string, value: any) => void;
3
+ get: (key: string) => any;
4
+ getAll: () => {
5
+ [key: string]: any;
6
+ };
7
+ getId: () => string;
8
+ reset: () => void;
9
+ }
10
+ declare const createState: (id: string) => StateInstance;
11
+ declare const getState: (id: string) => StateInstance | undefined;
12
+ export { createState, getState, StateInstance };
package/index.d.ts ADDED
@@ -0,0 +1,7 @@
1
+ export class AxCrew {
2
+ constructor(configPath: string);
3
+ addAgent(agent: any): void;
4
+ createAgent(agent: any): void;
5
+ addAgentsToCrew(agents: any[]): void;
6
+ destroy(): void;
7
+ }
package/package.json CHANGED
@@ -1,9 +1,10 @@
1
1
  {
2
2
  "type": "module",
3
3
  "name": "@amitdeshmukh/ax-crew",
4
- "version": "3.3.0",
4
+ "version": "3.3.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
+ "types": "dist/index.d.ts",
7
8
  "engines": {
8
9
  "node": ">=21.0.0"
9
10
  },
@@ -173,21 +173,19 @@ const getAgentConfigParams = (
173
173
  throw new Error(`Provider key name is missing in the agent configuration`);
174
174
  }
175
175
 
176
- // Create an instance of the AI agent
176
+ // Create an instance of the AI agent and set options
177
177
  const ai = new AIConstructor({
178
178
  apiKey,
179
179
  config: agentConfigData.ai,
180
180
  options: {
181
- debug: agentConfigData.debug || false
181
+ debug: agentConfigData.debug || false,
182
+ ...agentConfigData.options
182
183
  }
183
184
  });
184
185
  // If an apiURL is provided in the agent config, set it in the AI agent
185
186
  if (agentConfigData.apiURL) {
186
187
  ai.setAPIURL(agentConfigData.apiURL);
187
188
  }
188
-
189
- // Set all options from the agent configuration
190
- ai.setOptions({ ...agentConfigData.options });
191
189
 
192
190
  // Prepare functions for the AI agent
193
191
  const agentFunctions = (agentConfigData.functions || [])
@@ -1,14 +1,14 @@
1
- interface ModelUsage {
1
+ export interface ModelUsage {
2
2
  promptTokens: number;
3
3
  completionTokens: number;
4
4
  }
5
5
 
6
- interface ModelInfo {
6
+ export interface ModelInfo {
7
7
  promptTokenCostPer1M: number;
8
8
  completionTokenCostPer1M: number;
9
9
  }
10
10
 
11
- interface UsageCost {
11
+ export interface UsageCost {
12
12
  promptCost: number;
13
13
  completionCost: number;
14
14
  totalCost: number;
@@ -10,7 +10,7 @@ import { getAgentConfigParams } from "./agentConfig.js";
10
10
  import type { AgentConfigInput } from "./agentConfig.js";
11
11
  import { FunctionRegistryType } from "../functions/index.js";
12
12
  import { createState, StateInstance } from "../state/index.js";
13
- import { StateFulAxAgentUsage } from "./agentUseCosts.js";
13
+ import { StateFulAxAgentUsage, UsageCost } from "./agentUseCosts.js";
14
14
 
15
15
  // Define the interface for the agent configuration
16
16
  interface AgentConfigParams {
@@ -70,7 +70,7 @@ class StatefulAxAgent extends AxAgent<any, any> {
70
70
  }
71
71
 
72
72
  // Get the usage cost for a run of the agent
73
- getUsageCost() {
73
+ getUsageCost(): UsageCost | null {
74
74
  const { modelUsage, modelInfo, models } = this.axai;
75
75
  const currentModelInfo = modelInfo?.find((m: { name: string }) => m.name === models.model);
76
76
 
package/test1.js CHANGED
@@ -6,65 +6,73 @@ const config = {
6
6
  {
7
7
  name: "Planner",
8
8
  description: "Creates a plan to complete a task",
9
- signature: "task:string \"a task to be completed\" -> plan:string \"a plan to execute the task in 5 steps or less\"",
9
+ signature:
10
+ 'task:string "a task to be completed" -> plan:string "a plan to execute the task in 5 steps or less"',
10
11
  provider: "google-gemini",
11
12
  providerKeyName: "GEMINI_API_KEY",
12
13
  ai: {
13
14
  model: "gemini-1.5-flash",
14
- temperature: 0
15
+ temperature: 0,
15
16
  },
16
17
  options: {
17
- debug: false
18
- }
18
+ debug: false,
19
+ },
19
20
  },
20
21
  {
21
22
  name: "Calculator",
22
23
  description: "Solves math problems",
23
- signature: "mathProblem:string \"a math problem to be solved using Python code\" -> solution:string \"the solution to the math problem\"",
24
+ signature:
25
+ 'mathProblem:string "a math problem to be solved using Python code" -> solution:string "the solution to the math problem"',
24
26
  provider: "google-gemini",
25
27
  providerKeyName: "GEMINI_API_KEY",
26
28
  ai: {
27
29
  model: "gemini-1.5-pro",
28
- temperature: 0
30
+ temperature: 0,
29
31
  },
30
32
  options: {
31
33
  debug: true,
32
- codeExecution: true
34
+ codeExecution: true,
33
35
  },
34
- functions: ["CurrentDateTime", "DaysBetweenDates"]
36
+ functions: ["CurrentDateTime", "DaysBetweenDates"],
35
37
  },
36
38
  {
37
39
  name: "WebSearch",
38
- description: "Searches the web for the latest information using Google search",
39
- signature: "webSearchQuery:string \"a query for Google search\" -> webSearchResponse:string \"the result of the search\"",
40
+ description:
41
+ "Searches the web for the latest information using Google search",
42
+ signature:
43
+ 'webSearchQuery:string "a query for Google search" -> webSearchResponse:string "the result of the search"',
40
44
  provider: "google-gemini",
41
45
  providerKeyName: "GEMINI_API_KEY",
42
46
  ai: {
43
47
  model: "gemini-1.5-pro",
44
- temperature: 0
48
+ temperature: 0,
45
49
  },
46
50
  options: {
47
51
  debug: true,
48
- googleSearchRetrieval: true
52
+ googleSearchRetrieval: {
53
+ dynamic_retrieval_config: {
54
+ mode: "MODE_UNSPECIFIED",
55
+ },
56
+ },
49
57
  },
50
- functions: ["CurrentDateTime", "DaysBetweenDates"]
51
58
  },
52
59
  {
53
60
  name: "Manager",
54
61
  description: "Answers questions from the user",
55
- signature: "question:string \"a question from a user\", plan:string \"a suggested plan to answer the question\" -> answer:string \"the answer\"",
62
+ signature:
63
+ 'question:string "a question from a user", plan:string "a suggested plan to answer the question" -> answer:string "the answer"',
56
64
  provider: "openai",
57
65
  providerKeyName: "OPENAI_API_KEY",
58
66
  ai: {
59
67
  model: "gpt-4o-mini",
60
- temperature: 0
68
+ temperature: 0,
61
69
  },
62
70
  options: {
63
- debug: true
71
+ debug: true,
64
72
  },
65
- functions: ["CurrentDateTime", "DaysBetweenDates"]
66
- }
67
- ]
73
+ functions: ["CurrentDateTime", "DaysBetweenDates"],
74
+ },
75
+ ],
68
76
  };
69
77
 
70
78
  // Create crew instance with the direct configuration
@@ -81,16 +89,16 @@ const calculateAndPrintAgentCost = (agent, agentName) => {
81
89
  console.log(`\n${agentName} Usage:\nPrompt Token Cost: $${(promptTokens / 1000000 * modelDetails?.promptTokenCostPer1M).toFixed(6)}\nCompletion Token Cost: $${(completionTokens / 1000000 * modelDetails?.completionTokenCostPer1M).toFixed(6)}\nTotal Cost: $${totalCost.toFixed(6)}\nPrompt Tokens: ${promptTokens}\nCompletion Tokens: ${completionTokens}\nTotal Tokens: ${promptTokens + completionTokens}`);
82
90
  };
83
91
 
84
- const userQuery = "what is the cube root of the number of days between now and Christmas";
92
+ const userQuery = "best sushi in mumbai";
85
93
  console.log(`\n\nQuestion: ${userQuery}`);
86
94
 
87
- const Planner = crew.agents.get("Planner");
88
- const plannerResponse = await Planner.forward({ task: userQuery });
89
- console.log(`\n\nPlanner Response: ${plannerResponse.plan}`);
95
+ // const Planner = crew.agents.get("Planner");
96
+ // const plannerResponse = await Planner.forward({ task: userQuery });
97
+ // console.log(`\n\nPlanner Response: ${plannerResponse.plan}`);
90
98
 
91
- const Manager = crew.agents.get("Manager");
92
- const managerResponse = await Manager.forward({ question: userQuery, plan: plannerResponse.plan });
93
- console.log(`\n\nManager Response: ${managerResponse.answer}`);
99
+ const WebSearch = crew.agents.get("WebSearch");
100
+ const webSearchResponse = await WebSearch.forward({ webSearchQuery: userQuery });
101
+ console.log(`\n\nWeb Search Response: ${webSearchResponse.webSearchResponse}`);
94
102
 
95
103
  // const calculatorResponse = await crew.agents.get("Calculator").forward({ mathProblem: userQuery });
96
104
  // calculateAndPrintAgentCost(crew.agents.get("Calculator"), "Calculator");
package/tsconfig.json CHANGED
@@ -1,5 +1,6 @@
1
1
  {
2
2
  "compilerOptions": {
3
+ "declaration": true,
3
4
  "module": "ESNext",
4
5
  "target": "ES2020",
5
6
  "moduleResolution": "node",