agentnet 0.0.1 → 0.0.3
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/README.md +317 -364
- package/_OLD_README.md +554 -0
- package/assets/network01.png +0 -0
- package/examples/customer-support/README.md +66 -0
- package/examples/customer-support/agents.yaml +457 -0
- package/examples/customer-support/index.js +408 -0
- package/examples/event-planner/README.md +69 -0
- package/examples/event-planner/agents.yaml +318 -0
- package/examples/event-planner/index.js +547 -0
- package/{src/examples → examples/simple}/simple.js +2 -2
- package/{src/examples → examples/smartness}/agents-smartness.yaml +8 -17
- package/{src/examples/def3.js → examples/smartness/index.js} +9 -9
- package/jest.config.js +1 -0
- package/package.json +6 -3
- package/src/agent/agent-loader.js +75 -12
- package/src/agent/agent.js +13 -3
- package/src/agent/runtime.js +9 -6
- package/src/llm/base.js +131 -0
- package/src/llm/gemini.js +137 -117
- package/src/llm/gpt.js +131 -104
- package/src/store/store.js +82 -48
- package/src/tests/agent.test.js +350 -0
- package/src/tools/migrate-version.js +250 -0
- package/src/transport/README.md +123 -0
- package/src/transport/base.js +237 -0
- package/src/transport/index.js +89 -0
- package/src/transport/kafka.js +474 -0
- package/src/transport/nats.js +521 -0
- package/src/transport/rabbitmq.js +722 -0
- package/src/transport/redis.js +532 -0
- package/src/utils/version.js +212 -0
- package/src/agent/runtimes/nats.js +0 -379
- package/src/examples/agents.yaml +0 -394
- package/src/examples/def.js +0 -74
- package/src/examples/def2.js +0 -65
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { AgentLoaderFile, AgentClient, NatsIO, Bindings, Message, PostgresStore } from "
|
|
1
|
+
import { AgentLoaderFile, AgentClient, NatsIO, Bindings, Message, PostgresStore, RedisStore, MemoryStore } from "../../src/index.js"
|
|
2
2
|
|
|
3
3
|
// NatsIO instance
|
|
4
4
|
const io = NatsIO({
|
|
@@ -6,16 +6,16 @@ const io = NatsIO({
|
|
|
6
6
|
})
|
|
7
7
|
|
|
8
8
|
// Load the agents from the YAML file
|
|
9
|
-
const agents = await AgentLoaderFile('./
|
|
10
|
-
bindings: { [Bindings.NatsIO]: io, [Bindings.Postgres]: PostgresStore() }
|
|
9
|
+
const agents = await AgentLoaderFile('./examples/smartness/agents-smartness.yaml', {
|
|
10
|
+
bindings: { [Bindings.NatsIO]: io, [Bindings.Postgres]: PostgresStore(), [Bindings.Redis]: RedisStore(), [Bindings.Memory]: MemoryStore() }
|
|
11
11
|
})
|
|
12
12
|
|
|
13
13
|
// Entry point
|
|
14
|
-
const agentSmartness = await agents.
|
|
14
|
+
const agentSmartness = await agents.entrypoint
|
|
15
15
|
await agentSmartness.compile()
|
|
16
16
|
|
|
17
17
|
// Accomodation agent
|
|
18
|
-
const agentAccomodation = await agents.
|
|
18
|
+
const agentAccomodation = await agents.accomodation
|
|
19
19
|
agentAccomodation.tools.getRoomsListTool.bind(async (state, input) => {
|
|
20
20
|
return { answer: "We have Double room with a view of the sea and a single room with a view of the pool, and a suite with a view of the city." }
|
|
21
21
|
})
|
|
@@ -29,21 +29,21 @@ agentAccomodation.prompt(async (state, input) => {
|
|
|
29
29
|
await agentAccomodation.compile()
|
|
30
30
|
|
|
31
31
|
// Booking agent
|
|
32
|
-
const agentBooking = await agents.
|
|
32
|
+
const agentBooking = await agents.booking
|
|
33
33
|
agentBooking.tools.bookRoomTool.bind(async (state, input) => {
|
|
34
34
|
return { answer: "The room " + input.roomName + " has been booked for the dates " + input.checkinDate + " to " + input.checkoutDate + "." }
|
|
35
35
|
})
|
|
36
36
|
await agentBooking.compile()
|
|
37
37
|
|
|
38
38
|
// Hotel review agent
|
|
39
|
-
const agentHotelReview = await agents.
|
|
39
|
+
const agentHotelReview = await agents.review
|
|
40
40
|
agentHotelReview.tools.getHotelReviewsTool.bind(async (state, input) => {
|
|
41
41
|
return { answer: "The hotel " + input.hotelName + " has a 4.5 star rating and a 9.2 out of 10 guest satisfaction score." }
|
|
42
42
|
})
|
|
43
43
|
await agentHotelReview.compile()
|
|
44
44
|
|
|
45
45
|
// Pricing agent
|
|
46
|
-
const agentPricing = await agents.
|
|
46
|
+
const agentPricing = await agents.pricing
|
|
47
47
|
agentPricing.tools.getPricingTool.bind(async (state, input) => {
|
|
48
48
|
return { answer: "The room " + input.roomName + " has a price of 200€ per night." }
|
|
49
49
|
})
|
|
@@ -60,7 +60,7 @@ const message = new Message({
|
|
|
60
60
|
id: "67a71e42-a7d8-1db2-ad17-64e1c8546b21"
|
|
61
61
|
}
|
|
62
62
|
})
|
|
63
|
-
const res = await agentClient.queryIo(io, '
|
|
63
|
+
const res = await agentClient.queryIo(io, 'entrypoint', message)
|
|
64
64
|
console.log("=======\n", res.getContent())
|
|
65
65
|
console.log("=======\n", res.getSession())
|
|
66
66
|
//const res2 = await agentClient.queryIo(io, 'smartnessAgent', "Quanto costa la camera doppia del Flora per il 10-05-2025 per due persone? Prenotala se costa meno di 100€ la camera double con vista mare per il 10-05-2025 al hotel Flora")
|
package/jest.config.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export default { transform: {} }
|
package/package.json
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "agentnet",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.3",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Agent library used by Smartness",
|
|
6
6
|
"main": "index.js",
|
|
7
7
|
"scripts": {
|
|
8
|
-
"test": "
|
|
8
|
+
"test": "node --experimental-vm-modules ./node_modules/.bin/jest --rootDir=src/tests"
|
|
9
9
|
},
|
|
10
10
|
"author": "",
|
|
11
11
|
"license": "ISC",
|
|
@@ -15,9 +15,12 @@
|
|
|
15
15
|
"@nats-io/transport-node": "^3.0.2",
|
|
16
16
|
"colors": "^1.4.0",
|
|
17
17
|
"openai": "^4.97.0",
|
|
18
|
-
"pg": "^
|
|
18
|
+
"pg-promise": "^11.13.0",
|
|
19
19
|
"redis": "^5.0.1",
|
|
20
20
|
"uuid": "^11.1.0",
|
|
21
21
|
"yaml": "^2.7.1"
|
|
22
|
+
},
|
|
23
|
+
"devDependencies": {
|
|
24
|
+
"jest": "^29.7.0"
|
|
22
25
|
}
|
|
23
26
|
}
|
|
@@ -2,6 +2,18 @@ import fs from 'fs'
|
|
|
2
2
|
import { parse } from 'yaml'
|
|
3
3
|
import { Gemini } from "../index.js"
|
|
4
4
|
import { Agent } from "./agent.js"
|
|
5
|
+
import { logger } from "../utils/logger.js"
|
|
6
|
+
import { ConfigurationError } from "../errors/index.js"
|
|
7
|
+
import { validateApiVersion, DEFAULT_API_VERSION, API_VERSIONS } from '../utils/version.js'
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Version handlers for different API versions
|
|
11
|
+
*/
|
|
12
|
+
const VERSION_HANDLERS = {
|
|
13
|
+
'smartagent.io/v1alpha1': processV1Alpha1Definition,
|
|
14
|
+
'agentnet.io/v1alpha1': processV1Alpha1Definition
|
|
15
|
+
// Additional version handlers can be added here as the API evolves
|
|
16
|
+
};
|
|
5
17
|
|
|
6
18
|
/**
|
|
7
19
|
* Loads agent definitions from a YAML file
|
|
@@ -47,10 +59,10 @@ function parseAgentDefinitionsFromYaml(yamlContent) {
|
|
|
47
59
|
if (isValidAgentDefinition(definition)) {
|
|
48
60
|
agentDefinitions.push(definition);
|
|
49
61
|
} else {
|
|
50
|
-
|
|
62
|
+
logger.warn("Skipping invalid or non-AgentDefinition document in YAML.");
|
|
51
63
|
}
|
|
52
64
|
} catch (error) {
|
|
53
|
-
|
|
65
|
+
logger.warn(`Failed to parse YAML document: ${error.message}`);
|
|
54
66
|
}
|
|
55
67
|
}
|
|
56
68
|
|
|
@@ -66,6 +78,58 @@ function isValidAgentDefinition(definition) {
|
|
|
66
78
|
return definition && definition.kind === 'AgentDefinition' && definition.spec;
|
|
67
79
|
}
|
|
68
80
|
|
|
81
|
+
/**
|
|
82
|
+
* Gets the appropriate version handler for a definition
|
|
83
|
+
* @param {object} definition - Agent definition
|
|
84
|
+
* @returns {Function} Version handler function
|
|
85
|
+
* @throws {ConfigurationError} If version is unsupported
|
|
86
|
+
*/
|
|
87
|
+
function getVersionHandler(definition) {
|
|
88
|
+
// Validate the API version using our utility
|
|
89
|
+
const versionData = validateApiVersion(definition);
|
|
90
|
+
const apiVersion = versionData.version;
|
|
91
|
+
|
|
92
|
+
// Get the appropriate handler for this version
|
|
93
|
+
const handler = VERSION_HANDLERS[apiVersion];
|
|
94
|
+
|
|
95
|
+
if (!handler) {
|
|
96
|
+
throw new ConfigurationError(
|
|
97
|
+
`No implementation handler for apiVersion '${apiVersion}'`,
|
|
98
|
+
{ apiVersion, supportedHandlers: Object.keys(VERSION_HANDLERS) }
|
|
99
|
+
);
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
return handler;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
/**
|
|
106
|
+
* Process a v1alpha1 agent definition
|
|
107
|
+
* @param {object} definition - Agent definition
|
|
108
|
+
* @param {object} agentBuilder - Agent builder
|
|
109
|
+
* @param {object} bindings - IO and store bindings
|
|
110
|
+
* @returns {object} Processed agent interface and tool map
|
|
111
|
+
*/
|
|
112
|
+
async function processV1Alpha1Definition(definition, agentBuilder, bindings) {
|
|
113
|
+
const spec = definition.spec;
|
|
114
|
+
|
|
115
|
+
// Add apiVersion to agent metadata
|
|
116
|
+
agentBuilder.setMetadata({
|
|
117
|
+
...agentBuilder._config.metadata,
|
|
118
|
+
apiVersion: definition.apiVersion || DEFAULT_API_VERSION
|
|
119
|
+
});
|
|
120
|
+
|
|
121
|
+
// Configure different aspects of the agent
|
|
122
|
+
agentBuilder = configureIO(agentBuilder, spec.io, bindings);
|
|
123
|
+
agentBuilder = configureStore(agentBuilder, spec.store, bindings);
|
|
124
|
+
agentBuilder = await configureLLM(agentBuilder, spec.llm);
|
|
125
|
+
agentBuilder = configureDiscoverySchemas(agentBuilder, spec.discoverySchemas);
|
|
126
|
+
|
|
127
|
+
// Set up tools
|
|
128
|
+
const toolMap = configureTools(agentBuilder, spec.tools);
|
|
129
|
+
|
|
130
|
+
return { agentBuilder, toolMap };
|
|
131
|
+
}
|
|
132
|
+
|
|
69
133
|
/**
|
|
70
134
|
* Loads an LLM provider instance
|
|
71
135
|
* @param {string} providerName - Name of the provider
|
|
@@ -237,7 +301,6 @@ async function AgentLoader(agentsDefinitions, config = {}) {
|
|
|
237
301
|
throw new Error(`Invalid agent definition: missing spec`);
|
|
238
302
|
}
|
|
239
303
|
|
|
240
|
-
const spec = definition.spec;
|
|
241
304
|
const metadata = definition.metadata || {
|
|
242
305
|
name: "default",
|
|
243
306
|
description: "Agent from definition"
|
|
@@ -250,21 +313,21 @@ async function AgentLoader(agentsDefinitions, config = {}) {
|
|
|
250
313
|
// Initialize agent builder with metadata
|
|
251
314
|
let agentBuilder = Agent().setMetadata(metadata);
|
|
252
315
|
|
|
253
|
-
//
|
|
254
|
-
|
|
255
|
-
agentBuilder = configureStore(agentBuilder, spec.store, bindings);
|
|
256
|
-
agentBuilder = await configureLLM(agentBuilder, spec.llm);
|
|
257
|
-
agentBuilder = configureDiscoverySchemas(agentBuilder, spec.discoverySchemas);
|
|
316
|
+
// Get the appropriate version handler
|
|
317
|
+
const versionHandler = getVersionHandler(definition);
|
|
258
318
|
|
|
259
|
-
//
|
|
260
|
-
const toolMap =
|
|
319
|
+
// Process according to API version
|
|
320
|
+
const { agentBuilder: updatedBuilder, toolMap } =
|
|
321
|
+
await versionHandler(definition, agentBuilder, bindings);
|
|
261
322
|
|
|
262
323
|
// Create the agent interface
|
|
263
|
-
loadedAgents[metadata.name] = createAgentInterface(
|
|
324
|
+
loadedAgents[metadata.name] = createAgentInterface(updatedBuilder, toolMap);
|
|
325
|
+
|
|
326
|
+
logger.info(`Agent '${metadata.name}' loaded successfully with apiVersion: ${definition.apiVersion || DEFAULT_API_VERSION}`);
|
|
264
327
|
|
|
265
328
|
} catch (error) {
|
|
266
329
|
const agentName = definition.metadata?.name || 'Unnamed Agent';
|
|
267
|
-
|
|
330
|
+
logger.error(`Failed to load agent "${agentName}": ${error.message}`, { error });
|
|
268
331
|
// Optional: decide whether to throw or just log and continue
|
|
269
332
|
// throw error;
|
|
270
333
|
}
|
package/src/agent/agent.js
CHANGED
|
@@ -22,7 +22,9 @@ const DEFAULT_HOOKS = {
|
|
|
22
22
|
const DEFAULT_CONFIG = {
|
|
23
23
|
metadata: {
|
|
24
24
|
name: "default",
|
|
25
|
-
|
|
25
|
+
namespace: "default",
|
|
26
|
+
description: "A default agent",
|
|
27
|
+
apiVersion: "agentnet/v1alpha1" // Default API version
|
|
26
28
|
},
|
|
27
29
|
runner: {
|
|
28
30
|
maxRuns: 10
|
|
@@ -39,9 +41,11 @@ const AGENT_CONFIG_SCHEMA = {
|
|
|
39
41
|
type: 'object',
|
|
40
42
|
properties: {
|
|
41
43
|
name: { type: 'string' },
|
|
42
|
-
|
|
44
|
+
namespace: { type: 'string' },
|
|
45
|
+
description: { type: 'string' },
|
|
46
|
+
apiVersion: { type: 'string' }
|
|
43
47
|
},
|
|
44
|
-
required: ['name']
|
|
48
|
+
required: ['name', 'namespace']
|
|
45
49
|
},
|
|
46
50
|
llm: {
|
|
47
51
|
type: 'object',
|
|
@@ -118,6 +122,12 @@ export function Agent() {
|
|
|
118
122
|
metadata: config.metadata
|
|
119
123
|
});
|
|
120
124
|
}
|
|
125
|
+
|
|
126
|
+
if (!config.metadata.namespace.trim()) {
|
|
127
|
+
throw new ConfigurationError("Agent namespace cannot be empty", {
|
|
128
|
+
metadata: config.metadata
|
|
129
|
+
});
|
|
130
|
+
}
|
|
121
131
|
|
|
122
132
|
// LLM API validation
|
|
123
133
|
if (typeof config.llm.api !== 'object' || config.llm.api === null) {
|
package/src/agent/runtime.js
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
import { build, makeToolsAndHandoffsMap } from "./executor.js"
|
|
2
|
-
import { NatsIOAgentRuntime } from "./runtimes/nats.js"
|
|
3
2
|
import { logger } from "../utils/logger.js"
|
|
4
3
|
import { Response, SessionStore } from "../index.js"
|
|
4
|
+
import { createAgentRuntime } from "../transport/index.js"
|
|
5
5
|
|
|
6
6
|
export async function AgentRuntime(agentConfig) {
|
|
7
7
|
const {
|
|
8
8
|
toolsAndHandoffsMap,
|
|
9
9
|
hooks,
|
|
10
10
|
store,
|
|
11
|
-
metadata: { name: agentName },
|
|
11
|
+
metadata: { name: agentName, namespace },
|
|
12
12
|
llm: { api: llmApi, config: llmConfig },
|
|
13
13
|
runner,
|
|
14
14
|
toolsSchemas: tools,
|
|
@@ -19,10 +19,14 @@ export async function AgentRuntime(agentConfig) {
|
|
|
19
19
|
} = agentConfig
|
|
20
20
|
|
|
21
21
|
// Initialize IO runtime
|
|
22
|
-
const
|
|
23
|
-
|
|
22
|
+
const transportType = ioInterfaces.length > 0 ? ioInterfaces[0].type.replace('IO', '').toLowerCase() : 'nats';
|
|
23
|
+
logger.info(`Creating agent runtime with transport type: ${transportType}`);
|
|
24
|
+
|
|
25
|
+
const { handleTask, discoveredAgents } = await createAgentRuntime(
|
|
26
|
+
transportType,
|
|
27
|
+
namespace,
|
|
24
28
|
agentName,
|
|
25
|
-
|
|
29
|
+
ioInterfaces,
|
|
26
30
|
discoverySchemas
|
|
27
31
|
)
|
|
28
32
|
|
|
@@ -94,7 +98,6 @@ export async function AgentRuntime(agentConfig) {
|
|
|
94
98
|
|
|
95
99
|
// Execute agent runtime
|
|
96
100
|
const result = await taskFunction(storeState.state, storeState.conversation, promptContent);
|
|
97
|
-
|
|
98
101
|
// Process result through response hook
|
|
99
102
|
const responseMessage = await response(storeState.state, storeState.conversation, result);
|
|
100
103
|
// Save session state and session data
|
package/src/llm/base.js
ADDED
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
import { logger } from '../utils/logger.js'
|
|
2
|
+
import { LLMError } from '../errors/index.js'
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Base class for LLM implementations
|
|
6
|
+
* Provides common functionality and defines required interface
|
|
7
|
+
*/
|
|
8
|
+
export class BaseLLM {
|
|
9
|
+
/**
|
|
10
|
+
* @param {string} providerType - The LLM provider type (e.g., 'gemini', 'openai')
|
|
11
|
+
*/
|
|
12
|
+
constructor(providerType) {
|
|
13
|
+
this.type = providerType;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Initialize and get the LLM client
|
|
18
|
+
* @returns {Promise<any>} Initialized LLM client
|
|
19
|
+
* @throws {LLMError} If initialization fails
|
|
20
|
+
*/
|
|
21
|
+
async getClient() {
|
|
22
|
+
throw new Error('getClient() must be implemented by subclasses');
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Call the LLM model with the provided configuration and context
|
|
27
|
+
* @param {Object} config - LLM-specific configuration
|
|
28
|
+
* @param {Object} context - Context containing client, tools map and conversation
|
|
29
|
+
* @returns {Promise<Object>} The model response
|
|
30
|
+
* @throws {LLMError} If the API call fails
|
|
31
|
+
*/
|
|
32
|
+
async callModel(config, context) {
|
|
33
|
+
throw new Error('callModel() must be implemented by subclasses');
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Process the model response, handling text responses and function calls
|
|
38
|
+
* @param {Object} state - Current application state
|
|
39
|
+
* @param {Array} conversation - The conversation history
|
|
40
|
+
* @param {Object} toolsAndHandoffsMap - Map of available tools
|
|
41
|
+
* @param {Object} response - The model response to process
|
|
42
|
+
* @returns {Promise<string|null>} Text response or null if processing tool calls
|
|
43
|
+
*/
|
|
44
|
+
async onResponse(state, conversation, toolsAndHandoffsMap, response) {
|
|
45
|
+
throw new Error('onResponse() must be implemented by subclasses');
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* Add a user prompt to the conversation
|
|
50
|
+
* @param {Array} conversation - The conversation history
|
|
51
|
+
* @param {string} formattedPrompt - The formatted user prompt
|
|
52
|
+
* @returns {Promise<void>}
|
|
53
|
+
*/
|
|
54
|
+
async prompt(conversation, formattedPrompt) {
|
|
55
|
+
logger.debug('Adding user prompt to conversation', {
|
|
56
|
+
promptPreview: formattedPrompt.substring(0, 100)
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
// Subclasses must implement appropriate conversation format
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* Check if required API key is set in environment variables
|
|
64
|
+
* @param {string} keyName - Environment variable name for the API key
|
|
65
|
+
* @returns {void}
|
|
66
|
+
* @throws {LLMError} If API key is not set
|
|
67
|
+
*/
|
|
68
|
+
checkApiKey(keyName) {
|
|
69
|
+
if (!process.env[keyName]) {
|
|
70
|
+
throw new LLMError(
|
|
71
|
+
`${keyName} environment variable is not set`,
|
|
72
|
+
this.type
|
|
73
|
+
);
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* Execute a tool call from the model response
|
|
79
|
+
* @param {Object} toolCall - The tool call to execute
|
|
80
|
+
* @param {Object} state - Current application state
|
|
81
|
+
* @param {Array} conversation - The conversation history
|
|
82
|
+
* @param {Object} toolsAndHandoffsMap - Map of available tools
|
|
83
|
+
* @returns {Promise<any>} Result of the tool execution
|
|
84
|
+
*/
|
|
85
|
+
async executeToolCall(toolCall, name, args, state, conversation, toolsAndHandoffsMap) {
|
|
86
|
+
logger.debug(`Executing tool from ${this.type}`, {
|
|
87
|
+
toolName: name,
|
|
88
|
+
argsPreview: JSON.stringify(args).substring(0, 100)
|
|
89
|
+
});
|
|
90
|
+
|
|
91
|
+
try {
|
|
92
|
+
if (!toolsAndHandoffsMap[name] || !toolsAndHandoffsMap[name].function) {
|
|
93
|
+
throw new Error(`Tool "${name}" not found or has no function implementation`);
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
let result = null;
|
|
97
|
+
if (toolsAndHandoffsMap[name].type === 'handoff') {
|
|
98
|
+
result = await toolsAndHandoffsMap[name].function(conversation, state, args);
|
|
99
|
+
// Process handoff results if needed
|
|
100
|
+
this.processHandoffResult(result, state);
|
|
101
|
+
} else {
|
|
102
|
+
result = await toolsAndHandoffsMap[name].function(state, args);
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
logger.debug('Tool execution successful', { toolName: name });
|
|
106
|
+
return result;
|
|
107
|
+
|
|
108
|
+
} catch (error) {
|
|
109
|
+
logger.error(`Error executing tool "${name}"`, { error });
|
|
110
|
+
throw error;
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
/**
|
|
115
|
+
* Process the result of a handoff operation
|
|
116
|
+
* @param {string} result - The JSON string result from handoff
|
|
117
|
+
* @param {Object} state - The state to update
|
|
118
|
+
*/
|
|
119
|
+
processHandoffResult(result, state) {
|
|
120
|
+
try {
|
|
121
|
+
const resultParsed = JSON.parse(result);
|
|
122
|
+
if (resultParsed.session) {
|
|
123
|
+
Object.entries(resultParsed.session).forEach(([key, value]) => {
|
|
124
|
+
state[key] = value;
|
|
125
|
+
});
|
|
126
|
+
}
|
|
127
|
+
} catch (error) {
|
|
128
|
+
logger.error('Failed to process handoff result', { error });
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
}
|