@inkeep/agents-sdk 0.1.1 → 0.1.7

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.
Files changed (60) hide show
  1. package/SUPPLEMENTAL_TERMS.md +40 -0
  2. package/dist/index.cjs +3334 -0
  3. package/dist/index.d.cts +1131 -0
  4. package/dist/index.d.ts +1131 -11
  5. package/dist/index.js +3305 -10
  6. package/package.json +8 -7
  7. package/dist/__tests__/utils/testTenant.d.ts +0 -7
  8. package/dist/__tests__/utils/testTenant.d.ts.map +0 -1
  9. package/dist/__tests__/utils/testTenant.js +0 -10
  10. package/dist/__tests__/utils/testTenant.js.map +0 -1
  11. package/dist/agent.d.ts +0 -47
  12. package/dist/agent.d.ts.map +0 -1
  13. package/dist/agent.js +0 -601
  14. package/dist/agent.js.map +0 -1
  15. package/dist/artifact-component.d.ts +0 -27
  16. package/dist/artifact-component.d.ts.map +0 -1
  17. package/dist/artifact-component.js +0 -116
  18. package/dist/artifact-component.js.map +0 -1
  19. package/dist/builders.d.ts +0 -211
  20. package/dist/builders.d.ts.map +0 -1
  21. package/dist/builders.js +0 -244
  22. package/dist/builders.js.map +0 -1
  23. package/dist/data-component.d.ts +0 -25
  24. package/dist/data-component.d.ts.map +0 -1
  25. package/dist/data-component.js +0 -112
  26. package/dist/data-component.js.map +0 -1
  27. package/dist/environment-settings.d.ts +0 -28
  28. package/dist/environment-settings.d.ts.map +0 -1
  29. package/dist/environment-settings.js +0 -78
  30. package/dist/environment-settings.js.map +0 -1
  31. package/dist/externalAgent.d.ts +0 -58
  32. package/dist/externalAgent.d.ts.map +0 -1
  33. package/dist/externalAgent.js +0 -161
  34. package/dist/externalAgent.js.map +0 -1
  35. package/dist/graph.d.ts +0 -200
  36. package/dist/graph.d.ts.map +0 -1
  37. package/dist/graph.js +0 -1294
  38. package/dist/graph.js.map +0 -1
  39. package/dist/graphFullClient.d.ts +0 -22
  40. package/dist/graphFullClient.d.ts.map +0 -1
  41. package/dist/graphFullClient.js +0 -189
  42. package/dist/graphFullClient.js.map +0 -1
  43. package/dist/index.d.ts.map +0 -1
  44. package/dist/index.js.map +0 -1
  45. package/dist/module-hosted-tool-manager.d.ts +0 -37
  46. package/dist/module-hosted-tool-manager.d.ts.map +0 -1
  47. package/dist/module-hosted-tool-manager.js +0 -375
  48. package/dist/module-hosted-tool-manager.js.map +0 -1
  49. package/dist/runner.d.ts +0 -38
  50. package/dist/runner.d.ts.map +0 -1
  51. package/dist/runner.js +0 -164
  52. package/dist/runner.js.map +0 -1
  53. package/dist/tool.d.ts +0 -29
  54. package/dist/tool.d.ts.map +0 -1
  55. package/dist/tool.js +0 -122
  56. package/dist/tool.js.map +0 -1
  57. package/dist/types.d.ts +0 -285
  58. package/dist/types.d.ts.map +0 -1
  59. package/dist/types.js +0 -37
  60. package/dist/types.js.map +0 -1
