@inkeep/agents-sdk 0.39.4 → 0.40.0

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 (59) hide show
  1. package/dist/_virtual/rolldown_runtime.js +7 -0
  2. package/dist/agent.d.ts +186 -0
  3. package/dist/agent.js +720 -0
  4. package/dist/agentFullClient.d.ts +22 -0
  5. package/dist/agentFullClient.js +120 -0
  6. package/dist/artifact-component.d.ts +34 -0
  7. package/dist/artifact-component.js +104 -0
  8. package/dist/builderFunctions.d.ts +283 -0
  9. package/dist/builderFunctions.js +327 -0
  10. package/dist/builderFunctionsExperimental.d.ts +24 -0
  11. package/dist/builderFunctionsExperimental.js +27 -0
  12. package/dist/builders.d.ts +111 -0
  13. package/dist/builders.js +52 -0
  14. package/dist/credential-provider.d.ts +176 -0
  15. package/dist/credential-provider.js +237 -0
  16. package/dist/credential-ref.d.ts +60 -0
  17. package/dist/credential-ref.js +33 -0
  18. package/dist/data-component.d.ts +39 -0
  19. package/dist/data-component.js +109 -0
  20. package/dist/environment-settings.d.ts +27 -0
  21. package/dist/environment-settings.js +41 -0
  22. package/dist/external-agent.d.ts +64 -0
  23. package/dist/external-agent.js +156 -0
  24. package/dist/function-tool.d.ts +37 -0
  25. package/dist/function-tool.js +66 -0
  26. package/dist/index.d.ts +19 -1825
  27. package/dist/index.js +19 -4058
  28. package/dist/module-hosted-tool-manager.d.ts +40 -0
  29. package/dist/module-hosted-tool-manager.js +359 -0
  30. package/dist/project.d.ts +214 -0
  31. package/dist/project.js +615 -0
  32. package/dist/projectFullClient.d.ts +23 -0
  33. package/dist/projectFullClient.js +162 -0
  34. package/dist/runner.d.ts +41 -0
  35. package/dist/runner.js +145 -0
  36. package/dist/status-component.d.ts +22 -0
  37. package/dist/status-component.js +36 -0
  38. package/dist/subAgent.d.ts +52 -0
  39. package/dist/subAgent.js +616 -0
  40. package/dist/telemetry-provider.d.ts +218 -0
  41. package/dist/telemetry-provider.js +390 -0
  42. package/dist/tool.d.ts +53 -0
  43. package/dist/tool.js +130 -0
  44. package/dist/types.d.ts +296 -0
  45. package/dist/types.js +39 -0
  46. package/dist/utils/generateIdFromName.d.ts +9 -0
  47. package/dist/utils/generateIdFromName.js +12 -0
  48. package/dist/utils/getFunctionToolDeps.d.ts +17 -0
  49. package/dist/utils/getFunctionToolDeps.js +131 -0
  50. package/dist/utils/tool-normalization.d.ts +42 -0
  51. package/dist/utils/tool-normalization.js +41 -0
  52. package/dist/utils/validateFunction.d.ts +10 -0
  53. package/dist/utils/validateFunction.js +13 -0
  54. package/package.json +11 -16
  55. package/dist/index.cjs +0 -4147
  56. package/dist/index.d.cts +0 -1825
  57. package/dist/index.d.cts.map +0 -1
  58. package/dist/index.d.ts.map +0 -1
  59. package/dist/index.js.map +0 -1
