@inkeep/agents-sdk 0.0.0-chat-to-edit-20251119071712

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/dist/index.js ADDED
@@ -0,0 +1,4970 @@
1
+ import { getLogger, normalizeToolSelections, apiFetch, CredentialReferenceApiInsertSchema, MCPToolConfigSchema } from '@inkeep/agents-core';
2
+ export { ANTHROPIC_MODELS, GOOGLE_MODELS, OPENAI_MODELS } from '@inkeep/agents-core';
3
+ import { isZodSchema, convertZodToJsonSchemaWithPreview, convertZodToJsonSchema } from '@inkeep/agents-core/utils/schema-conversion';
4
+ import fs from 'fs';
5
+ import { builtinModules } from 'module';
6
+ import path from 'path';
7
+ import * as lockfile from '@yarnpkg/lockfile';
8
+ import * as yaml from 'js-yaml';
9
+ import ts from 'typescript';
10
+ import { z } from 'zod';
11
+
12
+ var __defProp = Object.defineProperty;
13
+ var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
14
+ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
15
+
16
+ // src/utils/generateIdFromName.ts
17
+ function generateIdFromName(name) {
18
+ return name.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "");
19
+ }
20
+
21
+ // src/artifact-component.ts
22
+ var logger = getLogger("artifactComponent");
23
+ var ArtifactComponent = class {
24
+ constructor(config) {
25
+ __publicField(this, "config");
26
+ __publicField(this, "baseURL");
27
+ __publicField(this, "tenantId");
28
+ __publicField(this, "projectId");
29
+ __publicField(this, "initialized", false);
30
+ __publicField(this, "id");
31
+ this.id = config.id || generateIdFromName(config.name);
32
+ let processedProps;
33
+ if (config.props && isZodSchema(config.props)) {
34
+ processedProps = convertZodToJsonSchemaWithPreview(config.props);
35
+ } else {
36
+ processedProps = config.props;
37
+ }
38
+ this.config = {
39
+ ...config,
40
+ id: this.id,
41
+ props: processedProps
42
+ };
43
+ this.baseURL = process.env.INKEEP_API_URL || "http://localhost:3002";
44
+ this.tenantId = "default";
45
+ this.projectId = "default";
46
+ logger.info(
47
+ {
48
+ artifactComponentId: this.getId(),
49
+ artifactComponentName: config.name
50
+ },
51
+ "ArtifactComponent constructor initialized"
52
+ );
53
+ }
54
+ // Set context (tenantId, projectId, and baseURL) from external source (agent, agent, CLI, etc)
55
+ setContext(tenantId, projectId, baseURL) {
56
+ this.tenantId = tenantId;
57
+ this.projectId = projectId;
58
+ if (baseURL) {
59
+ this.baseURL = baseURL;
60
+ }
61
+ }
62
+ // Compute ID from name using same slug transformation as agents
63
+ getId() {
64
+ return this.id;
65
+ }
66
+ getName() {
67
+ return this.config.name;
68
+ }
69
+ getDescription() {
70
+ return this.config.description;
71
+ }
72
+ getProps() {
73
+ return this.config.props;
74
+ }
75
+ // Public method to ensure artifact component exists in backend (with upsert behavior)
76
+ async init() {
77
+ if (this.initialized) return;
78
+ try {
79
+ await this.upsertArtifactComponent();
80
+ logger.info(
81
+ {
82
+ artifactComponentId: this.getId()
83
+ },
84
+ "ArtifactComponent initialized successfully"
85
+ );
86
+ this.initialized = true;
87
+ } catch (error) {
88
+ logger.error(
89
+ {
90
+ artifactComponentId: this.getId(),
91
+ error: error instanceof Error ? error.message : "Unknown error"
92
+ },
93
+ "Failed to initialize artifact component"
94
+ );
95
+ throw error;
96
+ }
97
+ }
98
+ // Private method to upsert artifact component (create or update)
99
+ async upsertArtifactComponent() {
100
+ const artifactComponentData = {
101
+ id: this.getId(),
102
+ name: this.config.name,
103
+ description: this.config.description,
104
+ props: this.config.props
105
+ };
106
+ logger.info({ artifactComponentData }, "artifactComponentData for create/update");
107
+ const updateResponse = await fetch(
108
+ `${this.baseURL}/tenants/${this.tenantId}/projects/${this.projectId}/artifact-components/${this.getId()}`,
109
+ {
110
+ method: "PUT",
111
+ headers: {
112
+ "Content-Type": "application/json"
113
+ },
114
+ body: JSON.stringify(artifactComponentData)
115
+ }
116
+ );
117
+ logger.info(
118
+ {
119
+ status: updateResponse.status,
120
+ artifactComponentId: this.getId()
121
+ },
122
+ "artifact component updateResponse"
123
+ );
124
+ if (updateResponse.ok) {
125
+ logger.info(
126
+ {
127
+ artifactComponentId: this.getId()
128
+ },
129
+ "ArtifactComponent updated successfully"
130
+ );
131
+ return;
132
+ }
133
+ if (updateResponse.status === 404) {
134
+ logger.info(
135
+ {
136
+ artifactComponentId: this.getId()
137
+ },
138
+ "ArtifactComponent not found, creating new artifact component"
139
+ );
140
+ const createResponse = await fetch(
141
+ `${this.baseURL}/tenants/${this.tenantId}/projects/${this.projectId}/artifact-components`,
142
+ {
143
+ method: "POST",
144
+ headers: {
145
+ "Content-Type": "application/json"
146
+ },
147
+ body: JSON.stringify(artifactComponentData)
148
+ }
149
+ );
150
+ if (!createResponse.ok) {
151
+ const errorText2 = await createResponse.text().catch(() => "Unknown error");
152
+ throw new Error(
153
+ `Failed to create artifact component: ${createResponse.status} ${createResponse.statusText} - ${errorText2}`
154
+ );
155
+ }
156
+ logger.info(
157
+ {
158
+ artifactComponentId: this.getId()
159
+ },
160
+ "ArtifactComponent created successfully"
161
+ );
162
+ return;
163
+ }
164
+ const errorText = await updateResponse.text().catch(() => "Unknown error");
165
+ throw new Error(
166
+ `Failed to update artifact component: ${updateResponse.status} ${updateResponse.statusText} - ${errorText}`
167
+ );
168
+ }
169
+ };
170
+ var logger2 = getLogger("projectFullClient");
171
+ async function createFullProjectViaAPI(tenantId, apiUrl, projectData, apiKey) {
172
+ logger2.info(
173
+ {
174
+ tenantId,
175
+ projectId: projectData.id,
176
+ apiUrl
177
+ },
178
+ "Creating full project via API"
179
+ );
180
+ const url = `${apiUrl}/tenants/${tenantId}/project-full`;
181
+ const headers = {};
182
+ if (apiKey) {
183
+ headers.Authorization = `Bearer ${apiKey}`;
184
+ }
185
+ let response;
186
+ try {
187
+ response = await apiFetch(url, {
188
+ method: "POST",
189
+ headers,
190
+ body: JSON.stringify(projectData)
191
+ });
192
+ } catch (fetchError) {
193
+ logger2.error(
194
+ {
195
+ error: fetchError instanceof Error ? fetchError.message : "Unknown fetch error",
196
+ url,
197
+ tenantId,
198
+ projectId: projectData.id
199
+ },
200
+ "Fetch request failed"
201
+ );
202
+ throw fetchError;
203
+ }
204
+ if (!response.ok) {
205
+ const errorText = await response.text();
206
+ const errorMessage = parseError(errorText) ?? `Failed to create project: ${response.status} ${response.statusText}`;
207
+ logger2.error(
208
+ {
209
+ status: response.status,
210
+ error: errorMessage
211
+ },
212
+ "Failed to create project via API"
213
+ );
214
+ throw new Error(errorMessage);
215
+ }
216
+ const result = await response.json();
217
+ logger2.info(
218
+ {
219
+ projectId: projectData.id
220
+ },
221
+ "Successfully created project via API"
222
+ );
223
+ return result.data;
224
+ }
225
+ async function updateFullProjectViaAPI(tenantId, apiUrl, projectId, projectData, apiKey) {
226
+ logger2.info(
227
+ {
228
+ tenantId,
229
+ projectId,
230
+ apiUrl
231
+ },
232
+ "Updating full project via API"
233
+ );
234
+ const url = `${apiUrl}/tenants/${tenantId}/project-full/${projectId}`;
235
+ const headers = {};
236
+ if (apiKey) {
237
+ headers.Authorization = `Bearer ${apiKey}`;
238
+ }
239
+ let response;
240
+ try {
241
+ response = await apiFetch(url, {
242
+ method: "PUT",
243
+ headers,
244
+ body: JSON.stringify(projectData)
245
+ });
246
+ } catch (fetchError) {
247
+ logger2.error(
248
+ {
249
+ error: fetchError instanceof Error ? fetchError.message : "Unknown fetch error",
250
+ url,
251
+ tenantId,
252
+ projectId
253
+ },
254
+ "Fetch request failed"
255
+ );
256
+ throw fetchError;
257
+ }
258
+ if (!response.ok) {
259
+ const errorText = await response.text();
260
+ const errorMessage = parseError(errorText) ?? `Failed to update project: ${response.status} ${response.statusText}`;
261
+ logger2.error(
262
+ {
263
+ status: response.status,
264
+ error: errorMessage
265
+ },
266
+ "Failed to update project via API"
267
+ );
268
+ throw new Error(errorMessage);
269
+ }
270
+ const result = await response.json();
271
+ logger2.info(
272
+ {
273
+ projectId
274
+ },
275
+ "Successfully updated project via API"
276
+ );
277
+ return result.data;
278
+ }
279
+ async function getFullProjectViaAPI(tenantId, apiUrl, projectId, apiKey) {
280
+ logger2.info(
281
+ {
282
+ tenantId,
283
+ projectId,
284
+ apiUrl
285
+ },
286
+ "Getting full project via API"
287
+ );
288
+ const url = `${apiUrl}/tenants/${tenantId}/project-full/${projectId}`;
289
+ const headers = {};
290
+ if (apiKey) {
291
+ headers.Authorization = `Bearer ${apiKey}`;
292
+ }
293
+ const response = await apiFetch(url, {
294
+ method: "GET",
295
+ headers
296
+ });
297
+ if (!response.ok) {
298
+ if (response.status === 404) {
299
+ logger2.info(
300
+ {
301
+ projectId
302
+ },
303
+ "Project not found"
304
+ );
305
+ return null;
306
+ }
307
+ const errorText = await response.text();
308
+ const errorMessage = parseError(errorText) ?? `Failed to get project: ${response.status} ${response.statusText}`;
309
+ logger2.error(
310
+ {
311
+ status: response.status,
312
+ error: errorMessage
313
+ },
314
+ "Failed to get project via API"
315
+ );
316
+ throw new Error(errorMessage);
317
+ }
318
+ const result = await response.json();
319
+ logger2.info(
320
+ {
321
+ projectId
322
+ },
323
+ "Successfully retrieved project via API"
324
+ );
325
+ return result.data;
326
+ }
327
+ async function deleteFullProjectViaAPI(tenantId, apiUrl, projectId, apiKey) {
328
+ logger2.info(
329
+ {
330
+ tenantId,
331
+ projectId,
332
+ apiUrl
333
+ },
334
+ "Deleting full project via API"
335
+ );
336
+ const url = `${apiUrl}/tenants/${tenantId}/project-full/${projectId}`;
337
+ const headers = {};
338
+ if (apiKey) {
339
+ headers.Authorization = `Bearer ${apiKey}`;
340
+ }
341
+ const response = await apiFetch(url, {
342
+ method: "DELETE",
343
+ headers
344
+ });
345
+ if (!response.ok) {
346
+ const errorText = await response.text();
347
+ const errorMessage = parseError(errorText) ?? `Failed to delete project: ${response.status} ${response.statusText}`;
348
+ logger2.error(
349
+ {
350
+ status: response.status,
351
+ error: errorMessage
352
+ },
353
+ "Failed to delete project via API"
354
+ );
355
+ throw new Error(errorMessage);
356
+ }
357
+ logger2.info(
358
+ {
359
+ projectId
360
+ },
361
+ "Successfully deleted project via API"
362
+ );
363
+ }
364
+ function parseError(errorText) {
365
+ try {
366
+ const errorJson = JSON.parse(errorText);
367
+ if (errorJson.error) {
368
+ const { error } = errorJson;
369
+ return error?.message ?? error;
370
+ }
371
+ } catch {
372
+ if (errorText) {
373
+ return errorText;
374
+ }
375
+ }
376
+ }
377
+
378
+ // src/agentFullClient.ts
379
+ var logger3 = getLogger("agentFullClient");
380
+ async function updateFullAgentViaAPI(tenantId, projectId, apiUrl, agentId, agentData) {
381
+ logger3.info(
382
+ {
383
+ tenantId,
384
+ projectId,
385
+ agentId,
386
+ apiUrl
387
+ },
388
+ "Updating full agent via API"
389
+ );
390
+ const url = `${apiUrl}/tenants/${tenantId}/projects/${projectId}/agent/${agentId}`;
391
+ const response = await fetch(url, {
392
+ method: "PUT",
393
+ headers: {
394
+ "Content-Type": "application/json"
395
+ },
396
+ body: JSON.stringify(agentData)
397
+ });
398
+ if (!response.ok) {
399
+ const errorText = await response.text();
400
+ const errorMessage = parseError(errorText) ?? `Failed to update agent: ${response.status} ${response.statusText}`;
401
+ logger3.error(
402
+ {
403
+ status: response.status,
404
+ error: errorMessage
405
+ },
406
+ "Failed to update agent via API"
407
+ );
408
+ throw new Error(errorMessage);
409
+ }
410
+ const result = await response.json();
411
+ logger3.info(
412
+ {
413
+ agentId
414
+ },
415
+ "Successfully updated agent via API"
416
+ );
417
+ return result.data;
418
+ }
419
+ var logger4 = getLogger("function-tool");
420
+ var getFunctionToolDeps = (name, code) => {
421
+ const { dependencies, warnings } = buildToolManifestFromCodeTS(code);
422
+ if (warnings.length > 0) {
423
+ logger4.warn({ warnings }, `FunctionTool dependencies warnings for ${name}`);
424
+ }
425
+ return dependencies;
426
+ };
427
+ var NODE_BUILTINS = new Set(builtinModules.concat(builtinModules.map((m) => `node:${m}`)));
428
+ var isExternal = (spec) => !spec.startsWith(".") && !spec.startsWith("/") && !NODE_BUILTINS.has(spec);
429
+ var collapseSubpath = (spec) => {
430
+ if (spec.startsWith("@")) {
431
+ const [scope, name] = spec.split("/");
432
+ return `${scope}/${name ?? ""}`;
433
+ }
434
+ return spec.split("/")[0];
435
+ };
436
+ var readJSON = (p) => JSON.parse(fs.readFileSync(p, "utf8"));
437
+ var findUp = (start, file) => {
438
+ let dir = path.resolve(start);
439
+ if (fs.existsSync(dir) && fs.statSync(dir).isFile()) dir = path.dirname(dir);
440
+ for (; ; ) {
441
+ const candidate = path.join(dir, file);
442
+ if (fs.existsSync(candidate)) return candidate;
443
+ const parent = path.dirname(dir);
444
+ if (parent === dir) return null;
445
+ dir = parent;
446
+ }
447
+ };
448
+ function collectDepsFromCodeTS(code) {
449
+ const info = ts.preProcessFile(
450
+ code,
451
+ /*readImportFiles*/
452
+ true,
453
+ /*detectJavaScriptImports*/
454
+ true
455
+ );
456
+ const add = /* @__PURE__ */ new Set();
457
+ const push = (spec) => {
458
+ if (isExternal(spec)) add.add(collapseSubpath(spec));
459
+ };
460
+ for (const f of info.importedFiles) {
461
+ const spec = f.fileName;
462
+ if (spec) push(spec);
463
+ }
464
+ const requireLike = /(?:require|import)\s*\(\s*(['"])([^'"]+)\1\s*\)/g;
465
+ let m;
466
+ while (m = requireLike.exec(code)) push(m[2]);
467
+ return add;
468
+ }
469
+ function resolveInstalledVersion(pkg, projectRoot) {
470
+ const pnpmLock = findUp(projectRoot, "pnpm-lock.yaml");
471
+ if (pnpmLock) {
472
+ const doc = yaml.load(fs.readFileSync(pnpmLock, "utf8"));
473
+ const pkgs = doc?.packages ?? {};
474
+ for (const key of Object.keys(pkgs)) {
475
+ if (key.startsWith(`${pkg}@`)) {
476
+ const ver = key.slice(key.indexOf("@") + 1);
477
+ if (ver) return { exact: String(ver) };
478
+ }
479
+ }
480
+ }
481
+ const npmLock = findUp(projectRoot, "package-lock.json");
482
+ if (npmLock) {
483
+ const lock = readJSON(npmLock);
484
+ if (lock.packages?.[`node_modules/${pkg}`]?.version) {
485
+ return { exact: String(lock.packages[`node_modules/${pkg}`].version) };
486
+ }
487
+ if (lock.dependencies?.[pkg]?.version) {
488
+ return { exact: String(lock.dependencies[pkg].version) };
489
+ }
490
+ }
491
+ const yarnLock = findUp(projectRoot, "yarn.lock");
492
+ if (yarnLock) {
493
+ const parsed = lockfile.parse(fs.readFileSync(yarnLock, "utf8"));
494
+ if (parsed.type === "success") {
495
+ for (const [key, val] of Object.entries(parsed.object)) {
496
+ if (key === pkg || key.startsWith(`${pkg}@`)) {
497
+ const ver = val.version;
498
+ if (ver) return { exact: String(ver) };
499
+ }
500
+ }
501
+ }
502
+ }
503
+ const host = {
504
+ fileExists: fs.existsSync,
505
+ readFile: (p) => fs.readFileSync(p, "utf8"),
506
+ realpath: (p) => fs.realpathSync.native?.(p) ?? fs.realpathSync(p),
507
+ directoryExists: (d) => {
508
+ try {
509
+ return fs.statSync(d).isDirectory();
510
+ } catch {
511
+ return false;
512
+ }
513
+ },
514
+ getCurrentDirectory: () => projectRoot,
515
+ getDirectories: (d) => fs.readdirSync(d, { withFileTypes: true }).filter((e) => e.isDirectory()).map((e) => e.name)
516
+ };
517
+ const res = ts.resolveModuleName(
518
+ `${pkg}/package.json`,
519
+ path.join(projectRoot, "__fake.ts"),
520
+ {},
521
+ host,
522
+ ts.ModuleKind.NodeNext
523
+ );
524
+ const pkgJsonPath = res?.resolvedModule?.resolvedFileName ?? // Try typical path as fallback
525
+ findUp(path.join(projectRoot, "node_modules", pkg), "package.json");
526
+ if (pkgJsonPath && fs.existsSync(pkgJsonPath)) {
527
+ try {
528
+ const version = readJSON(pkgJsonPath).version;
529
+ if (version) return { exact: String(version) };
530
+ } catch {
531
+ }
532
+ }
533
+ const hostPkg = findUp(projectRoot, "package.json");
534
+ if (hostPkg) {
535
+ const hostJson = readJSON(hostPkg);
536
+ const range = hostJson.dependencies?.[pkg] ?? hostJson.devDependencies?.[pkg] ?? hostJson.optionalDependencies?.[pkg];
537
+ if (range) return { range: String(range), unresolved: true };
538
+ }
539
+ return null;
540
+ }
541
+ function buildToolManifestFromCodeTS(code, projectRoot = process.cwd()) {
542
+ const deps = collectDepsFromCodeTS(code);
543
+ const warnings = [];
544
+ const dependencies = {};
545
+ for (const pkg of deps) {
546
+ try {
547
+ const v = resolveInstalledVersion(pkg, projectRoot);
548
+ if (!v) {
549
+ warnings.push(`Could not resolve version for "${pkg}"`);
550
+ continue;
551
+ }
552
+ if ("unresolved" in v) {
553
+ warnings.push(`Using range for "${pkg}" -> ${v.range} (no lockfile / not installed)`);
554
+ dependencies[pkg] = v.range;
555
+ } else {
556
+ dependencies[pkg] = v.exact;
557
+ }
558
+ } catch {
559
+ dependencies[pkg] = false;
560
+ }
561
+ }
562
+ return { dependencies, warnings };
563
+ }
564
+
565
+ // src/function-tool.ts
566
+ var logger5 = getLogger("function-tool");
567
+ var FunctionTool = class {
568
+ constructor(config) {
569
+ __publicField(this, "config");
570
+ __publicField(this, "id");
571
+ this.config = config;
572
+ this.id = generateIdFromName(config.name);
573
+ if (!config.dependencies) {
574
+ const executeCode = typeof config.execute === "string" ? config.execute : config.execute.toString();
575
+ const deps = getFunctionToolDeps(config.name, executeCode);
576
+ for (const dep in deps) {
577
+ if (deps[dep] === false) {
578
+ delete deps[dep];
579
+ throw new Error(
580
+ `Dependency \x1B[1;32m${dep}\x1B[0m used in function tool \x1B[1;32m${config.name}\x1B[0m is neither installed nor in dependencies object.`
581
+ );
582
+ }
583
+ }
584
+ this.config.dependencies = deps;
585
+ }
586
+ logger5.info(
587
+ {
588
+ id: this.id,
589
+ name: config.name
590
+ },
591
+ "FunctionTool constructor initialized"
592
+ );
593
+ }
594
+ getId() {
595
+ return this.id;
596
+ }
597
+ getName() {
598
+ return this.config.name;
599
+ }
600
+ getDescription() {
601
+ return this.config.description;
602
+ }
603
+ getInputSchema() {
604
+ return this.config.inputSchema;
605
+ }
606
+ getDependencies() {
607
+ return this.config.dependencies || {};
608
+ }
609
+ getExecuteFunction() {
610
+ if (typeof this.config.execute === "string") {
611
+ throw new Error(
612
+ "Cannot get execute function from string-based function tool. Use serializeFunction() instead."
613
+ );
614
+ }
615
+ return this.config.execute;
616
+ }
617
+ // Serialize the function (global entity) for storage
618
+ serializeFunction() {
619
+ const executeCode = typeof this.config.execute === "string" ? this.config.execute : this.config.execute.toString();
620
+ return {
621
+ id: this.id,
622
+ inputSchema: this.config.inputSchema,
623
+ executeCode,
624
+ dependencies: this.config.dependencies || {}
625
+ };
626
+ }
627
+ // Serialize the tool (project-scoped) for storage
628
+ serializeTool() {
629
+ return {
630
+ id: this.id,
631
+ name: this.config.name,
632
+ description: this.config.description,
633
+ functionId: this.id
634
+ // The function ID is the same as the tool ID in this context
635
+ };
636
+ }
637
+ };
638
+
639
+ // src/agent.ts
640
+ var logger6 = getLogger("agent");
641
+ function resolveGetter(value) {
642
+ if (typeof value === "function") {
643
+ return value();
644
+ }
645
+ return value;
646
+ }
647
+ var Agent = class {
648
+ constructor(config) {
649
+ __publicField(this, "subAgents", []);
650
+ __publicField(this, "agentMap", /* @__PURE__ */ new Map());
651
+ __publicField(this, "defaultSubAgent");
652
+ __publicField(this, "baseURL");
653
+ __publicField(this, "tenantId");
654
+ __publicField(this, "projectId");
655
+ __publicField(this, "agentId");
656
+ __publicField(this, "agentName");
657
+ __publicField(this, "agentDescription");
658
+ __publicField(this, "initialized", false);
659
+ __publicField(this, "contextConfig");
660
+ // ContextConfigBuilder
661
+ __publicField(this, "credentials");
662
+ __publicField(this, "models");
663
+ __publicField(this, "statusUpdateSettings");
664
+ __publicField(this, "prompt");
665
+ __publicField(this, "stopWhen");
666
+ this.defaultSubAgent = config.defaultSubAgent;
667
+ this.tenantId = "default";
668
+ this.projectId = "default";
669
+ this.agentId = config.id;
670
+ this.agentName = config.name || this.agentId;
671
+ this.agentDescription = config.description;
672
+ this.baseURL = process.env.INKEEP_API_URL || "http://localhost:3002";
673
+ this.contextConfig = config.contextConfig;
674
+ this.credentials = resolveGetter(config.credentials);
675
+ this.models = config.models;
676
+ this.statusUpdateSettings = config.statusUpdates;
677
+ this.prompt = config.prompt;
678
+ this.stopWhen = config.stopWhen ? {
679
+ transferCountIs: config.stopWhen.transferCountIs
680
+ } : void 0;
681
+ this.subAgents = resolveGetter(config.subAgents) || [];
682
+ this.agentMap = new Map(this.subAgents.map((agent2) => [agent2.getId(), agent2]));
683
+ if (this.defaultSubAgent) {
684
+ const isAlreadyPresent = this.subAgents.some(
685
+ (agent2) => agent2.getId() === this.defaultSubAgent?.getId()
686
+ );
687
+ if (!isAlreadyPresent) {
688
+ this.subAgents.push(this.defaultSubAgent);
689
+ }
690
+ this.agentMap.set(this.defaultSubAgent.getId(), this.defaultSubAgent);
691
+ }
692
+ if (this.models) {
693
+ this.propagateImmediateModelSettings();
694
+ }
695
+ logger6.info(
696
+ {
697
+ agentId: this.agentId,
698
+ tenantId: this.tenantId,
699
+ agentCount: this.subAgents.length,
700
+ defaultSubAgent: this.defaultSubAgent?.getName()
701
+ },
702
+ "Agent created"
703
+ );
704
+ }
705
+ /**
706
+ * Set or update the configuration (tenantId, projectId and apiUrl)
707
+ * This is used by the CLI to inject configuration from inkeep.config.ts
708
+ */
709
+ setConfig(tenantId, projectId, apiUrl) {
710
+ if (this.initialized) {
711
+ throw new Error("Cannot set config after agent has been initialized");
712
+ }
713
+ this.tenantId = tenantId;
714
+ this.projectId = projectId;
715
+ this.baseURL = apiUrl;
716
+ for (const subAgent2 of this.subAgents) {
717
+ if (subAgent2.setContext) {
718
+ subAgent2.setContext(tenantId, projectId, apiUrl);
719
+ }
720
+ const tools = subAgent2.getTools();
721
+ for (const [_, toolInstance] of Object.entries(tools)) {
722
+ if (toolInstance && typeof toolInstance === "object") {
723
+ if ("setContext" in toolInstance && typeof toolInstance.setContext === "function") {
724
+ toolInstance.setContext(tenantId, projectId, apiUrl);
725
+ }
726
+ }
727
+ }
728
+ }
729
+ if (this.contextConfig?.setContext) {
730
+ this.contextConfig.setContext(tenantId, projectId, this.agentId, this.baseURL);
731
+ }
732
+ logger6.info(
733
+ {
734
+ agentId: this.agentId,
735
+ tenantId: this.tenantId,
736
+ projectId: this.projectId,
737
+ apiUrl: this.baseURL
738
+ },
739
+ "Agent configuration updated"
740
+ );
741
+ }
742
+ /**
743
+ * Convert the Agent to FullAgentDefinition format for the new agent endpoint
744
+ */
745
+ async toFullAgentDefinition() {
746
+ const subAgentsObject = {};
747
+ const externalAgentsObject = {};
748
+ const functionToolsObject = {};
749
+ const functionsObject = {};
750
+ for (const subAgent2 of this.subAgents) {
751
+ const transfers = subAgent2.getTransfers();
752
+ const delegates = subAgent2.getDelegates();
753
+ const tools = [];
754
+ const selectedToolsMapping = {};
755
+ const headersMapping = {};
756
+ const toolPoliciesMapping = {};
757
+ const subAgentTools = subAgent2.getTools();
758
+ for (const [_toolName, toolInstance] of Object.entries(subAgentTools)) {
759
+ const toolId = toolInstance.getId();
760
+ if (toolInstance.selectedTools) {
761
+ selectedToolsMapping[toolId] = toolInstance.selectedTools;
762
+ }
763
+ if (toolInstance.headers) {
764
+ headersMapping[toolId] = toolInstance.headers;
765
+ }
766
+ if (toolInstance.toolPolicies) {
767
+ toolPoliciesMapping[toolId] = toolInstance.toolPolicies;
768
+ }
769
+ tools.push(toolId);
770
+ if (toolInstance.constructor.name === "FunctionTool" && toolInstance instanceof FunctionTool) {
771
+ if (!functionsObject[toolId]) {
772
+ const functionData = toolInstance.serializeFunction();
773
+ functionsObject[toolId] = functionData;
774
+ }
775
+ if (!functionToolsObject[toolId]) {
776
+ const toolData = toolInstance.serializeTool();
777
+ functionToolsObject[toolId] = {
778
+ id: toolData.id,
779
+ name: toolData.name,
780
+ description: toolData.description,
781
+ functionId: toolData.functionId,
782
+ agentId: this.agentId
783
+ // Include agentId for agent-scoped function tools
784
+ };
785
+ }
786
+ }
787
+ }
788
+ const subAgentExternalAgents = subAgent2.getExternalAgentDelegates();
789
+ for (const externalAgentDelegate of subAgentExternalAgents) {
790
+ const externalAgent2 = externalAgentDelegate.externalAgent;
791
+ externalAgentsObject[externalAgent2.getId()] = {
792
+ id: externalAgent2.getId(),
793
+ name: externalAgent2.getName(),
794
+ description: externalAgent2.getDescription(),
795
+ baseUrl: externalAgent2.getBaseUrl(),
796
+ credentialReferenceId: externalAgent2.getCredentialReferenceId(),
797
+ type: "external"
798
+ };
799
+ }
800
+ const dataComponents = [];
801
+ const subAgentDataComponents = subAgent2.getDataComponents();
802
+ if (subAgentDataComponents) {
803
+ for (const dataComponent2 of subAgentDataComponents) {
804
+ const dataComponentId = dataComponent2.id || dataComponent2.name.toLowerCase().replace(/\s+/g, "-");
805
+ dataComponents.push(dataComponentId);
806
+ }
807
+ }
808
+ const artifactComponents = [];
809
+ const subAgentArtifactComponents = subAgent2.getArtifactComponents();
810
+ if (subAgentArtifactComponents) {
811
+ for (const artifactComponent2 of subAgentArtifactComponents) {
812
+ const artifactComponentId = artifactComponent2.id || artifactComponent2.name.toLowerCase().replace(/\s+/g, "-");
813
+ artifactComponents.push(artifactComponentId);
814
+ }
815
+ }
816
+ const canUse = tools.map((toolId) => ({
817
+ toolId,
818
+ toolSelection: selectedToolsMapping[toolId] || null,
819
+ headers: headersMapping[toolId] || null,
820
+ toolPolicies: toolPoliciesMapping[toolId] || null
821
+ }));
822
+ subAgentsObject[subAgent2.getId()] = {
823
+ id: subAgent2.getId(),
824
+ name: subAgent2.getName(),
825
+ description: subAgent2.config.description || `Agent ${subAgent2.getName()}`,
826
+ prompt: subAgent2.getInstructions(),
827
+ models: subAgent2.config.models,
828
+ stopWhen: subAgent2.config.stopWhen,
829
+ canTransferTo: transfers.map((h) => h.getId()),
830
+ canDelegateTo: delegates.map((d) => {
831
+ if (typeof d === "object" && "externalAgent" in d) {
832
+ return {
833
+ externalAgentId: d.externalAgent.getId(),
834
+ ...d.headers && { headers: d.headers }
835
+ };
836
+ }
837
+ if (typeof d === "object" && "agent" in d) {
838
+ return {
839
+ agentId: d.agent.getId(),
840
+ ...d.headers && { headers: d.headers }
841
+ };
842
+ }
843
+ return d.getId();
844
+ }),
845
+ canUse,
846
+ dataComponents: dataComponents.length > 0 ? dataComponents : void 0,
847
+ artifactComponents: artifactComponents.length > 0 ? artifactComponents : void 0,
848
+ type: "internal"
849
+ };
850
+ }
851
+ const processedStatusUpdates = this.statusUpdateSettings ? {
852
+ ...this.statusUpdateSettings,
853
+ statusComponents: this.statusUpdateSettings.statusComponents?.map((comp) => {
854
+ if (comp && typeof comp.getType === "function") {
855
+ return {
856
+ type: comp.getType(),
857
+ description: comp.getDescription(),
858
+ detailsSchema: comp.getDetailsSchema()
859
+ };
860
+ }
861
+ if (comp && typeof comp === "object" && comp.detailsSchema && isZodSchema(comp.detailsSchema)) {
862
+ const jsonSchema = convertZodToJsonSchema(comp.detailsSchema);
863
+ return {
864
+ type: comp.type,
865
+ description: comp.description,
866
+ detailsSchema: {
867
+ type: "object",
868
+ properties: jsonSchema.properties || {},
869
+ required: jsonSchema.required || void 0
870
+ }
871
+ };
872
+ }
873
+ return comp;
874
+ })
875
+ } : void 0;
876
+ const agentToolsObject = {};
877
+ for (const subAgent2 of this.subAgents) {
878
+ const subAgentTools = subAgent2.getTools();
879
+ for (const [_toolName, toolInstance] of Object.entries(subAgentTools)) {
880
+ const toolId = toolInstance.getId();
881
+ if (toolInstance.constructor.name !== "FunctionTool") {
882
+ if (!agentToolsObject[toolId]) {
883
+ if ("config" in toolInstance && "serverUrl" in toolInstance.config) {
884
+ const mcpTool2 = toolInstance;
885
+ agentToolsObject[toolId] = {
886
+ id: toolId,
887
+ name: toolInstance.getName(),
888
+ description: null,
889
+ config: {
890
+ type: "mcp",
891
+ mcp: {
892
+ server: {
893
+ url: mcpTool2.config.serverUrl
894
+ },
895
+ transport: mcpTool2.config.transport,
896
+ activeTools: mcpTool2.config.activeTools
897
+ }
898
+ },
899
+ credentialReferenceId: null
900
+ };
901
+ }
902
+ }
903
+ }
904
+ }
905
+ }
906
+ return {
907
+ id: this.agentId,
908
+ name: this.agentName,
909
+ description: this.agentDescription,
910
+ defaultSubAgentId: this.defaultSubAgent?.getId() || "",
911
+ subAgents: subAgentsObject,
912
+ externalAgents: externalAgentsObject,
913
+ contextConfig: this.contextConfig?.toObject(),
914
+ // Include function tools at agent level
915
+ ...Object.keys(functionToolsObject).length > 0 && { functionTools: functionToolsObject },
916
+ ...Object.keys(functionsObject).length > 0 && { functions: functionsObject },
917
+ models: this.models,
918
+ stopWhen: this.stopWhen,
919
+ statusUpdates: processedStatusUpdates,
920
+ prompt: this.prompt,
921
+ createdAt: (/* @__PURE__ */ new Date()).toISOString(),
922
+ updatedAt: (/* @__PURE__ */ new Date()).toISOString()
923
+ };
924
+ }
925
+ /**
926
+ * Initialize all tools in all agents (especially IPCTools that need MCP server URLs)
927
+ */
928
+ async initializeAllTools() {
929
+ logger6.info({ agentId: this.agentId }, "Initializing all tools in agent");
930
+ const toolInitPromises = [];
931
+ for (const subAgent2 of this.subAgents) {
932
+ const agentTools = subAgent2.getTools();
933
+ for (const [toolName, toolInstance] of Object.entries(agentTools)) {
934
+ if (toolInstance && typeof toolInstance === "object") {
935
+ if (typeof toolInstance.init === "function") {
936
+ toolInitPromises.push(
937
+ (async () => {
938
+ try {
939
+ const skipDbRegistration = toolInstance.constructor.name === "IPCTool" || toolInstance.constructor.name === "HostedTool" || toolInstance.constructor.name === "Tool";
940
+ if (typeof toolInstance.init === "function") {
941
+ if (skipDbRegistration) {
942
+ await toolInstance.init({
943
+ skipDatabaseRegistration: true
944
+ });
945
+ } else {
946
+ await toolInstance.init();
947
+ }
948
+ }
949
+ logger6.debug(
950
+ {
951
+ subAgentId: subAgent2.getId(),
952
+ toolName,
953
+ toolType: toolInstance.constructor.name,
954
+ skipDbRegistration
955
+ },
956
+ "Tool initialized successfully"
957
+ );
958
+ } catch (error) {
959
+ logger6.error(
960
+ {
961
+ subAgentId: subAgent2.getId(),
962
+ toolName,
963
+ error: error instanceof Error ? error.message : "Unknown error"
964
+ },
965
+ "Failed to initialize tool"
966
+ );
967
+ throw error;
968
+ }
969
+ })()
970
+ );
971
+ }
972
+ }
973
+ }
974
+ }
975
+ await Promise.all(toolInitPromises);
976
+ logger6.info(
977
+ { agentId: this.agentId, toolCount: toolInitPromises.length },
978
+ "All tools initialized successfully"
979
+ );
980
+ }
981
+ /**
982
+ * Initialize the agent and all agents in the backend using the new agent endpoint
983
+ */
984
+ async init() {
985
+ if (this.initialized) {
986
+ logger6.info({ agentId: this.agentId }, "Agent already initialized");
987
+ return;
988
+ }
989
+ logger6.info(
990
+ {
991
+ agentId: this.agentId,
992
+ agentCount: this.subAgents.length
993
+ },
994
+ "Initializing agent using new agent endpoint"
995
+ );
996
+ try {
997
+ await this.initializeAllTools();
998
+ await this.applyModelInheritance();
999
+ const agentDefinition = await this.toFullAgentDefinition();
1000
+ logger6.info(
1001
+ {
1002
+ agentId: this.agentId,
1003
+ mode: "api-client",
1004
+ apiUrl: this.baseURL
1005
+ },
1006
+ "Using API client to create/update agent"
1007
+ );
1008
+ const createdAgent = await updateFullAgentViaAPI(
1009
+ this.tenantId,
1010
+ this.projectId,
1011
+ this.baseURL,
1012
+ this.agentId,
1013
+ agentDefinition
1014
+ );
1015
+ logger6.info(
1016
+ {
1017
+ agentId: this.agentId,
1018
+ agentCount: Object.keys(createdAgent.subAgents || {}).length
1019
+ },
1020
+ "Agent initialized successfully using agent endpoint"
1021
+ );
1022
+ this.initialized = true;
1023
+ } catch (error) {
1024
+ logger6.error(
1025
+ {
1026
+ agentId: this.agentId,
1027
+ error: error instanceof Error ? error.message : "Unknown error"
1028
+ },
1029
+ "Failed to initialize agent using agent endpoint"
1030
+ );
1031
+ throw error;
1032
+ }
1033
+ }
1034
+ /**
1035
+ * Generate a response using the default agent
1036
+ */
1037
+ async generate(input, options) {
1038
+ await this._init();
1039
+ if (!this.defaultSubAgent) {
1040
+ throw new Error("No default agent configured for this agent");
1041
+ }
1042
+ logger6.info(
1043
+ {
1044
+ agentId: this.agentId,
1045
+ defaultSubAgent: this.defaultSubAgent.getName(),
1046
+ conversationId: options?.conversationId
1047
+ },
1048
+ "Generating response with default agent"
1049
+ );
1050
+ const response = await this.executeWithBackend(input, options);
1051
+ return response;
1052
+ }
1053
+ /**
1054
+ * Stream a response using the default agent
1055
+ */
1056
+ async stream(input, options) {
1057
+ await this._init();
1058
+ if (!this.defaultSubAgent) {
1059
+ throw new Error("No default agent configured for this agent");
1060
+ }
1061
+ logger6.info(
1062
+ {
1063
+ agentId: this.agentId,
1064
+ defaultSubAgent: this.defaultSubAgent.getName(),
1065
+ conversationId: options?.conversationId
1066
+ },
1067
+ "Streaming response with default agent"
1068
+ );
1069
+ const textStream = async function* (agent2) {
1070
+ const response = await agent2.executeWithBackend(input, options);
1071
+ const words = response.split(" ");
1072
+ for (const word of words) {
1073
+ yield `${word} `;
1074
+ }
1075
+ };
1076
+ return {
1077
+ textStream: textStream(this)
1078
+ };
1079
+ }
1080
+ /**
1081
+ * Alias for stream() method for consistency with naming patterns
1082
+ */
1083
+ async generateStream(input, options) {
1084
+ return await this.stream(input, options);
1085
+ }
1086
+ /**
1087
+ * Run with a specific agent from the agent
1088
+ */
1089
+ async runWith(subAgentId, input, options) {
1090
+ await this._init();
1091
+ const agent2 = this.getSubAgent(subAgentId);
1092
+ if (!agent2) {
1093
+ throw new Error(`Agent '${subAgentId}' not found in agent`);
1094
+ }
1095
+ logger6.info(
1096
+ {
1097
+ agentId: this.agentId,
1098
+ subAgentId,
1099
+ conversationId: options?.conversationId
1100
+ },
1101
+ "Running with specific agent"
1102
+ );
1103
+ const response = await this.executeWithBackend(input, options);
1104
+ return {
1105
+ finalOutput: response,
1106
+ agent: agent2,
1107
+ turnCount: 1,
1108
+ usage: { inputTokens: 0, outputTokens: 0 },
1109
+ metadata: {
1110
+ toolCalls: [],
1111
+ transfers: []
1112
+ }
1113
+ };
1114
+ }
1115
+ /**
1116
+ * Get an agent by name (unified method for all agent types)
1117
+ */
1118
+ getSubAgent(name) {
1119
+ return this.agentMap.get(name);
1120
+ }
1121
+ /**
1122
+ * Add an agent to the agent
1123
+ */
1124
+ addSubAgent(agent2) {
1125
+ this.subAgents.push(agent2);
1126
+ this.agentMap.set(agent2.getId(), agent2);
1127
+ if (this.models) {
1128
+ this.propagateModelSettingsToAgent(agent2);
1129
+ }
1130
+ logger6.info(
1131
+ {
1132
+ agentId: this.agentId,
1133
+ subAgentId: agent2.getId()
1134
+ },
1135
+ "SubAgent added to agent"
1136
+ );
1137
+ }
1138
+ /**
1139
+ * Remove an agent from the agent
1140
+ */
1141
+ removeSubAgent(id) {
1142
+ const agentToRemove = this.agentMap.get(id);
1143
+ if (agentToRemove) {
1144
+ this.agentMap.delete(agentToRemove.getId());
1145
+ this.subAgents = this.subAgents.filter((agent2) => agent2.getId() !== agentToRemove.getId());
1146
+ logger6.info(
1147
+ {
1148
+ agentId: this.agentId,
1149
+ subAgentId: agentToRemove.getId()
1150
+ },
1151
+ "Agent removed from agent"
1152
+ );
1153
+ return true;
1154
+ }
1155
+ return false;
1156
+ }
1157
+ /**
1158
+ * Get all agents in the agent
1159
+ */
1160
+ getSubAgents() {
1161
+ return this.subAgents;
1162
+ }
1163
+ /**
1164
+ * Get all agent ids (unified method for all agent types)
1165
+ */
1166
+ getSubAgentIds() {
1167
+ return Array.from(this.agentMap.keys());
1168
+ }
1169
+ /**
1170
+ * Set the default agent
1171
+ */
1172
+ setDefaultSubAgent(agent2) {
1173
+ this.defaultSubAgent = agent2;
1174
+ this.addSubAgent(agent2);
1175
+ logger6.info(
1176
+ {
1177
+ agentId: this.agentId,
1178
+ defaultSubAgent: agent2.getId()
1179
+ },
1180
+ "Default agent updated"
1181
+ );
1182
+ }
1183
+ /**
1184
+ * Get the default agent
1185
+ */
1186
+ getDefaultSubAgent() {
1187
+ return this.defaultSubAgent;
1188
+ }
1189
+ /**
1190
+ * Get the agent ID
1191
+ */
1192
+ getId() {
1193
+ return this.agentId;
1194
+ }
1195
+ getName() {
1196
+ return this.agentName;
1197
+ }
1198
+ getDescription() {
1199
+ return this.agentDescription;
1200
+ }
1201
+ getTenantId() {
1202
+ return this.tenantId;
1203
+ }
1204
+ /**
1205
+ * Get the agent's model settingsuration
1206
+ */
1207
+ getModels() {
1208
+ return this.models;
1209
+ }
1210
+ /**
1211
+ * Set the agent's model settingsuration
1212
+ */
1213
+ setModels(models) {
1214
+ this.models = models;
1215
+ }
1216
+ /**
1217
+ * Get the agent's prompt configuration
1218
+ */
1219
+ getPrompt() {
1220
+ return this.prompt;
1221
+ }
1222
+ /**
1223
+ * Get the agent's stopWhen configuration
1224
+ */
1225
+ getStopWhen() {
1226
+ return this.stopWhen || { transferCountIs: 10 };
1227
+ }
1228
+ /**
1229
+ * Get the agent's status updates configuration
1230
+ */
1231
+ getStatusUpdateSettings() {
1232
+ return this.statusUpdateSettings;
1233
+ }
1234
+ /**
1235
+ * Get the summarizer model from the agent's model settings
1236
+ */
1237
+ getSummarizerModel() {
1238
+ return this.models?.summarizer;
1239
+ }
1240
+ /**
1241
+ * Get agent statistics
1242
+ */
1243
+ getStats() {
1244
+ return {
1245
+ agentCount: this.subAgents.length,
1246
+ defaultSubAgent: this.defaultSubAgent?.getName() || null,
1247
+ initialized: this.initialized,
1248
+ agentId: this.agentId,
1249
+ tenantId: this.tenantId
1250
+ };
1251
+ }
1252
+ with(options) {
1253
+ return {
1254
+ agent: this,
1255
+ headers: options.headers
1256
+ };
1257
+ }
1258
+ /**
1259
+ * Validate the agent configuration
1260
+ */
1261
+ validate() {
1262
+ const errors = [];
1263
+ if (this.subAgents.length === 0) {
1264
+ errors.push("Agent must contain at least one agent");
1265
+ }
1266
+ if (!this.defaultSubAgent) {
1267
+ errors.push("Agent must have a default agent");
1268
+ }
1269
+ const names = /* @__PURE__ */ new Set();
1270
+ for (const subAgent2 of this.subAgents) {
1271
+ const name = subAgent2.getName();
1272
+ if (names.has(name)) {
1273
+ errors.push(`Duplicate agent name: ${name}`);
1274
+ }
1275
+ names.add(name);
1276
+ }
1277
+ for (const subAgent2 of this.subAgents) {
1278
+ const transfers = subAgent2.getTransfers();
1279
+ for (const transferAgent of transfers) {
1280
+ if (!this.agentMap.has(transferAgent.getName())) {
1281
+ errors.push(
1282
+ `Agent '${subAgent2.getName()}' has transfer to '${transferAgent.getName()}' which is not in the agent`
1283
+ );
1284
+ }
1285
+ }
1286
+ const delegates = subAgent2.getDelegates();
1287
+ for (const delegateAgent of delegates) {
1288
+ if (this.isInternalAgent(delegateAgent)) {
1289
+ if (!this.agentMap.has(delegateAgent.getName())) {
1290
+ errors.push(
1291
+ `Agent '${subAgent2.getName()}' has delegation to '${delegateAgent.getName()}' which is not in the agent`
1292
+ );
1293
+ }
1294
+ }
1295
+ }
1296
+ }
1297
+ return {
1298
+ valid: errors.length === 0,
1299
+ errors
1300
+ };
1301
+ }
1302
+ // Private helper methods
1303
+ async _init() {
1304
+ if (!this.initialized) {
1305
+ await this.init();
1306
+ }
1307
+ }
1308
+ /**
1309
+ * Type guard to check if an agent is an internal AgentInterface
1310
+ */
1311
+ isInternalAgent(agent2) {
1312
+ return "getTransfers" in agent2 && typeof agent2.getTransfers === "function";
1313
+ }
1314
+ /**
1315
+ * Get project-level model settingsuration defaults
1316
+ */
1317
+ async getProjectModelDefaults() {
1318
+ try {
1319
+ const project2 = await getFullProjectViaAPI(this.tenantId, this.projectId, this.baseURL);
1320
+ return project2?.models;
1321
+ } catch (error) {
1322
+ logger6.warn(
1323
+ {
1324
+ tenantId: this.tenantId,
1325
+ projectId: this.projectId,
1326
+ error: error instanceof Error ? error.message : "Unknown error"
1327
+ },
1328
+ "Failed to get project model defaults"
1329
+ );
1330
+ return void 0;
1331
+ }
1332
+ }
1333
+ /**
1334
+ * Get project-level stopWhen configuration defaults
1335
+ */
1336
+ async getProjectStopWhenDefaults() {
1337
+ try {
1338
+ const project2 = await getFullProjectViaAPI(this.tenantId, this.projectId, this.baseURL);
1339
+ return project2?.stopWhen;
1340
+ } catch (error) {
1341
+ logger6.warn(
1342
+ {
1343
+ tenantId: this.tenantId,
1344
+ projectId: this.projectId,
1345
+ error: error instanceof Error ? error.message : "Unknown error"
1346
+ },
1347
+ "Failed to get project stopWhen defaults"
1348
+ );
1349
+ return void 0;
1350
+ }
1351
+ }
1352
+ /**
1353
+ * Apply model inheritance hierarchy: Project -> Agent -> Agent
1354
+ */
1355
+ async applyModelInheritance() {
1356
+ const projectModels = await this.getProjectModelDefaults();
1357
+ if (projectModels) {
1358
+ if (!this.models) {
1359
+ this.models = {};
1360
+ }
1361
+ if (!this.models.base && projectModels.base) {
1362
+ this.models.base = projectModels.base;
1363
+ }
1364
+ if (!this.models.structuredOutput && projectModels.structuredOutput) {
1365
+ this.models.structuredOutput = projectModels.structuredOutput;
1366
+ }
1367
+ if (!this.models.summarizer && projectModels.summarizer) {
1368
+ this.models.summarizer = projectModels.summarizer;
1369
+ }
1370
+ }
1371
+ await this.applyStopWhenInheritance();
1372
+ for (const subAgent2 of this.subAgents) {
1373
+ this.propagateModelSettingsToAgent(subAgent2);
1374
+ }
1375
+ }
1376
+ /**
1377
+ * Apply stopWhen inheritance hierarchy: Project -> Agent -> Agent
1378
+ */
1379
+ async applyStopWhenInheritance() {
1380
+ const projectStopWhen = await this.getProjectStopWhenDefaults();
1381
+ if (!this.stopWhen) {
1382
+ this.stopWhen = {};
1383
+ }
1384
+ if (this.stopWhen.transferCountIs === void 0 && projectStopWhen?.transferCountIs !== void 0) {
1385
+ this.stopWhen.transferCountIs = projectStopWhen.transferCountIs;
1386
+ }
1387
+ if (this.stopWhen.transferCountIs === void 0) {
1388
+ this.stopWhen.transferCountIs = 10;
1389
+ }
1390
+ if (projectStopWhen?.stepCountIs !== void 0) {
1391
+ for (const subAgent2 of this.subAgents) {
1392
+ if (!subAgent2.config.stopWhen) {
1393
+ subAgent2.config.stopWhen = {};
1394
+ }
1395
+ if (subAgent2.config.stopWhen.stepCountIs === void 0) {
1396
+ subAgent2.config.stopWhen.stepCountIs = projectStopWhen.stepCountIs;
1397
+ }
1398
+ }
1399
+ }
1400
+ logger6.debug(
1401
+ {
1402
+ agentId: this.agentId,
1403
+ agentStopWhen: this.stopWhen,
1404
+ projectStopWhen
1405
+ },
1406
+ "Applied stopWhen inheritance from project to agent"
1407
+ );
1408
+ }
1409
+ /**
1410
+ * Propagate agent-level model settings to agents (supporting partial inheritance)
1411
+ */
1412
+ propagateModelSettingsToAgent(agent2) {
1413
+ if (this.models) {
1414
+ if (!agent2.config.models) {
1415
+ agent2.config.models = {};
1416
+ }
1417
+ if (!agent2.config.models.base && this.models.base) {
1418
+ agent2.config.models.base = this.models.base;
1419
+ }
1420
+ if (!agent2.config.models.structuredOutput && this.models.structuredOutput) {
1421
+ agent2.config.models.structuredOutput = this.models.structuredOutput;
1422
+ }
1423
+ if (!agent2.config.models.summarizer && this.models.summarizer) {
1424
+ agent2.config.models.summarizer = this.models.summarizer;
1425
+ }
1426
+ }
1427
+ }
1428
+ /**
1429
+ * Immediately propagate agent-level models to all agents during construction
1430
+ */
1431
+ propagateImmediateModelSettings() {
1432
+ for (const subAgent2 of this.subAgents) {
1433
+ this.propagateModelSettingsToAgent(subAgent2);
1434
+ }
1435
+ }
1436
+ /**
1437
+ * Execute agent using the backend system instead of local runner
1438
+ */
1439
+ async executeWithBackend(input, options) {
1440
+ const normalizedMessages = this.normalizeMessages(input);
1441
+ const url = `${this.baseURL}/tenants/${this.tenantId}/agent/${this.agentId}/v1/chat/completions`;
1442
+ logger6.info({ url }, "Executing with backend");
1443
+ const requestBody = {
1444
+ model: "gpt-4o-mini",
1445
+ messages: normalizedMessages.map((msg) => ({
1446
+ role: msg.role,
1447
+ content: msg.content
1448
+ })),
1449
+ ...options,
1450
+ // Include conversationId for multi-turn support
1451
+ ...options?.conversationId && {
1452
+ conversationId: options.conversationId
1453
+ },
1454
+ // Include context data if available
1455
+ ...options?.customBodyParams && { ...options.customBodyParams },
1456
+ stream: false
1457
+ // Explicitly disable streaming - must come after options to override
1458
+ };
1459
+ try {
1460
+ const response = await fetch(url, {
1461
+ method: "POST",
1462
+ headers: {
1463
+ "Content-Type": "application/json",
1464
+ Accept: "application/json"
1465
+ },
1466
+ body: JSON.stringify(requestBody)
1467
+ });
1468
+ if (!response.ok) {
1469
+ throw new Error(`HTTP ${response.status}: ${response.statusText}`);
1470
+ }
1471
+ const responseText = await response.text();
1472
+ if (responseText.startsWith("data:")) {
1473
+ return this.parseStreamingResponse(responseText);
1474
+ }
1475
+ const data = JSON.parse(responseText);
1476
+ return data.result || data.choices?.[0]?.message?.content || "";
1477
+ } catch (error) {
1478
+ throw new Error(`Agent execution failed: ${error.message || "Unknown error"}`);
1479
+ }
1480
+ }
1481
+ /**
1482
+ * Parse streaming response in SSE format
1483
+ */
1484
+ parseStreamingResponse(text) {
1485
+ const lines = text.split("\n");
1486
+ let content = "";
1487
+ for (const line of lines) {
1488
+ if (line.startsWith("data: ")) {
1489
+ const dataStr = line.slice(6);
1490
+ if (dataStr === "[DONE]") break;
1491
+ try {
1492
+ const data = JSON.parse(dataStr);
1493
+ const delta = data.choices?.[0]?.delta?.content;
1494
+ if (delta) {
1495
+ content += delta;
1496
+ }
1497
+ } catch (_e) {
1498
+ }
1499
+ }
1500
+ }
1501
+ return content;
1502
+ }
1503
+ /**
1504
+ * Normalize input messages to the expected format
1505
+ */
1506
+ normalizeMessages(input) {
1507
+ if (typeof input === "string") {
1508
+ return [{ role: "user", content: input }];
1509
+ }
1510
+ if (Array.isArray(input)) {
1511
+ return input.map((msg) => typeof msg === "string" ? { role: "user", content: msg } : msg);
1512
+ }
1513
+ return [input];
1514
+ }
1515
+ async saveToDatabase() {
1516
+ try {
1517
+ const getUrl = `${this.baseURL}/tenants/${this.tenantId}/agents/${this.agentId}`;
1518
+ try {
1519
+ const getResponse = await fetch(getUrl, {
1520
+ method: "GET",
1521
+ headers: {
1522
+ "Content-Type": "application/json"
1523
+ }
1524
+ });
1525
+ if (getResponse.ok) {
1526
+ logger6.info({ agentId: this.agentId }, "Agent already exists in backend");
1527
+ return;
1528
+ }
1529
+ if (getResponse.status !== 404) {
1530
+ throw new Error(`HTTP ${getResponse.status}: ${getResponse.statusText}`);
1531
+ }
1532
+ } catch (error) {
1533
+ if (!error.message.includes("404")) {
1534
+ throw error;
1535
+ }
1536
+ }
1537
+ logger6.info({ agentId: this.agentId }, "Creating agent in backend");
1538
+ const createUrl = `${this.baseURL}/tenants/${this.tenantId}/agents`;
1539
+ const createResponse = await fetch(createUrl, {
1540
+ method: "POST",
1541
+ headers: {
1542
+ "Content-Type": "application/json"
1543
+ },
1544
+ body: JSON.stringify({
1545
+ id: this.agentId,
1546
+ name: this.agentName,
1547
+ defaultSubAgentId: this.defaultSubAgent?.getId() || "",
1548
+ contextConfigId: this.contextConfig?.getId(),
1549
+ models: this.models
1550
+ })
1551
+ });
1552
+ if (!createResponse.ok) {
1553
+ throw new Error(`HTTP ${createResponse.status}: ${createResponse.statusText}`);
1554
+ }
1555
+ const createData = await createResponse.json();
1556
+ this.agentId = createData.data.id;
1557
+ logger6.info({ agent: createData.data }, "Agent created in backend");
1558
+ } catch (error) {
1559
+ throw new Error(
1560
+ `Failed to save agent to database: ${error instanceof Error ? error.message : "Unknown error"}`
1561
+ );
1562
+ }
1563
+ }
1564
+ async saveRelations() {
1565
+ if (this.defaultSubAgent) {
1566
+ try {
1567
+ const updateUrl = `${this.baseURL}/tenants/${this.tenantId}/agents/${this.agentId}`;
1568
+ const updateResponse = await fetch(updateUrl, {
1569
+ method: "PUT",
1570
+ headers: {
1571
+ "Content-Type": "application/json"
1572
+ },
1573
+ body: JSON.stringify({
1574
+ id: this.agentId,
1575
+ defaultSubAgentId: this.defaultSubAgent.getId(),
1576
+ contextConfigId: this.contextConfig?.getId()
1577
+ })
1578
+ });
1579
+ if (!updateResponse.ok) {
1580
+ throw new Error(`HTTP ${updateResponse.status}: ${updateResponse.statusText}`);
1581
+ }
1582
+ logger6.debug(
1583
+ {
1584
+ agentId: this.agentId,
1585
+ defaultSubAgent: this.defaultSubAgent.getName()
1586
+ },
1587
+ "Agent relationships configured"
1588
+ );
1589
+ } catch (error) {
1590
+ logger6.error(
1591
+ {
1592
+ agentId: this.agentId,
1593
+ error: error instanceof Error ? error.message : "Unknown error"
1594
+ },
1595
+ "Failed to update agent relationships"
1596
+ );
1597
+ throw error;
1598
+ }
1599
+ }
1600
+ }
1601
+ async createSubAgentRelations() {
1602
+ const allSubAgentRelationPromises = [];
1603
+ for (const subAgent2 of this.subAgents) {
1604
+ const transfers = subAgent2.getTransfers();
1605
+ for (const transferAgent of transfers) {
1606
+ allSubAgentRelationPromises.push(
1607
+ this.createSubAgentRelation(subAgent2, transferAgent, "transfer")
1608
+ );
1609
+ }
1610
+ const delegates = subAgent2.getSubAgentDelegates();
1611
+ for (const delegate of delegates) {
1612
+ if (this.isInternalAgent(delegate)) {
1613
+ allSubAgentRelationPromises.push(
1614
+ this.createSubAgentRelation(subAgent2, delegate, "delegate")
1615
+ );
1616
+ }
1617
+ }
1618
+ }
1619
+ const results = await Promise.allSettled(allSubAgentRelationPromises);
1620
+ const errors = [];
1621
+ let successCount = 0;
1622
+ for (const result of results) {
1623
+ if (result.status === "fulfilled") {
1624
+ successCount++;
1625
+ } else {
1626
+ errors.push(result.reason);
1627
+ logger6.error(
1628
+ {
1629
+ error: result.reason instanceof Error ? result.reason.message : "Unknown error",
1630
+ agentId: this.agentId
1631
+ },
1632
+ "Failed to create agent relation"
1633
+ );
1634
+ }
1635
+ }
1636
+ logger6.info(
1637
+ {
1638
+ agentId: this.agentId,
1639
+ totalRelations: allSubAgentRelationPromises.length,
1640
+ successCount,
1641
+ errorCount: errors.length
1642
+ },
1643
+ "Completed agent relation creation batch"
1644
+ );
1645
+ if (errors.length > 0 && successCount === 0) {
1646
+ throw new Error(`All ${errors.length} agent relation creations failed`);
1647
+ }
1648
+ }
1649
+ async createSubAgentRelation(sourceAgent, targetAgent, relationType) {
1650
+ try {
1651
+ const response = await fetch(`${this.baseURL}/tenants/${this.tenantId}/agent-relations`, {
1652
+ method: "POST",
1653
+ headers: {
1654
+ "Content-Type": "application/json"
1655
+ },
1656
+ body: JSON.stringify({
1657
+ agentId: this.agentId,
1658
+ sourceSubAgentId: sourceAgent.getId(),
1659
+ targetSubAgentId: targetAgent.getId(),
1660
+ relationType
1661
+ })
1662
+ });
1663
+ if (!response.ok) {
1664
+ const errorText = await response.text().catch(() => "Unknown error");
1665
+ if (response.status === 422 && errorText.includes("already exists")) {
1666
+ logger6.info(
1667
+ {
1668
+ sourceSubAgentId: sourceAgent.getId(),
1669
+ targetSubAgentId: targetAgent.getId(),
1670
+ agentId: this.agentId,
1671
+ relationType
1672
+ },
1673
+ `${relationType} relation already exists, skipping creation`
1674
+ );
1675
+ return;
1676
+ }
1677
+ throw new Error(`Failed to create subAgent relation: ${response.status} - ${errorText}`);
1678
+ }
1679
+ logger6.info(
1680
+ {
1681
+ sourceSubAgentId: sourceAgent.getId(),
1682
+ targetSubAgentId: targetAgent.getId(),
1683
+ agentId: this.agentId,
1684
+ relationType
1685
+ },
1686
+ `${relationType} subAgent relation created successfully`
1687
+ );
1688
+ } catch (error) {
1689
+ logger6.error(
1690
+ {
1691
+ sourceSubAgentId: sourceAgent.getId(),
1692
+ targetSubAgentId: targetAgent.getId(),
1693
+ agentId: this.agentId,
1694
+ relationType,
1695
+ error: error instanceof Error ? error.message : "Unknown error"
1696
+ },
1697
+ `Failed to create ${relationType} subAgent relation`
1698
+ );
1699
+ throw error;
1700
+ }
1701
+ }
1702
+ };
1703
+ var logger7 = getLogger("dataComponent");
1704
+ var DataComponent = class {
1705
+ constructor(config) {
1706
+ __publicField(this, "config");
1707
+ __publicField(this, "baseURL");
1708
+ __publicField(this, "tenantId");
1709
+ __publicField(this, "projectId");
1710
+ __publicField(this, "initialized", false);
1711
+ __publicField(this, "id");
1712
+ this.id = config.id || generateIdFromName(config.name);
1713
+ let processedProps;
1714
+ if (config.props && isZodSchema(config.props)) {
1715
+ processedProps = convertZodToJsonSchema(config.props);
1716
+ } else {
1717
+ processedProps = config.props;
1718
+ }
1719
+ this.config = {
1720
+ ...config,
1721
+ id: this.id,
1722
+ props: processedProps,
1723
+ render: config.render || null
1724
+ };
1725
+ this.baseURL = process.env.INKEEP_API_URL || "http://localhost:3002";
1726
+ this.tenantId = "default";
1727
+ this.projectId = "default";
1728
+ logger7.info(
1729
+ {
1730
+ dataComponentId: this.getId(),
1731
+ dataComponentName: config.name
1732
+ },
1733
+ "DataComponent constructor initialized"
1734
+ );
1735
+ }
1736
+ // Set context (tenantId, projectId, and baseURL) from external source (sub-agent, agent, CLI, etc)
1737
+ setContext(tenantId, projectId, baseURL) {
1738
+ this.tenantId = tenantId;
1739
+ this.projectId = projectId;
1740
+ if (baseURL) {
1741
+ this.baseURL = baseURL;
1742
+ }
1743
+ }
1744
+ // Compute ID from name using same slug transformation as agents
1745
+ getId() {
1746
+ return this.id;
1747
+ }
1748
+ getName() {
1749
+ return this.config.name;
1750
+ }
1751
+ getDescription() {
1752
+ return this.config.description;
1753
+ }
1754
+ getProps() {
1755
+ return this.config.props;
1756
+ }
1757
+ getRender() {
1758
+ return this.config.render;
1759
+ }
1760
+ // Public method to ensure data component exists in backend (with upsert behavior)
1761
+ async init() {
1762
+ if (this.initialized) return;
1763
+ try {
1764
+ await this.upsertDataComponent();
1765
+ logger7.info(
1766
+ {
1767
+ dataComponentId: this.getId()
1768
+ },
1769
+ "DataComponent initialized successfully"
1770
+ );
1771
+ this.initialized = true;
1772
+ } catch (error) {
1773
+ logger7.error(
1774
+ {
1775
+ dataComponentId: this.getId(),
1776
+ error: error instanceof Error ? error.message : "Unknown error"
1777
+ },
1778
+ "Failed to initialize data component"
1779
+ );
1780
+ throw error;
1781
+ }
1782
+ }
1783
+ // Private method to upsert data component (create or update)
1784
+ async upsertDataComponent() {
1785
+ const dataComponentData = {
1786
+ id: this.getId(),
1787
+ name: this.config.name,
1788
+ description: this.config.description,
1789
+ props: this.config.props,
1790
+ render: this.config.render
1791
+ };
1792
+ logger7.info({ dataComponentData }, "dataComponentData for create/update");
1793
+ const updateResponse = await fetch(
1794
+ `${this.baseURL}/tenants/${this.tenantId}/projects/${this.projectId}/data-components/${this.getId()}`,
1795
+ {
1796
+ method: "PUT",
1797
+ headers: {
1798
+ "Content-Type": "application/json"
1799
+ },
1800
+ body: JSON.stringify(dataComponentData)
1801
+ }
1802
+ );
1803
+ logger7.info(
1804
+ {
1805
+ status: updateResponse.status,
1806
+ dataComponentId: this.getId()
1807
+ },
1808
+ "data component updateResponse"
1809
+ );
1810
+ if (updateResponse.ok) {
1811
+ logger7.info(
1812
+ {
1813
+ dataComponentId: this.getId()
1814
+ },
1815
+ "DataComponent updated successfully"
1816
+ );
1817
+ return;
1818
+ }
1819
+ if (updateResponse.status === 404) {
1820
+ logger7.info(
1821
+ {
1822
+ dataComponentId: this.getId()
1823
+ },
1824
+ "DataComponent not found, creating new data component"
1825
+ );
1826
+ const createResponse = await fetch(
1827
+ `${this.baseURL}/tenants/${this.tenantId}/projects/${this.projectId}/data-components`,
1828
+ {
1829
+ method: "POST",
1830
+ headers: {
1831
+ "Content-Type": "application/json"
1832
+ },
1833
+ body: JSON.stringify(dataComponentData)
1834
+ }
1835
+ );
1836
+ if (!createResponse.ok) {
1837
+ const errorText2 = await createResponse.text().catch(() => "Unknown error");
1838
+ throw new Error(
1839
+ `Failed to create data component: ${createResponse.status} ${createResponse.statusText} - ${errorText2}`
1840
+ );
1841
+ }
1842
+ logger7.info(
1843
+ {
1844
+ dataComponentId: this.getId()
1845
+ },
1846
+ "DataComponent created successfully"
1847
+ );
1848
+ return;
1849
+ }
1850
+ const errorText = await updateResponse.text().catch(() => "Unknown error");
1851
+ throw new Error(
1852
+ `Failed to update data component: ${updateResponse.status} ${updateResponse.statusText} - ${errorText}`
1853
+ );
1854
+ }
1855
+ };
1856
+ var logger8 = getLogger("project");
1857
+ var Project = class {
1858
+ constructor(config) {
1859
+ __publicField(this, "__type", "project");
1860
+ __publicField(this, "projectId");
1861
+ __publicField(this, "projectName");
1862
+ __publicField(this, "projectDescription");
1863
+ __publicField(this, "tenantId");
1864
+ __publicField(this, "baseURL");
1865
+ __publicField(this, "apiKey");
1866
+ __publicField(this, "initialized", false);
1867
+ __publicField(this, "models");
1868
+ __publicField(this, "stopWhen");
1869
+ __publicField(this, "agents", []);
1870
+ __publicField(this, "agentMap", /* @__PURE__ */ new Map());
1871
+ __publicField(this, "credentialReferences", []);
1872
+ __publicField(this, "projectTools", []);
1873
+ __publicField(this, "projectDataComponents", []);
1874
+ __publicField(this, "projectArtifactComponents", []);
1875
+ __publicField(this, "projectExternalAgents", []);
1876
+ __publicField(this, "externalAgentMap", /* @__PURE__ */ new Map());
1877
+ this.projectId = config.id;
1878
+ this.projectName = config.name;
1879
+ this.projectDescription = config.description;
1880
+ this.tenantId = process.env.INKEEP_TENANT_ID || "default";
1881
+ this.baseURL = process.env.INKEEP_API_URL || "http://localhost:3002";
1882
+ this.models = config.models;
1883
+ this.stopWhen = config.stopWhen;
1884
+ if (config.agents) {
1885
+ this.agents = config.agents();
1886
+ this.agentMap = new Map(this.agents.map((agent2) => [agent2.getId(), agent2]));
1887
+ for (const agent2 of this.agents) {
1888
+ agent2.setConfig(this.tenantId, this.projectId, this.baseURL);
1889
+ }
1890
+ }
1891
+ if (config.tools) {
1892
+ this.projectTools = config.tools();
1893
+ }
1894
+ if (config.dataComponents) {
1895
+ this.projectDataComponents = config.dataComponents();
1896
+ }
1897
+ if (config.artifactComponents) {
1898
+ this.projectArtifactComponents = config.artifactComponents();
1899
+ }
1900
+ if (config.credentialReferences) {
1901
+ this.credentialReferences = config.credentialReferences();
1902
+ }
1903
+ if (config.externalAgents) {
1904
+ this.projectExternalAgents = config.externalAgents();
1905
+ this.externalAgentMap = new Map(
1906
+ this.projectExternalAgents.map((externalAgent2) => [externalAgent2.getId(), externalAgent2])
1907
+ );
1908
+ }
1909
+ logger8.info(
1910
+ {
1911
+ projectId: this.projectId,
1912
+ tenantId: this.tenantId,
1913
+ agentCount: this.agents.length
1914
+ },
1915
+ "Project created"
1916
+ );
1917
+ }
1918
+ /**
1919
+ * Set or update the configuration (tenantId and apiUrl)
1920
+ * This is used by the CLI to inject configuration from inkeep.config.ts
1921
+ */
1922
+ setConfig(tenantId, apiUrl, models, apiKey) {
1923
+ if (this.initialized) {
1924
+ throw new Error("Cannot set config after project has been initialized");
1925
+ }
1926
+ this.tenantId = tenantId;
1927
+ this.baseURL = apiUrl;
1928
+ this.apiKey = apiKey;
1929
+ if (models) {
1930
+ this.models = models;
1931
+ }
1932
+ for (const agent2 of this.agents) {
1933
+ agent2.setConfig(tenantId, this.projectId, apiUrl);
1934
+ }
1935
+ logger8.info(
1936
+ {
1937
+ projectId: this.projectId,
1938
+ tenantId: this.tenantId,
1939
+ apiUrl: this.baseURL,
1940
+ hasModels: !!this.models,
1941
+ hasApiKey: !!this.apiKey
1942
+ },
1943
+ "Project configuration updated"
1944
+ );
1945
+ }
1946
+ /**
1947
+ * Set credential references for the project
1948
+ * This is used by the CLI to inject environment-specific credentials
1949
+ */
1950
+ setCredentials(credentials) {
1951
+ this.credentialReferences = Object.values(credentials);
1952
+ logger8.info(
1953
+ {
1954
+ projectId: this.projectId,
1955
+ credentialCount: this.credentialReferences?.length || 0
1956
+ },
1957
+ "Project credentials updated"
1958
+ );
1959
+ }
1960
+ /**
1961
+ * Initialize the project and create/update it in the backend using full project approach
1962
+ */
1963
+ async init() {
1964
+ if (this.initialized) {
1965
+ logger8.info({ projectId: this.projectId }, "Project already initialized");
1966
+ return;
1967
+ }
1968
+ logger8.info(
1969
+ {
1970
+ projectId: this.projectId,
1971
+ tenantId: this.tenantId,
1972
+ agentCount: this.agents.length
1973
+ },
1974
+ "Initializing project using full project endpoint"
1975
+ );
1976
+ try {
1977
+ const projectDefinition = await this.toFullProjectDefinition();
1978
+ logger8.info(
1979
+ {
1980
+ projectId: this.projectId,
1981
+ mode: "api-client",
1982
+ apiUrl: this.baseURL
1983
+ },
1984
+ "Using API client to create/update full project"
1985
+ );
1986
+ const createdProject = await updateFullProjectViaAPI(
1987
+ this.tenantId,
1988
+ this.baseURL,
1989
+ this.projectId,
1990
+ projectDefinition,
1991
+ this.apiKey
1992
+ );
1993
+ this.initialized = true;
1994
+ logger8.info(
1995
+ {
1996
+ projectId: this.projectId,
1997
+ tenantId: this.tenantId,
1998
+ agentCount: Object.keys(createdProject.agent || {}).length
1999
+ },
2000
+ "Project initialized successfully using full project endpoint"
2001
+ );
2002
+ } catch (error) {
2003
+ logger8.error(
2004
+ {
2005
+ projectId: this.projectId,
2006
+ error: error instanceof Error ? error.message : "Unknown error"
2007
+ },
2008
+ "Failed to initialize project using full project endpoint"
2009
+ );
2010
+ throw error;
2011
+ }
2012
+ }
2013
+ /**
2014
+ * Get the project ID
2015
+ */
2016
+ getId() {
2017
+ return this.projectId;
2018
+ }
2019
+ /**
2020
+ * Get the project name
2021
+ */
2022
+ getName() {
2023
+ return this.projectName;
2024
+ }
2025
+ /**
2026
+ * Get the project description
2027
+ */
2028
+ getDescription() {
2029
+ return this.projectDescription;
2030
+ }
2031
+ /**
2032
+ * Get the tenant ID
2033
+ */
2034
+ getTenantId() {
2035
+ return this.tenantId;
2036
+ }
2037
+ /**
2038
+ * Get the project's model configuration
2039
+ */
2040
+ getModels() {
2041
+ return this.models;
2042
+ }
2043
+ /**
2044
+ * Set the project's model configuration
2045
+ */
2046
+ setModels(models) {
2047
+ this.models = models;
2048
+ }
2049
+ /**
2050
+ * Get the project's stopWhen configuration
2051
+ */
2052
+ getStopWhen() {
2053
+ return this.stopWhen;
2054
+ }
2055
+ /**
2056
+ * Set the project's stopWhen configuration
2057
+ */
2058
+ setStopWhen(stopWhen) {
2059
+ this.stopWhen = stopWhen;
2060
+ }
2061
+ /**
2062
+ * Get credential tracking information
2063
+ */
2064
+ async getCredentialTracking() {
2065
+ const fullDef = await this.toFullProjectDefinition();
2066
+ const credentials = fullDef.credentialReferences || {};
2067
+ const usage = {};
2068
+ for (const [credId, credData] of Object.entries(credentials)) {
2069
+ if (credData.usedBy) {
2070
+ usage[credId] = credData.usedBy;
2071
+ }
2072
+ }
2073
+ return { credentials, usage };
2074
+ }
2075
+ async getFullDefinition() {
2076
+ return await this.toFullProjectDefinition();
2077
+ }
2078
+ /**
2079
+ * Get all agent in the project
2080
+ */
2081
+ getAgents() {
2082
+ return this.agents;
2083
+ }
2084
+ /**
2085
+ * Get all external agents in the project
2086
+ */
2087
+ getExternalAgents() {
2088
+ return this.projectExternalAgents;
2089
+ }
2090
+ /**
2091
+ * Get an external agent by ID
2092
+ */
2093
+ getExternalAgent(id) {
2094
+ return this.externalAgentMap.get(id);
2095
+ }
2096
+ /**
2097
+ * Add an external agent to the project
2098
+ */
2099
+ addExternalAgent(externalAgent2) {
2100
+ this.projectExternalAgents.push(externalAgent2);
2101
+ this.externalAgentMap.set(externalAgent2.getId(), externalAgent2);
2102
+ }
2103
+ /**
2104
+ * Remove an external agent from the project
2105
+ */
2106
+ removeExternalAgent(id) {
2107
+ const externalAgentToRemove = this.externalAgentMap.get(id);
2108
+ if (externalAgentToRemove) {
2109
+ this.externalAgentMap.delete(id);
2110
+ this.projectExternalAgents = this.projectExternalAgents.filter(
2111
+ (externalAgent2) => externalAgent2.getId() !== id
2112
+ );
2113
+ logger8.info(
2114
+ {
2115
+ projectId: this.projectId,
2116
+ externalAgentId: id
2117
+ },
2118
+ "External agent removed from project"
2119
+ );
2120
+ return true;
2121
+ }
2122
+ return false;
2123
+ }
2124
+ /**
2125
+ * Get an agent by ID
2126
+ */
2127
+ getAgent(id) {
2128
+ return this.agentMap.get(id);
2129
+ }
2130
+ /**
2131
+ * Add an agent to the project
2132
+ */
2133
+ addAgent(agent2) {
2134
+ this.agents.push(agent2);
2135
+ this.agentMap.set(agent2.getId(), agent2);
2136
+ agent2.setConfig(this.tenantId, this.projectId, this.baseURL);
2137
+ logger8.info(
2138
+ {
2139
+ projectId: this.projectId,
2140
+ agentId: agent2.getId()
2141
+ },
2142
+ "Agent added to project"
2143
+ );
2144
+ }
2145
+ /**
2146
+ * Remove an agent from the project
2147
+ */
2148
+ removeAgent(id) {
2149
+ const agentToRemove = this.agentMap.get(id);
2150
+ if (agentToRemove) {
2151
+ this.agentMap.delete(id);
2152
+ this.agents = this.agents.filter((agent2) => agent2.getId() !== id);
2153
+ logger8.info(
2154
+ {
2155
+ projectId: this.projectId,
2156
+ agentId: id
2157
+ },
2158
+ "Agent removed from project"
2159
+ );
2160
+ return true;
2161
+ }
2162
+ return false;
2163
+ }
2164
+ /**
2165
+ * Get project statistics
2166
+ */
2167
+ getStats() {
2168
+ return {
2169
+ projectId: this.projectId,
2170
+ tenantId: this.tenantId,
2171
+ agentCount: this.agents.length,
2172
+ initialized: this.initialized
2173
+ };
2174
+ }
2175
+ /**
2176
+ * Validate the project configuration
2177
+ */
2178
+ validate() {
2179
+ const errors = [];
2180
+ if (!this.projectId) {
2181
+ errors.push("Project must have an ID");
2182
+ }
2183
+ if (!this.projectName) {
2184
+ errors.push("Project must have a name");
2185
+ }
2186
+ const agentIds = /* @__PURE__ */ new Set();
2187
+ for (const agent2 of this.agents) {
2188
+ const id = agent2.getId();
2189
+ if (agentIds.has(id)) {
2190
+ errors.push(`Duplicate agent ID: ${id}`);
2191
+ }
2192
+ agentIds.add(id);
2193
+ }
2194
+ for (const agent2 of this.agents) {
2195
+ const agentValidation = agent2.validate();
2196
+ if (!agentValidation.valid) {
2197
+ errors.push(...agentValidation.errors.map((error) => `Agent '${agent2.getId()}': ${error}`));
2198
+ }
2199
+ }
2200
+ return {
2201
+ valid: errors.length === 0,
2202
+ errors
2203
+ };
2204
+ }
2205
+ /**
2206
+ * Convert the Project to FullProjectDefinition format
2207
+ */
2208
+ async toFullProjectDefinition() {
2209
+ const agentsObject = {};
2210
+ const toolsObject = {};
2211
+ const functionToolsObject = {};
2212
+ const functionsObject = {};
2213
+ const dataComponentsObject = {};
2214
+ const artifactComponentsObject = {};
2215
+ const credentialReferencesObject = {};
2216
+ const externalAgentsObject = {};
2217
+ const credentialUsageMap = {};
2218
+ for (const agent2 of this.agents) {
2219
+ logger8.info({ agentId: agent2.getId() }, "Agent id");
2220
+ const agentDefinition = await agent2.toFullAgentDefinition();
2221
+ agentsObject[agent2.getId()] = agentDefinition;
2222
+ const agentCredentials = agent2.credentials;
2223
+ if (agentCredentials && Array.isArray(agentCredentials)) {
2224
+ for (const credential2 of agentCredentials) {
2225
+ if (credential2?.__type === "credential-ref") {
2226
+ continue;
2227
+ }
2228
+ if (credential2?.id) {
2229
+ if (!credentialReferencesObject[credential2.id]) {
2230
+ credentialReferencesObject[credential2.id] = {
2231
+ id: credential2.id,
2232
+ name: credential2.name,
2233
+ type: credential2.type,
2234
+ credentialStoreId: credential2.credentialStoreId,
2235
+ retrievalParams: credential2.retrievalParams
2236
+ };
2237
+ credentialUsageMap[credential2.id] = [];
2238
+ }
2239
+ credentialUsageMap[credential2.id].push({
2240
+ type: "agent",
2241
+ id: agent2.getId()
2242
+ });
2243
+ }
2244
+ }
2245
+ }
2246
+ const agentContextConfig = agent2.contextConfig;
2247
+ if (agentContextConfig) {
2248
+ const contextVariables = agentContextConfig.getContextVariables?.() || agentContextConfig.contextVariables;
2249
+ if (contextVariables) {
2250
+ for (const [key, variable] of Object.entries(contextVariables)) {
2251
+ if (variable?.credential) {
2252
+ const credential2 = variable.credential;
2253
+ let credId;
2254
+ if (credential2.__type === "credential-ref") {
2255
+ credId = credential2.id;
2256
+ if (credId && this.credentialReferences) {
2257
+ const resolvedCred = this.credentialReferences.find((c) => c.id === credId);
2258
+ if (resolvedCred && !credentialReferencesObject[credId]) {
2259
+ credentialReferencesObject[credId] = resolvedCred;
2260
+ credentialUsageMap[credId] = [];
2261
+ }
2262
+ }
2263
+ } else if (credential2.id) {
2264
+ credId = credential2.id;
2265
+ if (credId && !credentialReferencesObject[credId]) {
2266
+ credentialReferencesObject[credId] = credential2;
2267
+ credentialUsageMap[credId] = [];
2268
+ }
2269
+ }
2270
+ if (credId) {
2271
+ if (!credentialUsageMap[credId]) {
2272
+ credentialUsageMap[credId] = [];
2273
+ }
2274
+ credentialUsageMap[credId].push({
2275
+ type: "contextVariable",
2276
+ id: key,
2277
+ agentId: agent2.getId()
2278
+ });
2279
+ }
2280
+ } else if (variable?.credentialReferenceId) {
2281
+ const credId = variable.credentialReferenceId;
2282
+ if (!credentialUsageMap[credId]) {
2283
+ credentialUsageMap[credId] = [];
2284
+ }
2285
+ credentialUsageMap[credId].push({
2286
+ type: "contextVariable",
2287
+ id: key,
2288
+ agentId: agent2.getId()
2289
+ });
2290
+ }
2291
+ }
2292
+ }
2293
+ }
2294
+ for (const subAgent2 of agent2.getSubAgents()) {
2295
+ const agentTools = subAgent2.getTools();
2296
+ for (const [, toolInstance] of Object.entries(agentTools)) {
2297
+ const actualTool = toolInstance;
2298
+ const toolId = actualTool.getId();
2299
+ if (actualTool.constructor.name === "FunctionTool" && actualTool instanceof FunctionTool) {
2300
+ if (!functionsObject[toolId]) {
2301
+ const functionData = actualTool.serializeFunction();
2302
+ functionsObject[toolId] = functionData;
2303
+ }
2304
+ if (!functionToolsObject[toolId]) {
2305
+ const toolData = actualTool.serializeTool();
2306
+ functionToolsObject[toolId] = {
2307
+ id: toolData.id,
2308
+ name: toolData.name,
2309
+ description: toolData.description,
2310
+ functionId: toolData.functionId
2311
+ };
2312
+ }
2313
+ } else {
2314
+ if (!toolsObject[toolId]) {
2315
+ if ("config" in actualTool && "serverUrl" in actualTool.config) {
2316
+ const mcpTool2 = actualTool;
2317
+ const toolConfig = {
2318
+ type: "mcp",
2319
+ mcp: {
2320
+ server: {
2321
+ url: mcpTool2.config.serverUrl
2322
+ },
2323
+ transport: mcpTool2.config.transport,
2324
+ activeTools: mcpTool2.config.activeTools
2325
+ }
2326
+ };
2327
+ const toolData = {
2328
+ id: toolId,
2329
+ name: actualTool.getName(),
2330
+ config: toolConfig
2331
+ };
2332
+ if (mcpTool2.config?.imageUrl) {
2333
+ toolData.imageUrl = mcpTool2.config.imageUrl;
2334
+ }
2335
+ if (mcpTool2.config?.headers) {
2336
+ toolData.headers = mcpTool2.config.headers;
2337
+ }
2338
+ if ("getCredentialReferenceId" in actualTool) {
2339
+ const credentialId = actualTool.getCredentialReferenceId();
2340
+ if (credentialId) {
2341
+ toolData.credentialReferenceId = credentialId;
2342
+ }
2343
+ }
2344
+ if ("credential" in mcpTool2.config && mcpTool2.config.credential) {
2345
+ const credential2 = mcpTool2.config.credential;
2346
+ if (credential2?.id && credential2.__type !== "credential-ref") {
2347
+ if (!credentialReferencesObject[credential2.id]) {
2348
+ credentialReferencesObject[credential2.id] = {
2349
+ id: credential2.id,
2350
+ name: credential2.name,
2351
+ type: credential2.type,
2352
+ credentialStoreId: credential2.credentialStoreId,
2353
+ retrievalParams: credential2.retrievalParams
2354
+ };
2355
+ credentialUsageMap[credential2.id] = [];
2356
+ }
2357
+ credentialUsageMap[credential2.id].push({
2358
+ type: "tool",
2359
+ id: toolId
2360
+ });
2361
+ }
2362
+ }
2363
+ toolsObject[toolId] = toolData;
2364
+ }
2365
+ }
2366
+ }
2367
+ }
2368
+ const subAgentDataComponents = subAgent2.getDataComponents?.();
2369
+ if (subAgentDataComponents) {
2370
+ for (const dataComponent2 of subAgentDataComponents) {
2371
+ let dataComponentId;
2372
+ let dataComponentName;
2373
+ let dataComponentDescription;
2374
+ let dataComponentProps;
2375
+ let dataComponentRender;
2376
+ if (dataComponent2.getId) {
2377
+ dataComponentId = dataComponent2.getId();
2378
+ dataComponentName = dataComponent2.getName();
2379
+ dataComponentDescription = dataComponent2.getDescription() || "";
2380
+ dataComponentProps = dataComponent2.getProps() || {};
2381
+ dataComponentRender = dataComponent2.getRender?.() || null;
2382
+ } else {
2383
+ dataComponentId = dataComponent2.id || (dataComponent2.name ? dataComponent2.name.toLowerCase().replace(/\s+/g, "-") : "");
2384
+ dataComponentName = dataComponent2.name || "";
2385
+ dataComponentDescription = dataComponent2.description || "";
2386
+ dataComponentProps = dataComponent2.props || {};
2387
+ dataComponentRender = dataComponent2.render || null;
2388
+ }
2389
+ if (!dataComponentsObject[dataComponentId] && dataComponentName) {
2390
+ dataComponentsObject[dataComponentId] = {
2391
+ id: dataComponentId,
2392
+ name: dataComponentName,
2393
+ description: dataComponentDescription,
2394
+ props: dataComponentProps,
2395
+ render: dataComponentRender
2396
+ };
2397
+ }
2398
+ }
2399
+ }
2400
+ const subAgentArtifactComponents = subAgent2.getArtifactComponents();
2401
+ if (subAgentArtifactComponents) {
2402
+ for (const artifactComponent2 of subAgentArtifactComponents) {
2403
+ let artifactComponentId;
2404
+ let artifactComponentName;
2405
+ let artifactComponentDescription;
2406
+ let artifactComponentProps;
2407
+ if ("getId" in artifactComponent2 && typeof artifactComponent2.getId === "function") {
2408
+ const component = artifactComponent2;
2409
+ artifactComponentId = component.getId();
2410
+ artifactComponentName = component.getName();
2411
+ artifactComponentDescription = component.getDescription() || "";
2412
+ artifactComponentProps = component.getProps() || {};
2413
+ } else {
2414
+ artifactComponentId = artifactComponent2.id || (artifactComponent2.name ? artifactComponent2.name.toLowerCase().replace(/\s+/g, "-") : "");
2415
+ artifactComponentName = artifactComponent2.name || "";
2416
+ artifactComponentDescription = artifactComponent2.description || "";
2417
+ artifactComponentProps = artifactComponent2.props || {};
2418
+ }
2419
+ if (!artifactComponentsObject[artifactComponentId] && artifactComponentName) {
2420
+ artifactComponentsObject[artifactComponentId] = {
2421
+ id: artifactComponentId,
2422
+ name: artifactComponentName,
2423
+ description: artifactComponentDescription,
2424
+ props: artifactComponentProps
2425
+ };
2426
+ }
2427
+ }
2428
+ }
2429
+ const subAgentExternalAgents = subAgent2.getExternalAgentDelegates();
2430
+ if (subAgentExternalAgents) {
2431
+ for (const externalAgentDelegate of subAgentExternalAgents) {
2432
+ const externalAgent2 = externalAgentDelegate.externalAgent;
2433
+ const credential2 = externalAgent2.getCredentialReference();
2434
+ if (credential2) {
2435
+ if (!credentialReferencesObject[credential2.id]) {
2436
+ credentialReferencesObject[credential2.id] = {
2437
+ id: credential2.id,
2438
+ name: credential2.name,
2439
+ type: credential2.type,
2440
+ credentialStoreId: credential2.credentialStoreId,
2441
+ retrievalParams: credential2.retrievalParams
2442
+ };
2443
+ credentialUsageMap[credential2.id] = [];
2444
+ }
2445
+ logger8.info({ credentialId: credential2.id }, "Credential id in external agent");
2446
+ credentialUsageMap[credential2.id].push({
2447
+ type: "externalAgent",
2448
+ id: externalAgent2.getId()
2449
+ });
2450
+ }
2451
+ logger8.info({ externalAgentId: externalAgent2.getId() }, "External agent id");
2452
+ externalAgentsObject[externalAgent2.getId()] = {
2453
+ id: externalAgent2.getId(),
2454
+ name: externalAgent2.getName(),
2455
+ description: externalAgent2.getDescription(),
2456
+ baseUrl: externalAgent2.getBaseUrl(),
2457
+ credentialReferenceId: externalAgent2.getCredentialReferenceId()
2458
+ };
2459
+ }
2460
+ }
2461
+ }
2462
+ }
2463
+ logger8.info({ externalAgentsObject }, "External agents object");
2464
+ for (const tool of this.projectTools) {
2465
+ const toolId = tool.getId();
2466
+ if (!toolsObject[toolId]) {
2467
+ const toolConfig = {
2468
+ type: "mcp",
2469
+ mcp: {
2470
+ server: {
2471
+ url: tool.config.serverUrl
2472
+ },
2473
+ transport: tool.config.transport,
2474
+ activeTools: tool.config.activeTools
2475
+ }
2476
+ };
2477
+ const toolData = {
2478
+ id: toolId,
2479
+ name: tool.getName(),
2480
+ config: toolConfig
2481
+ };
2482
+ if (tool.config?.imageUrl) {
2483
+ toolData.imageUrl = tool.config.imageUrl;
2484
+ }
2485
+ if (tool.config?.headers) {
2486
+ toolData.headers = tool.config.headers;
2487
+ }
2488
+ const credentialId = tool.getCredentialReferenceId();
2489
+ if (credentialId) {
2490
+ toolData.credentialReferenceId = credentialId;
2491
+ }
2492
+ toolsObject[toolId] = toolData;
2493
+ }
2494
+ }
2495
+ for (const dataComponent2 of this.projectDataComponents) {
2496
+ const dataComponentId = dataComponent2.getId();
2497
+ const dataComponentName = dataComponent2.getName();
2498
+ const dataComponentDescription = dataComponent2.getDescription() || "";
2499
+ const dataComponentProps = dataComponent2.getProps() || {};
2500
+ if (!dataComponentsObject[dataComponentId] && dataComponentName) {
2501
+ dataComponentsObject[dataComponentId] = {
2502
+ id: dataComponentId,
2503
+ name: dataComponentName,
2504
+ description: dataComponentDescription,
2505
+ props: dataComponentProps
2506
+ };
2507
+ }
2508
+ }
2509
+ for (const artifactComponent2 of this.projectArtifactComponents) {
2510
+ const artifactComponentId = artifactComponent2.getId();
2511
+ const artifactComponentName = artifactComponent2.getName();
2512
+ const artifactComponentDescription = artifactComponent2.getDescription() || "";
2513
+ const artifactComponentProps = artifactComponent2.getProps() || {};
2514
+ if (!artifactComponentsObject[artifactComponentId] && artifactComponentName) {
2515
+ artifactComponentsObject[artifactComponentId] = {
2516
+ id: artifactComponentId,
2517
+ name: artifactComponentName,
2518
+ description: artifactComponentDescription,
2519
+ props: artifactComponentProps
2520
+ };
2521
+ }
2522
+ }
2523
+ if (this.credentialReferences && this.credentialReferences.length > 0) {
2524
+ for (const credential2 of this.credentialReferences) {
2525
+ if (credential2.id) {
2526
+ if (!credentialReferencesObject[credential2.id]) {
2527
+ credentialReferencesObject[credential2.id] = credential2;
2528
+ credentialUsageMap[credential2.id] = [];
2529
+ }
2530
+ }
2531
+ }
2532
+ }
2533
+ for (const [credId, usages] of Object.entries(credentialUsageMap)) {
2534
+ if (credentialReferencesObject[credId]) {
2535
+ credentialReferencesObject[credId].usedBy = usages;
2536
+ }
2537
+ }
2538
+ return {
2539
+ id: this.projectId,
2540
+ name: this.projectName,
2541
+ description: this.projectDescription || "",
2542
+ models: this.models,
2543
+ stopWhen: this.stopWhen,
2544
+ agents: agentsObject,
2545
+ tools: toolsObject,
2546
+ functionTools: Object.keys(functionToolsObject).length > 0 ? functionToolsObject : void 0,
2547
+ functions: Object.keys(functionsObject).length > 0 ? functionsObject : void 0,
2548
+ dataComponents: Object.keys(dataComponentsObject).length > 0 ? dataComponentsObject : void 0,
2549
+ artifactComponents: Object.keys(artifactComponentsObject).length > 0 ? artifactComponentsObject : void 0,
2550
+ externalAgents: Object.keys(externalAgentsObject).length > 0 ? externalAgentsObject : void 0,
2551
+ credentialReferences: Object.keys(credentialReferencesObject).length > 0 ? credentialReferencesObject : void 0,
2552
+ createdAt: (/* @__PURE__ */ new Date()).toISOString(),
2553
+ updatedAt: (/* @__PURE__ */ new Date()).toISOString()
2554
+ };
2555
+ }
2556
+ };
2557
+ var logger9 = getLogger("statusComponent");
2558
+ var StatusComponent = class {
2559
+ constructor(config) {
2560
+ __publicField(this, "config");
2561
+ let processedDetailsSchema;
2562
+ if (config.detailsSchema && isZodSchema(config.detailsSchema)) {
2563
+ const jsonSchema = convertZodToJsonSchema(config.detailsSchema);
2564
+ processedDetailsSchema = {
2565
+ type: "object",
2566
+ properties: jsonSchema.properties || {},
2567
+ required: jsonSchema.required || void 0
2568
+ };
2569
+ } else {
2570
+ processedDetailsSchema = config.detailsSchema;
2571
+ }
2572
+ this.config = {
2573
+ ...config,
2574
+ detailsSchema: processedDetailsSchema
2575
+ };
2576
+ logger9.info(
2577
+ {
2578
+ statusComponentType: config.type
2579
+ },
2580
+ "StatusComponent constructor initialized"
2581
+ );
2582
+ }
2583
+ getType() {
2584
+ return this.config.type;
2585
+ }
2586
+ getDescription() {
2587
+ return this.config.description;
2588
+ }
2589
+ getDetailsSchema() {
2590
+ return this.config.detailsSchema;
2591
+ }
2592
+ };
2593
+ var logger10 = getLogger("tool");
2594
+ var Tool = class {
2595
+ constructor(config) {
2596
+ __publicField(this, "config");
2597
+ __publicField(this, "baseURL");
2598
+ __publicField(this, "tenantId");
2599
+ __publicField(this, "initialized", false);
2600
+ __publicField(this, "projectId");
2601
+ this.config = config;
2602
+ this.baseURL = process.env.INKEEP_API_URL || "http://localhost:3002";
2603
+ this.tenantId = "default";
2604
+ this.projectId = "default";
2605
+ logger10.info(
2606
+ {
2607
+ Id: this.getId(),
2608
+ Name: config.name
2609
+ },
2610
+ "Tool constructor initialized"
2611
+ );
2612
+ }
2613
+ // Set context (tenantId, projectId, and baseURL) from external source (agent, agent, CLI, etc)
2614
+ setContext(tenantId, projectId, baseURL) {
2615
+ this.tenantId = tenantId;
2616
+ this.projectId = projectId;
2617
+ if (baseURL) {
2618
+ this.baseURL = baseURL;
2619
+ }
2620
+ }
2621
+ // Compute ID from name using same slug transformation as agents
2622
+ getId() {
2623
+ return this.config.id;
2624
+ }
2625
+ getName() {
2626
+ return this.config.name;
2627
+ }
2628
+ getDescription() {
2629
+ return this.config.description || "";
2630
+ }
2631
+ getServerUrl() {
2632
+ return this.config.serverUrl;
2633
+ }
2634
+ getActiveTools() {
2635
+ return this.config.activeTools;
2636
+ }
2637
+ getCredentialReferenceId() {
2638
+ return this.config.credential?.id;
2639
+ }
2640
+ // Public method to ensure tool exists in backend (with upsert behavior)
2641
+ async init(options) {
2642
+ if (this.initialized) return;
2643
+ try {
2644
+ if (!options?.skipDatabaseRegistration) {
2645
+ await this.upsertTool();
2646
+ }
2647
+ logger10.info(
2648
+ {
2649
+ toolId: this.getId()
2650
+ },
2651
+ "Tool initialized successfully"
2652
+ );
2653
+ this.initialized = true;
2654
+ } catch (error) {
2655
+ logger10.error(
2656
+ {
2657
+ toolId: this.getId(),
2658
+ error: error instanceof Error ? error.message : "Unknown error"
2659
+ },
2660
+ "Failed to initialize tool"
2661
+ );
2662
+ throw error;
2663
+ }
2664
+ }
2665
+ // Private method to upsert tool (create or update)
2666
+ async upsertTool() {
2667
+ const toolDataForUpdate = {
2668
+ id: this.getId(),
2669
+ name: this.config.name,
2670
+ credentialReferenceId: this.config.credential?.id ?? null,
2671
+ headers: this.config.headers ?? null,
2672
+ imageUrl: this.config.imageUrl,
2673
+ config: {
2674
+ type: "mcp",
2675
+ mcp: {
2676
+ server: {
2677
+ url: this.config.serverUrl
2678
+ },
2679
+ transport: this.config.transport,
2680
+ activeTools: this.config.activeTools
2681
+ }
2682
+ }
2683
+ };
2684
+ const toolDataForCreate = {
2685
+ ...toolDataForUpdate
2686
+ };
2687
+ logger10.info({ toolDataForCreate }, "toolDataForCreate");
2688
+ const updateResponse = await fetch(
2689
+ `${this.baseURL}/tenants/${this.tenantId}/projects/${this.projectId}/tools/${this.getId()}`,
2690
+ {
2691
+ method: "PUT",
2692
+ headers: {
2693
+ "Content-Type": "application/json"
2694
+ },
2695
+ body: JSON.stringify(toolDataForUpdate)
2696
+ }
2697
+ );
2698
+ logger10.info({ updateResponse }, "tool updateResponse");
2699
+ if (updateResponse.ok) {
2700
+ logger10.info(
2701
+ {
2702
+ toolId: this.getId()
2703
+ },
2704
+ "Tool updated successfully"
2705
+ );
2706
+ return;
2707
+ }
2708
+ if (updateResponse.status === 404) {
2709
+ logger10.info(
2710
+ {
2711
+ toolId: this.getId()
2712
+ },
2713
+ "Tool not found, creating new tool"
2714
+ );
2715
+ const createResponse = await fetch(
2716
+ `${this.baseURL}/tenants/${this.tenantId}/projects/${this.projectId}/tools`,
2717
+ {
2718
+ method: "POST",
2719
+ headers: {
2720
+ "Content-Type": "application/json"
2721
+ },
2722
+ body: JSON.stringify(toolDataForCreate)
2723
+ }
2724
+ );
2725
+ if (!createResponse.ok) {
2726
+ throw new Error(`Failed to create tool: ${createResponse.status}`);
2727
+ }
2728
+ logger10.info(
2729
+ {
2730
+ toolId: this.getId()
2731
+ },
2732
+ "Tool created successfully"
2733
+ );
2734
+ return;
2735
+ }
2736
+ throw new Error(`Failed to update tool: ${updateResponse.status}`);
2737
+ }
2738
+ /**
2739
+ * Creates a new AgentMcpConfig with the given configuration.
2740
+ *
2741
+ * @param config - The configuration for the AgentMcpConfig
2742
+ * @returns A new AgentMcpConfig
2743
+ *
2744
+ * example:
2745
+ * ```typescript
2746
+ * const tool = new Tool({
2747
+ * id: 'tool-id',
2748
+ * name: 'Tool Name',
2749
+ * serverUrl: 'https://example.com/mcp',
2750
+ * });
2751
+ * const agentMcpConfig = tool.with({ selectedTools: ['tool-1', 'tool-2'], headers: { 'Authorization': 'Bearer token' } });
2752
+ * ```
2753
+ */
2754
+ with(config) {
2755
+ const { selectedTools, toolPolicies } = normalizeToolSelections(config.selectedTools);
2756
+ return {
2757
+ server: this,
2758
+ selectedTools,
2759
+ headers: config.headers,
2760
+ toolPolicies
2761
+ };
2762
+ }
2763
+ };
2764
+
2765
+ // src/utils/tool-normalization.ts
2766
+ function isAgentMcpConfig(value) {
2767
+ return value !== null && typeof value === "object" && "server" in value && value.server && typeof value.server === "object";
2768
+ }
2769
+ function isTool(value) {
2770
+ return value !== null && typeof value === "object" && "config" in value && (typeof value.getId === "function" || "id" in value);
2771
+ }
2772
+ function normalizeAgentCanUseType(value, fallbackName) {
2773
+ if (isAgentMcpConfig(value)) {
2774
+ return {
2775
+ tool: value.server,
2776
+ toolId: value.server.getId(),
2777
+ selectedTools: value.selectedTools,
2778
+ headers: value.headers,
2779
+ toolPolicies: value.toolPolicies,
2780
+ isWrapped: true
2781
+ };
2782
+ }
2783
+ if (isTool(value)) {
2784
+ const toolId = value.getId?.() || value.id || fallbackName || "unknown";
2785
+ return {
2786
+ tool: value,
2787
+ toolId,
2788
+ isWrapped: false
2789
+ };
2790
+ }
2791
+ throw new Error(`Invalid AgentCanUseType: expected Tool or AgentMcpConfig, got ${typeof value}`);
2792
+ }
2793
+
2794
+ // src/subAgent.ts
2795
+ var logger11 = getLogger("agent");
2796
+ function resolveGetter2(value) {
2797
+ if (typeof value === "function") {
2798
+ return value();
2799
+ }
2800
+ return value;
2801
+ }
2802
+ var SubAgent = class {
2803
+ constructor(config) {
2804
+ __publicField(this, "config");
2805
+ __publicField(this, "type", "internal");
2806
+ __publicField(this, "baseURL");
2807
+ __publicField(this, "tenantId");
2808
+ __publicField(this, "projectId");
2809
+ __publicField(this, "initialized", false);
2810
+ this.config = { ...config, type: "internal" };
2811
+ this.baseURL = process.env.INKEEP_API_URL || "http://localhost:3002";
2812
+ this.tenantId = "default";
2813
+ this.projectId = "default";
2814
+ logger11.info(
2815
+ {
2816
+ tenantId: this.tenantId,
2817
+ subAgentId: this.config.id,
2818
+ agentName: config.name
2819
+ },
2820
+ "Agent constructor initialized"
2821
+ );
2822
+ }
2823
+ // Set context (tenantId, projectId, and baseURL) from external source (agent, CLI, etc)
2824
+ setContext(tenantId, projectId, baseURL) {
2825
+ this.tenantId = tenantId;
2826
+ this.projectId = projectId;
2827
+ if (baseURL) {
2828
+ this.baseURL = baseURL;
2829
+ }
2830
+ }
2831
+ // Return the configured ID
2832
+ getId() {
2833
+ return this.config.id;
2834
+ }
2835
+ // Agent introspection methods
2836
+ getName() {
2837
+ return this.config.name;
2838
+ }
2839
+ getInstructions() {
2840
+ return this.config.prompt;
2841
+ }
2842
+ /**
2843
+ * Get the agent's description (the human-readable description field)
2844
+ */
2845
+ getDescription() {
2846
+ return this.config.description || "";
2847
+ }
2848
+ getTools() {
2849
+ const tools = resolveGetter2(this.config.canUse);
2850
+ if (!tools) {
2851
+ return {};
2852
+ }
2853
+ if (!Array.isArray(tools)) {
2854
+ throw new Error("tools getter must return an array");
2855
+ }
2856
+ const toolRecord = {};
2857
+ for (const tool of tools) {
2858
+ if (tool && typeof tool === "object") {
2859
+ let id;
2860
+ let toolInstance;
2861
+ if (isAgentMcpConfig(tool)) {
2862
+ id = tool.server.getId();
2863
+ toolInstance = tool.server;
2864
+ toolInstance.selectedTools = tool.selectedTools;
2865
+ toolInstance.headers = tool.headers;
2866
+ toolInstance.toolPolicies = tool.toolPolicies;
2867
+ } else {
2868
+ toolInstance = tool;
2869
+ id = toolInstance.getId();
2870
+ }
2871
+ if (id) {
2872
+ toolRecord[id] = toolInstance;
2873
+ }
2874
+ }
2875
+ }
2876
+ return toolRecord;
2877
+ }
2878
+ getModels() {
2879
+ return this.config.models;
2880
+ }
2881
+ setModels(models) {
2882
+ this.config.models = models;
2883
+ }
2884
+ getTransfers() {
2885
+ return typeof this.config.canTransferTo === "function" ? this.config.canTransferTo() : [];
2886
+ }
2887
+ getSubAgentDelegates() {
2888
+ return typeof this.config.canDelegateTo === "function" ? this.config.canDelegateTo().filter((delegate) => {
2889
+ if (typeof delegate === "object" && "externalAgent" in delegate) {
2890
+ return false;
2891
+ }
2892
+ if (typeof delegate === "object" && "agent" in delegate) {
2893
+ return false;
2894
+ }
2895
+ if (typeof delegate === "object" && "toFullAgentDefinition" in delegate) {
2896
+ return false;
2897
+ }
2898
+ if (typeof delegate === "object" && "type" in delegate && delegate.type === "external") {
2899
+ return false;
2900
+ }
2901
+ return true;
2902
+ }) : [];
2903
+ }
2904
+ getExternalAgentDelegates() {
2905
+ if (typeof this.config.canDelegateTo !== "function") {
2906
+ return [];
2907
+ }
2908
+ return this.config.canDelegateTo().filter((delegate) => {
2909
+ if (typeof delegate === "object" && "externalAgent" in delegate) {
2910
+ return true;
2911
+ }
2912
+ if (typeof delegate === "object" && "type" in delegate && delegate.type === "external") {
2913
+ return true;
2914
+ }
2915
+ return false;
2916
+ }).map((delegate) => {
2917
+ if ("externalAgent" in delegate) {
2918
+ return delegate;
2919
+ }
2920
+ return {
2921
+ externalAgent: delegate,
2922
+ headers: void 0
2923
+ };
2924
+ });
2925
+ }
2926
+ getTeamAgentDelegates() {
2927
+ if (typeof this.config.canDelegateTo !== "function") {
2928
+ return [];
2929
+ }
2930
+ return this.config.canDelegateTo().filter((delegate) => {
2931
+ if (typeof delegate === "object" && "agent" in delegate) {
2932
+ return true;
2933
+ }
2934
+ if (typeof delegate === "object" && "toFullAgentDefinition" in delegate) {
2935
+ return true;
2936
+ }
2937
+ return false;
2938
+ }).map((delegate) => {
2939
+ if ("agent" in delegate) {
2940
+ return delegate;
2941
+ }
2942
+ return {
2943
+ agent: delegate,
2944
+ headers: void 0
2945
+ };
2946
+ });
2947
+ }
2948
+ getDelegates() {
2949
+ return [
2950
+ ...this.getSubAgentDelegates(),
2951
+ ...this.getTeamAgentDelegates(),
2952
+ ...this.getExternalAgentDelegates()
2953
+ ];
2954
+ }
2955
+ getDataComponents() {
2956
+ const components = resolveGetter2(this.config.dataComponents) || [];
2957
+ return components.map((comp) => {
2958
+ if (comp && typeof comp.getId === "function") {
2959
+ return {
2960
+ id: comp.getId(),
2961
+ name: comp.getName(),
2962
+ description: comp.getDescription(),
2963
+ props: comp.getProps(),
2964
+ render: comp.getRender?.() || null
2965
+ };
2966
+ }
2967
+ if (comp && typeof comp === "object" && comp.props && isZodSchema(comp.props)) {
2968
+ return {
2969
+ id: comp.id,
2970
+ name: comp.name,
2971
+ description: comp.description,
2972
+ props: convertZodToJsonSchemaWithPreview(comp.props),
2973
+ render: comp.render || null
2974
+ };
2975
+ }
2976
+ return comp;
2977
+ });
2978
+ }
2979
+ getArtifactComponents() {
2980
+ const components = resolveGetter2(this.config.artifactComponents) || [];
2981
+ return components.map((comp) => {
2982
+ if (comp && typeof comp.getId === "function") {
2983
+ return {
2984
+ id: comp.getId(),
2985
+ name: comp.getName(),
2986
+ description: comp.getDescription(),
2987
+ props: comp.getProps?.() || comp.props
2988
+ };
2989
+ }
2990
+ if (comp && typeof comp === "object" && comp.props && isZodSchema(comp.props)) {
2991
+ return {
2992
+ id: comp.id,
2993
+ name: comp.name,
2994
+ description: comp.description,
2995
+ props: convertZodToJsonSchemaWithPreview(comp.props)
2996
+ };
2997
+ }
2998
+ return comp;
2999
+ });
3000
+ }
3001
+ // adjust
3002
+ addTool(_name, tool) {
3003
+ const existingTools = this.config.canUse ? this.config.canUse() : [];
3004
+ this.config.canUse = () => [...existingTools, tool];
3005
+ }
3006
+ addTransfer(...agents) {
3007
+ if (typeof this.config.canTransferTo === "function") {
3008
+ const existingTransfers = this.config.canTransferTo;
3009
+ this.config.canTransferTo = () => [...existingTransfers(), ...agents];
3010
+ } else {
3011
+ this.config.canTransferTo = () => agents;
3012
+ }
3013
+ }
3014
+ addDelegate(...agents) {
3015
+ if (typeof this.config.canDelegateTo === "function") {
3016
+ const existingDelegates = this.config.canDelegateTo;
3017
+ this.config.canDelegateTo = () => [...existingDelegates(), ...agents];
3018
+ } else {
3019
+ this.config.canDelegateTo = () => agents;
3020
+ }
3021
+ }
3022
+ // Public method to ensure agent exists in backend (with upsert behavior)
3023
+ async init() {
3024
+ if (this.initialized) return;
3025
+ try {
3026
+ await this.upsertAgent();
3027
+ await this.loadDataComponents();
3028
+ await this.loadArtifactComponents();
3029
+ await this.saveToolsAndRelations();
3030
+ await this.saveDataComponents();
3031
+ await this.saveArtifactComponents();
3032
+ logger11.info(
3033
+ {
3034
+ subAgentId: this.getId()
3035
+ },
3036
+ "Agent initialized successfully"
3037
+ );
3038
+ this.initialized = true;
3039
+ } catch (error) {
3040
+ logger11.error(
3041
+ {
3042
+ subAgentId: this.getId(),
3043
+ error: error instanceof Error ? error.message : "Unknown error"
3044
+ },
3045
+ "Failed to initialize agent"
3046
+ );
3047
+ throw error;
3048
+ }
3049
+ }
3050
+ // Private method to upsert agent (create or update)
3051
+ async upsertAgent() {
3052
+ const agentData = {
3053
+ id: this.getId(),
3054
+ name: this.config.name,
3055
+ description: this.config.description || "",
3056
+ prompt: this.config.prompt,
3057
+ conversationHistoryConfig: this.config.conversationHistoryConfig,
3058
+ models: this.config.models,
3059
+ stopWhen: this.config.stopWhen
3060
+ };
3061
+ const updateResponse = await fetch(
3062
+ `${this.baseURL}/tenants/${this.tenantId}/agents/${this.getId()}`,
3063
+ {
3064
+ method: "PUT",
3065
+ headers: {
3066
+ "Content-Type": "application/json"
3067
+ },
3068
+ body: JSON.stringify(agentData)
3069
+ }
3070
+ );
3071
+ if (updateResponse.ok) {
3072
+ logger11.info(
3073
+ {
3074
+ subAgentId: this.getId()
3075
+ },
3076
+ "Agent updated successfully"
3077
+ );
3078
+ return;
3079
+ }
3080
+ if (updateResponse.status === 404) {
3081
+ logger11.info(
3082
+ {
3083
+ subAgentId: this.getId()
3084
+ },
3085
+ "Agent not found, creating new agent"
3086
+ );
3087
+ const createResponse = await fetch(`${this.baseURL}/tenants/${this.tenantId}/agents`, {
3088
+ method: "POST",
3089
+ headers: {
3090
+ "Content-Type": "application/json"
3091
+ },
3092
+ body: JSON.stringify(agentData)
3093
+ });
3094
+ if (!createResponse.ok) {
3095
+ const errorText2 = await createResponse.text().catch(() => "Unknown error");
3096
+ throw new Error(
3097
+ `Failed to create agent: ${createResponse.status} ${createResponse.statusText} - ${errorText2}`
3098
+ );
3099
+ }
3100
+ logger11.info(
3101
+ {
3102
+ subAgentId: this.getId()
3103
+ },
3104
+ "Agent created successfully"
3105
+ );
3106
+ return;
3107
+ }
3108
+ const errorText = await updateResponse.text().catch(() => "Unknown error");
3109
+ throw new Error(
3110
+ `Failed to update agent: ${updateResponse.status} ${updateResponse.statusText} - ${errorText}`
3111
+ );
3112
+ }
3113
+ async saveToolsAndRelations() {
3114
+ if (this.config.canUse) {
3115
+ const tools = resolveGetter2(this.config.canUse);
3116
+ if (tools && Array.isArray(tools)) {
3117
+ for (let i = 0; i < tools.length; i++) {
3118
+ const toolConfig = tools[i];
3119
+ try {
3120
+ const normalizedTool = normalizeAgentCanUseType(toolConfig, `tool-${i}`);
3121
+ await this.createTool(normalizedTool.toolId, toolConfig);
3122
+ } catch (error) {
3123
+ logger11.error(
3124
+ {
3125
+ toolId: isAgentMcpConfig(toolConfig) ? toolConfig.server.getId() : toolConfig.getId?.(),
3126
+ error: error instanceof Error ? error.message : "Unknown error"
3127
+ },
3128
+ "Tool creation failed"
3129
+ );
3130
+ throw error;
3131
+ }
3132
+ }
3133
+ }
3134
+ }
3135
+ }
3136
+ async saveDataComponents() {
3137
+ logger11.info({ dataComponents: this.config.dataComponents }, "dataComponents and config");
3138
+ const components = resolveGetter2(this.config.dataComponents);
3139
+ if (components) {
3140
+ for (const dataComponent2 of components) {
3141
+ const plainComponent = dataComponent2 && typeof dataComponent2.getId === "function" ? {
3142
+ id: dataComponent2.getId(),
3143
+ name: dataComponent2.getName(),
3144
+ description: dataComponent2.getDescription(),
3145
+ props: dataComponent2.getProps()
3146
+ } : dataComponent2;
3147
+ await this.createDataComponent(plainComponent);
3148
+ }
3149
+ }
3150
+ }
3151
+ async saveArtifactComponents() {
3152
+ logger11.info(
3153
+ { artifactComponents: this.config.artifactComponents },
3154
+ "artifactComponents and config"
3155
+ );
3156
+ const components = resolveGetter2(this.config.artifactComponents);
3157
+ if (components) {
3158
+ for (const artifactComponent2 of components) {
3159
+ const plainComponent = artifactComponent2 && typeof artifactComponent2.getId === "function" ? {
3160
+ id: artifactComponent2.getId(),
3161
+ name: artifactComponent2.getName(),
3162
+ description: artifactComponent2.getDescription(),
3163
+ props: artifactComponent2.getProps?.() || artifactComponent2.props
3164
+ } : artifactComponent2;
3165
+ await this.createArtifactComponent(plainComponent);
3166
+ }
3167
+ }
3168
+ }
3169
+ async loadDataComponents() {
3170
+ try {
3171
+ const existingComponents = [];
3172
+ const dbDataComponents = existingComponents.map((component) => ({
3173
+ id: component.id,
3174
+ name: component.name,
3175
+ description: component.description,
3176
+ props: component.props,
3177
+ createdAt: component.createdAt,
3178
+ updatedAt: component.updatedAt
3179
+ }));
3180
+ const configComponents = resolveGetter2(this.config.dataComponents) || [];
3181
+ const normalizedConfigComponents = configComponents.map((comp) => {
3182
+ if (comp && typeof comp.getId === "function") {
3183
+ return {
3184
+ id: comp.getId(),
3185
+ name: comp.getName(),
3186
+ description: comp.getDescription(),
3187
+ props: comp.getProps()
3188
+ };
3189
+ }
3190
+ return comp;
3191
+ });
3192
+ const allComponents = [...dbDataComponents, ...normalizedConfigComponents];
3193
+ const uniqueComponents = allComponents.reduce((acc, component) => {
3194
+ const componentId = typeof component.getId === "function" ? component.getId() : component.id;
3195
+ const existingIndex = acc.findIndex((c) => {
3196
+ const cId = typeof c.getId === "function" ? c.getId() : c.id;
3197
+ return cId === componentId;
3198
+ });
3199
+ if (existingIndex >= 0) {
3200
+ acc[existingIndex] = component;
3201
+ } else {
3202
+ acc.push(component);
3203
+ }
3204
+ return acc;
3205
+ }, []);
3206
+ this.config.dataComponents = () => uniqueComponents;
3207
+ logger11.info(
3208
+ {
3209
+ subAgentId: this.getId(),
3210
+ dbComponentCount: dbDataComponents.length,
3211
+ configComponentCount: configComponents.length,
3212
+ totalComponentCount: uniqueComponents.length
3213
+ },
3214
+ "Loaded and merged data components"
3215
+ );
3216
+ } catch (error) {
3217
+ logger11.error(
3218
+ {
3219
+ subAgentId: this.getId(),
3220
+ error: error instanceof Error ? error.message : "Unknown error"
3221
+ },
3222
+ "Failed to load data components from database"
3223
+ );
3224
+ }
3225
+ }
3226
+ async loadArtifactComponents() {
3227
+ try {
3228
+ const existingComponents = [];
3229
+ const dbArtifactComponents = existingComponents.map((component) => ({
3230
+ id: component.id,
3231
+ name: component.name,
3232
+ description: component.description,
3233
+ props: component.props,
3234
+ createdAt: component.createdAt,
3235
+ updatedAt: component.updatedAt
3236
+ }));
3237
+ const configComponents = resolveGetter2(this.config.artifactComponents) || [];
3238
+ const normalizedConfigComponents = configComponents.map((comp) => {
3239
+ if (comp && typeof comp.getId === "function") {
3240
+ return {
3241
+ id: comp.getId(),
3242
+ name: comp.getName(),
3243
+ description: comp.getDescription(),
3244
+ props: comp.getProps?.() || comp.props
3245
+ };
3246
+ }
3247
+ return comp;
3248
+ });
3249
+ const allComponents = [...dbArtifactComponents, ...normalizedConfigComponents];
3250
+ const uniqueComponents = allComponents.reduce((acc, component) => {
3251
+ const componentId = typeof component.getId === "function" ? component.getId() : component.id;
3252
+ const existingIndex = acc.findIndex((c) => {
3253
+ const cId = typeof c.getId === "function" ? c.getId() : c.id;
3254
+ return cId === componentId;
3255
+ });
3256
+ if (existingIndex >= 0) {
3257
+ acc[existingIndex] = component;
3258
+ } else {
3259
+ acc.push(component);
3260
+ }
3261
+ return acc;
3262
+ }, []);
3263
+ this.config.artifactComponents = () => uniqueComponents;
3264
+ logger11.info(
3265
+ {
3266
+ subAgentId: this.getId(),
3267
+ dbComponentCount: dbArtifactComponents.length,
3268
+ configComponentCount: configComponents.length,
3269
+ totalComponentCount: uniqueComponents.length
3270
+ },
3271
+ "Loaded and merged artifact components"
3272
+ );
3273
+ } catch (error) {
3274
+ logger11.error(
3275
+ {
3276
+ subAgentId: this.getId(),
3277
+ error: error instanceof Error ? error.message : "Unknown error"
3278
+ },
3279
+ "Failed to load artifact components from database"
3280
+ );
3281
+ }
3282
+ }
3283
+ async createFunctionTool(toolId, functionTool2) {
3284
+ try {
3285
+ const functionData = functionTool2.serializeFunction();
3286
+ const toolData = functionTool2.serializeTool();
3287
+ const functionUrl = `${this.baseURL}/tenants/${this.tenantId}/crud/projects/${this.projectId}/functions`;
3288
+ logger11.info(
3289
+ {
3290
+ agentId: this.getId(),
3291
+ toolId,
3292
+ functionUrl
3293
+ },
3294
+ "Attempting to create global function"
3295
+ );
3296
+ const functionResponse = await fetch(functionUrl, {
3297
+ method: "POST",
3298
+ headers: {
3299
+ "Content-Type": "application/json"
3300
+ },
3301
+ body: JSON.stringify({
3302
+ id: functionData.id,
3303
+ inputSchema: functionData.inputSchema,
3304
+ executeCode: functionData.executeCode,
3305
+ dependencies: functionData.dependencies
3306
+ })
3307
+ });
3308
+ logger11.info(
3309
+ {
3310
+ agentId: this.getId(),
3311
+ toolId,
3312
+ functionStatus: functionResponse.status,
3313
+ functionStatusText: functionResponse.statusText
3314
+ },
3315
+ "Function creation response received"
3316
+ );
3317
+ if (!functionResponse.ok) {
3318
+ const errorText = await functionResponse.text();
3319
+ logger11.error(
3320
+ {
3321
+ agentId: this.getId(),
3322
+ toolId,
3323
+ functionStatus: functionResponse.status,
3324
+ functionStatusText: functionResponse.statusText,
3325
+ errorText
3326
+ },
3327
+ "Function creation failed"
3328
+ );
3329
+ throw new Error(`Failed to create function: ${functionResponse.status} ${errorText}`);
3330
+ }
3331
+ const toolUrl = `${this.baseURL}/tenants/${this.tenantId}/crud/projects/${this.projectId}/tools`;
3332
+ logger11.info(
3333
+ {
3334
+ agentId: this.getId(),
3335
+ toolId,
3336
+ toolUrl
3337
+ },
3338
+ "Attempting to create function tool"
3339
+ );
3340
+ const toolResponse = await fetch(toolUrl, {
3341
+ method: "POST",
3342
+ headers: {
3343
+ "Content-Type": "application/json"
3344
+ },
3345
+ body: JSON.stringify({
3346
+ id: toolData.id,
3347
+ name: toolData.name,
3348
+ description: toolData.description,
3349
+ functionId: toolData.functionId,
3350
+ config: {
3351
+ type: "function"
3352
+ // No inline function details - reference via functionId only
3353
+ }
3354
+ })
3355
+ });
3356
+ logger11.info(
3357
+ {
3358
+ agentId: this.getId(),
3359
+ toolId,
3360
+ toolStatus: toolResponse.status,
3361
+ toolStatusText: toolResponse.statusText
3362
+ },
3363
+ "Tool creation response received"
3364
+ );
3365
+ if (!toolResponse.ok) {
3366
+ const errorText = await toolResponse.text();
3367
+ logger11.error(
3368
+ {
3369
+ agentId: this.getId(),
3370
+ toolId,
3371
+ toolStatus: toolResponse.status,
3372
+ toolStatusText: toolResponse.statusText,
3373
+ errorText
3374
+ },
3375
+ "Tool creation failed"
3376
+ );
3377
+ throw new Error(`Failed to create tool: ${toolResponse.status} ${errorText}`);
3378
+ }
3379
+ await this.createAgentToolRelation(toolData.id);
3380
+ logger11.info(
3381
+ {
3382
+ agentId: this.getId(),
3383
+ functionId: functionData.id,
3384
+ toolId: toolData.id
3385
+ },
3386
+ "Function and tool created successfully"
3387
+ );
3388
+ } catch (error) {
3389
+ logger11.error(
3390
+ {
3391
+ agentId: this.getId(),
3392
+ toolId,
3393
+ error: error instanceof Error ? error.message : "Unknown error",
3394
+ stack: error instanceof Error ? error.stack : void 0
3395
+ },
3396
+ "Failed to create function tool"
3397
+ );
3398
+ throw error;
3399
+ }
3400
+ }
3401
+ async createTool(toolId, toolConfig) {
3402
+ try {
3403
+ if (toolConfig instanceof FunctionTool) {
3404
+ await this.createFunctionTool(toolId, toolConfig);
3405
+ return;
3406
+ }
3407
+ if (toolConfig.type === "function") {
3408
+ logger11.info(
3409
+ {
3410
+ subAgentId: this.getId(),
3411
+ toolId
3412
+ },
3413
+ "Skipping function tool creation - will be handled at runtime"
3414
+ );
3415
+ return;
3416
+ }
3417
+ let tool;
3418
+ let selectedTools;
3419
+ let headers;
3420
+ let toolPolicies;
3421
+ try {
3422
+ const normalizedTool = normalizeAgentCanUseType(toolConfig, toolId);
3423
+ tool = normalizedTool.tool;
3424
+ selectedTools = normalizedTool.selectedTools;
3425
+ headers = normalizedTool.headers;
3426
+ toolPolicies = normalizedTool.toolPolicies;
3427
+ tool.setContext(this.tenantId, this.projectId);
3428
+ await tool.init();
3429
+ } catch (_) {
3430
+ tool = new Tool({
3431
+ id: toolId,
3432
+ name: toolConfig.name || toolId,
3433
+ description: toolConfig.description || `MCP tool: ${toolId}`,
3434
+ serverUrl: toolConfig.config?.serverUrl || toolConfig.serverUrl || "http://localhost:3000",
3435
+ activeTools: toolConfig.config?.mcp?.activeTools,
3436
+ credential: toolConfig.credential
3437
+ });
3438
+ tool.setContext(this.tenantId, this.projectId);
3439
+ await tool.init();
3440
+ }
3441
+ await this.createAgentToolRelation(tool.getId(), selectedTools, headers, toolPolicies);
3442
+ logger11.info(
3443
+ {
3444
+ subAgentId: this.getId(),
3445
+ toolId: tool.getId()
3446
+ },
3447
+ "Tool created and linked to agent"
3448
+ );
3449
+ } catch (error) {
3450
+ logger11.error(
3451
+ {
3452
+ subAgentId: this.getId(),
3453
+ toolId,
3454
+ error: error instanceof Error ? error.message : "Unknown error"
3455
+ },
3456
+ "Failed to create tool"
3457
+ );
3458
+ throw error;
3459
+ }
3460
+ }
3461
+ async createDataComponent(dataComponent2) {
3462
+ try {
3463
+ const dc = new DataComponent({
3464
+ id: dataComponent2.id,
3465
+ name: dataComponent2.name,
3466
+ description: dataComponent2.description,
3467
+ props: dataComponent2.props,
3468
+ render: dataComponent2.render
3469
+ });
3470
+ dc.setContext(this.tenantId, this.projectId);
3471
+ await dc.init();
3472
+ await this.createAgentDataComponentRelation(dc.getId());
3473
+ logger11.info(
3474
+ {
3475
+ subAgentId: this.getId(),
3476
+ dataComponentId: dc.getId()
3477
+ },
3478
+ "DataComponent created and linked to agent"
3479
+ );
3480
+ } catch (error) {
3481
+ logger11.error(
3482
+ {
3483
+ subAgentId: this.getId(),
3484
+ dataComponentName: dataComponent2.name,
3485
+ error: error instanceof Error ? error.message : "Unknown error"
3486
+ },
3487
+ "Failed to create data component"
3488
+ );
3489
+ throw error;
3490
+ }
3491
+ }
3492
+ async createArtifactComponent(artifactComponent2) {
3493
+ try {
3494
+ const ac = new ArtifactComponent({
3495
+ id: artifactComponent2.id,
3496
+ name: artifactComponent2.name,
3497
+ description: artifactComponent2.description,
3498
+ props: artifactComponent2.props
3499
+ });
3500
+ ac.setContext(this.tenantId, this.projectId);
3501
+ await ac.init();
3502
+ await this.createAgentArtifactComponentRelation(ac.getId());
3503
+ logger11.info(
3504
+ {
3505
+ subAgentId: this.getId(),
3506
+ artifactComponentId: ac.getId()
3507
+ },
3508
+ "ArtifactComponent created and linked to agent"
3509
+ );
3510
+ } catch (error) {
3511
+ logger11.error(
3512
+ {
3513
+ subAgentId: this.getId(),
3514
+ artifactComponentName: artifactComponent2.name,
3515
+ error: error instanceof Error ? error.message : "Unknown error"
3516
+ },
3517
+ "Failed to create artifact component"
3518
+ );
3519
+ throw error;
3520
+ }
3521
+ }
3522
+ async createAgentDataComponentRelation(dataComponentId) {
3523
+ const relationResponse = await fetch(
3524
+ `${this.baseURL}/tenants/${this.tenantId}/agent-data-components`,
3525
+ {
3526
+ method: "POST",
3527
+ headers: {
3528
+ "Content-Type": "application/json"
3529
+ },
3530
+ body: JSON.stringify({
3531
+ id: `${this.getId()}-dc-${dataComponentId}`,
3532
+ tenantId: this.tenantId,
3533
+ subAgentId: this.getId(),
3534
+ dataComponentId
3535
+ })
3536
+ }
3537
+ );
3538
+ if (!relationResponse.ok) {
3539
+ throw new Error(
3540
+ `Failed to create agent-dataComponent relation: ${relationResponse.status} ${relationResponse.statusText}`
3541
+ );
3542
+ }
3543
+ logger11.info(
3544
+ {
3545
+ subAgentId: this.getId(),
3546
+ dataComponentId
3547
+ },
3548
+ "Created agent-dataComponent relation"
3549
+ );
3550
+ }
3551
+ async createAgentArtifactComponentRelation(artifactComponentId) {
3552
+ const relationResponse = await fetch(
3553
+ `${this.baseURL}/tenants/${this.tenantId}/agent-artifact-components`,
3554
+ {
3555
+ method: "POST",
3556
+ headers: {
3557
+ "Content-Type": "application/json"
3558
+ },
3559
+ body: JSON.stringify({
3560
+ id: crypto.randomUUID(),
3561
+ tenantId: this.tenantId,
3562
+ subAgentId: this.getId(),
3563
+ artifactComponentId
3564
+ })
3565
+ }
3566
+ );
3567
+ if (!relationResponse.ok) {
3568
+ throw new Error(
3569
+ `Failed to create agent-artifactComponent relation: ${relationResponse.status} ${relationResponse.statusText}`
3570
+ );
3571
+ }
3572
+ logger11.info(
3573
+ {
3574
+ subAgentId: this.getId(),
3575
+ artifactComponentId
3576
+ },
3577
+ "Created agent-artifactComponent relation"
3578
+ );
3579
+ }
3580
+ async createAgentToolRelation(toolId, selectedTools, headers, toolPolicies) {
3581
+ const relationData = {
3582
+ id: `${this.getId()}-tool-${toolId}`,
3583
+ tenantId: this.tenantId,
3584
+ projectId: this.projectId,
3585
+ subAgentId: this.getId(),
3586
+ toolId
3587
+ };
3588
+ if (selectedTools !== void 0) {
3589
+ relationData.selectedTools = selectedTools;
3590
+ }
3591
+ if (headers !== void 0) {
3592
+ relationData.headers = headers;
3593
+ }
3594
+ if (toolPolicies !== void 0 && Object.keys(toolPolicies).length > 0) {
3595
+ relationData.toolPolicies = toolPolicies;
3596
+ }
3597
+ const relationResponse = await fetch(
3598
+ `${this.baseURL}/tenants/${this.tenantId}/projects/${this.projectId}/agent-tool-relations`,
3599
+ {
3600
+ method: "POST",
3601
+ headers: {
3602
+ "Content-Type": "application/json"
3603
+ },
3604
+ body: JSON.stringify(relationData)
3605
+ }
3606
+ );
3607
+ if (!relationResponse.ok) {
3608
+ const errorBody = await relationResponse.text().catch(() => "Unknown error");
3609
+ throw new Error(
3610
+ `Failed to create agent-tool relation: ${relationResponse.status} - ${errorBody}`
3611
+ );
3612
+ }
3613
+ }
3614
+ };
3615
+
3616
+ // src/builderFunctions.ts
3617
+ function agent(config) {
3618
+ return new Agent(config);
3619
+ }
3620
+ function project(config) {
3621
+ return new Project(config);
3622
+ }
3623
+ function subAgent(config) {
3624
+ if (!config.id) {
3625
+ throw new Error(
3626
+ "Sub-Agent ID is required. Sub-Agents must have stable IDs for consistency across deployments."
3627
+ );
3628
+ }
3629
+ return new SubAgent(config);
3630
+ }
3631
+ function credential(config) {
3632
+ try {
3633
+ return CredentialReferenceApiInsertSchema.parse(config);
3634
+ } catch (error) {
3635
+ if (error instanceof Error) {
3636
+ const credId = config.id || "unknown";
3637
+ throw new Error(`Invalid credential '${credId}': ${error.message}`);
3638
+ }
3639
+ throw error;
3640
+ }
3641
+ }
3642
+ function mcpServer(config) {
3643
+ if (!config.serverUrl) {
3644
+ throw new Error("MCP server requires a serverUrl");
3645
+ }
3646
+ const id = config.id || generateIdFromName(config.name);
3647
+ return new Tool({
3648
+ id,
3649
+ name: config.name,
3650
+ description: config.description,
3651
+ serverUrl: config.serverUrl,
3652
+ credential: config.credential,
3653
+ activeTools: config.activeTools,
3654
+ headers: config.headers,
3655
+ imageUrl: config.imageUrl,
3656
+ transport: config.transport ? { type: config.transport } : void 0
3657
+ });
3658
+ }
3659
+ function mcpTool(config) {
3660
+ const configWithId = {
3661
+ ...config,
3662
+ id: config.id || generateIdFromName(config.name)
3663
+ };
3664
+ const validatedConfig = MCPToolConfigSchema.parse(configWithId);
3665
+ return new Tool(validatedConfig);
3666
+ }
3667
+ function artifactComponent(config) {
3668
+ const configWithId = {
3669
+ ...config,
3670
+ id: config.id || generateIdFromName(config.name)
3671
+ };
3672
+ return new ArtifactComponent(configWithId);
3673
+ }
3674
+ function dataComponent(config) {
3675
+ const configWithId = {
3676
+ ...config,
3677
+ id: config.id || generateIdFromName(config.name)
3678
+ };
3679
+ return new DataComponent(configWithId);
3680
+ }
3681
+ function statusComponent(config) {
3682
+ return new StatusComponent(config);
3683
+ }
3684
+ function agentMcp(config) {
3685
+ return {
3686
+ server: config.server,
3687
+ selectedTools: config.selectedTools,
3688
+ headers: config.headers
3689
+ };
3690
+ }
3691
+ function functionTool(config) {
3692
+ return new FunctionTool(config);
3693
+ }
3694
+
3695
+ // src/utils/validateFunction.ts
3696
+ function validateFunction(value, name) {
3697
+ if (typeof value !== "function") {
3698
+ throw new Error(`${name} must be a function`);
3699
+ }
3700
+ }
3701
+
3702
+ // src/builders.ts
3703
+ var TransferConfigSchema = z.object({
3704
+ agent: z.instanceof(SubAgent),
3705
+ description: z.string().optional()
3706
+ });
3707
+ function transfer(targetAgent, description, condition) {
3708
+ if (condition !== void 0) {
3709
+ validateFunction(condition, "condition");
3710
+ }
3711
+ const config = {
3712
+ agent: targetAgent,
3713
+ description: description || `Hand off to ${targetAgent.getName()}`,
3714
+ condition
3715
+ };
3716
+ TransferConfigSchema.parse({
3717
+ agent: config.agent,
3718
+ description: config.description
3719
+ });
3720
+ return config;
3721
+ }
3722
+
3723
+ // src/credential-ref.ts
3724
+ function credentialRef(id) {
3725
+ return {
3726
+ __type: "credential-ref",
3727
+ id
3728
+ };
3729
+ }
3730
+ function isCredentialReference(value) {
3731
+ return value && typeof value === "object" && value.__type === "credential-ref";
3732
+ }
3733
+
3734
+ // src/environment-settings.ts
3735
+ function createEnvironmentSettings(environments) {
3736
+ return {
3737
+ getEnvironmentCredential: (key) => {
3738
+ const currentEnv = process.env.INKEEP_ENV || "development";
3739
+ const env = environments[currentEnv];
3740
+ if (!env) {
3741
+ throw new Error(
3742
+ `Environment '${currentEnv}' not found. Available: ${Object.keys(environments).join(", ")}`
3743
+ );
3744
+ }
3745
+ const credential2 = env.credentials?.[key];
3746
+ if (!credential2) {
3747
+ throw new Error(`Credential '${String(key)}' not found in environment '${currentEnv}'`);
3748
+ }
3749
+ return credential2;
3750
+ },
3751
+ getEnvironmentMcp: (key) => {
3752
+ const currentEnv = process.env.INKEEP_ENV || "development";
3753
+ const env = environments[currentEnv];
3754
+ if (!env) {
3755
+ throw new Error(
3756
+ `Environment '${currentEnv}' not found. Available: ${Object.keys(environments).join(", ")}`
3757
+ );
3758
+ }
3759
+ const mcpServer2 = env.mcpServers?.[key];
3760
+ if (!mcpServer2) {
3761
+ throw new Error(`MCP Server '${String(key)}' not found in environment '${currentEnv}'`);
3762
+ }
3763
+ return mcpServer2;
3764
+ },
3765
+ //Deprecated: Use getEnvironmentCredential instead
3766
+ getEnvironmentSetting: (key) => {
3767
+ const currentEnv = process.env.INKEEP_ENV || "development";
3768
+ const env = environments[currentEnv];
3769
+ if (!env) {
3770
+ throw new Error(
3771
+ `Environment '${currentEnv}' not found. Available: ${Object.keys(environments).join(", ")}`
3772
+ );
3773
+ }
3774
+ const credential2 = env.credentials?.[key];
3775
+ if (!credential2) {
3776
+ throw new Error(`Credential '${String(key)}' not found in environment '${currentEnv}'`);
3777
+ }
3778
+ return credential2;
3779
+ }
3780
+ };
3781
+ }
3782
+ function registerEnvironmentSettings(config) {
3783
+ return config;
3784
+ }
3785
+ var logger12 = getLogger("evaluationClient");
3786
+ function parseError2(errorText) {
3787
+ try {
3788
+ const errorJson = JSON.parse(errorText);
3789
+ if (errorJson.error) {
3790
+ const { error } = errorJson;
3791
+ return error?.message ?? error;
3792
+ }
3793
+ } catch {
3794
+ if (errorText) {
3795
+ return errorText;
3796
+ }
3797
+ }
3798
+ }
3799
+ function buildUrl(apiUrl, tenantId, projectId, ...pathSegments) {
3800
+ return `${apiUrl}/tenants/${tenantId}/projects/${projectId}/evaluations/${pathSegments.join("/")}`;
3801
+ }
3802
+ function buildHeaders(apiKey) {
3803
+ const headers = {
3804
+ "Content-Type": "application/json"
3805
+ };
3806
+ if (apiKey) {
3807
+ headers.Authorization = `Bearer ${apiKey}`;
3808
+ }
3809
+ return headers;
3810
+ }
3811
+ async function listDatasets(tenantId, projectId, apiUrl, apiKey) {
3812
+ logger12.info({ tenantId, projectId }, "Listing datasets via API");
3813
+ const url = buildUrl(apiUrl, tenantId, projectId, "datasets");
3814
+ try {
3815
+ const response = await apiFetch(url, {
3816
+ method: "GET",
3817
+ headers: buildHeaders(apiKey)
3818
+ });
3819
+ if (!response.ok) {
3820
+ const errorText = await response.text();
3821
+ const errorMessage = parseError2(errorText) ?? `Failed to list datasets: ${response.status} ${response.statusText}`;
3822
+ logger12.error(
3823
+ { status: response.status, error: errorMessage },
3824
+ "Failed to list datasets via API"
3825
+ );
3826
+ throw new Error(errorMessage);
3827
+ }
3828
+ const result = await response.json();
3829
+ return result.data;
3830
+ } catch (error) {
3831
+ logger12.error({ error, tenantId, projectId }, "Failed to list datasets");
3832
+ throw error;
3833
+ }
3834
+ }
3835
+ async function getDataset(tenantId, projectId, datasetId, apiUrl, apiKey) {
3836
+ logger12.info({ tenantId, projectId, datasetId }, "Getting dataset via API");
3837
+ const url = buildUrl(apiUrl, tenantId, projectId, "datasets", datasetId);
3838
+ try {
3839
+ const response = await apiFetch(url, {
3840
+ method: "GET",
3841
+ headers: buildHeaders(apiKey)
3842
+ });
3843
+ if (!response.ok) {
3844
+ if (response.status === 404) {
3845
+ logger12.info({ datasetId }, "Dataset not found");
3846
+ return null;
3847
+ }
3848
+ const errorText = await response.text();
3849
+ const errorMessage = parseError2(errorText) ?? `Failed to get dataset: ${response.status} ${response.statusText}`;
3850
+ logger12.error(
3851
+ { status: response.status, error: errorMessage },
3852
+ "Failed to get dataset via API"
3853
+ );
3854
+ throw new Error(errorMessage);
3855
+ }
3856
+ const result = await response.json();
3857
+ return result.data;
3858
+ } catch (error) {
3859
+ logger12.error({ error, tenantId, projectId, datasetId }, "Failed to get dataset");
3860
+ throw error;
3861
+ }
3862
+ }
3863
+ async function createDataset(tenantId, projectId, apiUrl, datasetData, apiKey) {
3864
+ logger12.info({ tenantId, projectId }, "Creating dataset via API");
3865
+ const url = buildUrl(apiUrl, tenantId, projectId, "datasets");
3866
+ try {
3867
+ const response = await apiFetch(url, {
3868
+ method: "POST",
3869
+ headers: buildHeaders(apiKey),
3870
+ body: JSON.stringify(datasetData)
3871
+ });
3872
+ if (!response.ok) {
3873
+ const errorText = await response.text();
3874
+ const errorMessage = parseError2(errorText) ?? `Failed to create dataset: ${response.status} ${response.statusText}`;
3875
+ logger12.error(
3876
+ { status: response.status, error: errorMessage },
3877
+ "Failed to create dataset via API"
3878
+ );
3879
+ throw new Error(errorMessage);
3880
+ }
3881
+ const result = await response.json();
3882
+ logger12.info({ tenantId, projectId }, "Successfully created dataset via API");
3883
+ return result.data;
3884
+ } catch (error) {
3885
+ logger12.error({ error, tenantId, projectId }, "Failed to create dataset");
3886
+ throw error;
3887
+ }
3888
+ }
3889
+ async function updateDataset(tenantId, projectId, datasetId, apiUrl, updateData, apiKey) {
3890
+ logger12.info({ tenantId, projectId, datasetId }, "Updating dataset via API");
3891
+ const url = buildUrl(apiUrl, tenantId, projectId, "datasets", datasetId);
3892
+ try {
3893
+ const response = await apiFetch(url, {
3894
+ method: "PATCH",
3895
+ headers: buildHeaders(apiKey),
3896
+ body: JSON.stringify(updateData)
3897
+ });
3898
+ if (!response.ok) {
3899
+ const errorText = await response.text();
3900
+ const errorMessage = parseError2(errorText) ?? `Failed to update dataset: ${response.status} ${response.statusText}`;
3901
+ logger12.error(
3902
+ { status: response.status, error: errorMessage },
3903
+ "Failed to update dataset via API"
3904
+ );
3905
+ throw new Error(errorMessage);
3906
+ }
3907
+ const result = await response.json();
3908
+ logger12.info({ tenantId, projectId, datasetId }, "Successfully updated dataset via API");
3909
+ return result.data;
3910
+ } catch (error) {
3911
+ logger12.error({ error, tenantId, projectId, datasetId }, "Failed to update dataset");
3912
+ throw error;
3913
+ }
3914
+ }
3915
+ async function deleteDataset(tenantId, projectId, datasetId, apiUrl, apiKey) {
3916
+ logger12.info({ tenantId, projectId, datasetId }, "Deleting dataset via API");
3917
+ const url = buildUrl(apiUrl, tenantId, projectId, "datasets", datasetId);
3918
+ try {
3919
+ const response = await apiFetch(url, {
3920
+ method: "DELETE",
3921
+ headers: buildHeaders(apiKey)
3922
+ });
3923
+ if (!response.ok) {
3924
+ const errorText = await response.text();
3925
+ const errorMessage = parseError2(errorText) ?? `Failed to delete dataset: ${response.status} ${response.statusText}`;
3926
+ logger12.error(
3927
+ { status: response.status, error: errorMessage },
3928
+ "Failed to delete dataset via API"
3929
+ );
3930
+ throw new Error(errorMessage);
3931
+ }
3932
+ logger12.info({ tenantId, projectId, datasetId }, "Successfully deleted dataset via API");
3933
+ } catch (error) {
3934
+ logger12.error({ error, tenantId, projectId, datasetId }, "Failed to delete dataset");
3935
+ throw error;
3936
+ }
3937
+ }
3938
+ async function listDatasetItems(tenantId, projectId, datasetId, apiUrl, apiKey) {
3939
+ logger12.info({ tenantId, projectId, datasetId }, "Listing dataset items via API");
3940
+ const url = buildUrl(apiUrl, tenantId, projectId, "datasets", datasetId, "items");
3941
+ try {
3942
+ const response = await apiFetch(url, {
3943
+ method: "GET",
3944
+ headers: buildHeaders(apiKey)
3945
+ });
3946
+ if (!response.ok) {
3947
+ const errorText = await response.text();
3948
+ const errorMessage = parseError2(errorText) ?? `Failed to list dataset items: ${response.status} ${response.statusText}`;
3949
+ logger12.error(
3950
+ { status: response.status, error: errorMessage },
3951
+ "Failed to list dataset items via API"
3952
+ );
3953
+ throw new Error(errorMessage);
3954
+ }
3955
+ const result = await response.json();
3956
+ return result.data;
3957
+ } catch (error) {
3958
+ logger12.error({ error, tenantId, projectId, datasetId }, "Failed to list dataset items");
3959
+ throw error;
3960
+ }
3961
+ }
3962
+ async function getDatasetItem(tenantId, projectId, datasetId, itemId, apiUrl, apiKey) {
3963
+ logger12.info({ tenantId, projectId, datasetId, itemId }, "Getting dataset item via API");
3964
+ const url = buildUrl(apiUrl, tenantId, projectId, "datasets", datasetId, "items", itemId);
3965
+ try {
3966
+ const response = await apiFetch(url, {
3967
+ method: "GET",
3968
+ headers: buildHeaders(apiKey)
3969
+ });
3970
+ if (!response.ok) {
3971
+ if (response.status === 404) {
3972
+ logger12.info({ itemId }, "Dataset item not found");
3973
+ return null;
3974
+ }
3975
+ const errorText = await response.text();
3976
+ const errorMessage = parseError2(errorText) ?? `Failed to get dataset item: ${response.status} ${response.statusText}`;
3977
+ logger12.error(
3978
+ { status: response.status, error: errorMessage },
3979
+ "Failed to get dataset item via API"
3980
+ );
3981
+ throw new Error(errorMessage);
3982
+ }
3983
+ const result = await response.json();
3984
+ return result.data;
3985
+ } catch (error) {
3986
+ logger12.error({ error, tenantId, projectId, datasetId, itemId }, "Failed to get dataset item");
3987
+ throw error;
3988
+ }
3989
+ }
3990
+ async function createDatasetItem(tenantId, projectId, datasetId, apiUrl, itemData, apiKey) {
3991
+ logger12.info({ tenantId, projectId, datasetId }, "Creating dataset item via API");
3992
+ const url = buildUrl(apiUrl, tenantId, projectId, "datasets", datasetId, "items");
3993
+ try {
3994
+ const response = await apiFetch(url, {
3995
+ method: "POST",
3996
+ headers: buildHeaders(apiKey),
3997
+ body: JSON.stringify(itemData)
3998
+ });
3999
+ if (!response.ok) {
4000
+ const errorText = await response.text();
4001
+ const errorMessage = parseError2(errorText) ?? `Failed to create dataset item: ${response.status} ${response.statusText}`;
4002
+ logger12.error(
4003
+ { status: response.status, error: errorMessage },
4004
+ "Failed to create dataset item via API"
4005
+ );
4006
+ throw new Error(errorMessage);
4007
+ }
4008
+ const result = await response.json();
4009
+ logger12.info({ tenantId, projectId, datasetId }, "Successfully created dataset item via API");
4010
+ return result.data;
4011
+ } catch (error) {
4012
+ logger12.error({ error, tenantId, projectId, datasetId }, "Failed to create dataset item");
4013
+ throw error;
4014
+ }
4015
+ }
4016
+ async function createDatasetItems(tenantId, projectId, datasetId, apiUrl, itemsData, apiKey) {
4017
+ logger12.info(
4018
+ { tenantId, projectId, datasetId, count: itemsData.length },
4019
+ "Creating dataset items via API"
4020
+ );
4021
+ const url = buildUrl(apiUrl, tenantId, projectId, "datasets", datasetId, "items", "bulk");
4022
+ try {
4023
+ const response = await apiFetch(url, {
4024
+ method: "POST",
4025
+ headers: buildHeaders(apiKey),
4026
+ body: JSON.stringify({ items: itemsData })
4027
+ });
4028
+ if (!response.ok) {
4029
+ const errorText = await response.text();
4030
+ const errorMessage = parseError2(errorText) ?? `Failed to create dataset items: ${response.status} ${response.statusText}`;
4031
+ logger12.error(
4032
+ { status: response.status, error: errorMessage },
4033
+ "Failed to create dataset items via API"
4034
+ );
4035
+ throw new Error(errorMessage);
4036
+ }
4037
+ const result = await response.json();
4038
+ logger12.info(
4039
+ { tenantId, projectId, datasetId, count: result.data.length },
4040
+ "Successfully created dataset items via API"
4041
+ );
4042
+ return result.data;
4043
+ } catch (error) {
4044
+ logger12.error({ error, tenantId, projectId, datasetId }, "Failed to create dataset items");
4045
+ throw error;
4046
+ }
4047
+ }
4048
+ async function updateDatasetItem(tenantId, projectId, datasetId, itemId, apiUrl, updateData, apiKey) {
4049
+ logger12.info({ tenantId, projectId, datasetId, itemId }, "Updating dataset item via API");
4050
+ const url = buildUrl(apiUrl, tenantId, projectId, "datasets", datasetId, "items", itemId);
4051
+ try {
4052
+ const response = await apiFetch(url, {
4053
+ method: "PATCH",
4054
+ headers: buildHeaders(apiKey),
4055
+ body: JSON.stringify(updateData)
4056
+ });
4057
+ if (!response.ok) {
4058
+ const errorText = await response.text();
4059
+ const errorMessage = parseError2(errorText) ?? `Failed to update dataset item: ${response.status} ${response.statusText}`;
4060
+ logger12.error(
4061
+ { status: response.status, error: errorMessage },
4062
+ "Failed to update dataset item via API"
4063
+ );
4064
+ throw new Error(errorMessage);
4065
+ }
4066
+ const result = await response.json();
4067
+ logger12.info(
4068
+ { tenantId, projectId, datasetId, itemId },
4069
+ "Successfully updated dataset item via API"
4070
+ );
4071
+ return result.data;
4072
+ } catch (error) {
4073
+ logger12.error(
4074
+ { error, tenantId, projectId, datasetId, itemId },
4075
+ "Failed to update dataset item"
4076
+ );
4077
+ throw error;
4078
+ }
4079
+ }
4080
+ async function deleteDatasetItem(tenantId, projectId, datasetId, itemId, apiUrl, apiKey) {
4081
+ logger12.info({ tenantId, projectId, datasetId, itemId }, "Deleting dataset item via API");
4082
+ const url = buildUrl(apiUrl, tenantId, projectId, "datasets", datasetId, "items", itemId);
4083
+ try {
4084
+ const response = await apiFetch(url, {
4085
+ method: "DELETE",
4086
+ headers: buildHeaders(apiKey)
4087
+ });
4088
+ if (!response.ok) {
4089
+ const errorText = await response.text();
4090
+ const errorMessage = parseError2(errorText) ?? `Failed to delete dataset item: ${response.status} ${response.statusText}`;
4091
+ logger12.error(
4092
+ { status: response.status, error: errorMessage },
4093
+ "Failed to delete dataset item via API"
4094
+ );
4095
+ throw new Error(errorMessage);
4096
+ }
4097
+ logger12.info(
4098
+ { tenantId, projectId, datasetId, itemId },
4099
+ "Successfully deleted dataset item via API"
4100
+ );
4101
+ } catch (error) {
4102
+ logger12.error(
4103
+ { error, tenantId, projectId, datasetId, itemId },
4104
+ "Failed to delete dataset item"
4105
+ );
4106
+ throw error;
4107
+ }
4108
+ }
4109
+ async function listEvaluators(tenantId, projectId, apiUrl, apiKey) {
4110
+ logger12.info({ tenantId, projectId }, "Listing evaluators via API");
4111
+ const url = buildUrl(apiUrl, tenantId, projectId, "evaluators");
4112
+ try {
4113
+ const response = await apiFetch(url, {
4114
+ method: "GET",
4115
+ headers: buildHeaders(apiKey)
4116
+ });
4117
+ if (!response.ok) {
4118
+ const errorText = await response.text();
4119
+ const errorMessage = parseError2(errorText) ?? `Failed to list evaluators: ${response.status} ${response.statusText}`;
4120
+ logger12.error(
4121
+ { status: response.status, error: errorMessage },
4122
+ "Failed to list evaluators via API"
4123
+ );
4124
+ throw new Error(errorMessage);
4125
+ }
4126
+ const result = await response.json();
4127
+ return result.data;
4128
+ } catch (error) {
4129
+ logger12.error({ error, tenantId, projectId }, "Failed to list evaluators");
4130
+ throw error;
4131
+ }
4132
+ }
4133
+ async function getEvaluator(tenantId, projectId, evaluatorId, apiUrl, apiKey) {
4134
+ logger12.info({ tenantId, projectId, evaluatorId }, "Getting evaluator via API");
4135
+ const url = buildUrl(apiUrl, tenantId, projectId, "evaluators", evaluatorId);
4136
+ try {
4137
+ const response = await apiFetch(url, {
4138
+ method: "GET",
4139
+ headers: buildHeaders(apiKey)
4140
+ });
4141
+ if (!response.ok) {
4142
+ if (response.status === 404) {
4143
+ logger12.info({ evaluatorId }, "Evaluator not found");
4144
+ return null;
4145
+ }
4146
+ const errorText = await response.text();
4147
+ const errorMessage = parseError2(errorText) ?? `Failed to get evaluator: ${response.status} ${response.statusText}`;
4148
+ logger12.error(
4149
+ { status: response.status, error: errorMessage },
4150
+ "Failed to get evaluator via API"
4151
+ );
4152
+ throw new Error(errorMessage);
4153
+ }
4154
+ const result = await response.json();
4155
+ return result.data;
4156
+ } catch (error) {
4157
+ logger12.error({ error, tenantId, projectId, evaluatorId }, "Failed to get evaluator");
4158
+ throw error;
4159
+ }
4160
+ }
4161
+ async function createEvaluator(tenantId, projectId, apiUrl, evaluatorData, apiKey) {
4162
+ logger12.info({ tenantId, projectId }, "Creating evaluator via API");
4163
+ const url = buildUrl(apiUrl, tenantId, projectId, "evaluators");
4164
+ try {
4165
+ const response = await apiFetch(url, {
4166
+ method: "POST",
4167
+ headers: buildHeaders(apiKey),
4168
+ body: JSON.stringify(evaluatorData)
4169
+ });
4170
+ if (!response.ok) {
4171
+ const errorText = await response.text();
4172
+ const errorMessage = parseError2(errorText) ?? `Failed to create evaluator: ${response.status} ${response.statusText}`;
4173
+ logger12.error(
4174
+ { status: response.status, error: errorMessage },
4175
+ "Failed to create evaluator via API"
4176
+ );
4177
+ throw new Error(errorMessage);
4178
+ }
4179
+ const result = await response.json();
4180
+ logger12.info({ tenantId, projectId }, "Successfully created evaluator via API");
4181
+ return result.data;
4182
+ } catch (error) {
4183
+ logger12.error({ error, tenantId, projectId }, "Failed to create evaluator");
4184
+ throw error;
4185
+ }
4186
+ }
4187
+ async function updateEvaluator(tenantId, projectId, evaluatorId, apiUrl, updateData, apiKey) {
4188
+ logger12.info({ tenantId, projectId, evaluatorId }, "Updating evaluator via API");
4189
+ const url = buildUrl(apiUrl, tenantId, projectId, "evaluators", evaluatorId);
4190
+ try {
4191
+ const response = await apiFetch(url, {
4192
+ method: "PATCH",
4193
+ headers: buildHeaders(apiKey),
4194
+ body: JSON.stringify(updateData)
4195
+ });
4196
+ if (!response.ok) {
4197
+ const errorText = await response.text();
4198
+ const errorMessage = parseError2(errorText) ?? `Failed to update evaluator: ${response.status} ${response.statusText}`;
4199
+ logger12.error(
4200
+ { status: response.status, error: errorMessage },
4201
+ "Failed to update evaluator via API"
4202
+ );
4203
+ throw new Error(errorMessage);
4204
+ }
4205
+ const result = await response.json();
4206
+ logger12.info({ tenantId, projectId, evaluatorId }, "Successfully updated evaluator via API");
4207
+ return result.data;
4208
+ } catch (error) {
4209
+ logger12.error({ error, tenantId, projectId, evaluatorId }, "Failed to update evaluator");
4210
+ throw error;
4211
+ }
4212
+ }
4213
+ async function deleteEvaluator(tenantId, projectId, evaluatorId, apiUrl, apiKey) {
4214
+ logger12.info({ tenantId, projectId, evaluatorId }, "Deleting evaluator via API");
4215
+ const url = buildUrl(apiUrl, tenantId, projectId, "evaluators", evaluatorId);
4216
+ try {
4217
+ const response = await apiFetch(url, {
4218
+ method: "DELETE",
4219
+ headers: buildHeaders(apiKey)
4220
+ });
4221
+ if (!response.ok) {
4222
+ const errorText = await response.text();
4223
+ const errorMessage = parseError2(errorText) ?? `Failed to delete evaluator: ${response.status} ${response.statusText}`;
4224
+ logger12.error(
4225
+ { status: response.status, error: errorMessage },
4226
+ "Failed to delete evaluator via API"
4227
+ );
4228
+ throw new Error(errorMessage);
4229
+ }
4230
+ logger12.info({ tenantId, projectId, evaluatorId }, "Successfully deleted evaluator via API");
4231
+ } catch (error) {
4232
+ logger12.error({ error, tenantId, projectId, evaluatorId }, "Failed to delete evaluator");
4233
+ throw error;
4234
+ }
4235
+ }
4236
+ async function listEvaluationSuiteConfigs(tenantId, projectId, apiUrl, apiKey) {
4237
+ logger12.info({ tenantId, projectId }, "Listing evaluation suite configs via API");
4238
+ const url = buildUrl(apiUrl, tenantId, projectId, "evaluation-suite-configs");
4239
+ try {
4240
+ const response = await apiFetch(url, {
4241
+ method: "GET",
4242
+ headers: buildHeaders(apiKey)
4243
+ });
4244
+ if (!response.ok) {
4245
+ const errorText = await response.text();
4246
+ const errorMessage = parseError2(errorText) ?? `Failed to list evaluation suite configs: ${response.status} ${response.statusText}`;
4247
+ logger12.error(
4248
+ { status: response.status, error: errorMessage },
4249
+ "Failed to list evaluation suite configs via API"
4250
+ );
4251
+ throw new Error(errorMessage);
4252
+ }
4253
+ const result = await response.json();
4254
+ return result.data;
4255
+ } catch (error) {
4256
+ logger12.error({ error, tenantId, projectId }, "Failed to list evaluation suite configs");
4257
+ throw error;
4258
+ }
4259
+ }
4260
+ async function getEvaluationSuiteConfig(tenantId, projectId, configId, apiUrl, apiKey) {
4261
+ logger12.info({ tenantId, projectId, configId }, "Getting evaluation suite config via API");
4262
+ const url = buildUrl(apiUrl, tenantId, projectId, "evaluation-suite-configs", configId);
4263
+ try {
4264
+ const response = await apiFetch(url, {
4265
+ method: "GET",
4266
+ headers: buildHeaders(apiKey)
4267
+ });
4268
+ if (!response.ok) {
4269
+ if (response.status === 404) {
4270
+ logger12.info({ configId }, "Evaluation suite config not found");
4271
+ return null;
4272
+ }
4273
+ const errorText = await response.text();
4274
+ const errorMessage = parseError2(errorText) ?? `Failed to get evaluation suite config: ${response.status} ${response.statusText}`;
4275
+ logger12.error(
4276
+ { status: response.status, error: errorMessage },
4277
+ "Failed to get evaluation suite config via API"
4278
+ );
4279
+ throw new Error(errorMessage);
4280
+ }
4281
+ const result = await response.json();
4282
+ return result.data;
4283
+ } catch (error) {
4284
+ logger12.error({ error, tenantId, projectId, configId }, "Failed to get evaluation suite config");
4285
+ throw error;
4286
+ }
4287
+ }
4288
+ async function createEvaluationSuiteConfig(tenantId, projectId, apiUrl, configData, apiKey) {
4289
+ logger12.info({ tenantId, projectId }, "Creating evaluation suite config via API");
4290
+ const url = buildUrl(apiUrl, tenantId, projectId, "evaluation-suite-configs");
4291
+ try {
4292
+ const response = await apiFetch(url, {
4293
+ method: "POST",
4294
+ headers: buildHeaders(apiKey),
4295
+ body: JSON.stringify(configData)
4296
+ });
4297
+ if (!response.ok) {
4298
+ const errorText = await response.text();
4299
+ const errorMessage = parseError2(errorText) ?? `Failed to create evaluation suite config: ${response.status} ${response.statusText}`;
4300
+ logger12.error(
4301
+ { status: response.status, error: errorMessage },
4302
+ "Failed to create evaluation suite config via API"
4303
+ );
4304
+ throw new Error(errorMessage);
4305
+ }
4306
+ const result = await response.json();
4307
+ logger12.info({ tenantId, projectId }, "Successfully created evaluation suite config via API");
4308
+ return result.data;
4309
+ } catch (error) {
4310
+ logger12.error({ error, tenantId, projectId }, "Failed to create evaluation suite config");
4311
+ throw error;
4312
+ }
4313
+ }
4314
+ async function updateEvaluationSuiteConfig(tenantId, projectId, configId, apiUrl, updateData, apiKey) {
4315
+ logger12.info({ tenantId, projectId, configId }, "Updating evaluation suite config via API");
4316
+ const url = buildUrl(apiUrl, tenantId, projectId, "evaluation-suite-configs", configId);
4317
+ try {
4318
+ const response = await apiFetch(url, {
4319
+ method: "PATCH",
4320
+ headers: buildHeaders(apiKey),
4321
+ body: JSON.stringify(updateData)
4322
+ });
4323
+ if (!response.ok) {
4324
+ const errorText = await response.text();
4325
+ const errorMessage = parseError2(errorText) ?? `Failed to update evaluation suite config: ${response.status} ${response.statusText}`;
4326
+ logger12.error(
4327
+ { status: response.status, error: errorMessage },
4328
+ "Failed to update evaluation suite config via API"
4329
+ );
4330
+ throw new Error(errorMessage);
4331
+ }
4332
+ const result = await response.json();
4333
+ logger12.info(
4334
+ { tenantId, projectId, configId },
4335
+ "Successfully updated evaluation suite config via API"
4336
+ );
4337
+ return result.data;
4338
+ } catch (error) {
4339
+ logger12.error(
4340
+ { error, tenantId, projectId, configId },
4341
+ "Failed to update evaluation suite config"
4342
+ );
4343
+ throw error;
4344
+ }
4345
+ }
4346
+ async function deleteEvaluationSuiteConfig(tenantId, projectId, configId, apiUrl, apiKey) {
4347
+ logger12.info({ tenantId, projectId, configId }, "Deleting evaluation suite config via API");
4348
+ const url = buildUrl(apiUrl, tenantId, projectId, "evaluation-suite-configs", configId);
4349
+ try {
4350
+ const response = await apiFetch(url, {
4351
+ method: "DELETE",
4352
+ headers: buildHeaders(apiKey)
4353
+ });
4354
+ if (!response.ok) {
4355
+ const errorText = await response.text();
4356
+ const errorMessage = parseError2(errorText) ?? `Failed to delete evaluation suite config: ${response.status} ${response.statusText}`;
4357
+ logger12.error(
4358
+ { status: response.status, error: errorMessage },
4359
+ "Failed to delete evaluation suite config via API"
4360
+ );
4361
+ throw new Error(errorMessage);
4362
+ }
4363
+ logger12.info(
4364
+ { tenantId, projectId, configId },
4365
+ "Successfully deleted evaluation suite config via API"
4366
+ );
4367
+ } catch (error) {
4368
+ logger12.error(
4369
+ { error, tenantId, projectId, configId },
4370
+ "Failed to delete evaluation suite config"
4371
+ );
4372
+ throw error;
4373
+ }
4374
+ }
4375
+ async function listEvaluationSuiteConfigEvaluators(tenantId, projectId, configId, apiUrl, apiKey) {
4376
+ logger12.info(
4377
+ { tenantId, projectId, configId },
4378
+ "Listing evaluators for evaluation suite config via API"
4379
+ );
4380
+ const url = buildUrl(
4381
+ apiUrl,
4382
+ tenantId,
4383
+ projectId,
4384
+ "evaluation-suite-configs",
4385
+ configId,
4386
+ "evaluators"
4387
+ );
4388
+ try {
4389
+ const response = await apiFetch(url, {
4390
+ method: "GET",
4391
+ headers: buildHeaders(apiKey)
4392
+ });
4393
+ if (!response.ok) {
4394
+ const errorText = await response.text();
4395
+ const errorMessage = parseError2(errorText) ?? `Failed to list evaluators for evaluation suite config: ${response.status} ${response.statusText}`;
4396
+ logger12.error(
4397
+ { status: response.status, error: errorMessage },
4398
+ "Failed to list evaluators for evaluation suite config via API"
4399
+ );
4400
+ throw new Error(errorMessage);
4401
+ }
4402
+ const result = await response.json();
4403
+ return result.data;
4404
+ } catch (error) {
4405
+ logger12.error(
4406
+ { error, tenantId, projectId, configId },
4407
+ "Failed to list evaluators for evaluation suite config"
4408
+ );
4409
+ throw error;
4410
+ }
4411
+ }
4412
+ async function addEvaluatorToSuiteConfig(tenantId, projectId, configId, evaluatorId, apiUrl, apiKey) {
4413
+ logger12.info(
4414
+ { tenantId, projectId, configId, evaluatorId },
4415
+ "Adding evaluator to evaluation suite config via API"
4416
+ );
4417
+ const url = buildUrl(
4418
+ apiUrl,
4419
+ tenantId,
4420
+ projectId,
4421
+ "evaluation-suite-configs",
4422
+ configId,
4423
+ "evaluators",
4424
+ evaluatorId
4425
+ );
4426
+ try {
4427
+ const response = await apiFetch(url, {
4428
+ method: "POST",
4429
+ headers: buildHeaders(apiKey)
4430
+ });
4431
+ if (!response.ok) {
4432
+ const errorText = await response.text();
4433
+ const errorMessage = parseError2(errorText) ?? `Failed to add evaluator to evaluation suite config: ${response.status} ${response.statusText}`;
4434
+ logger12.error(
4435
+ { status: response.status, error: errorMessage },
4436
+ "Failed to add evaluator to evaluation suite config via API"
4437
+ );
4438
+ throw new Error(errorMessage);
4439
+ }
4440
+ const result = await response.json();
4441
+ logger12.info(
4442
+ { tenantId, projectId, configId, evaluatorId },
4443
+ "Successfully added evaluator to evaluation suite config via API"
4444
+ );
4445
+ return result.data;
4446
+ } catch (error) {
4447
+ logger12.error(
4448
+ { error, tenantId, projectId, configId, evaluatorId },
4449
+ "Failed to add evaluator to evaluation suite config"
4450
+ );
4451
+ throw error;
4452
+ }
4453
+ }
4454
+ async function removeEvaluatorFromSuiteConfig(tenantId, projectId, configId, evaluatorId, apiUrl, apiKey) {
4455
+ logger12.info(
4456
+ { tenantId, projectId, configId, evaluatorId },
4457
+ "Removing evaluator from evaluation suite config via API"
4458
+ );
4459
+ const url = buildUrl(
4460
+ apiUrl,
4461
+ tenantId,
4462
+ projectId,
4463
+ "evaluation-suite-configs",
4464
+ configId,
4465
+ "evaluators",
4466
+ evaluatorId
4467
+ );
4468
+ try {
4469
+ const response = await apiFetch(url, {
4470
+ method: "DELETE",
4471
+ headers: buildHeaders(apiKey)
4472
+ });
4473
+ if (!response.ok) {
4474
+ const errorText = await response.text();
4475
+ const errorMessage = parseError2(errorText) ?? `Failed to remove evaluator from evaluation suite config: ${response.status} ${response.statusText}`;
4476
+ logger12.error(
4477
+ { status: response.status, error: errorMessage },
4478
+ "Failed to remove evaluator from evaluation suite config via API"
4479
+ );
4480
+ throw new Error(errorMessage);
4481
+ }
4482
+ logger12.info(
4483
+ { tenantId, projectId, configId, evaluatorId },
4484
+ "Successfully removed evaluator from evaluation suite config via API"
4485
+ );
4486
+ } catch (error) {
4487
+ logger12.error(
4488
+ { error, tenantId, projectId, configId, evaluatorId },
4489
+ "Failed to remove evaluator from evaluation suite config"
4490
+ );
4491
+ throw error;
4492
+ }
4493
+ }
4494
+ async function getEvaluationResult(tenantId, projectId, resultId, apiUrl, apiKey) {
4495
+ logger12.info({ tenantId, projectId, resultId }, "Getting evaluation result via API");
4496
+ const url = buildUrl(apiUrl, tenantId, projectId, "evaluation-results", resultId);
4497
+ try {
4498
+ const response = await apiFetch(url, {
4499
+ method: "GET",
4500
+ headers: buildHeaders(apiKey)
4501
+ });
4502
+ if (!response.ok) {
4503
+ if (response.status === 404) {
4504
+ logger12.info({ resultId }, "Evaluation result not found");
4505
+ return null;
4506
+ }
4507
+ const errorText = await response.text();
4508
+ const errorMessage = parseError2(errorText) ?? `Failed to get evaluation result: ${response.status} ${response.statusText}`;
4509
+ logger12.error(
4510
+ { status: response.status, error: errorMessage },
4511
+ "Failed to get evaluation result via API"
4512
+ );
4513
+ throw new Error(errorMessage);
4514
+ }
4515
+ const result = await response.json();
4516
+ return result.data;
4517
+ } catch (error) {
4518
+ logger12.error({ error, tenantId, projectId, resultId }, "Failed to get evaluation result");
4519
+ throw error;
4520
+ }
4521
+ }
4522
+ async function createEvaluationResult(tenantId, projectId, apiUrl, resultData, apiKey) {
4523
+ logger12.info({ tenantId, projectId }, "Creating evaluation result via API");
4524
+ const url = buildUrl(apiUrl, tenantId, projectId, "evaluation-results");
4525
+ try {
4526
+ const response = await apiFetch(url, {
4527
+ method: "POST",
4528
+ headers: buildHeaders(apiKey),
4529
+ body: JSON.stringify(resultData)
4530
+ });
4531
+ if (!response.ok) {
4532
+ const errorText = await response.text();
4533
+ const errorMessage = parseError2(errorText) ?? `Failed to create evaluation result: ${response.status} ${response.statusText}`;
4534
+ logger12.error(
4535
+ { status: response.status, error: errorMessage },
4536
+ "Failed to create evaluation result via API"
4537
+ );
4538
+ throw new Error(errorMessage);
4539
+ }
4540
+ const result = await response.json();
4541
+ logger12.info({ tenantId, projectId }, "Successfully created evaluation result via API");
4542
+ return result.data;
4543
+ } catch (error) {
4544
+ logger12.error({ error, tenantId, projectId }, "Failed to create evaluation result");
4545
+ throw error;
4546
+ }
4547
+ }
4548
+ async function updateEvaluationResult(tenantId, projectId, resultId, apiUrl, updateData, apiKey) {
4549
+ logger12.info({ tenantId, projectId, resultId }, "Updating evaluation result via API");
4550
+ const url = buildUrl(apiUrl, tenantId, projectId, "evaluation-results", resultId);
4551
+ try {
4552
+ const response = await apiFetch(url, {
4553
+ method: "PATCH",
4554
+ headers: buildHeaders(apiKey),
4555
+ body: JSON.stringify(updateData)
4556
+ });
4557
+ if (!response.ok) {
4558
+ const errorText = await response.text();
4559
+ const errorMessage = parseError2(errorText) ?? `Failed to update evaluation result: ${response.status} ${response.statusText}`;
4560
+ logger12.error(
4561
+ { status: response.status, error: errorMessage },
4562
+ "Failed to update evaluation result via API"
4563
+ );
4564
+ throw new Error(errorMessage);
4565
+ }
4566
+ const result = await response.json();
4567
+ logger12.info(
4568
+ { tenantId, projectId, resultId },
4569
+ "Successfully updated evaluation result via API"
4570
+ );
4571
+ return result.data;
4572
+ } catch (error) {
4573
+ logger12.error({ error, tenantId, projectId, resultId }, "Failed to update evaluation result");
4574
+ throw error;
4575
+ }
4576
+ }
4577
+ async function deleteEvaluationResult(tenantId, projectId, resultId, apiUrl, apiKey) {
4578
+ logger12.info({ tenantId, projectId, resultId }, "Deleting evaluation result via API");
4579
+ const url = buildUrl(apiUrl, tenantId, projectId, "evaluation-results", resultId);
4580
+ try {
4581
+ const response = await apiFetch(url, {
4582
+ method: "DELETE",
4583
+ headers: buildHeaders(apiKey)
4584
+ });
4585
+ if (!response.ok) {
4586
+ const errorText = await response.text();
4587
+ const errorMessage = parseError2(errorText) ?? `Failed to delete evaluation result: ${response.status} ${response.statusText}`;
4588
+ logger12.error(
4589
+ { status: response.status, error: errorMessage },
4590
+ "Failed to delete evaluation result via API"
4591
+ );
4592
+ throw new Error(errorMessage);
4593
+ }
4594
+ logger12.info(
4595
+ { tenantId, projectId, resultId },
4596
+ "Successfully deleted evaluation result via API"
4597
+ );
4598
+ } catch (error) {
4599
+ logger12.error({ error, tenantId, projectId, resultId }, "Failed to delete evaluation result");
4600
+ throw error;
4601
+ }
4602
+ }
4603
+ var logger13 = getLogger("external-agent-builder");
4604
+ var ExternalAgent = class {
4605
+ constructor(config) {
4606
+ __publicField(this, "config");
4607
+ __publicField(this, "type", "external");
4608
+ __publicField(this, "initialized", false);
4609
+ __publicField(this, "tenantId");
4610
+ __publicField(this, "projectId");
4611
+ __publicField(this, "baseURL");
4612
+ this.config = { ...config, type: "external" };
4613
+ this.tenantId = "default";
4614
+ this.projectId = "default";
4615
+ this.baseURL = this.config.baseUrl;
4616
+ logger13.debug(
4617
+ {
4618
+ externalAgentName: this.config.name,
4619
+ baseUrl: this.config.baseUrl,
4620
+ tenantId: this.tenantId
4621
+ },
4622
+ "External Agent constructor initialized"
4623
+ );
4624
+ }
4625
+ /**
4626
+ * Initialize the external agent by upserting it in the database
4627
+ */
4628
+ async init() {
4629
+ if (this.initialized) return;
4630
+ try {
4631
+ await this.upsertExternalAgent();
4632
+ logger13.info(
4633
+ {
4634
+ externalSubAgentId: this.getId()
4635
+ },
4636
+ "External agent initialized successfully"
4637
+ );
4638
+ this.initialized = true;
4639
+ } catch (error) {
4640
+ logger13.error(
4641
+ {
4642
+ externalSubAgentId: this.getId(),
4643
+ error: error instanceof Error ? error.message : "Unknown error"
4644
+ },
4645
+ "Failed to initialize external agent"
4646
+ );
4647
+ throw error;
4648
+ }
4649
+ }
4650
+ // Set context (tenantId and baseURL) from external source (agent, CLI, etc)
4651
+ setContext(tenantId, projectId) {
4652
+ this.tenantId = tenantId;
4653
+ this.projectId = projectId;
4654
+ }
4655
+ // Compute ID from name using a simple slug transformation
4656
+ getId() {
4657
+ return this.config.id;
4658
+ }
4659
+ with(options) {
4660
+ return {
4661
+ externalAgent: this,
4662
+ headers: options.headers
4663
+ };
4664
+ }
4665
+ // Private method to upsert external agent (create or update)
4666
+ async upsertExternalAgent() {
4667
+ const externalAgentData = {
4668
+ id: this.getId(),
4669
+ name: this.config.name,
4670
+ description: this.config.description,
4671
+ baseUrl: this.config.baseUrl,
4672
+ credentialReferenceId: this.config.credentialReference?.id || void 0
4673
+ };
4674
+ const updateResponse = await fetch(
4675
+ `${this.baseURL}/tenants/${this.tenantId}/projects/${this.projectId}/external-agents/${this.getId()}`,
4676
+ {
4677
+ method: "PUT",
4678
+ headers: {
4679
+ "Content-Type": "application/json"
4680
+ },
4681
+ body: JSON.stringify(externalAgentData)
4682
+ }
4683
+ );
4684
+ if (updateResponse.ok) {
4685
+ logger13.info(
4686
+ {
4687
+ externalSubAgentId: this.getId()
4688
+ },
4689
+ "External agent updated successfully"
4690
+ );
4691
+ return;
4692
+ }
4693
+ if (updateResponse.status === 404) {
4694
+ logger13.info(
4695
+ {
4696
+ externalSubAgentId: this.getId()
4697
+ },
4698
+ "External agent not found, creating new external agent"
4699
+ );
4700
+ const createResponse = await fetch(
4701
+ `${this.baseURL}/tenants/${this.tenantId}/projects/${this.projectId}/external-agents`,
4702
+ {
4703
+ method: "POST",
4704
+ headers: {
4705
+ "Content-Type": "application/json"
4706
+ },
4707
+ body: JSON.stringify(externalAgentData)
4708
+ }
4709
+ );
4710
+ if (!createResponse.ok) {
4711
+ const errorText2 = await createResponse.text().catch(() => "Unknown error");
4712
+ throw new Error(
4713
+ `Failed to create external agent: ${createResponse.status} ${createResponse.statusText} - ${errorText2}`
4714
+ );
4715
+ }
4716
+ logger13.info(
4717
+ {
4718
+ externalSubAgentId: this.getId()
4719
+ },
4720
+ "External agent created successfully"
4721
+ );
4722
+ return;
4723
+ }
4724
+ const errorText = await updateResponse.text().catch(() => "Unknown error");
4725
+ throw new Error(
4726
+ `Failed to update external agent: ${updateResponse.status} ${updateResponse.statusText} - ${errorText}`
4727
+ );
4728
+ }
4729
+ /**
4730
+ * Get the external agent configuration
4731
+ */
4732
+ getConfig() {
4733
+ return { ...this.config };
4734
+ }
4735
+ /**
4736
+ * Get the external agent name
4737
+ */
4738
+ getName() {
4739
+ return this.config.name;
4740
+ }
4741
+ /**
4742
+ * Get the external agent base URL
4743
+ */
4744
+ getBaseUrl() {
4745
+ return this.config.baseUrl;
4746
+ }
4747
+ /**
4748
+ * Get the tenant ID
4749
+ */
4750
+ getTenantId() {
4751
+ return this.tenantId;
4752
+ }
4753
+ getDescription() {
4754
+ return this.config.description || "";
4755
+ }
4756
+ getCredentialReferenceId() {
4757
+ return this.config.credentialReference?.id || void 0;
4758
+ }
4759
+ getCredentialReference() {
4760
+ return this.config.credentialReference || void 0;
4761
+ }
4762
+ };
4763
+ function externalAgent(config) {
4764
+ return new ExternalAgent(config);
4765
+ }
4766
+ function externalAgents(configs) {
4767
+ const builders = {};
4768
+ for (const [name, config] of Object.entries(configs)) {
4769
+ builders[name] = externalAgent(config);
4770
+ }
4771
+ return builders;
4772
+ }
4773
+
4774
+ // src/types.ts
4775
+ var AgentError = class extends Error {
4776
+ constructor(message, code, details) {
4777
+ super(message);
4778
+ this.code = code;
4779
+ this.details = details;
4780
+ this.name = "AgentError";
4781
+ }
4782
+ };
4783
+ var MaxTurnsExceededError = class extends AgentError {
4784
+ constructor(maxTurns) {
4785
+ super(`Maximum turns (${maxTurns}) exceeded`);
4786
+ this.code = "MAX_TURNS_EXCEEDED";
4787
+ }
4788
+ };
4789
+
4790
+ // src/runner.ts
4791
+ var logger14 = getLogger("runner");
4792
+ var Runner = class _Runner {
4793
+ /**
4794
+ * Run an agent until completion, handling transfers and tool calls
4795
+ * Similar to OpenAI's Runner.run() pattern
4796
+ * NOTE: This now requires an agent instead of an agent
4797
+ */
4798
+ static async run(agent2, messages, options) {
4799
+ const maxTurns = options?.maxTurns || 10;
4800
+ let turnCount = 0;
4801
+ const messageHistory = _Runner.normalizeToMessageHistory(messages);
4802
+ const allToolCalls = [];
4803
+ logger14.info(
4804
+ {
4805
+ agentId: agent2.getId(),
4806
+ defaultSubAgent: agent2.getDefaultSubAgent()?.getName(),
4807
+ maxTurns,
4808
+ initialMessageCount: messageHistory.length
4809
+ },
4810
+ "Starting agent run"
4811
+ );
4812
+ while (turnCount < maxTurns) {
4813
+ logger14.debug(
4814
+ {
4815
+ agentId: agent2.getId(),
4816
+ turnCount,
4817
+ messageHistoryLength: messageHistory.length
4818
+ },
4819
+ "Starting turn"
4820
+ );
4821
+ const response = await agent2.generate(messageHistory, options);
4822
+ turnCount++;
4823
+ logger14.info(
4824
+ {
4825
+ agentId: agent2.getId(),
4826
+ turnCount,
4827
+ responseLength: response.length
4828
+ },
4829
+ "Agent generation completed"
4830
+ );
4831
+ return {
4832
+ finalOutput: response,
4833
+ agent: agent2.getDefaultSubAgent() || {},
4834
+ turnCount,
4835
+ usage: { inputTokens: 0, outputTokens: 0 },
4836
+ metadata: {
4837
+ toolCalls: allToolCalls,
4838
+ transfers: []
4839
+ // Agent handles transfers internally
4840
+ }
4841
+ };
4842
+ }
4843
+ logger14.error(
4844
+ {
4845
+ agentId: agent2.getId(),
4846
+ maxTurns,
4847
+ finalTurnCount: turnCount
4848
+ },
4849
+ "Maximum turns exceeded"
4850
+ );
4851
+ throw new MaxTurnsExceededError(maxTurns);
4852
+ }
4853
+ /**
4854
+ * Stream an agent's response
4855
+ */
4856
+ static async stream(agent2, messages, options) {
4857
+ logger14.info(
4858
+ {
4859
+ agentId: agent2.getId(),
4860
+ defaultSubAgent: agent2.getDefaultSubAgent()?.getName()
4861
+ },
4862
+ "Starting agent stream"
4863
+ );
4864
+ return agent2.stream(messages, options);
4865
+ }
4866
+ /**
4867
+ * Execute multiple agent in parallel and return the first successful result
4868
+ */
4869
+ static async raceAgents(agent2, messages, options) {
4870
+ if (agent2.length === 0) {
4871
+ throw new Error("No agent provided for race");
4872
+ }
4873
+ logger14.info(
4874
+ {
4875
+ agentCount: agent2.length,
4876
+ agentIds: agent2.map((g) => g.getId())
4877
+ },
4878
+ "Starting agent race"
4879
+ );
4880
+ const promises = agent2.map(async (agent3, index) => {
4881
+ try {
4882
+ const result2 = await _Runner.run(agent3, messages, options);
4883
+ return { ...result2, raceIndex: index };
4884
+ } catch (error) {
4885
+ logger14.error(
4886
+ {
4887
+ agentId: agent3.getId(),
4888
+ error: error instanceof Error ? error.message : "Unknown error"
4889
+ },
4890
+ "Agent failed in race"
4891
+ );
4892
+ throw error;
4893
+ }
4894
+ });
4895
+ const result = await Promise.race(promises);
4896
+ logger14.info(
4897
+ {
4898
+ winningAgentId: result.agentId || "unknown",
4899
+ raceIndex: result.raceIndex
4900
+ },
4901
+ "Agent race completed"
4902
+ );
4903
+ return result;
4904
+ }
4905
+ // Private helper methods
4906
+ static normalizeToMessageHistory(messages) {
4907
+ if (typeof messages === "string") {
4908
+ return [{ role: "user", content: messages }];
4909
+ }
4910
+ if (Array.isArray(messages)) {
4911
+ return messages.map(
4912
+ (msg) => typeof msg === "string" ? { role: "user", content: msg } : msg
4913
+ );
4914
+ }
4915
+ return [messages];
4916
+ }
4917
+ /**
4918
+ * Validate agent configuration before running
4919
+ */
4920
+ static validateAgent(agent2) {
4921
+ const errors = [];
4922
+ if (!agent2.getId()) {
4923
+ errors.push("Agent ID is required");
4924
+ }
4925
+ const defaultSubAgent = agent2.getDefaultSubAgent();
4926
+ if (!defaultSubAgent) {
4927
+ errors.push("Default agent is required");
4928
+ } else {
4929
+ if (!defaultSubAgent.getName()) {
4930
+ errors.push("Default agent name is required");
4931
+ }
4932
+ if (!defaultSubAgent.getInstructions()) {
4933
+ errors.push("Default agent instructions are required");
4934
+ }
4935
+ }
4936
+ const subAgents = agent2.getSubAgents();
4937
+ if (subAgents.length === 0) {
4938
+ errors.push("Agent must contain at least one subagent");
4939
+ }
4940
+ for (const subAgent2 of subAgents) {
4941
+ if (!subAgent2.getName()) {
4942
+ errors.push(`Agent missing name`);
4943
+ }
4944
+ }
4945
+ return {
4946
+ valid: errors.length === 0,
4947
+ errors
4948
+ };
4949
+ }
4950
+ /**
4951
+ * Get execution statistics for an agent
4952
+ */
4953
+ static async getExecutionStats(agent2, messages, options) {
4954
+ const subAgents = agent2.getSubAgents();
4955
+ const defaultSubAgent = agent2.getDefaultSubAgent();
4956
+ const messageCount = Array.isArray(messages) ? messages.length : 1;
4957
+ return {
4958
+ estimatedTurns: Math.min(Math.max(messageCount, 1), options?.maxTurns || 10),
4959
+ estimatedTokens: messageCount * 100,
4960
+ // Rough estimate
4961
+ subAgentCount: subAgents.length,
4962
+ defaultSubAgent: defaultSubAgent?.getName()
4963
+ };
4964
+ }
4965
+ };
4966
+ var run = Runner.run.bind(Runner);
4967
+ var stream = Runner.stream.bind(Runner);
4968
+ var raceAgents = Runner.raceAgents.bind(Runner);
4969
+
4970
+ export { ArtifactComponent, DataComponent, ExternalAgent, FunctionTool, Project, Runner, StatusComponent, SubAgent, Tool, addEvaluatorToSuiteConfig, agent, agentMcp, artifactComponent, createDataset, createDatasetItem, createDatasetItems, createEnvironmentSettings, createEvaluationResult, createEvaluationSuiteConfig, createEvaluator, createFullProjectViaAPI, credential, credentialRef, dataComponent, deleteDataset, deleteDatasetItem, deleteEvaluationResult, deleteEvaluationSuiteConfig, deleteEvaluator, deleteFullProjectViaAPI, externalAgent, externalAgents, functionTool, getDataset, getDatasetItem, getEvaluationResult, getEvaluationSuiteConfig, getEvaluator, getFullProjectViaAPI, isCredentialReference, listDatasetItems, listDatasets, listEvaluationSuiteConfigEvaluators, listEvaluationSuiteConfigs, listEvaluators, mcpServer, mcpTool, project, raceAgents, registerEnvironmentSettings, removeEvaluatorFromSuiteConfig, run, statusComponent, stream, subAgent, transfer, updateDataset, updateDatasetItem, updateEvaluationResult, updateEvaluationSuiteConfig, updateEvaluator, updateFullProjectViaAPI };