@inkeep/agents-cli 0.59.2 → 0.59.4
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/agents-cli/package.js +1 -1
- package/dist/commands/pull-v4/collector-common.js +128 -0
- package/dist/commands/pull-v4/collector-common.js.map +1 -0
- package/dist/commands/pull-v4/collector-reference-helpers.js +323 -0
- package/dist/commands/pull-v4/collector-reference-helpers.js.map +1 -0
- package/dist/commands/pull-v4/component-parser.js +2 -1
- package/dist/commands/pull-v4/component-parser.js.map +1 -1
- package/dist/commands/pull-v4/file-scope.js +43 -0
- package/dist/commands/pull-v4/file-scope.js.map +1 -0
- package/dist/commands/pull-v4/generation-resolver.js +305 -0
- package/dist/commands/pull-v4/generation-resolver.js.map +1 -0
- package/dist/commands/pull-v4/generation-types.js +56 -0
- package/dist/commands/pull-v4/generation-types.js.map +1 -0
- package/dist/commands/pull-v4/generators/agent-generator.helpers.js +4 -10
- package/dist/commands/pull-v4/generators/agent-generator.helpers.js.map +1 -1
- package/dist/commands/pull-v4/generators/agent-generator.js +154 -81
- package/dist/commands/pull-v4/generators/agent-generator.js.map +1 -1
- package/dist/commands/pull-v4/generators/artifact-component-generator.js +48 -27
- package/dist/commands/pull-v4/generators/artifact-component-generator.js.map +1 -1
- package/dist/commands/pull-v4/generators/context-config-generator.js +147 -129
- package/dist/commands/pull-v4/generators/context-config-generator.js.map +1 -1
- package/dist/commands/pull-v4/generators/credential-generator.js +36 -14
- package/dist/commands/pull-v4/generators/credential-generator.js.map +1 -1
- package/dist/commands/pull-v4/generators/data-component-generator.js +55 -19
- package/dist/commands/pull-v4/generators/data-component-generator.js.map +1 -1
- package/dist/commands/pull-v4/generators/environment-generator.js +29 -33
- package/dist/commands/pull-v4/generators/environment-generator.js.map +1 -1
- package/dist/commands/pull-v4/generators/environment-settings-generator.js +57 -0
- package/dist/commands/pull-v4/generators/environment-settings-generator.js.map +1 -0
- package/dist/commands/pull-v4/generators/external-agent-generator.js +51 -23
- package/dist/commands/pull-v4/generators/external-agent-generator.js.map +1 -1
- package/dist/commands/pull-v4/generators/function-tool-generator.js +50 -14
- package/dist/commands/pull-v4/generators/function-tool-generator.js.map +1 -1
- package/dist/commands/pull-v4/generators/helpers/agent.js +129 -0
- package/dist/commands/pull-v4/generators/helpers/agent.js.map +1 -0
- package/dist/commands/pull-v4/generators/helpers/sub-agent.js +65 -0
- package/dist/commands/pull-v4/generators/helpers/sub-agent.js.map +1 -0
- package/dist/commands/pull-v4/generators/index.js +38 -0
- package/dist/commands/pull-v4/generators/index.js.map +1 -0
- package/dist/commands/pull-v4/generators/mcp-tool-generator.js +48 -27
- package/dist/commands/pull-v4/generators/mcp-tool-generator.js.map +1 -1
- package/dist/commands/pull-v4/generators/project-generator.js +144 -110
- package/dist/commands/pull-v4/generators/project-generator.js.map +1 -1
- package/dist/commands/pull-v4/generators/scheduled-trigger-generator.js +66 -0
- package/dist/commands/pull-v4/generators/scheduled-trigger-generator.js.map +1 -0
- package/dist/commands/pull-v4/generators/status-component-generator.js +55 -20
- package/dist/commands/pull-v4/generators/status-component-generator.js.map +1 -1
- package/dist/commands/pull-v4/generators/sub-agent-generator.helpers.js +4 -1
- package/dist/commands/pull-v4/generators/sub-agent-generator.helpers.js.map +1 -1
- package/dist/commands/pull-v4/generators/sub-agent-generator.js +282 -166
- package/dist/commands/pull-v4/generators/sub-agent-generator.js.map +1 -1
- package/dist/commands/pull-v4/generators/trigger-generator.js +62 -27
- package/dist/commands/pull-v4/generators/trigger-generator.js.map +1 -1
- package/dist/commands/pull-v4/import-plan.js +40 -0
- package/dist/commands/pull-v4/import-plan.js.map +1 -0
- package/dist/commands/pull-v4/introspect/index.js +11 -7
- package/dist/commands/pull-v4/introspect/index.js.map +1 -1
- package/dist/commands/pull-v4/introspect-generator.js +15 -1218
- package/dist/commands/pull-v4/introspect-generator.js.map +1 -1
- package/dist/commands/pull-v4/module-merge.js +14 -5
- package/dist/commands/pull-v4/module-merge.js.map +1 -1
- package/dist/commands/pull-v4/reference-resolution.js +111 -0
- package/dist/commands/pull-v4/reference-resolution.js.map +1 -0
- package/dist/commands/pull-v4/simple-factory-generator.js +54 -0
- package/dist/commands/pull-v4/simple-factory-generator.js.map +1 -0
- package/dist/commands/pull-v4/{generators/skill-generator.js → skill.js} +18 -6
- package/dist/commands/pull-v4/skill.js.map +1 -0
- package/dist/commands/pull-v4/typescript-file-writer.js +78 -0
- package/dist/commands/pull-v4/typescript-file-writer.js.map +1 -0
- package/dist/commands/pull-v4/utils/code-values.js +64 -0
- package/dist/commands/pull-v4/utils/code-values.js.map +1 -0
- package/dist/commands/pull-v4/utils/factory-writer.js +128 -0
- package/dist/commands/pull-v4/utils/factory-writer.js.map +1 -0
- package/dist/commands/pull-v4/utils/index.js +8 -0
- package/dist/commands/pull-v4/utils/naming.js +74 -0
- package/dist/commands/pull-v4/utils/naming.js.map +1 -0
- package/dist/commands/pull-v4/utils/schema-rendering.js +20 -0
- package/dist/commands/pull-v4/utils/schema-rendering.js.map +1 -0
- package/dist/commands/pull-v4/utils/shared.js +18 -0
- package/dist/commands/pull-v4/utils/shared.js.map +1 -0
- package/dist/commands/pull-v4/utils/templates.js +58 -0
- package/dist/commands/pull-v4/utils/templates.js.map +1 -0
- package/package.json +4 -4
- package/dist/commands/pull-v4/generators/skill-generator.js.map +0 -1
- package/dist/commands/pull-v4/scheduled-trigger-generator.js +0 -38
- package/dist/commands/pull-v4/scheduled-trigger-generator.js.map +0 -1
- package/dist/commands/pull-v4/utils.js +0 -320
- package/dist/commands/pull-v4/utils.js.map +0 -1
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
//#region src/commands/pull-v4/utils/naming.ts
|
|
2
|
+
const UUID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
|
|
3
|
+
const CUID_RE = /^c[a-z0-9]{24,}$/;
|
|
4
|
+
const NANOID_RE = /^[a-z0-9]{16,}$/;
|
|
5
|
+
const ID_SUFFIX_LENGTH = 8;
|
|
6
|
+
function resolveNonCollidingName(baseName, reservedNames, startIndex = 1) {
|
|
7
|
+
if (!reservedNames.has(baseName)) {
|
|
8
|
+
reservedNames.add(baseName);
|
|
9
|
+
return baseName;
|
|
10
|
+
}
|
|
11
|
+
let index = startIndex;
|
|
12
|
+
while (reservedNames.has(`${baseName}${index}`)) index += 1;
|
|
13
|
+
const uniqueName = `${baseName}${index}`;
|
|
14
|
+
reservedNames.add(uniqueName);
|
|
15
|
+
return uniqueName;
|
|
16
|
+
}
|
|
17
|
+
function toCamelCase(input) {
|
|
18
|
+
const result = input.toLowerCase().replaceAll(/\W/g, " ").trim().replaceAll(/[\s_]+(.)/g, (_, char) => char.toUpperCase()).replace(/^[0-9]/, "_$&");
|
|
19
|
+
return result.charAt(0).toLowerCase() + result.slice(1);
|
|
20
|
+
}
|
|
21
|
+
function toToolReferenceName(input) {
|
|
22
|
+
const base = toCamelCase(input);
|
|
23
|
+
return base.endsWith("Tool") ? base : `${base}Tool`;
|
|
24
|
+
}
|
|
25
|
+
function toCredentialReferenceName(input) {
|
|
26
|
+
const base = toCamelCase(input);
|
|
27
|
+
return base.endsWith("Credential") ? base : `${base}Credential`;
|
|
28
|
+
}
|
|
29
|
+
function toTriggerReferenceName(input) {
|
|
30
|
+
const base = toCamelCase(input);
|
|
31
|
+
return base.endsWith("Trigger") ? base : `${base}Trigger`;
|
|
32
|
+
}
|
|
33
|
+
function toKebabCase(input) {
|
|
34
|
+
return input.trim().replace(/([a-z])([A-Z])/g, "$1-$2").replace(/[^a-zA-Z0-9]+/g, "-").replace(/^-+|-+$/g, "").toLowerCase();
|
|
35
|
+
}
|
|
36
|
+
function isHumanReadableId(id) {
|
|
37
|
+
if (UUID_RE.test(id) || CUID_RE.test(id) || NANOID_RE.test(id)) return false;
|
|
38
|
+
const segments = id.split(/[-_]/);
|
|
39
|
+
if (segments.length === 1 && id.length > 8) {
|
|
40
|
+
const hasLetters = /[a-zA-Z]/.test(id);
|
|
41
|
+
const hasDigits = /[0-9]/.test(id);
|
|
42
|
+
if (hasLetters && hasDigits) return false;
|
|
43
|
+
}
|
|
44
|
+
return segments.filter((s) => /^[a-zA-Z]+\d{0,2}$/.test(s)).length / segments.length >= .5;
|
|
45
|
+
}
|
|
46
|
+
function buildComponentFileName(id, name) {
|
|
47
|
+
if (!name || isHumanReadableId(id)) return `${id}.ts`;
|
|
48
|
+
const kebabName = toKebabCase(name);
|
|
49
|
+
if (!kebabName || kebabName === id) return `${id}.ts`;
|
|
50
|
+
return `${kebabName}-${id.slice(-ID_SUFFIX_LENGTH)}.ts`;
|
|
51
|
+
}
|
|
52
|
+
function createUniqueReferenceName(baseName, reservedNames, conflictSuffix) {
|
|
53
|
+
if (!reservedNames.has(baseName)) {
|
|
54
|
+
reservedNames.add(baseName);
|
|
55
|
+
return baseName;
|
|
56
|
+
}
|
|
57
|
+
const baseCandidate = `${baseName}${conflictSuffix}`;
|
|
58
|
+
if (!reservedNames.has(baseCandidate)) {
|
|
59
|
+
reservedNames.add(baseCandidate);
|
|
60
|
+
return baseCandidate;
|
|
61
|
+
}
|
|
62
|
+
return resolveNonCollidingName(baseCandidate, reservedNames, 2);
|
|
63
|
+
}
|
|
64
|
+
function resolveReferenceName(referenceId, referenceOverrides) {
|
|
65
|
+
for (const overrideMap of referenceOverrides) {
|
|
66
|
+
const overrideName = overrideMap?.[referenceId];
|
|
67
|
+
if (overrideName) return overrideName;
|
|
68
|
+
}
|
|
69
|
+
return toCamelCase(referenceId);
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
//#endregion
|
|
73
|
+
export { buildComponentFileName, createUniqueReferenceName, isHumanReadableId, resolveNonCollidingName, resolveReferenceName, toCamelCase, toCredentialReferenceName, toKebabCase, toToolReferenceName, toTriggerReferenceName };
|
|
74
|
+
//# sourceMappingURL=naming.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"naming.js","names":[],"sources":["../../../../src/commands/pull-v4/utils/naming.ts"],"sourcesContent":["const UUID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;\nconst CUID_RE = /^c[a-z0-9]{24,}$/;\nconst NANOID_RE = /^[a-z0-9]{16,}$/;\nconst ID_SUFFIX_LENGTH = 8;\ntype ReferenceOverrideMap = Record<string, string>;\n\nexport function resolveNonCollidingName(\n baseName: string,\n reservedNames: Set<string>,\n startIndex = 1\n): string {\n if (!reservedNames.has(baseName)) {\n reservedNames.add(baseName);\n return baseName;\n }\n\n let index = startIndex;\n while (reservedNames.has(`${baseName}${index}`)) {\n index += 1;\n }\n\n const uniqueName = `${baseName}${index}`;\n reservedNames.add(uniqueName);\n return uniqueName;\n}\n\nexport function toCamelCase(input: string): string {\n const result = input\n .toLowerCase()\n .replaceAll(/\\W/g, ' ')\n .trim()\n .replaceAll(/[\\s_]+(.)/g, (_, char: string) => char.toUpperCase())\n .replace(/^[0-9]/, '_$&');\n\n return result.charAt(0).toLowerCase() + result.slice(1);\n}\n\nexport function toToolReferenceName(input: string): string {\n const base = toCamelCase(input);\n return base.endsWith('Tool') ? base : `${base}Tool`;\n}\n\nexport function toCredentialReferenceName(input: string): string {\n const base = toCamelCase(input);\n return base.endsWith('Credential') ? base : `${base}Credential`;\n}\n\nexport function toTriggerReferenceName(input: string): string {\n const base = toCamelCase(input);\n return base.endsWith('Trigger') ? base : `${base}Trigger`;\n}\n\nexport function toKebabCase(input: string): string {\n return input\n .trim()\n .replace(/([a-z])([A-Z])/g, '$1-$2')\n .replace(/[^a-zA-Z0-9]+/g, '-')\n .replace(/^-+|-+$/g, '')\n .toLowerCase();\n}\n\nexport function isHumanReadableId(id: string): boolean {\n if (UUID_RE.test(id) || CUID_RE.test(id) || NANOID_RE.test(id)) {\n return false;\n }\n\n const segments = id.split(/[-_]/);\n if (segments.length === 1 && id.length > 8) {\n const hasLetters = /[a-zA-Z]/.test(id);\n const hasDigits = /[0-9]/.test(id);\n if (hasLetters && hasDigits) {\n return false;\n }\n }\n\n const wordLikeSegments = segments.filter((s) => /^[a-zA-Z]+\\d{0,2}$/.test(s));\n return wordLikeSegments.length / segments.length >= 0.5;\n}\n\nexport function buildComponentFileName(id: string, name?: string): string {\n if (!name || isHumanReadableId(id)) {\n return `${id}.ts`;\n }\n\n const kebabName = toKebabCase(name);\n if (!kebabName || kebabName === id) {\n return `${id}.ts`;\n }\n\n const shortId = id.slice(-ID_SUFFIX_LENGTH);\n return `${kebabName}-${shortId}.ts`;\n}\n\nexport function createUniqueReferenceName(\n baseName: string,\n reservedNames: Set<string>,\n conflictSuffix: string\n): string {\n if (!reservedNames.has(baseName)) {\n reservedNames.add(baseName);\n return baseName;\n }\n\n const baseCandidate = `${baseName}${conflictSuffix}`;\n if (!reservedNames.has(baseCandidate)) {\n reservedNames.add(baseCandidate);\n return baseCandidate;\n }\n\n return resolveNonCollidingName(baseCandidate, reservedNames, 2);\n}\n\nexport function resolveReferenceName(\n referenceId: string,\n referenceOverrides: Array<ReferenceOverrideMap | undefined>\n): string {\n for (const overrideMap of referenceOverrides) {\n const overrideName = overrideMap?.[referenceId];\n if (overrideName) {\n return overrideName;\n }\n }\n\n return toCamelCase(referenceId);\n}\n"],"mappings":";AAAA,MAAM,UAAU;AAChB,MAAM,UAAU;AAChB,MAAM,YAAY;AAClB,MAAM,mBAAmB;AAGzB,SAAgB,wBACd,UACA,eACA,aAAa,GACL;AACR,KAAI,CAAC,cAAc,IAAI,SAAS,EAAE;AAChC,gBAAc,IAAI,SAAS;AAC3B,SAAO;;CAGT,IAAI,QAAQ;AACZ,QAAO,cAAc,IAAI,GAAG,WAAW,QAAQ,CAC7C,UAAS;CAGX,MAAM,aAAa,GAAG,WAAW;AACjC,eAAc,IAAI,WAAW;AAC7B,QAAO;;AAGT,SAAgB,YAAY,OAAuB;CACjD,MAAM,SAAS,MACZ,aAAa,CACb,WAAW,OAAO,IAAI,CACtB,MAAM,CACN,WAAW,eAAe,GAAG,SAAiB,KAAK,aAAa,CAAC,CACjE,QAAQ,UAAU,MAAM;AAE3B,QAAO,OAAO,OAAO,EAAE,CAAC,aAAa,GAAG,OAAO,MAAM,EAAE;;AAGzD,SAAgB,oBAAoB,OAAuB;CACzD,MAAM,OAAO,YAAY,MAAM;AAC/B,QAAO,KAAK,SAAS,OAAO,GAAG,OAAO,GAAG,KAAK;;AAGhD,SAAgB,0BAA0B,OAAuB;CAC/D,MAAM,OAAO,YAAY,MAAM;AAC/B,QAAO,KAAK,SAAS,aAAa,GAAG,OAAO,GAAG,KAAK;;AAGtD,SAAgB,uBAAuB,OAAuB;CAC5D,MAAM,OAAO,YAAY,MAAM;AAC/B,QAAO,KAAK,SAAS,UAAU,GAAG,OAAO,GAAG,KAAK;;AAGnD,SAAgB,YAAY,OAAuB;AACjD,QAAO,MACJ,MAAM,CACN,QAAQ,mBAAmB,QAAQ,CACnC,QAAQ,kBAAkB,IAAI,CAC9B,QAAQ,YAAY,GAAG,CACvB,aAAa;;AAGlB,SAAgB,kBAAkB,IAAqB;AACrD,KAAI,QAAQ,KAAK,GAAG,IAAI,QAAQ,KAAK,GAAG,IAAI,UAAU,KAAK,GAAG,CAC5D,QAAO;CAGT,MAAM,WAAW,GAAG,MAAM,OAAO;AACjC,KAAI,SAAS,WAAW,KAAK,GAAG,SAAS,GAAG;EAC1C,MAAM,aAAa,WAAW,KAAK,GAAG;EACtC,MAAM,YAAY,QAAQ,KAAK,GAAG;AAClC,MAAI,cAAc,UAChB,QAAO;;AAKX,QADyB,SAAS,QAAQ,MAAM,qBAAqB,KAAK,EAAE,CAAC,CACrD,SAAS,SAAS,UAAU;;AAGtD,SAAgB,uBAAuB,IAAY,MAAuB;AACxE,KAAI,CAAC,QAAQ,kBAAkB,GAAG,CAChC,QAAO,GAAG,GAAG;CAGf,MAAM,YAAY,YAAY,KAAK;AACnC,KAAI,CAAC,aAAa,cAAc,GAC9B,QAAO,GAAG,GAAG;AAIf,QAAO,GAAG,UAAU,GADJ,GAAG,MAAM,CAAC,iBAAiB,CACZ;;AAGjC,SAAgB,0BACd,UACA,eACA,gBACQ;AACR,KAAI,CAAC,cAAc,IAAI,SAAS,EAAE;AAChC,gBAAc,IAAI,SAAS;AAC3B,SAAO;;CAGT,MAAM,gBAAgB,GAAG,WAAW;AACpC,KAAI,CAAC,cAAc,IAAI,cAAc,EAAE;AACrC,gBAAc,IAAI,cAAc;AAChC,SAAO;;AAGT,QAAO,wBAAwB,eAAe,eAAe,EAAE;;AAGjE,SAAgB,qBACd,aACA,oBACQ;AACR,MAAK,MAAM,eAAe,oBAAoB;EAC5C,MAAM,eAAe,cAAc;AACnC,MAAI,aACF,QAAO;;AAIX,QAAO,YAAY,YAAY"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { isPlainObject } from "./shared.js";
|
|
2
|
+
import { jsonSchemaToZod } from "json-schema-to-zod";
|
|
3
|
+
|
|
4
|
+
//#region src/commands/pull-v4/utils/schema-rendering.ts
|
|
5
|
+
function convertJsonSchemaToZodSafe(schema, options) {
|
|
6
|
+
if (!isPlainObject(schema)) {
|
|
7
|
+
console.warn("Schema conversion skipped: non-object schema provided, using z.any()");
|
|
8
|
+
return "z.any()";
|
|
9
|
+
}
|
|
10
|
+
try {
|
|
11
|
+
return jsonSchemaToZod(schema, options?.conversionOptions);
|
|
12
|
+
} catch (error) {
|
|
13
|
+
console.warn(`Schema conversion failed: ${error instanceof Error ? error.message : String(error)}. Falling back to z.any()`);
|
|
14
|
+
return "z.any()";
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
//#endregion
|
|
19
|
+
export { convertJsonSchemaToZodSafe };
|
|
20
|
+
//# sourceMappingURL=schema-rendering.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schema-rendering.js","names":[],"sources":["../../../../src/commands/pull-v4/utils/schema-rendering.ts"],"sourcesContent":["import { jsonSchemaToZod } from 'json-schema-to-zod';\nimport { isPlainObject } from './shared';\n\nexport function convertJsonSchemaToZodSafe(\n schema: unknown,\n options?: { conversionOptions?: Parameters<typeof jsonSchemaToZod>[1] }\n): string {\n if (!isPlainObject(schema)) {\n console.warn('Schema conversion skipped: non-object schema provided, using z.any()');\n return 'z.any()';\n }\n try {\n return jsonSchemaToZod(schema, options?.conversionOptions);\n } catch (error) {\n console.warn(\n `Schema conversion failed: ${error instanceof Error ? error.message : String(error)}. Falling back to z.any()`\n );\n return 'z.any()';\n }\n}\n"],"mappings":";;;;AAGA,SAAgB,2BACd,QACA,SACQ;AACR,KAAI,CAAC,cAAc,OAAO,EAAE;AAC1B,UAAQ,KAAK,uEAAuE;AACpF,SAAO;;AAET,KAAI;AACF,SAAO,gBAAgB,QAAQ,SAAS,kBAAkB;UACnD,OAAO;AACd,UAAQ,KACN,6BAA6B,iBAAiB,QAAQ,MAAM,UAAU,OAAO,MAAM,CAAC,2BACrF;AACD,SAAO"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import path from "node:path";
|
|
2
|
+
|
|
3
|
+
//#region src/commands/pull-v4/utils/shared.ts
|
|
4
|
+
function isPlainObject(value) {
|
|
5
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
6
|
+
}
|
|
7
|
+
async function expectSnapshots(definitionV4) {
|
|
8
|
+
const { currentTestName, snapshotState } = expect.getState();
|
|
9
|
+
const snapshotDir = path.basename(snapshotState.testFilePath).replace("-generator.test.ts", "");
|
|
10
|
+
await expect(definitionV4).toMatchFileSnapshot(`__snapshots__/${snapshotDir}/${currentTestName}-v4.txt`);
|
|
11
|
+
}
|
|
12
|
+
function hasReferences(references) {
|
|
13
|
+
return Array.isArray(references) && references.length > 0;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
//#endregion
|
|
17
|
+
export { expectSnapshots, hasReferences, isPlainObject };
|
|
18
|
+
//# sourceMappingURL=shared.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"shared.js","names":[],"sources":["../../../../src/commands/pull-v4/utils/shared.ts"],"sourcesContent":["import path from 'node:path';\n\nexport function isPlainObject(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\nexport async function expectSnapshots(definitionV4: string): Promise<void> {\n const { currentTestName, snapshotState } = expect.getState();\n\n const snapshotDir = path.basename(snapshotState.testFilePath).replace('-generator.test.ts', '');\n await expect(definitionV4).toMatchFileSnapshot(\n `__snapshots__/${snapshotDir}/${currentTestName}-v4.txt`\n );\n}\n\nexport function hasReferences<T>(references?: T[]): references is T[] {\n return Array.isArray(references) && references.length > 0;\n}\n"],"mappings":";;;AAEA,SAAgB,cAAc,OAAkD;AAC9E,QAAO,OAAO,UAAU,YAAY,UAAU,QAAQ,CAAC,MAAM,QAAQ,MAAM;;AAG7E,eAAsB,gBAAgB,cAAqC;CACzE,MAAM,EAAE,iBAAiB,kBAAkB,OAAO,UAAU;CAE5D,MAAM,cAAc,KAAK,SAAS,cAAc,aAAa,CAAC,QAAQ,sBAAsB,GAAG;AAC/F,OAAM,OAAO,aAAa,CAAC,oBACzB,iBAAiB,YAAY,GAAG,gBAAgB,SACjD;;AAGH,SAAgB,cAAiB,YAAqC;AACpE,QAAO,MAAM,QAAQ,WAAW,IAAI,WAAW,SAAS"}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { isPlainObject } from "./shared.js";
|
|
2
|
+
|
|
3
|
+
//#region src/commands/pull-v4/utils/templates.ts
|
|
4
|
+
const QUOTE = Object.freeze({
|
|
5
|
+
single: "'",
|
|
6
|
+
double: "\"",
|
|
7
|
+
template: "`"
|
|
8
|
+
});
|
|
9
|
+
const TEMPLATE_VARIABLE_REGEX = /\{\{(?!\{)(?<variableName>[^{}]+)}}/g;
|
|
10
|
+
function formatStringLiteral(value) {
|
|
11
|
+
const hasSingleQuote = value.includes(QUOTE.single);
|
|
12
|
+
const hasDoubleQuote = value.includes(QUOTE.double);
|
|
13
|
+
const quote = value.includes("\n") || value.includes("${") || hasSingleQuote && hasDoubleQuote ? QUOTE.template : hasSingleQuote ? QUOTE.double : QUOTE.single;
|
|
14
|
+
if (quote === QUOTE.template) {}
|
|
15
|
+
return escapeStringLiteral(value, quote);
|
|
16
|
+
}
|
|
17
|
+
function collectTemplateVariableNames(value) {
|
|
18
|
+
const variables = [];
|
|
19
|
+
for (const match of value.matchAll(TEMPLATE_VARIABLE_REGEX)) {
|
|
20
|
+
const variableName = match.groups?.variableName?.trim();
|
|
21
|
+
if (variableName) variables.push(variableName);
|
|
22
|
+
}
|
|
23
|
+
return variables;
|
|
24
|
+
}
|
|
25
|
+
function formatTemplate(value, references) {
|
|
26
|
+
if (!value.length) return value;
|
|
27
|
+
let didReplace = false;
|
|
28
|
+
const rewrittenValue = value.replace(TEMPLATE_VARIABLE_REGEX, (match, ...args) => {
|
|
29
|
+
const maybeGroups = args.at(-1);
|
|
30
|
+
const variableName = isPlainObject(maybeGroups) && typeof maybeGroups.variableName === "string" ? maybeGroups.variableName.trim() : void 0;
|
|
31
|
+
if (!variableName) return match;
|
|
32
|
+
if (variableName.startsWith("headers.")) {
|
|
33
|
+
const headerPath = variableName.slice(8);
|
|
34
|
+
if (!headerPath || !references.headersReference) return match;
|
|
35
|
+
didReplace = true;
|
|
36
|
+
return `\${${references.headersReference}.toTemplate(${JSON.stringify(headerPath)})}`;
|
|
37
|
+
}
|
|
38
|
+
if (!references.contextReference) return match;
|
|
39
|
+
didReplace = true;
|
|
40
|
+
return `\${${references.contextReference}.toTemplate(${JSON.stringify(variableName)})}`;
|
|
41
|
+
});
|
|
42
|
+
return didReplace ? rewrittenValue : value;
|
|
43
|
+
}
|
|
44
|
+
function formatPropertyName(key) {
|
|
45
|
+
if (/^[a-zA-Z_$][a-zA-Z0-9_$]*$/.test(key)) return key;
|
|
46
|
+
return formatStringLiteral(key);
|
|
47
|
+
}
|
|
48
|
+
function escapeStringLiteral(value, quote) {
|
|
49
|
+
return [
|
|
50
|
+
quote,
|
|
51
|
+
value.replaceAll("\\", "\\\\").replaceAll(quote, `\\${quote}`),
|
|
52
|
+
quote
|
|
53
|
+
].join("");
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
//#endregion
|
|
57
|
+
export { TEMPLATE_VARIABLE_REGEX, collectTemplateVariableNames, formatPropertyName, formatStringLiteral, formatTemplate };
|
|
58
|
+
//# sourceMappingURL=templates.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"templates.js","names":[],"sources":["../../../../src/commands/pull-v4/utils/templates.ts"],"sourcesContent":["import { isPlainObject } from './shared';\n\nconst QUOTE = Object.freeze({\n single: \"'\",\n double: '\"',\n template: '`',\n});\n\ntype Quote = (typeof QUOTE)[keyof typeof QUOTE];\n\nexport const TEMPLATE_VARIABLE_REGEX = /\\{\\{(?!\\{)(?<variableName>[^{}]+)}}/g;\n\ninterface TemplateReplacementReferences {\n contextReference?: string;\n headersReference?: string;\n}\n\nexport function formatStringLiteral(value: string): string {\n const hasSingleQuote = value.includes(QUOTE.single);\n const hasDoubleQuote = value.includes(QUOTE.double);\n const quote =\n value.includes('\\n') || value.includes('${') || (hasSingleQuote && hasDoubleQuote)\n ? QUOTE.template\n : hasSingleQuote\n ? QUOTE.double\n : QUOTE.single;\n if (quote === QUOTE.template) {\n // TODO: should escape variables except when we inject context variables and headers\n // value = value.replaceAll('${', '\\\\${');\n }\n return escapeStringLiteral(value, quote);\n}\n\nexport function collectTemplateVariableNames(value: string): string[] {\n const variables: string[] = [];\n for (const match of value.matchAll(TEMPLATE_VARIABLE_REGEX)) {\n const variableName = match.groups?.variableName?.trim();\n if (variableName) {\n variables.push(variableName);\n }\n }\n return variables;\n}\n\nexport function formatTemplate(value: string, references: TemplateReplacementReferences): string {\n if (!value.length) {\n return value;\n }\n\n let didReplace = false;\n const rewrittenValue = value.replace(\n TEMPLATE_VARIABLE_REGEX,\n (match: string, ...args: unknown[]): string => {\n const maybeGroups = args.at(-1);\n const variableName =\n isPlainObject(maybeGroups) && typeof maybeGroups.variableName === 'string'\n ? maybeGroups.variableName.trim()\n : undefined;\n\n if (!variableName) {\n return match;\n }\n\n if (variableName.startsWith('headers.')) {\n const headerPath = variableName.slice('headers.'.length);\n if (!headerPath || !references.headersReference) {\n return match;\n }\n didReplace = true;\n return `\\${${references.headersReference}.toTemplate(${JSON.stringify(headerPath)})}`;\n }\n\n if (!references.contextReference) {\n return match;\n }\n\n didReplace = true;\n return `\\${${references.contextReference}.toTemplate(${JSON.stringify(variableName)})}`;\n }\n );\n\n return didReplace ? rewrittenValue : value;\n}\n\nexport function formatPropertyName(key: string): string {\n if (/^[a-zA-Z_$][a-zA-Z0-9_$]*$/.test(key)) {\n return key;\n }\n return formatStringLiteral(key);\n}\n\nfunction escapeStringLiteral(value: string, quote: Quote): string {\n return [quote, value.replaceAll('\\\\', '\\\\\\\\').replaceAll(quote, `\\\\${quote}`), quote].join('');\n}\n"],"mappings":";;;AAEA,MAAM,QAAQ,OAAO,OAAO;CAC1B,QAAQ;CACR,QAAQ;CACR,UAAU;CACX,CAAC;AAIF,MAAa,0BAA0B;AAOvC,SAAgB,oBAAoB,OAAuB;CACzD,MAAM,iBAAiB,MAAM,SAAS,MAAM,OAAO;CACnD,MAAM,iBAAiB,MAAM,SAAS,MAAM,OAAO;CACnD,MAAM,QACJ,MAAM,SAAS,KAAK,IAAI,MAAM,SAAS,KAAK,IAAK,kBAAkB,iBAC/D,MAAM,WACN,iBACE,MAAM,SACN,MAAM;AACd,KAAI,UAAU,MAAM,UAAU;AAI9B,QAAO,oBAAoB,OAAO,MAAM;;AAG1C,SAAgB,6BAA6B,OAAyB;CACpE,MAAM,YAAsB,EAAE;AAC9B,MAAK,MAAM,SAAS,MAAM,SAAS,wBAAwB,EAAE;EAC3D,MAAM,eAAe,MAAM,QAAQ,cAAc,MAAM;AACvD,MAAI,aACF,WAAU,KAAK,aAAa;;AAGhC,QAAO;;AAGT,SAAgB,eAAe,OAAe,YAAmD;AAC/F,KAAI,CAAC,MAAM,OACT,QAAO;CAGT,IAAI,aAAa;CACjB,MAAM,iBAAiB,MAAM,QAC3B,0BACC,OAAe,GAAG,SAA4B;EAC7C,MAAM,cAAc,KAAK,GAAG,GAAG;EAC/B,MAAM,eACJ,cAAc,YAAY,IAAI,OAAO,YAAY,iBAAiB,WAC9D,YAAY,aAAa,MAAM,GAC/B;AAEN,MAAI,CAAC,aACH,QAAO;AAGT,MAAI,aAAa,WAAW,WAAW,EAAE;GACvC,MAAM,aAAa,aAAa,MAAM,EAAkB;AACxD,OAAI,CAAC,cAAc,CAAC,WAAW,iBAC7B,QAAO;AAET,gBAAa;AACb,UAAO,MAAM,WAAW,iBAAiB,cAAc,KAAK,UAAU,WAAW,CAAC;;AAGpF,MAAI,CAAC,WAAW,iBACd,QAAO;AAGT,eAAa;AACb,SAAO,MAAM,WAAW,iBAAiB,cAAc,KAAK,UAAU,aAAa,CAAC;GAEvF;AAED,QAAO,aAAa,iBAAiB;;AAGvC,SAAgB,mBAAmB,KAAqB;AACtD,KAAI,6BAA6B,KAAK,IAAI,CACxC,QAAO;AAET,QAAO,oBAAoB,IAAI;;AAGjC,SAAS,oBAAoB,OAAe,OAAsB;AAChE,QAAO;EAAC;EAAO,MAAM,WAAW,MAAM,OAAO,CAAC,WAAW,OAAO,KAAK,QAAQ;EAAE;EAAM,CAAC,KAAK,GAAG"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@inkeep/agents-cli",
|
|
3
|
-
"version": "0.59.
|
|
3
|
+
"version": "0.59.4",
|
|
4
4
|
"description": "Inkeep CLI tool",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -37,8 +37,8 @@
|
|
|
37
37
|
"tsx": "^4.20.5",
|
|
38
38
|
"yaml": "^2.7.0",
|
|
39
39
|
"zod": "^4.3.6",
|
|
40
|
-
"@inkeep/agents-core": "^0.59.
|
|
41
|
-
"@inkeep/agents-sdk": "^0.59.
|
|
40
|
+
"@inkeep/agents-core": "^0.59.4",
|
|
41
|
+
"@inkeep/agents-sdk": "^0.59.4"
|
|
42
42
|
},
|
|
43
43
|
"devDependencies": {
|
|
44
44
|
"diff": "^8.0.3",
|
|
@@ -46,7 +46,7 @@
|
|
|
46
46
|
"@types/fs-extra": "^11.0.4",
|
|
47
47
|
"@types/node": "^22",
|
|
48
48
|
"@vitest/coverage-v8": "^3.2.4",
|
|
49
|
-
"typescript": "^
|
|
49
|
+
"typescript": "^6.0.2",
|
|
50
50
|
"vitest": "^3.2.4"
|
|
51
51
|
},
|
|
52
52
|
"peerDependencies": {
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"skill-generator.js","names":[],"sources":["../../../../src/commands/pull-v4/generators/skill-generator.ts"],"sourcesContent":["import { mkdir, writeFile } from 'node:fs/promises';\nimport { join } from 'node:path';\nimport { FullProjectDefinitionSchema } from '@inkeep/agents-core';\nimport { stringify } from 'yaml';\nimport type { z } from 'zod';\n\nconst MySchema = FullProjectDefinitionSchema.shape.skills.unwrap().valueType;\n\ntype SkillInput = z.input<typeof MySchema>;\n\ntype SkillMap = Record<string, SkillInput>;\n\nfunction formatMetadata(metadata: NonNullable<SkillInput['metadata']>): string {\n const yaml = stringify(metadata);\n const indented = yaml\n .split('\\n')\n .filter((line) => line.trim() !== '')\n .map((line) => ` ${line}`)\n .join('\\n');\n return `metadata:\\n${indented}`;\n}\n\nexport async function generateSkills(skills: SkillMap, skillsDir: string): Promise<void> {\n await mkdir(skillsDir, { recursive: true });\n\n for (const [skillId, skill] of Object.entries(skills)) {\n const parts: string[] = ['---', `name: ${JSON.stringify(skill.name)}`];\n parts.push(`description: ${JSON.stringify(skill.description ?? '')}`);\n\n if (skill.metadata && Object.keys(skill.metadata).length > 0) {\n parts.push(formatMetadata(skill.metadata));\n }\n\n parts.push('---', '', skill.content || '');\n\n const skillDir = join(skillsDir, skillId);\n await mkdir(skillDir, { recursive: true });\n\n const filePath = join(skillDir, 'SKILL.md');\n await writeFile(filePath, parts.join('\\n'), 'utf8');\n }\n}\n"],"mappings":";;;;;;AAMiB,4BAA4B,MAAM,OAAO,QAAQ,CAAC;AAMnE,SAAS,eAAe,UAAuD;AAO7E,QAAO,cANM,UAAU,SAAS,CAE7B,MAAM,KAAK,CACX,QAAQ,SAAS,KAAK,MAAM,KAAK,GAAG,CACpC,KAAK,SAAS,KAAK,OAAO,CAC1B,KAAK,KAAK;;AAIf,eAAsB,eAAe,QAAkB,WAAkC;AACvF,OAAM,MAAM,WAAW,EAAE,WAAW,MAAM,CAAC;AAE3C,MAAK,MAAM,CAAC,SAAS,UAAU,OAAO,QAAQ,OAAO,EAAE;EACrD,MAAM,QAAkB,CAAC,OAAO,SAAS,KAAK,UAAU,MAAM,KAAK,GAAG;AACtE,QAAM,KAAK,gBAAgB,KAAK,UAAU,MAAM,eAAe,GAAG,GAAG;AAErE,MAAI,MAAM,YAAY,OAAO,KAAK,MAAM,SAAS,CAAC,SAAS,EACzD,OAAM,KAAK,eAAe,MAAM,SAAS,CAAC;AAG5C,QAAM,KAAK,OAAO,IAAI,MAAM,WAAW,GAAG;EAE1C,MAAM,WAAW,KAAK,WAAW,QAAQ;AACzC,QAAM,MAAM,UAAU,EAAE,WAAW,MAAM,CAAC;AAG1C,QAAM,UADW,KAAK,UAAU,WAAW,EACjB,MAAM,KAAK,KAAK,EAAE,OAAO"}
|
|
@@ -1,38 +0,0 @@
|
|
|
1
|
-
import { addValueToObject, createFactoryDefinition, toTriggerReferenceName } from "./utils.js";
|
|
2
|
-
import { FullProjectDefinitionSchema } from "@inkeep/agents-core";
|
|
3
|
-
import { z } from "zod";
|
|
4
|
-
import { SyntaxKind } from "ts-morph";
|
|
5
|
-
|
|
6
|
-
//#region src/commands/pull-v4/scheduled-trigger-generator.ts
|
|
7
|
-
const MySchema = FullProjectDefinitionSchema.shape.agents.valueType.shape.scheduledTriggers.unwrap().valueType.omit({
|
|
8
|
-
id: true,
|
|
9
|
-
runAsUserId: true,
|
|
10
|
-
createdBy: true
|
|
11
|
-
});
|
|
12
|
-
const ScheduledTriggerSchema = z.strictObject({
|
|
13
|
-
scheduledTriggerId: z.string().nonempty(),
|
|
14
|
-
...MySchema.shape,
|
|
15
|
-
description: z.preprocess((v) => v ?? void 0, MySchema.shape.description),
|
|
16
|
-
runAt: z.preprocess((v) => v ?? void 0, MySchema.shape.runAt),
|
|
17
|
-
payload: z.preprocess((v) => v ?? void 0, MySchema.shape.payload)
|
|
18
|
-
});
|
|
19
|
-
function generateScheduledTriggerDefinition({ id, runAsUserId, createdBy, ...data }) {
|
|
20
|
-
const result = ScheduledTriggerSchema.safeParse(data);
|
|
21
|
-
if (!result.success) throw new Error(`Validation failed for scheduled trigger:\n${z.prettifyError(result.error)}`);
|
|
22
|
-
const parsed = result.data;
|
|
23
|
-
const { sourceFile, configObject } = createFactoryDefinition({
|
|
24
|
-
importName: "ScheduledTrigger",
|
|
25
|
-
variableName: toTriggerReferenceName(parsed.name),
|
|
26
|
-
syntaxKind: SyntaxKind.NewExpression
|
|
27
|
-
});
|
|
28
|
-
const { scheduledTriggerId, ...rest } = parsed;
|
|
29
|
-
for (const [key, value] of Object.entries({
|
|
30
|
-
id: scheduledTriggerId,
|
|
31
|
-
...rest
|
|
32
|
-
})) addValueToObject(configObject, key, value);
|
|
33
|
-
return sourceFile;
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
//#endregion
|
|
37
|
-
export { generateScheduledTriggerDefinition };
|
|
38
|
-
//# sourceMappingURL=scheduled-trigger-generator.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"scheduled-trigger-generator.js","names":[],"sources":["../../../src/commands/pull-v4/scheduled-trigger-generator.ts"],"sourcesContent":["import { FullProjectDefinitionSchema } from '@inkeep/agents-core';\nimport { type SourceFile, SyntaxKind } from 'ts-morph';\nimport { z } from 'zod';\nimport { addValueToObject, createFactoryDefinition, toTriggerReferenceName } from './utils';\n\nconst MySchema = FullProjectDefinitionSchema.shape.agents.valueType.shape.scheduledTriggers\n .unwrap()\n .valueType.omit({\n id: true,\n runAsUserId: true,\n createdBy: true,\n });\n\nconst ScheduledTriggerSchema = z.strictObject({\n scheduledTriggerId: z.string().nonempty(),\n ...MySchema.shape,\n description: z.preprocess((v) => v ?? undefined, MySchema.shape.description),\n runAt: z.preprocess((v) => v ?? undefined, MySchema.shape.runAt),\n payload: z.preprocess((v) => v ?? undefined, MySchema.shape.payload),\n});\n\ntype ScheduledTriggerInput = z.input<typeof ScheduledTriggerSchema>;\n\nexport function generateScheduledTriggerDefinition({\n id,\n runAsUserId,\n createdBy,\n ...data\n}: ScheduledTriggerInput & Record<string, unknown>): SourceFile {\n const result = ScheduledTriggerSchema.safeParse(data);\n if (!result.success) {\n throw new Error(`Validation failed for scheduled trigger:\\n${z.prettifyError(result.error)}`);\n }\n\n const parsed = result.data;\n const { sourceFile, configObject } = createFactoryDefinition({\n importName: 'ScheduledTrigger',\n variableName: toTriggerReferenceName(parsed.name),\n syntaxKind: SyntaxKind.NewExpression,\n });\n\n const { scheduledTriggerId, ...rest } = parsed;\n\n for (const [key, value] of Object.entries({\n id: scheduledTriggerId,\n ...rest,\n })) {\n addValueToObject(configObject, key, value);\n }\n\n return sourceFile;\n}\n"],"mappings":";;;;;;AAKA,MAAM,WAAW,4BAA4B,MAAM,OAAO,UAAU,MAAM,kBACvE,QAAQ,CACR,UAAU,KAAK;CACd,IAAI;CACJ,aAAa;CACb,WAAW;CACZ,CAAC;AAEJ,MAAM,yBAAyB,EAAE,aAAa;CAC5C,oBAAoB,EAAE,QAAQ,CAAC,UAAU;CACzC,GAAG,SAAS;CACZ,aAAa,EAAE,YAAY,MAAM,KAAK,QAAW,SAAS,MAAM,YAAY;CAC5E,OAAO,EAAE,YAAY,MAAM,KAAK,QAAW,SAAS,MAAM,MAAM;CAChE,SAAS,EAAE,YAAY,MAAM,KAAK,QAAW,SAAS,MAAM,QAAQ;CACrE,CAAC;AAIF,SAAgB,mCAAmC,EACjD,IACA,aACA,WACA,GAAG,QAC2D;CAC9D,MAAM,SAAS,uBAAuB,UAAU,KAAK;AACrD,KAAI,CAAC,OAAO,QACV,OAAM,IAAI,MAAM,6CAA6C,EAAE,cAAc,OAAO,MAAM,GAAG;CAG/F,MAAM,SAAS,OAAO;CACtB,MAAM,EAAE,YAAY,iBAAiB,wBAAwB;EAC3D,YAAY;EACZ,cAAc,uBAAuB,OAAO,KAAK;EACjD,YAAY,WAAW;EACxB,CAAC;CAEF,MAAM,EAAE,oBAAoB,GAAG,SAAS;AAExC,MAAK,MAAM,CAAC,KAAK,UAAU,OAAO,QAAQ;EACxC,IAAI;EACJ,GAAG;EACJ,CAAC,CACA,kBAAiB,cAAc,KAAK,MAAM;AAG5C,QAAO"}
|
|
@@ -1,320 +0,0 @@
|
|
|
1
|
-
import path from "node:path";
|
|
2
|
-
import { IndentationText, NewLineKind, Project, QuoteKind, SyntaxKind, VariableDeclarationKind } from "ts-morph";
|
|
3
|
-
import { jsonSchemaToZod } from "json-schema-to-zod";
|
|
4
|
-
|
|
5
|
-
//#region src/commands/pull-v4/utils.ts
|
|
6
|
-
function createInMemoryProject() {
|
|
7
|
-
return new Project({
|
|
8
|
-
useInMemoryFileSystem: true,
|
|
9
|
-
skipLoadingLibFiles: true,
|
|
10
|
-
manipulationSettings: {
|
|
11
|
-
indentationText: IndentationText.TwoSpaces,
|
|
12
|
-
quoteKind: QuoteKind.Single,
|
|
13
|
-
newLineKind: NewLineKind.LineFeed,
|
|
14
|
-
useTrailingCommas: true
|
|
15
|
-
}
|
|
16
|
-
});
|
|
17
|
-
}
|
|
18
|
-
/**
|
|
19
|
-
* Create variable in following pattern
|
|
20
|
-
*
|
|
21
|
-
* (export)? const VARIABLE_NAME = (new)?IMPORT_NAME({})
|
|
22
|
-
*/
|
|
23
|
-
function addFactoryConfigVariable({ sourceFile, importName, variableName, isExported, syntaxKind = SyntaxKind.CallExpression }) {
|
|
24
|
-
const initializer = `${syntaxKind === SyntaxKind.NewExpression ? "new " : ""}${importName}({})`;
|
|
25
|
-
const [declaration] = sourceFile.addVariableStatement({
|
|
26
|
-
declarationKind: VariableDeclarationKind.Const,
|
|
27
|
-
isExported,
|
|
28
|
-
declarations: [{
|
|
29
|
-
name: variableName,
|
|
30
|
-
initializer
|
|
31
|
-
}]
|
|
32
|
-
}).getDeclarations();
|
|
33
|
-
const [configArg] = declaration.getInitializerIfKindOrThrow(syntaxKind).getArguments();
|
|
34
|
-
return { configObject: configArg.asKindOrThrow(SyntaxKind.ObjectLiteralExpression) };
|
|
35
|
-
}
|
|
36
|
-
function createFactoryDefinition({ importName, variableName: name, fileName = "definition.ts", moduleSpecifier = "@inkeep/agents-sdk", syntaxKind }) {
|
|
37
|
-
const sourceFile = createInMemoryProject().createSourceFile(fileName, "", { overwrite: true });
|
|
38
|
-
sourceFile.addImportDeclaration({
|
|
39
|
-
namedImports: [importName],
|
|
40
|
-
moduleSpecifier
|
|
41
|
-
});
|
|
42
|
-
const localVariableName = resolveNonCollidingName(name, collectTakenNames(sourceFile));
|
|
43
|
-
const shouldAliasExport = localVariableName !== name;
|
|
44
|
-
const { configObject } = addFactoryConfigVariable({
|
|
45
|
-
sourceFile,
|
|
46
|
-
importName,
|
|
47
|
-
variableName: localVariableName,
|
|
48
|
-
isExported: !shouldAliasExport,
|
|
49
|
-
syntaxKind
|
|
50
|
-
});
|
|
51
|
-
if (shouldAliasExport) sourceFile.addExportDeclaration({ namedExports: [{
|
|
52
|
-
name: localVariableName,
|
|
53
|
-
alias: name
|
|
54
|
-
}] });
|
|
55
|
-
return {
|
|
56
|
-
sourceFile,
|
|
57
|
-
configObject
|
|
58
|
-
};
|
|
59
|
-
}
|
|
60
|
-
function collectTakenNames(sourceFile) {
|
|
61
|
-
const takenNames = /* @__PURE__ */ new Set();
|
|
62
|
-
for (const importDeclaration of sourceFile.getImportDeclarations()) {
|
|
63
|
-
const defaultImport = importDeclaration.getDefaultImport()?.getText();
|
|
64
|
-
if (defaultImport) takenNames.add(defaultImport);
|
|
65
|
-
const namespaceImport = importDeclaration.getNamespaceImport()?.getText();
|
|
66
|
-
if (namespaceImport) takenNames.add(namespaceImport);
|
|
67
|
-
for (const namedImport of importDeclaration.getNamedImports()) {
|
|
68
|
-
const localName = namedImport.getAliasNode()?.getText() ?? namedImport.getName();
|
|
69
|
-
takenNames.add(localName);
|
|
70
|
-
}
|
|
71
|
-
}
|
|
72
|
-
for (const variableDeclaration of sourceFile.getVariableDeclarations()) takenNames.add(variableDeclaration.getName());
|
|
73
|
-
return takenNames;
|
|
74
|
-
}
|
|
75
|
-
function resolveNonCollidingName(baseName, reservedNames, startIndex = 1) {
|
|
76
|
-
if (!reservedNames.has(baseName)) {
|
|
77
|
-
reservedNames.add(baseName);
|
|
78
|
-
return baseName;
|
|
79
|
-
}
|
|
80
|
-
let index = startIndex;
|
|
81
|
-
while (reservedNames.has(`${baseName}${index}`)) index += 1;
|
|
82
|
-
const uniqueName = `${baseName}${index}`;
|
|
83
|
-
reservedNames.add(uniqueName);
|
|
84
|
-
return uniqueName;
|
|
85
|
-
}
|
|
86
|
-
function toCamelCase(input) {
|
|
87
|
-
const result = input.toLowerCase().replaceAll(/\W/g, " ").trim().replaceAll(/[\s_]+(.)/g, (_, char) => char.toUpperCase()).replace(/^[0-9]/, "_$&");
|
|
88
|
-
return result.charAt(0).toLowerCase() + result.slice(1);
|
|
89
|
-
}
|
|
90
|
-
function toToolReferenceName(input) {
|
|
91
|
-
const base = toCamelCase(input);
|
|
92
|
-
return base.endsWith("Tool") ? base : `${base}Tool`;
|
|
93
|
-
}
|
|
94
|
-
function toCredentialReferenceName(input) {
|
|
95
|
-
const base = toCamelCase(input);
|
|
96
|
-
return base.endsWith("Credential") ? base : `${base}Credential`;
|
|
97
|
-
}
|
|
98
|
-
function toTriggerReferenceName(input) {
|
|
99
|
-
const base = toCamelCase(input);
|
|
100
|
-
return base.endsWith("Trigger") ? base : `${base}Trigger`;
|
|
101
|
-
}
|
|
102
|
-
function toKebabCase(input) {
|
|
103
|
-
return input.trim().replace(/([a-z])([A-Z])/g, "$1-$2").replace(/[^a-zA-Z0-9]+/g, "-").replace(/^-+|-+$/g, "").toLowerCase();
|
|
104
|
-
}
|
|
105
|
-
const UUID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
|
|
106
|
-
const CUID_RE = /^c[a-z0-9]{24,}$/;
|
|
107
|
-
const NANOID_RE = /^[a-z0-9]{16,}$/;
|
|
108
|
-
function isHumanReadableId(id) {
|
|
109
|
-
if (UUID_RE.test(id) || CUID_RE.test(id) || NANOID_RE.test(id)) return false;
|
|
110
|
-
const segments = id.split(/[-_]/);
|
|
111
|
-
if (segments.length === 1 && id.length > 8) {
|
|
112
|
-
const hasLetters = /[a-zA-Z]/.test(id);
|
|
113
|
-
const hasDigits = /[0-9]/.test(id);
|
|
114
|
-
if (hasLetters && hasDigits) return false;
|
|
115
|
-
}
|
|
116
|
-
return segments.filter((s) => /^[a-zA-Z]+\d{0,2}$/.test(s)).length / segments.length >= .5;
|
|
117
|
-
}
|
|
118
|
-
const ID_SUFFIX_LENGTH = 8;
|
|
119
|
-
function buildComponentFileName(id, name) {
|
|
120
|
-
if (!name || isHumanReadableId(id)) return `${id}.ts`;
|
|
121
|
-
const kebabName = toKebabCase(name);
|
|
122
|
-
if (!kebabName || kebabName === id) return `${id}.ts`;
|
|
123
|
-
return `${kebabName}-${id.slice(-ID_SUFFIX_LENGTH)}.ts`;
|
|
124
|
-
}
|
|
125
|
-
function createUniqueReferenceName(baseName, reservedNames, conflictSuffix) {
|
|
126
|
-
if (!reservedNames.has(baseName)) {
|
|
127
|
-
reservedNames.add(baseName);
|
|
128
|
-
return baseName;
|
|
129
|
-
}
|
|
130
|
-
const baseCandidate = `${baseName}${conflictSuffix}`;
|
|
131
|
-
if (!reservedNames.has(baseCandidate)) {
|
|
132
|
-
reservedNames.add(baseCandidate);
|
|
133
|
-
return baseCandidate;
|
|
134
|
-
}
|
|
135
|
-
return resolveNonCollidingName(baseCandidate, reservedNames, 2);
|
|
136
|
-
}
|
|
137
|
-
function resolveImportedReference(importName, reservedNames, conflictSuffix, isLocal = false) {
|
|
138
|
-
if (isLocal) {
|
|
139
|
-
reservedNames.add(importName);
|
|
140
|
-
return { referenceName: importName };
|
|
141
|
-
}
|
|
142
|
-
const referenceName = createUniqueReferenceName(importName, reservedNames, conflictSuffix);
|
|
143
|
-
return {
|
|
144
|
-
referenceName,
|
|
145
|
-
namedImport: importName === referenceName ? importName : {
|
|
146
|
-
name: importName,
|
|
147
|
-
alias: referenceName
|
|
148
|
-
}
|
|
149
|
-
};
|
|
150
|
-
}
|
|
151
|
-
function resolveContextTemplateImports(options) {
|
|
152
|
-
const namedImports = [];
|
|
153
|
-
let contextReferenceName;
|
|
154
|
-
let headersReferenceName;
|
|
155
|
-
if (options.shouldResolveContextReference) {
|
|
156
|
-
const contextImportName = options.contextConfigReference?.name ?? options.defaultContextImportName;
|
|
157
|
-
if (contextImportName) {
|
|
158
|
-
const contextImportRef = resolveImportedReference(contextImportName, options.reservedNames, "ContextConfig", options.contextConfigReference?.local === true);
|
|
159
|
-
contextReferenceName = contextImportRef.referenceName;
|
|
160
|
-
if (contextImportRef.namedImport) namedImports.push(contextImportRef.namedImport);
|
|
161
|
-
}
|
|
162
|
-
}
|
|
163
|
-
if (options.shouldResolveHeadersReference) {
|
|
164
|
-
const headersImportName = options.contextConfigHeadersReference?.name ?? options.defaultHeadersImportName;
|
|
165
|
-
if (headersImportName) {
|
|
166
|
-
const headersImportRef = resolveImportedReference(headersImportName, options.reservedNames, "Headers", options.contextConfigHeadersReference?.local === true);
|
|
167
|
-
headersReferenceName = headersImportRef.referenceName;
|
|
168
|
-
if (headersImportRef.namedImport) namedImports.push(headersImportRef.namedImport);
|
|
169
|
-
}
|
|
170
|
-
}
|
|
171
|
-
return {
|
|
172
|
-
contextReferenceName,
|
|
173
|
-
headersReferenceName,
|
|
174
|
-
namedImports
|
|
175
|
-
};
|
|
176
|
-
}
|
|
177
|
-
function resolveReferenceName(referenceId, referenceOverrides) {
|
|
178
|
-
for (const overrideMap of referenceOverrides) {
|
|
179
|
-
const overrideName = overrideMap?.[referenceId];
|
|
180
|
-
if (overrideName) return overrideName;
|
|
181
|
-
}
|
|
182
|
-
return toCamelCase(referenceId);
|
|
183
|
-
}
|
|
184
|
-
function convertJsonSchemaToZodSafe(schema, options) {
|
|
185
|
-
if (!isPlainObject(schema)) {
|
|
186
|
-
console.warn("Schema conversion skipped: non-object schema provided, using z.any()");
|
|
187
|
-
return "z.any()";
|
|
188
|
-
}
|
|
189
|
-
try {
|
|
190
|
-
return jsonSchemaToZod(schema, options?.conversionOptions);
|
|
191
|
-
} catch (error) {
|
|
192
|
-
console.warn(`Schema conversion failed: ${error instanceof Error ? error.message : String(error)}. Falling back to z.any()`);
|
|
193
|
-
return "z.any()";
|
|
194
|
-
}
|
|
195
|
-
}
|
|
196
|
-
function isPlainObject(value) {
|
|
197
|
-
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
198
|
-
}
|
|
199
|
-
const QUOTE = Object.freeze({
|
|
200
|
-
single: "'",
|
|
201
|
-
double: "\"",
|
|
202
|
-
template: "`"
|
|
203
|
-
});
|
|
204
|
-
const TEMPLATE_VARIABLE_REGEX = /\{\{(?!\{)(?<variableName>[^{}]+)}}/g;
|
|
205
|
-
function formatStringLiteral(value) {
|
|
206
|
-
const hasSingleQuote = value.includes(QUOTE.single);
|
|
207
|
-
const hasDoubleQuote = value.includes(QUOTE.double);
|
|
208
|
-
return escapeStringLiteral(value, value.includes("\n") || value.includes("${") || hasSingleQuote && hasDoubleQuote ? QUOTE.template : hasSingleQuote ? QUOTE.double : QUOTE.single);
|
|
209
|
-
}
|
|
210
|
-
function collectTemplateVariableNames(value) {
|
|
211
|
-
const variables = [];
|
|
212
|
-
for (const match of value.matchAll(TEMPLATE_VARIABLE_REGEX)) {
|
|
213
|
-
const variableName = match.groups?.variableName?.trim();
|
|
214
|
-
if (variableName) variables.push(variableName);
|
|
215
|
-
}
|
|
216
|
-
return variables;
|
|
217
|
-
}
|
|
218
|
-
function formatTemplate(value, references) {
|
|
219
|
-
if (!value.length) return value;
|
|
220
|
-
let didReplace = false;
|
|
221
|
-
const rewrittenValue = value.replace(TEMPLATE_VARIABLE_REGEX, (match, ...args) => {
|
|
222
|
-
const maybeGroups = args.at(-1);
|
|
223
|
-
const variableName = isPlainObject(maybeGroups) && typeof maybeGroups.variableName === "string" ? maybeGroups.variableName.trim() : void 0;
|
|
224
|
-
if (!variableName) return match;
|
|
225
|
-
if (variableName.startsWith("headers.")) {
|
|
226
|
-
const headerPath = variableName.slice(8);
|
|
227
|
-
if (!headerPath || !references.headersReference) return match;
|
|
228
|
-
didReplace = true;
|
|
229
|
-
return `\${${references.headersReference}.toTemplate(${JSON.stringify(headerPath)})}`;
|
|
230
|
-
}
|
|
231
|
-
if (!references.contextReference) return match;
|
|
232
|
-
didReplace = true;
|
|
233
|
-
return `\${${references.contextReference}.toTemplate(${JSON.stringify(variableName)})}`;
|
|
234
|
-
});
|
|
235
|
-
return didReplace ? rewrittenValue : value;
|
|
236
|
-
}
|
|
237
|
-
function escapeStringLiteral(value, quote) {
|
|
238
|
-
return [
|
|
239
|
-
quote,
|
|
240
|
-
value.replaceAll("\\", "\\\\").replaceAll(quote, `\\${quote}`),
|
|
241
|
-
quote
|
|
242
|
-
].join("");
|
|
243
|
-
}
|
|
244
|
-
function formatPropertyName(key) {
|
|
245
|
-
if (/^[a-zA-Z_$][a-zA-Z0-9_$]*$/.test(key)) return key;
|
|
246
|
-
return formatStringLiteral(key);
|
|
247
|
-
}
|
|
248
|
-
function formatInlineLiteral(value) {
|
|
249
|
-
if (typeof value === "string") return formatStringLiteral(value);
|
|
250
|
-
if (typeof value === "number" || typeof value === "bigint") return String(value);
|
|
251
|
-
if (typeof value === "boolean") return value ? "true" : "false";
|
|
252
|
-
if (value === null) return "null";
|
|
253
|
-
if (Array.isArray(value)) return `[${value.map((item) => formatInlineLiteral(item)).join(", ")}]`;
|
|
254
|
-
if (isPlainObject(value)) {
|
|
255
|
-
const entries = Object.entries(value).filter(([, entryValue]) => entryValue !== void 0);
|
|
256
|
-
if (!entries.length) return "{}";
|
|
257
|
-
return `{ ${entries.map(([key, entryValue]) => `${formatPropertyName(key)}: ${formatInlineLiteral(entryValue)}`).join(", ")} }`;
|
|
258
|
-
}
|
|
259
|
-
return "undefined";
|
|
260
|
-
}
|
|
261
|
-
function addReferenceGetterProperty(configObject, key, refs) {
|
|
262
|
-
configObject.addPropertyAssignment({
|
|
263
|
-
name: key,
|
|
264
|
-
initializer: "() => []"
|
|
265
|
-
}).getInitializerIfKindOrThrow(SyntaxKind.ArrowFunction).getBody().asKindOrThrow(SyntaxKind.ArrayLiteralExpression).addElements(refs);
|
|
266
|
-
}
|
|
267
|
-
function addStringProperty(configObject, key, value) {
|
|
268
|
-
configObject.addPropertyAssignment({
|
|
269
|
-
name: key,
|
|
270
|
-
initializer: formatStringLiteral(value)
|
|
271
|
-
});
|
|
272
|
-
}
|
|
273
|
-
function addValueToObject(obj, key, value) {
|
|
274
|
-
if (value === void 0) return;
|
|
275
|
-
if (isPlainObject(value)) {
|
|
276
|
-
const child = obj.addPropertyAssignment({
|
|
277
|
-
name: formatPropertyName(key),
|
|
278
|
-
initializer: "{}"
|
|
279
|
-
}).getInitializerIfKindOrThrow(SyntaxKind.ObjectLiteralExpression);
|
|
280
|
-
for (const [k, v] of Object.entries(value)) addValueToObject(child, k, v);
|
|
281
|
-
return;
|
|
282
|
-
}
|
|
283
|
-
if (Array.isArray(value)) {
|
|
284
|
-
const arr = obj.addPropertyAssignment({
|
|
285
|
-
name: formatPropertyName(key),
|
|
286
|
-
initializer: "[]"
|
|
287
|
-
}).getInitializerIfKindOrThrow(SyntaxKind.ArrayLiteralExpression);
|
|
288
|
-
for (const item of value) addValueToArray(arr, item);
|
|
289
|
-
return;
|
|
290
|
-
}
|
|
291
|
-
obj.addPropertyAssignment({
|
|
292
|
-
name: formatPropertyName(key),
|
|
293
|
-
initializer: formatInlineLiteral(value)
|
|
294
|
-
});
|
|
295
|
-
}
|
|
296
|
-
function addValueToArray(arr, value) {
|
|
297
|
-
if (isPlainObject(value)) {
|
|
298
|
-
const child = arr.addElement("{}").asKindOrThrow(SyntaxKind.ObjectLiteralExpression);
|
|
299
|
-
for (const [k, v] of Object.entries(value)) addValueToObject(child, k, v);
|
|
300
|
-
return;
|
|
301
|
-
}
|
|
302
|
-
if (Array.isArray(value)) {
|
|
303
|
-
const child = arr.addElement("[]").asKindOrThrow(SyntaxKind.ArrayLiteralExpression);
|
|
304
|
-
for (const item of value) addValueToArray(child, item);
|
|
305
|
-
return;
|
|
306
|
-
}
|
|
307
|
-
arr.addElement(formatInlineLiteral(value));
|
|
308
|
-
}
|
|
309
|
-
async function expectSnapshots(definitionV4) {
|
|
310
|
-
const { currentTestName, snapshotState } = expect.getState();
|
|
311
|
-
const snapshotDir = path.basename(snapshotState.testFilePath).replace("-generator.test.ts", "");
|
|
312
|
-
await expect(definitionV4).toMatchFileSnapshot(`__snapshots__/${snapshotDir}/${currentTestName}-v4.txt`);
|
|
313
|
-
}
|
|
314
|
-
function hasReferences(references) {
|
|
315
|
-
return Array.isArray(references) && references.length > 0;
|
|
316
|
-
}
|
|
317
|
-
|
|
318
|
-
//#endregion
|
|
319
|
-
export { TEMPLATE_VARIABLE_REGEX, addFactoryConfigVariable, addReferenceGetterProperty, addStringProperty, addValueToObject, buildComponentFileName, collectTemplateVariableNames, convertJsonSchemaToZodSafe, createFactoryDefinition, createInMemoryProject, createUniqueReferenceName, expectSnapshots, formatInlineLiteral, formatPropertyName, formatStringLiteral, formatTemplate, hasReferences, isHumanReadableId, isPlainObject, resolveContextTemplateImports, resolveImportedReference, resolveNonCollidingName, resolveReferenceName, toCamelCase, toCredentialReferenceName, toKebabCase, toToolReferenceName, toTriggerReferenceName };
|
|
320
|
-
//# sourceMappingURL=utils.js.map
|