@inkeep/agents-cli 0.39.5 → 0.41.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/_virtual/rolldown_runtime.js +7 -0
- package/dist/api.js +185 -0
- package/dist/commands/add.js +139 -0
- package/dist/commands/config.js +86 -0
- package/dist/commands/dev.js +259 -0
- package/dist/commands/init.js +360 -0
- package/dist/commands/list-agents.js +56 -0
- package/dist/commands/login.js +179 -0
- package/dist/commands/logout.js +56 -0
- package/dist/commands/profile.js +276 -0
- package/dist/{component-parser2.js → commands/pull-v3/component-parser.js} +16 -3
- package/dist/commands/pull-v3/component-updater.js +710 -0
- package/dist/commands/pull-v3/components/agent-generator.js +241 -0
- package/dist/commands/pull-v3/components/artifact-component-generator.js +143 -0
- package/dist/commands/pull-v3/components/context-config-generator.js +190 -0
- package/dist/commands/pull-v3/components/credential-generator.js +89 -0
- package/dist/commands/pull-v3/components/data-component-generator.js +102 -0
- package/dist/commands/pull-v3/components/environment-generator.js +170 -0
- package/dist/commands/pull-v3/components/external-agent-generator.js +75 -0
- package/dist/commands/pull-v3/components/function-tool-generator.js +94 -0
- package/dist/commands/pull-v3/components/mcp-tool-generator.js +86 -0
- package/dist/commands/pull-v3/components/project-generator.js +145 -0
- package/dist/commands/pull-v3/components/status-component-generator.js +92 -0
- package/dist/commands/pull-v3/components/sub-agent-generator.js +285 -0
- package/dist/commands/pull-v3/index.js +510 -0
- package/dist/commands/pull-v3/introspect-generator.js +278 -0
- package/dist/commands/pull-v3/llm-content-merger.js +192 -0
- package/dist/{new-component-generator.js → commands/pull-v3/new-component-generator.js} +14 -3
- package/dist/commands/pull-v3/project-comparator.js +914 -0
- package/dist/{project-index-generator.js → commands/pull-v3/project-index-generator.js} +1 -2
- package/dist/{project-validator.js → commands/pull-v3/project-validator.js} +4 -4
- package/dist/commands/pull-v3/targeted-typescript-placeholders.js +173 -0
- package/dist/commands/pull-v3/utils/component-registry.js +369 -0
- package/dist/commands/pull-v3/utils/component-tracker.js +165 -0
- package/dist/commands/pull-v3/utils/generator-utils.js +146 -0
- package/dist/commands/pull-v3/utils/model-provider-detector.js +44 -0
- package/dist/commands/push.js +326 -0
- package/dist/commands/status.js +89 -0
- package/dist/commands/update.js +97 -0
- package/dist/commands/whoami.js +38 -0
- package/dist/config.js +0 -1
- package/dist/env.js +30 -0
- package/dist/exports.js +3 -0
- package/dist/index.js +28 -196514
- package/dist/instrumentation.js +47 -0
- package/dist/types/agent.js +1 -0
- package/dist/types/tsx.d.d.ts +1 -0
- package/dist/utils/background-version-check.js +19 -0
- package/dist/utils/ci-environment.js +87 -0
- package/dist/utils/cli-pipeline.js +158 -0
- package/dist/utils/config.js +290 -0
- package/dist/utils/credentials.js +132 -0
- package/dist/utils/environment-loader.js +28 -0
- package/dist/utils/file-finder.js +62 -0
- package/dist/utils/json-comparator.js +185 -0
- package/dist/utils/json-comparison.js +232 -0
- package/dist/utils/mcp-runner.js +120 -0
- package/dist/utils/model-config.js +182 -0
- package/dist/utils/package-manager.js +58 -0
- package/dist/utils/profile-config.js +85 -0
- package/dist/utils/profiles/index.js +4 -0
- package/dist/utils/profiles/profile-manager.js +219 -0
- package/dist/utils/profiles/types.js +62 -0
- package/dist/utils/project-directory.js +33 -0
- package/dist/utils/project-loader.js +29 -0
- package/dist/utils/schema-introspection.js +44 -0
- package/dist/utils/templates.js +198 -0
- package/dist/utils/tsx-loader.js +27 -0
- package/dist/utils/url.js +26 -0
- package/dist/utils/version-check.js +79 -0
- package/package.json +9 -24
- package/dist/component-parser.js +0 -4
- package/dist/component-updater.js +0 -4
- package/dist/config2.js +0 -4
- package/dist/credential-stores.js +0 -4
- package/dist/environment-generator.js +0 -4
- package/dist/nodefs.js +0 -27
- package/dist/opfs-ahp.js +0 -368
- package/dist/project-loader.js +0 -4
- package/dist/tsx-loader.js +0 -4
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
1
|
+
import { buildComponentRegistryFromParsing } from "./component-parser.js";
|
|
2
|
+
import { compareProjects } from "./project-comparator.js";
|
|
3
|
+
import { enrichCanDelegateToWithTypes } from "./index.js";
|
|
4
4
|
import { copyFileSync, existsSync, mkdirSync, readdirSync, rmSync, statSync } from "node:fs";
|
|
5
5
|
import { dirname, join } from "node:path";
|
|
6
6
|
import chalk from "chalk";
|
|
@@ -138,7 +138,7 @@ function getComponentFromProject(project, componentType, componentId) {
|
|
|
138
138
|
*/
|
|
139
139
|
async function validateProjectEquivalence(tempDir, remoteProject) {
|
|
140
140
|
try {
|
|
141
|
-
const { loadProject } = await import("
|
|
141
|
+
const { loadProject } = await import("../../utils/project-loader.js");
|
|
142
142
|
const tempProject = await loadProject(tempDir);
|
|
143
143
|
const tempProjectDefinition = await Promise.race([tempProject.getFullDefinition(), new Promise((_, reject) => {
|
|
144
144
|
setTimeout(() => {
|
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
import { randomBytes } from "node:crypto";
|
|
2
|
+
import { Node, Project } from "ts-morph";
|
|
3
|
+
|
|
4
|
+
//#region src/commands/pull-v3/targeted-typescript-placeholders.ts
|
|
5
|
+
/**
|
|
6
|
+
* Targeted TypeScript Placeholder System
|
|
7
|
+
*
|
|
8
|
+
* Uses AST parsing to intelligently identify large content blocks for replacement:
|
|
9
|
+
* - prompt: (template literals or strings)
|
|
10
|
+
* - description: (string literals)
|
|
11
|
+
* - inputSchema: (object literals)
|
|
12
|
+
* - detailsSchema: (object literals)
|
|
13
|
+
* - props: (object literals in artifact/data components)
|
|
14
|
+
*/
|
|
15
|
+
/**
|
|
16
|
+
* Generate a unique placeholder ID
|
|
17
|
+
*/
|
|
18
|
+
function generatePlaceholderId() {
|
|
19
|
+
return randomBytes(4).toString("hex").toUpperCase();
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Minimum length threshold for replacement (only replace if longer than this)
|
|
23
|
+
*/
|
|
24
|
+
const MIN_REPLACEMENT_LENGTH = 10;
|
|
25
|
+
/**
|
|
26
|
+
* Create targeted placeholders using AST parsing for better accuracy
|
|
27
|
+
*/
|
|
28
|
+
function createTargetedTypeScriptPlaceholders(content, debug = false) {
|
|
29
|
+
const replacements = {};
|
|
30
|
+
let replacedFields = 0;
|
|
31
|
+
const originalSize = content.length;
|
|
32
|
+
try {
|
|
33
|
+
const sourceFile = new Project({ useInMemoryFileSystem: true }).createSourceFile("temp.ts", content);
|
|
34
|
+
const replacementOperations = [];
|
|
35
|
+
sourceFile.forEachDescendant((node) => {
|
|
36
|
+
if (Node.isPropertyAssignment(node)) {
|
|
37
|
+
const propertyName = node.getName();
|
|
38
|
+
const valueNode = node.getInitializer();
|
|
39
|
+
if (!valueNode) return;
|
|
40
|
+
let valueText = valueNode.getText();
|
|
41
|
+
if (valueText.trim().length < MIN_REPLACEMENT_LENGTH) return;
|
|
42
|
+
let placeholderPrefix = "";
|
|
43
|
+
switch (propertyName) {
|
|
44
|
+
case "prompt":
|
|
45
|
+
placeholderPrefix = "PROMPT";
|
|
46
|
+
break;
|
|
47
|
+
case "description":
|
|
48
|
+
placeholderPrefix = "DESC";
|
|
49
|
+
break;
|
|
50
|
+
case "inputSchema":
|
|
51
|
+
placeholderPrefix = "INPUT_SCHEMA";
|
|
52
|
+
break;
|
|
53
|
+
case "detailsSchema":
|
|
54
|
+
placeholderPrefix = "DETAILS_SCHEMA";
|
|
55
|
+
break;
|
|
56
|
+
case "props":
|
|
57
|
+
placeholderPrefix = "PROPS";
|
|
58
|
+
break;
|
|
59
|
+
case "render":
|
|
60
|
+
placeholderPrefix = "RENDER";
|
|
61
|
+
break;
|
|
62
|
+
default: return;
|
|
63
|
+
}
|
|
64
|
+
const start = valueNode.getStart();
|
|
65
|
+
let end = valueNode.getEnd();
|
|
66
|
+
const propertyEnd = node.getEnd();
|
|
67
|
+
if (propertyName === "inputSchema" || propertyName === "render") {
|
|
68
|
+
const searchStart = start;
|
|
69
|
+
let braceCount = 0;
|
|
70
|
+
let correctEnd = -1;
|
|
71
|
+
let inString = false;
|
|
72
|
+
let stringChar = "";
|
|
73
|
+
for (let i = searchStart; i < content.length; i++) {
|
|
74
|
+
const char = content[i];
|
|
75
|
+
const prevChar = i > 0 ? content[i - 1] : "";
|
|
76
|
+
if ((char === "\"" || char === "'") && prevChar !== "\\") {
|
|
77
|
+
if (!inString) {
|
|
78
|
+
inString = true;
|
|
79
|
+
stringChar = char;
|
|
80
|
+
} else if (char === stringChar) {
|
|
81
|
+
inString = false;
|
|
82
|
+
stringChar = "";
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
if (!inString) {
|
|
86
|
+
if (char === "{") braceCount++;
|
|
87
|
+
else if (char === "}") {
|
|
88
|
+
braceCount--;
|
|
89
|
+
if (braceCount === 0) {
|
|
90
|
+
let j = i + 1;
|
|
91
|
+
while (j < content.length && /\s/.test(content[j])) j++;
|
|
92
|
+
if (j < content.length && content[j] === ",") {
|
|
93
|
+
correctEnd = j + 1;
|
|
94
|
+
break;
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
if (correctEnd > start && correctEnd < end + 100) {
|
|
101
|
+
end = correctEnd;
|
|
102
|
+
valueText = content.slice(start, end);
|
|
103
|
+
}
|
|
104
|
+
} else if (!content.slice(end, end + 20).match(/^\s*[,}]/)) {
|
|
105
|
+
let correctEnd = end;
|
|
106
|
+
while (correctEnd > start && !content.slice(correctEnd, correctEnd + 10).match(/^\s*[,}]/)) correctEnd--;
|
|
107
|
+
if (correctEnd > start) {
|
|
108
|
+
end = correctEnd;
|
|
109
|
+
valueText = content.slice(start, end);
|
|
110
|
+
} else return;
|
|
111
|
+
}
|
|
112
|
+
if (end > propertyEnd) return;
|
|
113
|
+
const actualText = content.slice(start, end);
|
|
114
|
+
if (valueText !== actualText) return;
|
|
115
|
+
if (!content.slice(end, end + 20).match(/^\s*[,}]/)) return;
|
|
116
|
+
const placeholder = `<${placeholderPrefix}_${generatePlaceholderId()}>`;
|
|
117
|
+
replacements[placeholder] = valueText;
|
|
118
|
+
replacedFields++;
|
|
119
|
+
replacementOperations.push({
|
|
120
|
+
start,
|
|
121
|
+
end,
|
|
122
|
+
placeholder,
|
|
123
|
+
originalText: valueText
|
|
124
|
+
});
|
|
125
|
+
}
|
|
126
|
+
});
|
|
127
|
+
replacementOperations.sort((a, b) => b.start - a.start);
|
|
128
|
+
let processedContent = content;
|
|
129
|
+
for (const op of replacementOperations) processedContent = processedContent.slice(0, op.start) + op.placeholder + processedContent.slice(op.end);
|
|
130
|
+
const processedSize = processedContent.length;
|
|
131
|
+
const savings = originalSize - processedSize;
|
|
132
|
+
const savingsPercentage = originalSize > 0 ? savings / originalSize * 100 : 0;
|
|
133
|
+
return {
|
|
134
|
+
processedContent,
|
|
135
|
+
replacements,
|
|
136
|
+
stats: {
|
|
137
|
+
originalSize,
|
|
138
|
+
processedSize,
|
|
139
|
+
savings,
|
|
140
|
+
savingsPercentage,
|
|
141
|
+
replacedFields
|
|
142
|
+
}
|
|
143
|
+
};
|
|
144
|
+
} catch (error) {
|
|
145
|
+
return {
|
|
146
|
+
processedContent: content,
|
|
147
|
+
replacements: {},
|
|
148
|
+
stats: {
|
|
149
|
+
originalSize,
|
|
150
|
+
processedSize: originalSize,
|
|
151
|
+
savings: 0,
|
|
152
|
+
savingsPercentage: 0,
|
|
153
|
+
replacedFields: 0
|
|
154
|
+
}
|
|
155
|
+
};
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
/**
|
|
159
|
+
* Restore placeholders in TypeScript content
|
|
160
|
+
*/
|
|
161
|
+
function restoreTargetedTypeScriptPlaceholders(content, replacements) {
|
|
162
|
+
let restoredContent = content;
|
|
163
|
+
const sortedPlaceholders = Object.keys(replacements).sort((a, b) => b.length - a.length);
|
|
164
|
+
for (const placeholder of sortedPlaceholders) {
|
|
165
|
+
const originalValue = replacements[placeholder];
|
|
166
|
+
if (!restoredContent.includes(placeholder)) continue;
|
|
167
|
+
restoredContent = restoredContent.replace(placeholder, originalValue);
|
|
168
|
+
}
|
|
169
|
+
return restoredContent;
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
//#endregion
|
|
173
|
+
export { createTargetedTypeScriptPlaceholders, restoreTargetedTypeScriptPlaceholders };
|
|
@@ -0,0 +1,369 @@
|
|
|
1
|
+
import { existsSync, readFileSync } from "node:fs";
|
|
2
|
+
import { join } from "node:path";
|
|
3
|
+
|
|
4
|
+
//#region src/commands/pull-v3/utils/component-registry.ts
|
|
5
|
+
var ComponentRegistry = class {
|
|
6
|
+
components = /* @__PURE__ */ new Map();
|
|
7
|
+
componentsByTypeAndId = /* @__PURE__ */ new Map();
|
|
8
|
+
usedNames = /* @__PURE__ */ new Set();
|
|
9
|
+
/**
|
|
10
|
+
* Register a component with both unique name and file path
|
|
11
|
+
*/
|
|
12
|
+
register(id, type, filePath, exportName, isInline = false) {
|
|
13
|
+
const typeKey = `${type}:${id}`;
|
|
14
|
+
const existing = this.componentsByTypeAndId.get(typeKey);
|
|
15
|
+
if (existing) return existing;
|
|
16
|
+
let name;
|
|
17
|
+
let actualExportName;
|
|
18
|
+
if (exportName) {
|
|
19
|
+
name = exportName;
|
|
20
|
+
actualExportName = exportName;
|
|
21
|
+
} else {
|
|
22
|
+
const baseName = this.toCamelCase(id);
|
|
23
|
+
const uniqueName = this.ensureUniqueName(baseName, type);
|
|
24
|
+
name = uniqueName;
|
|
25
|
+
actualExportName = uniqueName;
|
|
26
|
+
}
|
|
27
|
+
const info = {
|
|
28
|
+
id,
|
|
29
|
+
name,
|
|
30
|
+
type,
|
|
31
|
+
filePath,
|
|
32
|
+
exportName: actualExportName,
|
|
33
|
+
isInline
|
|
34
|
+
};
|
|
35
|
+
this.components.set(id, info);
|
|
36
|
+
this.componentsByTypeAndId.set(typeKey, info);
|
|
37
|
+
this.usedNames.add(name);
|
|
38
|
+
if (actualExportName && actualExportName !== name) this.usedNames.add(actualExportName);
|
|
39
|
+
return info;
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Override a credential component with environment settings key
|
|
43
|
+
* This allows env settings registration to take precedence over standalone credentials
|
|
44
|
+
*/
|
|
45
|
+
overrideCredentialWithEnvKey(id, filePath, envKey) {
|
|
46
|
+
const typeKey = `credentials:${id}`;
|
|
47
|
+
const info = {
|
|
48
|
+
id,
|
|
49
|
+
type: "credentials",
|
|
50
|
+
name: envKey,
|
|
51
|
+
filePath,
|
|
52
|
+
exportName: envKey,
|
|
53
|
+
isInline: true
|
|
54
|
+
};
|
|
55
|
+
this.componentsByTypeAndId.set(typeKey, info);
|
|
56
|
+
this.components.set(`${filePath}:${envKey}`, info);
|
|
57
|
+
return info;
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Get component info by ID and type
|
|
61
|
+
*/
|
|
62
|
+
get(id, type) {
|
|
63
|
+
const typeKey = `${type}:${id}`;
|
|
64
|
+
return this.componentsByTypeAndId.get(typeKey);
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Get component info by variable name (since variable names are globally unique)
|
|
68
|
+
*/
|
|
69
|
+
getByVariableName(variableName) {
|
|
70
|
+
for (const component of this.componentsByTypeAndId.values()) if (component.name === variableName) return component;
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Get unique variable name for a component by ID and type
|
|
74
|
+
*/
|
|
75
|
+
getVariableName(id, type) {
|
|
76
|
+
const typeKey = `${type}:${id}`;
|
|
77
|
+
return this.componentsByTypeAndId.get(typeKey)?.name;
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Get import statement for a component
|
|
81
|
+
*/
|
|
82
|
+
getImportStatement(fromFilePath, componentId, componentType) {
|
|
83
|
+
const component = this.get(componentId, componentType);
|
|
84
|
+
if (!component) return void 0;
|
|
85
|
+
if (this.normalizeToProjectPath(fromFilePath) === this.normalizeToProjectPath(component.filePath)) return;
|
|
86
|
+
const relativePath = this.calculateRelativeImport(fromFilePath, component.filePath);
|
|
87
|
+
return `import { ${component.exportName} } from '${relativePath}';`;
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* Format an array of references for code generation
|
|
91
|
+
*/
|
|
92
|
+
formatReferencesForCode(references, componentType, style, indentLevel) {
|
|
93
|
+
if (!Array.isArray(references) || references.length === 0) return "[]";
|
|
94
|
+
const variableNames = [];
|
|
95
|
+
for (const ref of references) {
|
|
96
|
+
const id = this.extractIdFromReference(ref);
|
|
97
|
+
if (id) {
|
|
98
|
+
const component = this.get(id, componentType);
|
|
99
|
+
if (component) variableNames.push(component.name);
|
|
100
|
+
else {
|
|
101
|
+
console.warn(`ComponentRegistry: Component not found: ${id} (type: ${componentType})`);
|
|
102
|
+
variableNames.push(this.toCamelCase(id));
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
if (variableNames.length === 0) return "[]";
|
|
107
|
+
if (variableNames.length === 1) return `[${variableNames[0]}]`;
|
|
108
|
+
const { indentation } = style;
|
|
109
|
+
const indent = indentation.repeat(indentLevel);
|
|
110
|
+
const lines = ["["];
|
|
111
|
+
for (let i = 0; i < variableNames.length; i++) {
|
|
112
|
+
const isLast = i === variableNames.length - 1;
|
|
113
|
+
lines.push(`${indent}${variableNames[i]}${isLast ? "" : ","}`);
|
|
114
|
+
}
|
|
115
|
+
lines.push(`${indentation.repeat(indentLevel - 1)}]`);
|
|
116
|
+
return lines.join("\n");
|
|
117
|
+
}
|
|
118
|
+
/**
|
|
119
|
+
* Get all import statements needed for a file
|
|
120
|
+
*/
|
|
121
|
+
getImportsForFile(fromFilePath, referencedComponents) {
|
|
122
|
+
const imports = [];
|
|
123
|
+
const seenImports = /* @__PURE__ */ new Set();
|
|
124
|
+
for (const { id, type } of referencedComponents) {
|
|
125
|
+
const importStatement = this.getImportStatement(fromFilePath, id, type);
|
|
126
|
+
if (importStatement && !seenImports.has(importStatement)) {
|
|
127
|
+
imports.push(importStatement);
|
|
128
|
+
seenImports.add(importStatement);
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
return imports;
|
|
132
|
+
}
|
|
133
|
+
/**
|
|
134
|
+
* Get all component IDs referenced in arrays for import generation
|
|
135
|
+
*/
|
|
136
|
+
getReferencedComponentIds(referenceArrays) {
|
|
137
|
+
const componentIds = [];
|
|
138
|
+
for (const refArray of referenceArrays) if (Array.isArray(refArray)) for (const ref of refArray) {
|
|
139
|
+
const id = this.extractIdFromReference(ref);
|
|
140
|
+
if (id) componentIds.push(id);
|
|
141
|
+
}
|
|
142
|
+
return componentIds;
|
|
143
|
+
}
|
|
144
|
+
/**
|
|
145
|
+
* Extract ID from a reference (string or object) based on component type
|
|
146
|
+
*/
|
|
147
|
+
extractIdFromReference(ref) {
|
|
148
|
+
if (typeof ref === "string") return ref;
|
|
149
|
+
if (typeof ref === "object" && ref) {
|
|
150
|
+
if (ref.toolId) return ref.toolId;
|
|
151
|
+
if (ref.agentId) return ref.agentId;
|
|
152
|
+
if (ref.externalAgentId) return ref.externalAgentId;
|
|
153
|
+
if (ref.credentialStoreId) return ref.credentialStoreId;
|
|
154
|
+
if (ref.type && !ref.agentId && !ref.toolId && !ref.externalAgentId) return ref.type;
|
|
155
|
+
if (ref.id) return ref.id;
|
|
156
|
+
if (ref.name) return ref.name;
|
|
157
|
+
console.warn("ComponentRegistry: Reference without recognized ID field:", ref);
|
|
158
|
+
return null;
|
|
159
|
+
}
|
|
160
|
+
return null;
|
|
161
|
+
}
|
|
162
|
+
/**
|
|
163
|
+
* Convert string to camelCase and ensure it's a valid JavaScript identifier
|
|
164
|
+
*/
|
|
165
|
+
toCamelCase(str) {
|
|
166
|
+
return str.toLowerCase().replace(/[-_](.)/g, (_, char) => char.toUpperCase()).replace(/[^a-zA-Z0-9]/g, "").replace(/^[0-9]/, "_$&");
|
|
167
|
+
}
|
|
168
|
+
/**
|
|
169
|
+
* Ensure a name is unique by adding prefixes/suffixes if needed
|
|
170
|
+
*/
|
|
171
|
+
ensureUniqueName(baseName, type) {
|
|
172
|
+
let uniqueName = baseName;
|
|
173
|
+
let counter = 1;
|
|
174
|
+
while (this.usedNames.has(uniqueName)) {
|
|
175
|
+
if (counter === 1) uniqueName = `${this.getTypePrefix(type)}${baseName.charAt(0).toUpperCase() + baseName.slice(1)}`;
|
|
176
|
+
else uniqueName = `${baseName}${counter}`;
|
|
177
|
+
counter++;
|
|
178
|
+
if (counter > 100) {
|
|
179
|
+
uniqueName = `${baseName}_${Date.now()}`;
|
|
180
|
+
break;
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
return uniqueName;
|
|
184
|
+
}
|
|
185
|
+
/**
|
|
186
|
+
* Get type prefix for uniqueness resolution
|
|
187
|
+
*/
|
|
188
|
+
getTypePrefix(type) {
|
|
189
|
+
switch (type) {
|
|
190
|
+
case "agents": return "agent";
|
|
191
|
+
case "subAgents": return "sub";
|
|
192
|
+
case "externalAgents": return "ext";
|
|
193
|
+
case "tools": return "tool";
|
|
194
|
+
case "functionTools": return "func";
|
|
195
|
+
case "functions": return "func";
|
|
196
|
+
case "dataComponents": return "data";
|
|
197
|
+
case "artifactComponents": return "artifact";
|
|
198
|
+
case "statusComponents": return "status";
|
|
199
|
+
case "environments": return "env";
|
|
200
|
+
case "credentials": return "cred";
|
|
201
|
+
case "contextConfigs": return "context";
|
|
202
|
+
case "fetchDefinitions": return "fetch";
|
|
203
|
+
case "headers": return "header";
|
|
204
|
+
case "models": return "model";
|
|
205
|
+
case "project": return "project";
|
|
206
|
+
default: return "comp";
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
/**
|
|
210
|
+
* Normalize path to project-relative format using existing registry paths as templates
|
|
211
|
+
*/
|
|
212
|
+
normalizeToProjectPath(filePath) {
|
|
213
|
+
if (!filePath.includes("/") || filePath.match(/^(agents|tools|environments|data-components)/)) return filePath;
|
|
214
|
+
const knownDirs = /* @__PURE__ */ new Set();
|
|
215
|
+
for (const component of this.components.values()) {
|
|
216
|
+
const firstDir = component.filePath.split("/")[0];
|
|
217
|
+
if (firstDir) knownDirs.add(firstDir);
|
|
218
|
+
}
|
|
219
|
+
const segments = filePath.split("/");
|
|
220
|
+
for (let i = segments.length - 1; i >= 0; i--) if (knownDirs.has(segments[i])) return segments.slice(i).join("/");
|
|
221
|
+
return segments[segments.length - 1] || filePath;
|
|
222
|
+
}
|
|
223
|
+
/**
|
|
224
|
+
* Calculate relative import path between files
|
|
225
|
+
*/
|
|
226
|
+
calculateRelativeImport(fromPath, toPath) {
|
|
227
|
+
const fromParts = fromPath.replace(".ts", "").split("/");
|
|
228
|
+
const toParts = toPath.replace(".ts", "").split("/");
|
|
229
|
+
const fromDir = fromParts.slice(0, -1);
|
|
230
|
+
const toFile = toParts;
|
|
231
|
+
let commonLength = 0;
|
|
232
|
+
while (commonLength < fromDir.length && commonLength < toFile.length - 1 && fromDir[commonLength] === toFile[commonLength]) commonLength++;
|
|
233
|
+
let relativePath = "";
|
|
234
|
+
const upLevels = fromDir.length - commonLength;
|
|
235
|
+
for (let i = 0; i < upLevels; i++) relativePath += "../";
|
|
236
|
+
const remainingPath = toFile.slice(commonLength).join("/");
|
|
237
|
+
relativePath += remainingPath;
|
|
238
|
+
if (relativePath.startsWith("../")) return relativePath;
|
|
239
|
+
return "./" + relativePath;
|
|
240
|
+
}
|
|
241
|
+
/**
|
|
242
|
+
* Get all components for debugging
|
|
243
|
+
*/
|
|
244
|
+
getAllComponents() {
|
|
245
|
+
return Array.from(this.componentsByTypeAndId.values());
|
|
246
|
+
}
|
|
247
|
+
/**
|
|
248
|
+
* Get all components in a specific file
|
|
249
|
+
*/
|
|
250
|
+
getComponentsInFile(filePath) {
|
|
251
|
+
return Array.from(this.componentsByTypeAndId.values()).filter((component) => component.filePath === filePath);
|
|
252
|
+
}
|
|
253
|
+
/**
|
|
254
|
+
* Remove a component from the registry
|
|
255
|
+
*/
|
|
256
|
+
removeComponent(type, id) {
|
|
257
|
+
const key = `${type}:${id}`;
|
|
258
|
+
const component = this.componentsByTypeAndId.get(key);
|
|
259
|
+
if (component) {
|
|
260
|
+
this.componentsByTypeAndId.delete(key);
|
|
261
|
+
this.components.delete(component.name);
|
|
262
|
+
if (!Array.from(this.componentsByTypeAndId.values()).some((comp) => comp.name === component.name)) this.usedNames.delete(component.name);
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
/**
|
|
266
|
+
* Clear all components (for testing)
|
|
267
|
+
*/
|
|
268
|
+
clear() {
|
|
269
|
+
this.components.clear();
|
|
270
|
+
this.componentsByTypeAndId.clear();
|
|
271
|
+
this.usedNames.clear();
|
|
272
|
+
}
|
|
273
|
+
};
|
|
274
|
+
/**
|
|
275
|
+
* Register all components from a project with their file paths
|
|
276
|
+
*/
|
|
277
|
+
function registerAllComponents(project, registry) {
|
|
278
|
+
registry.register(project.id, "project", "index.ts");
|
|
279
|
+
if (project.credentialReferences) for (const credId of Object.keys(project.credentialReferences)) registry.register(credId, "credentials", `credentials/${credId}.ts`);
|
|
280
|
+
if (project.tools) for (const toolId of Object.keys(project.tools)) registry.register(toolId, "tools", `tools/${toolId}.ts`);
|
|
281
|
+
const registeredFunctionToolIds = /* @__PURE__ */ new Set();
|
|
282
|
+
if (project.functionTools) for (const funcToolId of Object.keys(project.functionTools)) {
|
|
283
|
+
registry.register(funcToolId, "functionTools", `tools/functions/${funcToolId}.ts`);
|
|
284
|
+
registeredFunctionToolIds.add(funcToolId);
|
|
285
|
+
}
|
|
286
|
+
if (project.agents) for (const agentData of Object.values(project.agents)) {
|
|
287
|
+
const agentFunctionTools = agentData.functionTools;
|
|
288
|
+
if (agentFunctionTools) {
|
|
289
|
+
for (const funcToolId of Object.keys(agentFunctionTools)) if (!registeredFunctionToolIds.has(funcToolId)) {
|
|
290
|
+
registry.register(funcToolId, "functionTools", `tools/functions/${funcToolId}.ts`);
|
|
291
|
+
registeredFunctionToolIds.add(funcToolId);
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
}
|
|
295
|
+
if (project.dataComponents) for (const componentId of Object.keys(project.dataComponents)) registry.register(componentId, "dataComponents", `data-components/${componentId}.ts`);
|
|
296
|
+
if (project.artifactComponents) for (const componentId of Object.keys(project.artifactComponents)) registry.register(componentId, "artifactComponents", `artifact-components/${componentId}.ts`);
|
|
297
|
+
if (project.externalAgents) for (const extAgentId of Object.keys(project.externalAgents)) registry.register(extAgentId, "externalAgents", `external-agents/${extAgentId}.ts`);
|
|
298
|
+
const statusComponents = extractStatusComponents(project);
|
|
299
|
+
for (const statusId of Object.keys(statusComponents)) registry.register(statusId, "statusComponents", `status-components/${statusId}.ts`);
|
|
300
|
+
if (project.agents) for (const agentId of Object.keys(project.agents)) registry.register(agentId, "agents", `agents/${agentId}.ts`);
|
|
301
|
+
const subAgents = extractSubAgents(project);
|
|
302
|
+
for (const subAgentId of Object.keys(subAgents)) registry.register(subAgentId, "subAgents", `agents/sub-agents/${subAgentId}.ts`);
|
|
303
|
+
const contextConfigs = extractContextConfigs(project);
|
|
304
|
+
for (const contextId of Object.keys(contextConfigs)) registry.register(contextId, "contextConfigs", `context-configs/${contextId}.ts`);
|
|
305
|
+
}
|
|
306
|
+
/**
|
|
307
|
+
* Extract status components from project agents
|
|
308
|
+
*/
|
|
309
|
+
function extractStatusComponents(project) {
|
|
310
|
+
const statusComponents = {};
|
|
311
|
+
if (project.agents) {
|
|
312
|
+
for (const [agentId, agentData] of Object.entries(project.agents)) if (agentData.statusUpdates && agentData.statusUpdates.statusComponents) for (const statusComp of agentData.statusUpdates.statusComponents) {
|
|
313
|
+
let statusId;
|
|
314
|
+
if (typeof statusComp === "string") statusId = statusComp;
|
|
315
|
+
else if (typeof statusComp === "object" && statusComp) statusId = statusComp.type;
|
|
316
|
+
else continue;
|
|
317
|
+
if (statusId && !statusComponents[statusId]) statusComponents[statusId] = {
|
|
318
|
+
...statusComp,
|
|
319
|
+
id: statusId,
|
|
320
|
+
type: statusComp.type || statusId,
|
|
321
|
+
description: statusComp.description || `Status component for ${statusId}`,
|
|
322
|
+
detailsSchema: statusComp.detailsSchema
|
|
323
|
+
};
|
|
324
|
+
}
|
|
325
|
+
}
|
|
326
|
+
return statusComponents;
|
|
327
|
+
}
|
|
328
|
+
/**
|
|
329
|
+
* Extract sub-agents from project agents
|
|
330
|
+
*/
|
|
331
|
+
function extractSubAgents(project) {
|
|
332
|
+
const subAgents = {};
|
|
333
|
+
if (project.agents) {
|
|
334
|
+
for (const [agentId, agentData] of Object.entries(project.agents)) if (agentData.subAgents) for (const [subAgentId, subAgentData] of Object.entries(agentData.subAgents)) subAgents[subAgentId] = subAgentData;
|
|
335
|
+
}
|
|
336
|
+
return subAgents;
|
|
337
|
+
}
|
|
338
|
+
/**
|
|
339
|
+
* Extract context configs from project agents
|
|
340
|
+
*/
|
|
341
|
+
function extractContextConfigs(project) {
|
|
342
|
+
const contextConfigs = {};
|
|
343
|
+
if (project.agents) {
|
|
344
|
+
for (const [agentId, agentData] of Object.entries(project.agents)) if (agentData.contextConfig) {
|
|
345
|
+
const contextConfigId = agentData.contextConfig.id;
|
|
346
|
+
if (contextConfigId) contextConfigs[contextConfigId] = agentData.contextConfig;
|
|
347
|
+
else console.warn(`contextConfig for agent ${agentId} is missing required 'id' field`);
|
|
348
|
+
}
|
|
349
|
+
}
|
|
350
|
+
return contextConfigs;
|
|
351
|
+
}
|
|
352
|
+
/**
|
|
353
|
+
* Find sub-agent data with parent agent info for contextConfig resolution
|
|
354
|
+
*/
|
|
355
|
+
function findSubAgentWithParent(project, subAgentId) {
|
|
356
|
+
if (project.agents) {
|
|
357
|
+
for (const [agentId, agentData] of Object.entries(project.agents)) if (agentData.subAgents && agentData.subAgents[subAgentId]) {
|
|
358
|
+
const contextConfigData = agentData.contextConfig?.id ? agentData.contextConfig : void 0;
|
|
359
|
+
return {
|
|
360
|
+
subAgentData: agentData.subAgents[subAgentId],
|
|
361
|
+
parentAgentId: agentId,
|
|
362
|
+
contextConfigData
|
|
363
|
+
};
|
|
364
|
+
}
|
|
365
|
+
}
|
|
366
|
+
}
|
|
367
|
+
|
|
368
|
+
//#endregion
|
|
369
|
+
export { ComponentRegistry, extractSubAgents, findSubAgentWithParent, registerAllComponents };
|