@@ -0,0 +1,40 @@
1
+ import { ChildProcess } from "node:child_process";
2
+
3
+ //#region src/module-hosted-tool-manager.d.ts
4
+ interface InlineToolFunction {
5
+ name: string;
6
+ description?: string;
7
+ execute: (params: any) => Promise<any>;
8
+ parameters?: Record<string, any>;
9
+ }
10
+ interface ModuleHostedToolServer {
11
+ toolFunction: InlineToolFunction;
12
+ process?: ChildProcess;
13
+ port: number;
14
+ serverUrl: string;
15
+ status: 'starting' | 'running' | 'stopped' | 'error';
16
+ pid?: number;
17
+ moduleFile: string;
18
+ }
19
+ declare class ModuleHostedToolManager {
20
+ private servers;
21
+ private portCounter;
22
+ private readonly baseDir;
23
+ private toolModules;
24
+ constructor();
25
+ deployInlineTool(toolFunction: InlineToolFunction): Promise<ModuleHostedToolServer>;
26
+ stopTool(toolName: string): Promise<void>;
27
+ getServer(toolName: string): ModuleHostedToolServer | undefined;
28
+ getAllServers(): ModuleHostedToolServer[];
29
+ private getToolId;
30
+ private getNextPort;
31
+ private generateModuleFiles;
32
+ private createToolModule;
33
+ private createMCPServerCode;
34
+ private startServer;
35
+ private handleFunctionExecution;
36
+ private waitForServerReady;
37
+ }
38
+ declare const moduleHostedToolManager: ModuleHostedToolManager;
39
+ //#endregion
40
+ export { InlineToolFunction, ModuleHostedToolManager, ModuleHostedToolServer, moduleHostedToolManager };
@@ -0,0 +1,359 @@
1
+ import { getLogger } from "@inkeep/agents-core";
2
+ import { existsSync, mkdirSync, writeFileSync } from "node:fs";
3
+ import { join } from "node:path";
4
+ import { spawn } from "node:child_process";
5
+
6
+ //#region src/module-hosted-tool-manager.ts
7
+ const logger = getLogger("module-hosted-tool-manager");
8
+ var ModuleHostedToolManager = class {
9
+ servers = /* @__PURE__ */ new Map();
10
+ portCounter = 3011;
11
+ baseDir;
12
+ toolModules = /* @__PURE__ */ new Map();
13
+ constructor() {
14
+ this.baseDir = join(process.cwd(), ".hosted-tools");
15
+ if (!existsSync(this.baseDir)) mkdirSync(this.baseDir, { recursive: true });
16
+ }
17
+ async deployInlineTool(toolFunction) {
18
+ const toolId = this.getToolId(toolFunction.name);
19
+ if (this.servers.has(toolId)) {
20
+ const existingServer = this.servers.get(toolId);
21
+ if (existingServer?.status === "running") {
22
+ logger.info({ toolId }, "Inline tool already deployed and running");
23
+ return existingServer;
24
+ }
25
+ }
26
+ const port = this.getNextPort();
27
+ const serverUrl = `http://localhost:${port}/mcp`;
28
+ this.toolModules.set(toolId, toolFunction);
29
+ const server = {
30
+ toolFunction,
31
+ port,
32
+ serverUrl,
33
+ status: "starting",
34
+ moduleFile: ""
35
+ };
36
+ this.servers.set(toolId, server);
37
+ try {
38
+ await this.generateModuleFiles(server);
39
+ await this.startServer(server);
40
+ await this.waitForServerReady(server);
41
+ server.status = "running";
42
+ logger.info({
43
+ toolId,
44
+ port,
45
+ serverUrl
46
+ }, "Inline tool deployed successfully");
47
+ return server;
48
+ } catch (error) {
49
+ server.status = "error";
50
+ logger.error({
51
+ toolId,
52
+ error: error instanceof Error ? error.message : "Unknown error"
53
+ }, "Failed to deploy inline tool");
54
+ throw error;
55
+ }
56
+ }
57
+ async stopTool(toolName) {
58
+ const toolId = this.getToolId(toolName);
59
+ const server = this.servers.get(toolId);
60
+ if (!server || !server.process) {
61
+ logger.warn({ toolId }, "Inline tool not found or not running");
62
+ return;
63
+ }
64
+ return new Promise((resolve) => {
65
+ server.process?.on("exit", () => {
66
+ server.status = "stopped";
67
+ server.process = void 0;
68
+ server.pid = void 0;
69
+ this.toolModules.delete(toolId);
70
+ logger.info({ toolId }, "Inline tool stopped successfully");
71
+ resolve();
72
+ });
73
+ server.process?.kill("SIGTERM");
74
+ setTimeout(() => {
75
+ if (server.process && !server.process.killed) server.process.kill("SIGKILL");
76
+ }, 5e3);
77
+ });
78
+ }
79
+ getServer(toolName) {
80
+ const toolId = this.getToolId(toolName);
81
+ return this.servers.get(toolId);
82
+ }
83
+ getAllServers() {
84
+ return Array.from(this.servers.values());
85
+ }
86
+ getToolId(name) {
87
+ return name.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "");
88
+ }
89
+ getNextPort() {
90
+ return this.portCounter++;
91
+ }
92
+ async generateModuleFiles(server) {
93
+ const toolId = this.getToolId(server.toolFunction.name);
94
+ const serverDir = join(this.baseDir, toolId);
95
+ if (!existsSync(serverDir)) mkdirSync(serverDir, { recursive: true });
96
+ const toolModuleFile = join(serverDir, "tool-function.mjs");
97
+ writeFileSync(toolModuleFile, this.createToolModule(server.toolFunction), "utf8");
98
+ const serverFile = join(serverDir, "server.mjs");
99
+ writeFileSync(serverFile, this.createMCPServerCode(server, toolId), "utf8");
100
+ server.moduleFile = serverFile;
101
+ const packageJson = {
102
+ name: `hosted-tool-${toolId}`,
103
+ version: "1.0.0",
104
+ type: "module",
105
+ main: "server.mjs",
106
+ dependencies: {
107
+ "@modelcontextprotocol/sdk": "^1.12.1",
108
+ zod: "^3.25.31"
109
+ }
110
+ };
111
+ writeFileSync(join(serverDir, "package.json"), JSON.stringify(packageJson, null, 2), "utf8");
112
+ logger.info({
113
+ toolId,
114
+ serverFile,
115
+ toolModuleFile
116
+ }, "Generated module-based MCP server code");
117
+ }
118
+ createToolModule(toolFunction) {
119
+ return `// Auto-generated tool function module
120
+ export const toolName = '${toolFunction.name}';
121
+ export const toolDescription = '${toolFunction.description || ""}';
122
+
123
+ // Re-export the tool function
124
+ // Note: This approach requires the function to be passed through a registry
125
+ export async function execute(params) {
126
+ // This will be resolved at runtime through the parent process communication
127
+ const result = await parentProcessExecute(params);
128
+ return result;
129
+ }
130
+
131
+ // Parameters schema (if provided)
132
+ export const parameters = ${toolFunction.parameters ? JSON.stringify(toolFunction.parameters, null, 2) : "undefined"};
133
+ `;
134
+ }
135
+ createMCPServerCode(server, toolId) {
136
+ return `#!/usr/bin/env node
137
+ import { McpServer } from '@modelcontextprotocol/sdk/server/mcp';
138
+ import { StreamableHTTPServerTransport } from '@modelcontextprotocol/sdk/server/streamableHttp';
139
+ import { z } from 'zod';
140
+ import { createServer } from 'node:http';
141
+
142
+ const server = new McpServer({
143
+ name: '${server.toolFunction.name}',
144
+ version: '1.0.0',
145
+ }, { capabilities: { logging: {} } });
146
+
147
+ // Parameter schema
148
+ const parameterSchema = z.object({${server.toolFunction.parameters ? `${Object.keys(server.toolFunction.parameters).map((key) => `\n ${key}: z.any()`).join(",")}\n` : ""}});
149
+
150
+ // Communication with parent process for function execution
151
+ let parentProcess = null;
152
+
153
+ // Set up IPC communication
154
+ process.on('message', (message) => {
155
+ if (message.type === 'function-result') {
156
+ // Handle function execution result
157
+ const { requestId, result, error } = message;
158
+ // Resolve the pending promise (this would need a proper promise registry)
159
+ handleFunctionResult(requestId, result, error);
160
+ }
161
+ });
162
+
163
+ const pendingRequests = new Map();
164
+ let requestIdCounter = 0;
165
+
166
+ async function executeToolFunction(params) {
167
+ return new Promise((resolve, reject) => {
168
+ const requestId = ++requestIdCounter;
169
+ pendingRequests.set(requestId, { resolve, reject });
170
+
171
+ // Send execution request to parent process
172
+ process.send({
173
+ type: 'execute-function',
174
+ requestId,
175
+ toolName: '${server.toolFunction.name}',
176
+ params
177
+ });
178
+
179
+ // Timeout after 30 seconds
180
+ setTimeout(() => {
181
+ if (pendingRequests.has(requestId)) {
182
+ pendingRequests.delete(requestId);
183
+ reject(new Error('Function execution timeout'));
184
+ }
185
+ }, 30000);
186
+ });
187
+ }
188
+
189
+ function handleFunctionResult(requestId, result, error) {
190
+ const pending = pendingRequests.get(requestId);
191
+ if (pending) {
192
+ pendingRequests.delete(requestId);
193
+ if (error) {
194
+ pending.reject(new Error(error));
195
+ } else {
196
+ pending.resolve(result);
197
+ }
198
+ }
199
+ }
200
+
201
+ // Register the tool
202
+ server.tool('${toolId}', '${server.toolFunction.description || ""}', parameterSchema.shape, async (params) => {
203
+ try {
204
+ const result = await executeToolFunction(params);
205
+ return {
206
+ content: [{
207
+ type: 'text',
208
+ text: typeof result === 'string' ? result : JSON.stringify(result)
209
+ }]
210
+ };
211
+ } catch (error) {
212
+ return {
213
+ content: [{
214
+ type: 'text',
215
+ text: \`Error executing tool: \${error instanceof Error ? error.message : 'Unknown error'}\`
216
+ }],
217
+ isError: true
218
+ };
219
+ }
220
+ });
221
+
222
+ // Create HTTP server
223
+ const httpServer = createServer();
224
+ const transport = new StreamableHTTPServerTransport({});
225
+
226
+ httpServer.on('request', async (req, res) => {
227
+ if (req.url === '/mcp' && req.method === 'POST') {
228
+ let body = '';
229
+ req.on('data', chunk => body += chunk);
230
+ req.on('end', async () => {
231
+ try {
232
+ const jsonBody = JSON.parse(body);
233
+ await transport.handleRequest(req, res, jsonBody);
234
+ } catch (error) {
235
+ res.writeHead(500, { 'Content-Type': 'application/json' });
236
+ res.end(JSON.stringify({ error: 'Invalid JSON' }));
237
+ }
238
+ });
239
+ } else if (req.url === '/health' && req.method === 'GET') {
240
+ res.writeHead(200, { 'Content-Type': 'application/json' });
241
+ res.end(JSON.stringify({ status: 'healthy', tool: '${server.toolFunction.name}' }));
242
+ } else {
243
+ res.writeHead(404, { 'Content-Type': 'application/json' });
244
+ res.end(JSON.stringify({ error: 'Not found' }));
245
+ }
246
+ });
247
+
248
+ // Start the server
249
+ await server.connect(transport);
250
+ httpServer.listen(${server.port}, () => {
251
+ console.log(\`MCP tool server '${server.toolFunction.name}' listening on port ${server.port}\`);
252
+
253
+ // Notify parent that server is ready
254
+ if (process.send) {
255
+ process.send({ type: 'server-ready' });
256
+ }
257
+ });
258
+
259
+ process.on('SIGTERM', () => {
260
+ httpServer.close(() => {
261
+ console.log('Server stopped');
262
+ process.exit(0);
263
+ });
264
+ });
265
+ `;
266
+ }
267
+ async startServer(server) {
268
+ const toolId = this.getToolId(server.toolFunction.name);
269
+ const serverDir = join(this.baseDir, toolId);
270
+ const serverFile = server.moduleFile;
271
+ return new Promise((resolve, reject) => {
272
+ const childProcess = spawn("node", [serverFile], {
273
+ cwd: serverDir,
274
+ stdio: [
275
+ "ignore",
276
+ "pipe",
277
+ "pipe",
278
+ "ipc"
279
+ ],
280
+ detached: false
281
+ });
282
+ server.process = childProcess;
283
+ server.pid = childProcess.pid;
284
+ childProcess.on("message", (message) => {
285
+ if (message.type === "execute-function") this.handleFunctionExecution(message, childProcess);
286
+ else if (message.type === "server-ready") logger.info({ toolId }, "Tool server reported ready via IPC");
287
+ });
288
+ childProcess.stdout?.on("data", (data) => {
289
+ logger.info({ toolId }, `Tool server stdout: ${data.toString().trim()}`);
290
+ });
291
+ childProcess.stderr?.on("data", (data) => {
292
+ logger.error({ toolId }, `Tool server stderr: ${data.toString().trim()}`);
293
+ });
294
+ childProcess.on("error", (error) => {
295
+ logger.error({
296
+ toolId,
297
+ error: error.message
298
+ }, "Failed to start tool server");
299
+ reject(error);
300
+ });
301
+ childProcess.on("exit", (code, signal) => {
302
+ logger.info({
303
+ toolId,
304
+ code,
305
+ signal
306
+ }, "Tool server process exited");
307
+ server.status = "stopped";
308
+ server.process = void 0;
309
+ server.pid = void 0;
310
+ });
311
+ setTimeout(() => {
312
+ if (childProcess.pid) resolve();
313
+ else reject(/* @__PURE__ */ new Error("Failed to start server process"));
314
+ }, 1e3);
315
+ });
316
+ }
317
+ async handleFunctionExecution(message, childProcess) {
318
+ const { requestId, toolName, params } = message;
319
+ const toolFunction = this.toolModules.get(this.getToolId(toolName));
320
+ if (!toolFunction) {
321
+ childProcess.send({
322
+ type: "function-result",
323
+ requestId,
324
+ error: `Tool function not found: ${toolName}`
325
+ });
326
+ return;
327
+ }
328
+ try {
329
+ const result = await toolFunction.execute(params);
330
+ childProcess.send({
331
+ type: "function-result",
332
+ requestId,
333
+ result
334
+ });
335
+ } catch (error) {
336
+ childProcess.send({
337
+ type: "function-result",
338
+ requestId,
339
+ error: error instanceof Error ? error.message : "Unknown error"
340
+ });
341
+ }
342
+ }
343
+ async waitForServerReady(server, maxRetries = 10) {
344
+ for (let i = 0; i < maxRetries; i++) {
345
+ try {
346
+ if ((await fetch(`http://localhost:${server.port}/health`)).ok) {
347
+ logger.info({ toolId: this.getToolId(server.toolFunction.name) }, "Server health check passed");
348
+ return;
349
+ }
350
+ } catch (_error) {}
351
+ await new Promise((resolve) => setTimeout(resolve, 500));
352
+ }
353
+ throw new Error(`Server failed to become ready after ${maxRetries} attempts`);
354
+ }
355
+ };
356
+ const moduleHostedToolManager = new ModuleHostedToolManager();
357
+
358
+ //#endregion
359
+ export { ModuleHostedToolManager, moduleHostedToolManager };
@@ -0,0 +1,214 @@
1
+ import { ArtifactComponent } from "./artifact-component.js";
2
+ import { Tool } from "./tool.js";
3
+ import { DataComponent } from "./data-component.js";
4
+ import { ExternalAgent } from "./external-agent.js";
5
+ import { ModelSettings } from "./types.js";
6
+ import { Agent } from "./agent.js";
7
+ import { CredentialReferenceApiInsert, FullProjectDefinition, StopWhen } from "@inkeep/agents-core";
8
+
9
+ //#region src/project.d.ts
10
+
11
+ /**
12
+ * Project configuration interface for the SDK
13
+ */
14
+ interface ProjectConfig {
15
+ id: string;
16
+ name: string;
17
+ description?: string;
18
+ models?: {
19
+ base?: ModelSettings;
20
+ structuredOutput?: ModelSettings;
21
+ summarizer?: ModelSettings;
22
+ };
23
+ stopWhen?: StopWhen;
24
+ agents?: () => Agent[];
25
+ tools?: () => Tool[];
26
+ externalAgents?: () => ExternalAgent[];
27
+ dataComponents?: () => DataComponent[];
28
+ artifactComponents?: () => ArtifactComponent[];
29
+ credentialReferences?: () => CredentialReferenceApiInsert[];
30
+ }
31
+ /**
32
+ * Project interface for operations
33
+ */
34
+ interface ProjectInterface {
35
+ init(): Promise<void>;
36
+ setConfig(tenantId: string, apiUrl: string): void;
37
+ getId(): string;
38
+ getName(): string;
39
+ getDescription(): string | undefined;
40
+ getTenantId(): string;
41
+ getModels(): ProjectConfig['models'];
42
+ getStopWhen(): ProjectConfig['stopWhen'];
43
+ getAgents(): Agent[];
44
+ addAgent(agent: Agent): void;
45
+ removeAgent(id: string): boolean;
46
+ getStats(): {
47
+ projectId: string;
48
+ tenantId: string;
49
+ agentCount: number;
50
+ initialized: boolean;
51
+ };
52
+ validate(): {
53
+ valid: boolean;
54
+ errors: string[];
55
+ };
56
+ }
57
+ /**
58
+ * Project class for managing agent projects
59
+ *
60
+ * Projects are the top-level organizational unit that contains Agents, Sub Agents, and shared configurations.
61
+ * They provide model inheritance and execution limits that cascade down to Agents and Sub Agents.
62
+ *
63
+ * @example
64
+ * ```typescript
65
+ * const myProject = new Project({
66
+ * id: 'customer-support-project',
67
+ * name: 'Customer Support System',
68
+ * description: 'Multi-agent customer support system',
69
+ * models: {
70
+ * base: { model: 'gpt-4.1-mini' },
71
+ * structuredOutput: { model: 'gpt-4.1' }
72
+ * },
73
+ * stopWhen: {
74
+ * transferCountIs: 10,
75
+ * stepCountIs: 50
76
+ * }
77
+ * });
78
+ *
79
+ * await myProject.init();
80
+ * ```
81
+ */
82
+ declare class Project implements ProjectInterface {
83
+ readonly __type: "project";
84
+ private projectId;
85
+ private projectName;
86
+ private projectDescription?;
87
+ private tenantId;
88
+ private baseURL;
89
+ private apiKey?;
90
+ private initialized;
91
+ private models?;
92
+ private stopWhen?;
93
+ private agents;
94
+ private agentMap;
95
+ private credentialReferences?;
96
+ private projectTools;
97
+ private projectDataComponents;
98
+ private projectArtifactComponents;
99
+ private projectExternalAgents;
100
+ private externalAgentMap;
101
+ constructor(config: ProjectConfig);
102
+ /**
103
+ * Set or update the configuration (tenantId and apiUrl)
104
+ * This is used by the CLI to inject configuration from inkeep.config.ts
105
+ */
106
+ setConfig(tenantId: string, apiUrl: string, models?: ProjectConfig['models'], apiKey?: string): void;
107
+ /**
108
+ * Set credential references for the project
109
+ * This is used by the CLI to inject environment-specific credentials
110
+ */
111
+ setCredentials(credentials: Record<string, CredentialReferenceApiInsert>): void;
112
+ /**
113
+ * Initialize the project and create/update it in the backend using full project approach
114
+ */
115
+ init(): Promise<void>;
116
+ /**
117
+ * Get the project ID
118
+ */
119
+ getId(): string;
120
+ /**
121
+ * Get the project name
122
+ */
123
+ getName(): string;
124
+ /**
125
+ * Get the project description
126
+ */
127
+ getDescription(): string | undefined;
128
+ /**
129
+ * Get the tenant ID
130
+ */
131
+ getTenantId(): string;
132
+ /**
133
+ * Get the project's model configuration
134
+ */
135
+ getModels(): ProjectConfig['models'];
136
+ /**
137
+ * Set the project's model configuration
138
+ */
139
+ setModels(models: ProjectConfig['models']): void;
140
+ /**
141
+ * Get the project's stopWhen configuration
142
+ */
143
+ getStopWhen(): ProjectConfig['stopWhen'];
144
+ /**
145
+ * Set the project's stopWhen configuration
146
+ */
147
+ setStopWhen(stopWhen: ProjectConfig['stopWhen']): void;
148
+ /**
149
+ * Get credential tracking information
150
+ */
151
+ getCredentialTracking(): Promise<{
152
+ credentials: Record<string, any>;
153
+ usage: Record<string, Array<{
154
+ type: string;
155
+ id: string;
156
+ agentId?: string;
157
+ }>>;
158
+ }>;
159
+ getFullDefinition(): Promise<FullProjectDefinition>;
160
+ /**
161
+ * Get all agent in the project
162
+ */
163
+ getAgents(): Agent[];
164
+ /**
165
+ * Get all external agents in the project
166
+ */
167
+ getExternalAgents(): ExternalAgent[];
168
+ /**
169
+ * Get an external agent by ID
170
+ */
171
+ getExternalAgent(id: string): ExternalAgent | undefined;
172
+ /**
173
+ * Add an external agent to the project
174
+ */
175
+ addExternalAgent(externalAgent: ExternalAgent): void;
176
+ /**
177
+ * Remove an external agent from the project
178
+ */
179
+ removeExternalAgent(id: string): boolean;
180
+ /**
181
+ * Get an agent by ID
182
+ */
183
+ getAgent(id: string): Agent | undefined;
184
+ /**
185
+ * Add an agent to the project
186
+ */
187
+ addAgent(agent: Agent): void;
188
+ /**
189
+ * Remove an agent from the project
190
+ */
191
+ removeAgent(id: string): boolean;
192
+ /**
193
+ * Get project statistics
194
+ */
195
+ getStats(): {
196
+ projectId: string;
197
+ tenantId: string;
198
+ agentCount: number;
199
+ initialized: boolean;
200
+ };
201
+ /**
202
+ * Validate the project configuration
203
+ */
204
+ validate(): {
205
+ valid: boolean;
206
+ errors: string[];
207
+ };
208
+ /**
209
+ * Convert the Project to FullProjectDefinition format
210
+ */
211
+ private toFullProjectDefinition;
212
+ }
213
+ //#endregion
214
+ export { Project, ProjectConfig, ProjectInterface };