package/dist/graph.js DELETED
@@ -1,1294 +0,0 @@
1
- import { createDatabaseClient, getLogger, getProject } from '@inkeep/agents-core';
2
- import { ExternalAgent } from './externalAgent';
3
- import { updateFullGraphViaAPI } from './graphFullClient';
4
- const logger = getLogger('graph');
5
- // Helper function to resolve getter functions
6
- function resolveGetter(value) {
7
- if (typeof value === 'function') {
8
- return value();
9
- }
10
- return value;
11
- }
12
- export class AgentGraph {
13
- agents = [];
14
- agentMap = new Map();
15
- defaultAgent;
16
- baseURL;
17
- tenantId;
18
- projectId;
19
- graphId;
20
- graphName;
21
- graphDescription;
22
- initialized = false;
23
- contextConfig; // ContextConfigBuilder
24
- credentials;
25
- models;
26
- statusUpdateSettings;
27
- graphPrompt;
28
- stopWhen;
29
- dbClient;
30
- constructor(config) {
31
- this.defaultAgent = config.defaultAgent;
32
- this.tenantId = config.tenantId || 'default';
33
- this.projectId = 'default'; // Default project ID, will be overridden by setConfig
34
- this.graphId = config.id;
35
- this.graphName = config.name || this.graphId;
36
- this.graphDescription = config.description;
37
- this.baseURL = process.env.INKEEP_API_URL || 'http://localhost:3002';
38
- this.contextConfig = config.contextConfig;
39
- this.credentials = resolveGetter(config.credentials);
40
- this.models = config.models;
41
- // Initialize database client
42
- // In test environment, always use in-memory database
43
- const dbUrl = process.env.ENVIRONMENT === 'test'
44
- ? ':memory:'
45
- : process.env.DB_FILE_NAME || process.env.DATABASE_URL || ':memory:';
46
- this.dbClient = createDatabaseClient({
47
- url: dbUrl,
48
- });
49
- this.statusUpdateSettings = config.statusUpdates;
50
- this.graphPrompt = config.graphPrompt;
51
- // Set stopWhen - preserve original config or set default during inheritance
52
- this.stopWhen = config.stopWhen
53
- ? {
54
- transferCountIs: config.stopWhen.transferCountIs,
55
- }
56
- : undefined;
57
- this.agents = resolveGetter(config.agents) || [];
58
- this.agentMap = new Map(this.agents.map((agent) => [agent.getId(), agent]));
59
- // Add default agent to map
60
- if (this.defaultAgent) {
61
- this.agents.push(this.defaultAgent);
62
- this.agentMap.set(this.defaultAgent.getId(), this.defaultAgent);
63
- }
64
- // Propagate graph-level models to agents immediately (if graph has models)
65
- if (this.models) {
66
- this.propagateImmediateModelSettings();
67
- }
68
- logger.info({
69
- graphId: this.graphId,
70
- tenantId: this.tenantId,
71
- agentCount: this.agents.length,
72
- defaultAgent: this.defaultAgent?.getName(),
73
- }, 'AgentGraph created');
74
- }
75
- /**
76
- * Set or update the configuration (tenantId, projectId and apiUrl)
77
- * This is used by the CLI to inject configuration from inkeep.config.ts
78
- */
79
- setConfig(tenantId, projectId, apiUrl) {
80
- if (this.initialized) {
81
- throw new Error('Cannot set config after graph has been initialized');
82
- }
83
- this.tenantId = tenantId;
84
- this.projectId = projectId;
85
- this.baseURL = apiUrl;
86
- // Propagate tenantId to all agents and their tools
87
- for (const agent of this.agents) {
88
- if (this.isInternalAgent(agent)) {
89
- const internalAgent = agent;
90
- if (!internalAgent.config.tenantId) {
91
- internalAgent.config.tenantId = tenantId;
92
- }
93
- // Also update tools in this agent
94
- const tools = internalAgent.getTools();
95
- for (const [_, toolInstance] of Object.entries(tools)) {
96
- if (toolInstance && typeof toolInstance === 'object' && toolInstance.config) {
97
- if (!toolInstance.config.tenantId) {
98
- toolInstance.config.tenantId = tenantId;
99
- }
100
- // Also update baseURL for tools if they have one
101
- if ('baseURL' in toolInstance && !toolInstance.baseURL) {
102
- toolInstance.baseURL = apiUrl;
103
- }
104
- }
105
- }
106
- }
107
- }
108
- // Update context config tenant ID if present
109
- if (this.contextConfig && !this.contextConfig.tenantId) {
110
- this.contextConfig.tenantId = tenantId;
111
- }
112
- logger.info({
113
- graphId: this.graphId,
114
- tenantId: this.tenantId,
115
- projectId: this.projectId,
116
- apiUrl: this.baseURL,
117
- }, 'Graph configuration updated');
118
- }
119
- /**
120
- * Convert the AgentGraph to FullGraphDefinition format for the new graph endpoint
121
- */
122
- async toFullGraphDefinition() {
123
- const agentsObject = {};
124
- for (const agent of this.agents) {
125
- if (this.isInternalAgent(agent)) {
126
- // Handle internal agents
127
- const internalAgent = agent;
128
- // Get agent relationships
129
- const transfers = internalAgent.getTransfers();
130
- const delegates = internalAgent.getDelegates();
131
- // Convert tools to the expected format (agent.tools should be an array of tool IDs)
132
- const tools = [];
133
- const agentTools = internalAgent.getTools();
134
- for (const [toolName, toolInstance] of Object.entries(agentTools)) {
135
- if (toolInstance && typeof toolInstance === 'object') {
136
- const toolId = toolInstance.getId?.() || toolInstance.id || toolName;
137
- tools.push(toolId);
138
- }
139
- }
140
- // Convert dataComponents to the expected format (agent.dataComponents should be an array of dataComponent IDs)
141
- const dataComponents = [];
142
- const agentDataComponents = internalAgent.getDataComponents();
143
- if (agentDataComponents) {
144
- for (const dataComponent of agentDataComponents) {
145
- const dataComponentId = dataComponent.id || dataComponent.name.toLowerCase().replace(/\s+/g, '-');
146
- dataComponents.push(dataComponentId);
147
- }
148
- }
149
- // Convert artifactComponents to the expected format (agent.artifactComponents should be an array of artifactComponent IDs)
150
- const artifactComponents = [];
151
- const agentArtifactComponents = internalAgent.getArtifactComponents();
152
- if (agentArtifactComponents) {
153
- for (const artifactComponent of agentArtifactComponents) {
154
- const artifactComponentId = artifactComponent.id || artifactComponent.name.toLowerCase().replace(/\s+/g, '-');
155
- artifactComponents.push(artifactComponentId);
156
- }
157
- }
158
- agentsObject[internalAgent.getId()] = {
159
- id: internalAgent.getId(),
160
- name: internalAgent.getName(),
161
- description: internalAgent.config.description || `Agent ${internalAgent.getName()}`,
162
- prompt: internalAgent.getInstructions(),
163
- models: internalAgent.config.models,
164
- canTransferTo: transfers.map((h) => h.getId()),
165
- canDelegateTo: delegates.map((d) => d.getId()),
166
- tools,
167
- dataComponents: dataComponents.length > 0 ? dataComponents : undefined,
168
- artifactComponents: artifactComponents.length > 0 ? artifactComponents : undefined,
169
- type: 'internal',
170
- };
171
- }
172
- else {
173
- // Handle external agents
174
- const externalAgent = agent;
175
- agentsObject[externalAgent.getId()] = {
176
- id: externalAgent.getId(),
177
- name: externalAgent.getName(),
178
- description: externalAgent.getDescription(),
179
- baseUrl: externalAgent.getBaseUrl(),
180
- credentialReferenceId: externalAgent.getCredentialReferenceId(),
181
- headers: externalAgent.getHeaders(),
182
- tools: [], // External agents don't have tools in this context
183
- type: 'external',
184
- };
185
- }
186
- }
187
- // Collect all tools from all agents
188
- const toolsObject = {};
189
- for (const agent of this.agents) {
190
- if (!agent.getTransfers) {
191
- continue; // Skip external agents
192
- }
193
- const internalAgent = agent;
194
- const agentTools = internalAgent.getTools();
195
- for (const [toolName, toolInstance] of Object.entries(agentTools)) {
196
- if (toolInstance && typeof toolInstance === 'object') {
197
- const toolId = toolInstance.getId?.() || toolInstance.id || toolName;
198
- // Only add if not already added (avoid duplicates across agents)
199
- if (!toolsObject[toolId]) {
200
- let toolConfig;
201
- // Check if it's an IPCTool with MCP server configuration
202
- if (toolInstance.config?.serverUrl) {
203
- toolConfig = {
204
- type: 'mcp',
205
- mcp: {
206
- server: {
207
- url: toolInstance.config.serverUrl,
208
- },
209
- },
210
- };
211
- }
212
- else if (toolInstance.config?.type === 'mcp') {
213
- // Already has proper MCP config
214
- toolConfig = toolInstance.config;
215
- }
216
- else {
217
- // Fallback for function tools or uninitialized tools
218
- toolConfig = {
219
- type: 'function',
220
- parameters: toolInstance.parameters || {},
221
- };
222
- }
223
- const toolData = {
224
- id: toolId,
225
- name: toolInstance.config?.name || toolInstance.name || toolName,
226
- config: toolConfig,
227
- status: toolInstance.getStatus?.() || toolInstance.status || 'unknown',
228
- };
229
- // Add additional fields if available
230
- if (toolInstance.config?.imageUrl) {
231
- toolData.imageUrl = toolInstance.config.imageUrl;
232
- }
233
- if (toolInstance.config?.headers) {
234
- toolData.headers = toolInstance.config.headers;
235
- }
236
- if (toolInstance.capabilities) {
237
- toolData.capabilities = toolInstance.capabilities;
238
- }
239
- if (toolInstance.lastHealthCheck) {
240
- toolData.lastHealthCheck = toolInstance.lastHealthCheck;
241
- }
242
- if (toolInstance.availableTools) {
243
- toolData.availableTools = toolInstance.availableTools;
244
- }
245
- if (toolInstance.lastError) {
246
- toolData.lastError = toolInstance.lastError;
247
- }
248
- if (toolInstance.lastToolsSync) {
249
- toolData.lastToolsSync = toolInstance.lastToolsSync;
250
- }
251
- // Add credential reference ID if available
252
- if (toolInstance.getCredentialReferenceId?.()) {
253
- toolData.credentialReferenceId = toolInstance.getCredentialReferenceId();
254
- }
255
- toolsObject[toolId] = toolData;
256
- }
257
- }
258
- }
259
- }
260
- // Collect all dataComponents from all agents
261
- const dataComponentsObject = {};
262
- for (const agent of this.agents) {
263
- if (!this.isInternalAgent(agent)) {
264
- continue; // Skip external agents
265
- }
266
- const internalAgent = agent;
267
- const agentDataComponents = internalAgent.getDataComponents();
268
- if (agentDataComponents) {
269
- for (const dataComponent of agentDataComponents) {
270
- const dataComponentId = dataComponent.id || dataComponent.name.toLowerCase().replace(/\s+/g, '-');
271
- // Only add if not already added (avoid duplicates across agents)
272
- if (!dataComponentsObject[dataComponentId]) {
273
- dataComponentsObject[dataComponentId] = {
274
- id: dataComponentId,
275
- name: dataComponent.name,
276
- description: dataComponent.description || '',
277
- props: dataComponent.props || {},
278
- };
279
- }
280
- }
281
- }
282
- }
283
- // Collect all artifactComponents from all agents
284
- const artifactComponentsObject = {};
285
- for (const agent of this.agents) {
286
- if (!this.isInternalAgent(agent)) {
287
- continue; // Skip external agents
288
- }
289
- const internalAgent = agent;
290
- const agentArtifactComponents = internalAgent.getArtifactComponents();
291
- if (agentArtifactComponents) {
292
- for (const artifactComponent of agentArtifactComponents) {
293
- const artifactComponentId = artifactComponent.id || artifactComponent.name.toLowerCase().replace(/\s+/g, '-');
294
- // Only add if not already added (avoid duplicates across agents)
295
- if (!artifactComponentsObject[artifactComponentId]) {
296
- artifactComponentsObject[artifactComponentId] = {
297
- id: artifactComponentId,
298
- name: artifactComponent.name,
299
- description: artifactComponent.description || '',
300
- summaryProps: artifactComponent.summaryProps || {},
301
- fullProps: artifactComponent.fullProps || {},
302
- };
303
- }
304
- }
305
- }
306
- }
307
- return {
308
- id: this.graphId,
309
- name: this.graphName,
310
- description: this.graphDescription,
311
- defaultAgentId: this.defaultAgent?.getId() || '',
312
- agents: agentsObject,
313
- tools: toolsObject,
314
- contextConfig: this.contextConfig?.toObject(),
315
- credentialReferences: this.credentials?.map((credentialReference) => ({
316
- type: credentialReference.type,
317
- id: credentialReference.id,
318
- credentialStoreId: credentialReference.credentialStoreId,
319
- retrievalParams: credentialReference.retrievalParams || {},
320
- })),
321
- models: this.models,
322
- statusUpdates: this.statusUpdateSettings,
323
- graphPrompt: this.graphPrompt,
324
- dataComponents: Object.keys(dataComponentsObject).length > 0 ? dataComponentsObject : undefined,
325
- artifactComponents: Object.keys(artifactComponentsObject).length > 0 ? artifactComponentsObject : undefined,
326
- createdAt: new Date().toISOString(),
327
- updatedAt: new Date().toISOString(),
328
- };
329
- }
330
- /**
331
- * Initialize all tools in all agents (especially IPCTools that need MCP server URLs)
332
- */
333
- async initializeAllTools() {
334
- logger.info({ graphId: this.graphId }, 'Initializing all tools in graph');
335
- const toolInitPromises = [];
336
- for (const agent of this.agents) {
337
- // Skip external agents as they don't have getTools method
338
- if (!agent.getTools) {
339
- continue;
340
- }
341
- const internalAgent = agent;
342
- const agentTools = internalAgent.getTools();
343
- for (const [toolName, toolInstance] of Object.entries(agentTools)) {
344
- if (toolInstance && typeof toolInstance === 'object') {
345
- // Check if this is a tool that needs initialization
346
- if (typeof toolInstance.init === 'function') {
347
- toolInitPromises.push((async () => {
348
- try {
349
- // Skip database registration for all tools since graphFull will handle it
350
- const skipDbRegistration = toolInstance.constructor.name === 'IPCTool' ||
351
- toolInstance.constructor.name === 'HostedTool' ||
352
- toolInstance.constructor.name === 'Tool';
353
- if (typeof toolInstance.init === 'function') {
354
- if (skipDbRegistration) {
355
- await toolInstance.init({
356
- skipDatabaseRegistration: true,
357
- });
358
- }
359
- else {
360
- await toolInstance.init();
361
- }
362
- }
363
- logger.debug({
364
- agentId: agent.getId(),
365
- toolName,
366
- toolType: toolInstance.constructor.name,
367
- skipDbRegistration,
368
- }, 'Tool initialized successfully');
369
- }
370
- catch (error) {
371
- logger.error({
372
- agentId: agent.getId(),
373
- toolName,
374
- error: error instanceof Error ? error.message : 'Unknown error',
375
- }, 'Failed to initialize tool');
376
- throw error;
377
- }
378
- })());
379
- }
380
- }
381
- }
382
- }
383
- await Promise.all(toolInitPromises);
384
- logger.info({ graphId: this.graphId, toolCount: toolInitPromises.length }, 'All tools initialized successfully');
385
- }
386
- /**
387
- * Initialize the graph and all agents in the backend using the new graph endpoint
388
- */
389
- async init() {
390
- if (this.initialized) {
391
- logger.info({ graphId: this.graphId }, 'Graph already initialized');
392
- return;
393
- }
394
- logger.info({
395
- graphId: this.graphId,
396
- agentCount: this.agents.length,
397
- }, 'Initializing agent graph using new graph endpoint');
398
- try {
399
- // Initialize all tools first (especially IPCTools that need MCP server URLs)
400
- await this.initializeAllTools();
401
- // Apply model inheritance hierarchy (Project -> Graph -> Agent)
402
- await this.applyModelInheritance();
403
- // Convert to FullGraphDefinition format
404
- const graphDefinition = await this.toFullGraphDefinition();
405
- // Always use API mode (baseURL is always set)
406
- logger.info({
407
- graphId: this.graphId,
408
- mode: 'api-client',
409
- apiUrl: this.baseURL,
410
- }, 'Using API client to create/update graph');
411
- // Try update first (upsert behavior)
412
- const createdGraph = await updateFullGraphViaAPI(this.tenantId, this.projectId, this.baseURL, this.graphId, graphDefinition);
413
- logger.info({
414
- graphId: this.graphId,
415
- agentCount: Object.keys(createdGraph.agents || {}).length,
416
- }, 'Agent graph initialized successfully using graph endpoint');
417
- this.initialized = true;
418
- }
419
- catch (error) {
420
- logger.error({
421
- graphId: this.graphId,
422
- error: error instanceof Error ? error.message : 'Unknown error',
423
- }, 'Failed to initialize agent graph using graph endpoint');
424
- throw error;
425
- }
426
- }
427
- /**
428
- * Legacy initialization method - kept for backward compatibility
429
- * Initialize the graph and all agents in the backend using individual endpoints
430
- */
431
- async initLegacy() {
432
- if (this.initialized) {
433
- logger.info({ graphId: this.graphId }, 'Graph already initialized');
434
- return;
435
- }
436
- logger.info({
437
- graphId: this.graphId,
438
- agentCount: this.agents.length,
439
- }, 'Initializing agent graph');
440
- try {
441
- // Component mode has been removed
442
- // Step 2: Initialize context configuration if provided
443
- if (this.contextConfig) {
444
- await this.contextConfig.init();
445
- logger.info({
446
- graphId: this.graphId,
447
- contextConfigId: this.contextConfig.getId(),
448
- }, 'Context configuration initialized for graph');
449
- }
450
- // Step 3: Initialize all agents
451
- const initPromises = this.agents.map(async (agent) => {
452
- try {
453
- // Set the graphId on the agent config before initialization
454
- agent.config.graphId = this.graphId;
455
- await agent.init();
456
- logger.debug({
457
- agentId: agent.getId(),
458
- graphId: this.graphId,
459
- }, 'Agent initialized in graph');
460
- }
461
- catch (error) {
462
- logger.error({
463
- agentId: agent.getId(),
464
- graphId: this.graphId,
465
- error: error instanceof Error ? error.message : 'Unknown error',
466
- }, 'Failed to initialize agent in graph');
467
- throw error;
468
- }
469
- });
470
- await Promise.all(initPromises);
471
- // Step 2: Create agent graph in database (now that agents exist)
472
- await this.saveToDatabase();
473
- // Step 3: Create external agents in database
474
- await this.createExternalAgents();
475
- // Step 4: Create agent relations (transfer and delegation) using the graph's graphId
476
- await this.createAgentRelations();
477
- // Step 5: Set up graph-level relationships
478
- await this.saveRelations();
479
- this.initialized = true;
480
- logger.info({
481
- graphId: this.graphId,
482
- agentCount: this.agents.length,
483
- }, 'Agent graph initialized successfully');
484
- }
485
- catch (error) {
486
- logger.error({
487
- graphId: this.graphId,
488
- error: error instanceof Error ? error.message : 'Unknown error',
489
- }, 'Failed to initialize agent graph');
490
- throw error;
491
- }
492
- }
493
- /**
494
- * Generate a response using the default agent
495
- */
496
- async generate(input, options) {
497
- await this._init();
498
- if (!this.defaultAgent) {
499
- throw new Error('No default agent configured for this graph');
500
- }
501
- logger.info({
502
- graphId: this.graphId,
503
- defaultAgent: this.defaultAgent.getName(),
504
- conversationId: options?.conversationId,
505
- }, 'Generating response with default agent');
506
- // Use the proper backend execution instead of the local runner
507
- const response = await this.executeWithBackend(input, options);
508
- return response;
509
- }
510
- /**
511
- * Stream a response using the default agent
512
- */
513
- async stream(input, options) {
514
- await this._init();
515
- if (!this.defaultAgent) {
516
- throw new Error('No default agent configured for this graph');
517
- }
518
- logger.info({
519
- graphId: this.graphId,
520
- defaultAgent: this.defaultAgent.getName(),
521
- conversationId: options?.conversationId,
522
- }, 'Streaming response with default agent');
523
- // Delegate to the graph's stream method with backend
524
- // For now, create a simple async generator that yields the response
525
- const textStream = async function* (graph) {
526
- const response = await graph.executeWithBackend(input, options);
527
- // Simulate streaming by yielding chunks
528
- const words = response.split(' ');
529
- for (const word of words) {
530
- yield `${word} `;
531
- }
532
- };
533
- return {
534
- textStream: textStream(this),
535
- };
536
- }
537
- /**
538
- * Alias for stream() method for consistency with naming patterns
539
- */
540
- async generateStream(input, options) {
541
- return await this.stream(input, options);
542
- }
543
- /**
544
- * Run with a specific agent from the graph
545
- */
546
- async runWith(agentId, input, options) {
547
- await this._init();
548
- const agent = this.getAgent(agentId);
549
- if (!agent) {
550
- throw new Error(`Agent '${agentId}' not found in graph`);
551
- }
552
- // Only internal agents can be run directly via this method
553
- if (!this.isInternalAgent(agent)) {
554
- throw new Error(`Agent '${agentId}' is an external agent and cannot be run directly. External agents are only accessible via delegation.`);
555
- }
556
- logger.info({
557
- graphId: this.graphId,
558
- agentId,
559
- conversationId: options?.conversationId,
560
- }, 'Running with specific agent');
561
- // Use backend execution and wrap result in RunResult format
562
- const response = await this.executeWithBackend(input, options);
563
- return {
564
- finalOutput: response,
565
- agent: agent,
566
- turnCount: 1,
567
- usage: { inputTokens: 0, outputTokens: 0 },
568
- metadata: {
569
- toolCalls: [],
570
- transfers: [],
571
- },
572
- };
573
- }
574
- /**
575
- * Get an agent by name (unified method for all agent types)
576
- */
577
- getAgent(name) {
578
- return this.agentMap.get(name);
579
- }
580
- /**
581
- * Add an agent to the graph
582
- */
583
- addAgent(agent) {
584
- this.agents.push(agent);
585
- this.agentMap.set(agent.getId(), agent);
586
- // Apply immediate model inheritance if graph has models
587
- if (this.models && this.isInternalAgent(agent)) {
588
- this.propagateModelSettingsToAgent(agent);
589
- }
590
- logger.info({
591
- graphId: this.graphId,
592
- agentId: agent.getId(),
593
- agentType: this.isInternalAgent(agent) ? 'internal' : 'external',
594
- }, 'Agent added to graph');
595
- }
596
- /**
597
- * Remove an agent from the graph
598
- */
599
- removeAgent(id) {
600
- const agentToRemove = this.agentMap.get(id);
601
- if (agentToRemove) {
602
- this.agentMap.delete(agentToRemove.getId());
603
- this.agents = this.agents.filter((agent) => agent.getId() !== agentToRemove.getId());
604
- logger.info({
605
- graphId: this.graphId,
606
- agentId: agentToRemove.getId(),
607
- }, 'Agent removed from graph');
608
- return true;
609
- }
610
- return false;
611
- }
612
- /**
613
- * Get all agents in the graph
614
- */
615
- getAgents() {
616
- return this.agents;
617
- }
618
- /**
619
- * Get all agent ids (unified method for all agent types)
620
- */
621
- getAgentIds() {
622
- return Array.from(this.agentMap.keys());
623
- }
624
- /**
625
- * Set the default agent
626
- */
627
- setDefaultAgent(agent) {
628
- this.defaultAgent = agent;
629
- this.addAgent(agent); // Ensure it's in the graph
630
- logger.info({
631
- graphId: this.graphId,
632
- defaultAgent: agent.getId(),
633
- }, 'Default agent updated');
634
- }
635
- /**
636
- * Get the default agent
637
- */
638
- getDefaultAgent() {
639
- return this.defaultAgent;
640
- }
641
- /**
642
- * Get the graph ID
643
- */
644
- getId() {
645
- return this.graphId;
646
- }
647
- getName() {
648
- return this.graphName;
649
- }
650
- getDescription() {
651
- return this.graphDescription;
652
- }
653
- getTenantId() {
654
- return this.tenantId;
655
- }
656
- /**
657
- * Get the graph's model settingsuration
658
- */
659
- getModels() {
660
- return this.models;
661
- }
662
- /**
663
- * Set the graph's model settingsuration
664
- */
665
- setModels(models) {
666
- this.models = models;
667
- }
668
- /**
669
- * Get the graph's prompt configuration
670
- */
671
- getGraphPrompt() {
672
- return this.graphPrompt;
673
- }
674
- /**
675
- * Get the graph's stopWhen configuration
676
- */
677
- getStopWhen() {
678
- return this.stopWhen || { transferCountIs: 10 };
679
- }
680
- /**
681
- * Get the graph's status updates configuration
682
- */
683
- getStatusUpdateSettings() {
684
- return this.statusUpdateSettings;
685
- }
686
- /**
687
- * Get the summarizer model from the graph's model settings
688
- */
689
- getSummarizerModel() {
690
- return this.models?.summarizer;
691
- }
692
- /**
693
- * Get graph statistics
694
- */
695
- getStats() {
696
- return {
697
- agentCount: this.agents.length,
698
- defaultAgent: this.defaultAgent?.getName() || null,
699
- initialized: this.initialized,
700
- graphId: this.graphId,
701
- tenantId: this.tenantId,
702
- };
703
- }
704
- /**
705
- * Validate the graph configuration
706
- */
707
- validate() {
708
- const errors = [];
709
- if (this.agents.length === 0) {
710
- errors.push('Graph must contain at least one agent');
711
- }
712
- if (!this.defaultAgent) {
713
- errors.push('Graph must have a default agent');
714
- }
715
- // Validate agent names are unique
716
- const names = new Set();
717
- for (const agent of this.agents) {
718
- const name = agent.getName();
719
- if (names.has(name)) {
720
- errors.push(`Duplicate agent name: ${name}`);
721
- }
722
- names.add(name);
723
- }
724
- // Validate agent relationships (transfer and delegation) for internal agents only
725
- for (const agent of this.agents) {
726
- if (!this.isInternalAgent(agent))
727
- continue; // Skip external agents for relationship validation
728
- // Validate transfer relationships
729
- const transfers = agent.getTransfers();
730
- for (const transferAgent of transfers) {
731
- if (!this.agentMap.has(transferAgent.getName())) {
732
- errors.push(`Agent '${agent.getName()}' has transfer to '${transferAgent.getName()}' which is not in the graph`);
733
- }
734
- }
735
- // Validate delegation relationships
736
- const delegates = agent.getDelegates();
737
- for (const delegateAgent of delegates) {
738
- if (!this.agentMap.has(delegateAgent.getName())) {
739
- errors.push(`Agent '${agent.getName()}' has delegation to '${delegateAgent.getName()}' which is not in the graph`);
740
- }
741
- }
742
- }
743
- return {
744
- valid: errors.length === 0,
745
- errors,
746
- };
747
- }
748
- // Private helper methods
749
- async _init() {
750
- if (!this.initialized) {
751
- await this.init();
752
- }
753
- }
754
- /**
755
- * Type guard to check if an agent is an internal AgentInterface
756
- */
757
- isInternalAgent(agent) {
758
- // Internal agents have getTransfers, getDelegates, and other AgentInterface methods
759
- // External agents only have basic identification methods
760
- return 'getTransfers' in agent && typeof agent.getTransfers === 'function';
761
- }
762
- /**
763
- * Get project-level model settingsuration defaults
764
- */
765
- async getProjectModelDefaults() {
766
- try {
767
- const project = await getProject(this.dbClient)({
768
- scopes: { tenantId: this.tenantId, projectId: this.projectId },
769
- });
770
- return project?.models;
771
- }
772
- catch (error) {
773
- logger.warn({
774
- tenantId: this.tenantId,
775
- projectId: this.projectId,
776
- error: error instanceof Error ? error.message : 'Unknown error',
777
- }, 'Failed to get project model defaults');
778
- return undefined;
779
- }
780
- }
781
- /**
782
- * Get project-level stopWhen configuration defaults
783
- */
784
- async getProjectStopWhenDefaults() {
785
- try {
786
- const project = await getProject(this.dbClient)({
787
- scopes: { tenantId: this.tenantId, projectId: this.projectId },
788
- });
789
- return project?.stopWhen;
790
- }
791
- catch (error) {
792
- logger.warn({
793
- tenantId: this.tenantId,
794
- projectId: this.projectId,
795
- error: error instanceof Error ? error.message : 'Unknown error',
796
- }, 'Failed to get project stopWhen defaults');
797
- return undefined;
798
- }
799
- }
800
- /**
801
- * Apply model inheritance hierarchy: Project -> Graph -> Agent
802
- */
803
- async applyModelInheritance() {
804
- // Always get project defaults to check for partial inheritance
805
- const projectModels = await this.getProjectModelDefaults();
806
- if (projectModels) {
807
- // Initialize models object if it doesn't exist
808
- if (!this.models) {
809
- this.models = {};
810
- }
811
- // Inherit individual model types from project if not set at graph level
812
- if (!this.models.base && projectModels.base) {
813
- this.models.base = projectModels.base;
814
- }
815
- if (!this.models.structuredOutput && projectModels.structuredOutput) {
816
- this.models.structuredOutput = projectModels.structuredOutput;
817
- }
818
- if (!this.models.summarizer && projectModels.summarizer) {
819
- this.models.summarizer = projectModels.summarizer;
820
- }
821
- }
822
- // Apply stopWhen inheritance: Project -> Graph -> Agent
823
- await this.applyStopWhenInheritance();
824
- // Propagate to agents
825
- for (const agent of this.agents) {
826
- if (this.isInternalAgent(agent)) {
827
- this.propagateModelSettingsToAgent(agent);
828
- }
829
- }
830
- }
831
- /**
832
- * Apply stopWhen inheritance hierarchy: Project -> Graph -> Agent
833
- */
834
- async applyStopWhenInheritance() {
835
- // Get project stopWhen defaults
836
- const projectStopWhen = await this.getProjectStopWhenDefaults();
837
- // Initialize stopWhen if it doesn't exist (graph had no stopWhen config)
838
- if (!this.stopWhen) {
839
- this.stopWhen = {};
840
- }
841
- // Inherit transferCountIs from project if graph doesn't have it explicitly set
842
- if (this.stopWhen.transferCountIs === undefined &&
843
- projectStopWhen?.transferCountIs !== undefined) {
844
- this.stopWhen.transferCountIs = projectStopWhen.transferCountIs;
845
- }
846
- // Set default transferCountIs if still not set
847
- if (this.stopWhen.transferCountIs === undefined) {
848
- this.stopWhen.transferCountIs = 10;
849
- }
850
- // Propagate stepCountIs from project to agents
851
- if (projectStopWhen?.stepCountIs !== undefined) {
852
- for (const agent of this.agents) {
853
- if (this.isInternalAgent(agent)) {
854
- const internalAgent = agent;
855
- // Initialize agent stopWhen if it doesn't exist
856
- if (!internalAgent.config.stopWhen) {
857
- internalAgent.config.stopWhen = {};
858
- }
859
- // Inherit stepCountIs from project if not set at agent level
860
- if (internalAgent.config.stopWhen.stepCountIs === undefined) {
861
- internalAgent.config.stopWhen.stepCountIs = projectStopWhen.stepCountIs;
862
- }
863
- }
864
- }
865
- }
866
- logger.debug({
867
- graphId: this.graphId,
868
- graphStopWhen: this.stopWhen,
869
- projectStopWhen,
870
- }, 'Applied stopWhen inheritance from project to graph');
871
- }
872
- /**
873
- * Propagate graph-level model settings to agents (supporting partial inheritance)
874
- */
875
- propagateModelSettingsToAgent(agent) {
876
- if (this.models) {
877
- // Initialize agent models if they don't exist
878
- if (!agent.config.models) {
879
- agent.config.models = {};
880
- }
881
- // Inherit individual model types from graph if not set at agent level
882
- if (!agent.config.models.base && this.models.base) {
883
- agent.config.models.base = this.models.base;
884
- }
885
- if (!agent.config.models.structuredOutput && this.models.structuredOutput) {
886
- agent.config.models.structuredOutput = this.models.structuredOutput;
887
- }
888
- if (!agent.config.models.summarizer && this.models.summarizer) {
889
- agent.config.models.summarizer = this.models.summarizer;
890
- }
891
- }
892
- }
893
- /**
894
- * Immediately propagate graph-level models to all agents during construction
895
- */
896
- propagateImmediateModelSettings() {
897
- for (const agent of this.agents) {
898
- if (this.isInternalAgent(agent)) {
899
- this.propagateModelSettingsToAgent(agent);
900
- }
901
- }
902
- }
903
- /**
904
- * Type guard to check if an agent is an external AgentInterface
905
- */
906
- isExternalAgent(agent) {
907
- return !this.isInternalAgent(agent);
908
- }
909
- /**
910
- * Execute agent using the backend system instead of local runner
911
- */
912
- async executeWithBackend(input, options) {
913
- const normalizedMessages = this.normalizeMessages(input);
914
- const url = `${this.baseURL}/tenants/${this.tenantId}/graphs/${this.graphId}/v1/chat/completions`;
915
- logger.info({ url }, 'Executing with backend');
916
- const requestBody = {
917
- model: 'gpt-4o-mini',
918
- messages: normalizedMessages.map((msg) => ({
919
- role: msg.role,
920
- content: msg.content,
921
- })),
922
- ...options,
923
- // Include conversationId for multi-turn support
924
- ...(options?.conversationId && { conversationId: options.conversationId }),
925
- // Include context data if available
926
- ...(options?.customBodyParams && { ...options.customBodyParams }),
927
- stream: false, // Explicitly disable streaming - must come after options to override
928
- };
929
- try {
930
- const response = await fetch(url, {
931
- method: 'POST',
932
- headers: {
933
- 'Content-Type': 'application/json',
934
- Accept: 'application/json',
935
- },
936
- body: JSON.stringify(requestBody),
937
- });
938
- if (!response.ok) {
939
- throw new Error(`HTTP ${response.status}: ${response.statusText}`);
940
- }
941
- const responseText = await response.text();
942
- // Check if response is SSE format (starts with "data:")
943
- if (responseText.startsWith('data:')) {
944
- // Parse SSE response
945
- return this.parseStreamingResponse(responseText);
946
- }
947
- // Parse regular JSON response
948
- const data = JSON.parse(responseText);
949
- return data.result || data.choices?.[0]?.message?.content || '';
950
- }
951
- catch (error) {
952
- throw new Error(`Graph execution failed: ${error.message || 'Unknown error'}`);
953
- }
954
- }
955
- /**
956
- * Parse streaming response in SSE format
957
- */
958
- parseStreamingResponse(text) {
959
- const lines = text.split('\n');
960
- let content = '';
961
- for (const line of lines) {
962
- if (line.startsWith('data: ')) {
963
- const dataStr = line.slice(6); // Remove 'data: ' prefix
964
- if (dataStr === '[DONE]')
965
- break;
966
- try {
967
- const data = JSON.parse(dataStr);
968
- const delta = data.choices?.[0]?.delta?.content;
969
- if (delta) {
970
- content += delta;
971
- }
972
- }
973
- catch (e) {
974
- // Skip invalid JSON lines
975
- }
976
- }
977
- }
978
- return content;
979
- }
980
- /**
981
- * Normalize input messages to the expected format
982
- */
983
- normalizeMessages(input) {
984
- if (typeof input === 'string') {
985
- return [{ role: 'user', content: input }];
986
- }
987
- if (Array.isArray(input)) {
988
- return input.map((msg) => (typeof msg === 'string' ? { role: 'user', content: msg } : msg));
989
- }
990
- return [input];
991
- }
992
- async saveToDatabase() {
993
- try {
994
- // Check if graph already exists
995
- const getUrl = `${this.baseURL}/tenants/${this.tenantId}/crud/agent-graphs/${this.graphId}`;
996
- try {
997
- const getResponse = await fetch(getUrl, {
998
- method: 'GET',
999
- headers: {
1000
- 'Content-Type': 'application/json',
1001
- },
1002
- });
1003
- if (getResponse.ok) {
1004
- logger.info({ graphId: this.graphId }, 'Graph already exists in backend');
1005
- return;
1006
- }
1007
- if (getResponse.status !== 404) {
1008
- throw new Error(`HTTP ${getResponse.status}: ${getResponse.statusText}`);
1009
- }
1010
- }
1011
- catch (error) {
1012
- if (!error.message.includes('404')) {
1013
- throw error;
1014
- }
1015
- }
1016
- // Graph doesn't exist, create it
1017
- logger.info({ graphId: this.graphId }, 'Creating graph in backend');
1018
- const createUrl = `${this.baseURL}/tenants/${this.tenantId}/crud/agent-graphs`;
1019
- const createResponse = await fetch(createUrl, {
1020
- method: 'POST',
1021
- headers: {
1022
- 'Content-Type': 'application/json',
1023
- },
1024
- body: JSON.stringify({
1025
- id: this.graphId,
1026
- name: this.graphName,
1027
- defaultAgentId: this.defaultAgent?.getId() || '',
1028
- contextConfigId: this.contextConfig?.getId(),
1029
- models: this.models,
1030
- }),
1031
- });
1032
- if (!createResponse.ok) {
1033
- throw new Error(`HTTP ${createResponse.status}: ${createResponse.statusText}`);
1034
- }
1035
- const createData = (await createResponse.json());
1036
- this.graphId = createData.data.id;
1037
- logger.info({ graph: createData.data }, 'Graph created in backend');
1038
- }
1039
- catch (error) {
1040
- throw new Error(`Failed to save graph to database: ${error instanceof Error ? error.message : 'Unknown error'}`);
1041
- }
1042
- }
1043
- async saveRelations() {
1044
- if (this.defaultAgent) {
1045
- try {
1046
- const updateUrl = `${this.baseURL}/tenants/${this.tenantId}/crud/agent-graphs/${this.graphId}`;
1047
- const updateResponse = await fetch(updateUrl, {
1048
- method: 'PUT',
1049
- headers: {
1050
- 'Content-Type': 'application/json',
1051
- },
1052
- body: JSON.stringify({
1053
- id: this.graphId,
1054
- defaultAgentId: this.defaultAgent.getId(),
1055
- contextConfigId: this.contextConfig?.getId(),
1056
- }),
1057
- });
1058
- if (!updateResponse.ok) {
1059
- throw new Error(`HTTP ${updateResponse.status}: ${updateResponse.statusText}`);
1060
- }
1061
- logger.debug({
1062
- graphId: this.graphId,
1063
- defaultAgent: this.defaultAgent.getName(),
1064
- }, 'Graph relationships configured');
1065
- }
1066
- catch (error) {
1067
- logger.error({
1068
- graphId: this.graphId,
1069
- error: error instanceof Error ? error.message : 'Unknown error',
1070
- }, 'Failed to update graph relationships');
1071
- throw error;
1072
- }
1073
- }
1074
- }
1075
- async createAgentRelations() {
1076
- // Create both transfer and delegation relations for all agents now that they have graphId
1077
- const allRelationPromises = [];
1078
- // Collect all relation creation promises from all agents
1079
- for (const agent of this.agents) {
1080
- if (this.isInternalAgent(agent)) {
1081
- // Create internal transfer relations
1082
- const transfers = agent.getTransfers();
1083
- for (const transferAgent of transfers) {
1084
- allRelationPromises.push(this.createInternalAgentRelation(agent, transferAgent, 'transfer'));
1085
- }
1086
- // Create internal delegation relations
1087
- const delegates = agent.getDelegates();
1088
- for (const delegate of delegates) {
1089
- // Check if delegate is an ExternalAgent instance
1090
- if (delegate instanceof ExternalAgent) {
1091
- allRelationPromises.push(this.createExternalAgentRelation(agent, delegate, 'delegate'));
1092
- }
1093
- else {
1094
- // Must be an internal agent (AgentInterface)
1095
- allRelationPromises.push(this.createInternalAgentRelation(agent, delegate, 'delegate'));
1096
- }
1097
- }
1098
- }
1099
- }
1100
- // Use Promise.allSettled for better error handling - allows all operations to complete
1101
- const results = await Promise.allSettled(allRelationPromises);
1102
- // Log and collect errors without failing the entire operation
1103
- const errors = [];
1104
- let successCount = 0;
1105
- for (const result of results) {
1106
- if (result.status === 'fulfilled') {
1107
- successCount++;
1108
- }
1109
- else {
1110
- errors.push(result.reason);
1111
- logger.error({
1112
- error: result.reason instanceof Error ? result.reason.message : 'Unknown error',
1113
- graphId: this.graphId,
1114
- }, 'Failed to create agent relation');
1115
- }
1116
- }
1117
- logger.info({
1118
- graphId: this.graphId,
1119
- totalRelations: allRelationPromises.length,
1120
- successCount,
1121
- errorCount: errors.length,
1122
- }, 'Completed agent relation creation batch');
1123
- // Only throw if ALL relations failed, allowing partial success
1124
- if (errors.length > 0 && successCount === 0) {
1125
- throw new Error(`All ${errors.length} agent relation creations failed`);
1126
- }
1127
- }
1128
- async createInternalAgentRelation(sourceAgent, targetAgent, relationType) {
1129
- try {
1130
- const response = await fetch(`${this.baseURL}/tenants/${this.tenantId}/crud/agent-relations`, {
1131
- method: 'POST',
1132
- headers: {
1133
- 'Content-Type': 'application/json',
1134
- },
1135
- body: JSON.stringify({
1136
- graphId: this.graphId,
1137
- sourceAgentId: sourceAgent.getId(),
1138
- targetAgentId: targetAgent.getId(),
1139
- relationType,
1140
- }),
1141
- });
1142
- if (!response.ok) {
1143
- const errorText = await response.text().catch(() => 'Unknown error');
1144
- // Check if this is a duplicate relation (which is acceptable)
1145
- if (response.status === 422 && errorText.includes('already exists')) {
1146
- logger.info({
1147
- sourceAgentId: sourceAgent.getId(),
1148
- targetAgentId: targetAgent.getId(),
1149
- graphId: this.graphId,
1150
- relationType,
1151
- }, `${relationType} relation already exists, skipping creation`);
1152
- return;
1153
- }
1154
- throw new Error(`Failed to create agent relation: ${response.status} - ${errorText}`);
1155
- }
1156
- logger.info({
1157
- sourceAgentId: sourceAgent.getId(),
1158
- targetAgentId: targetAgent.getId(),
1159
- graphId: this.graphId,
1160
- relationType,
1161
- }, `${relationType} relation created successfully`);
1162
- }
1163
- catch (error) {
1164
- logger.error({
1165
- sourceAgentId: sourceAgent.getId(),
1166
- targetAgentId: targetAgent.getId(),
1167
- graphId: this.graphId,
1168
- relationType,
1169
- error: error instanceof Error ? error.message : 'Unknown error',
1170
- }, `Failed to create ${relationType} relation`);
1171
- throw error;
1172
- }
1173
- }
1174
- // enableComponentMode removed – feature deprecated
1175
- async createExternalAgentRelation(sourceAgent, externalAgent, relationType) {
1176
- try {
1177
- const response = await fetch(`${this.baseURL}/tenants/${this.tenantId}/crud/agent-relations`, {
1178
- method: 'POST',
1179
- headers: {
1180
- 'Content-Type': 'application/json',
1181
- },
1182
- body: JSON.stringify({
1183
- graphId: this.graphId,
1184
- sourceAgentId: sourceAgent.getId(),
1185
- externalAgentId: externalAgent.getId(),
1186
- relationType,
1187
- }),
1188
- });
1189
- if (!response.ok) {
1190
- const errorText = await response.text().catch(() => 'Unknown error');
1191
- // Check if this is a duplicate relation (which is acceptable)
1192
- if (response.status === 422 && errorText.includes('already exists')) {
1193
- logger.info({
1194
- sourceAgentId: sourceAgent.getId(),
1195
- externalAgentId: externalAgent.getId(),
1196
- graphId: this.graphId,
1197
- relationType,
1198
- }, `${relationType} relation already exists, skipping creation`);
1199
- return;
1200
- }
1201
- throw new Error(`Failed to create external agent relation: ${response.status} - ${errorText}`);
1202
- }
1203
- logger.info({
1204
- sourceAgentId: sourceAgent.getId(),
1205
- externalAgentId: externalAgent.getId(),
1206
- graphId: this.graphId,
1207
- relationType,
1208
- }, `${relationType} relation created successfully`);
1209
- }
1210
- catch (error) {
1211
- logger.error({
1212
- sourceAgentId: sourceAgent.getId(),
1213
- externalAgentId: externalAgent.getId(),
1214
- graphId: this.graphId,
1215
- relationType,
1216
- error: error instanceof Error ? error.message : 'Unknown error',
1217
- }, `Failed to create ${relationType} relation`);
1218
- throw error;
1219
- }
1220
- }
1221
- /**
1222
- * Create external agents in the database
1223
- */
1224
- async createExternalAgents() {
1225
- const externalAgents = this.agents.filter((agent) => this.isExternalAgent(agent));
1226
- logger.info({
1227
- graphId: this.graphId,
1228
- externalAgentCount: externalAgents.length,
1229
- }, 'Creating external agents in database');
1230
- const initPromises = externalAgents.map(async (externalAgent) => {
1231
- try {
1232
- await externalAgent.init();
1233
- logger.debug({
1234
- externalAgentId: externalAgent.getId(),
1235
- graphId: this.graphId,
1236
- }, 'External agent created in database');
1237
- }
1238
- catch (error) {
1239
- logger.error({
1240
- externalAgentId: externalAgent.getId(),
1241
- graphId: this.graphId,
1242
- error: error instanceof Error ? error.message : 'Unknown error',
1243
- }, 'Failed to create external agent in database');
1244
- throw error;
1245
- }
1246
- });
1247
- try {
1248
- await Promise.all(initPromises);
1249
- logger.info({
1250
- graphId: this.graphId,
1251
- externalAgentCount: externalAgents.length,
1252
- }, 'All external agents created successfully');
1253
- }
1254
- catch (error) {
1255
- logger.error({
1256
- graphId: this.graphId,
1257
- error: error instanceof Error ? error.message : 'Unknown error',
1258
- }, 'Failed to create some external agents');
1259
- throw error;
1260
- }
1261
- }
1262
- }
1263
- /**
1264
- * Helper function to create graphs - OpenAI style
1265
- */
1266
- export function agentGraph(config) {
1267
- return new AgentGraph(config);
1268
- }
1269
- /**
1270
- * Factory function to create graph from configuration file
1271
- */
1272
- export async function generateGraph(configPath) {
1273
- logger.info({ configPath }, 'Loading graph configuration');
1274
- try {
1275
- const config = await import(configPath);
1276
- const graphConfig = config.default || config;
1277
- const graph = agentGraph(graphConfig);
1278
- await graph.init();
1279
- logger.info({
1280
- configPath,
1281
- graphId: graph.getStats().graphId,
1282
- agentCount: graph.getStats().agentCount,
1283
- }, 'Graph generated successfully');
1284
- return graph;
1285
- }
1286
- catch (error) {
1287
- logger.error({
1288
- configPath,
1289
- error: error instanceof Error ? error.message : 'Unknown error',
1290
- }, 'Failed to generate graph from configuration');
1291
- throw error;
1292
- }
1293
- }
1294
- //# sourceMappingURL=graph.js.map