@inkeep/agents-cli 0.51.0 → 0.53.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (76) hide show
  1. package/dist/agents-cli/package.js +6 -0
  2. package/dist/commands/config.js +1 -1
  3. package/dist/commands/dev.js +1 -1
  4. package/dist/commands/init.js +1 -1
  5. package/dist/commands/{pull-v3 → pull-v4}/component-parser.js +6 -12
  6. package/dist/commands/{pull-v3/utils → pull-v4}/component-registry.js +1 -1
  7. package/dist/commands/pull-v4/generators/agent-generator.js +258 -0
  8. package/dist/commands/pull-v4/generators/artifact-component-generator.js +69 -0
  9. package/dist/commands/pull-v4/generators/context-config-generator.js +264 -0
  10. package/dist/commands/pull-v4/generators/credential-generator.js +30 -0
  11. package/dist/commands/pull-v4/generators/data-component-generator.js +50 -0
  12. package/dist/commands/pull-v4/generators/environment-generator.js +123 -0
  13. package/dist/commands/pull-v4/generators/external-agent-generator.js +56 -0
  14. package/dist/commands/pull-v4/generators/function-tool-generator.js +48 -0
  15. package/dist/commands/pull-v4/generators/mcp-tool-generator.js +91 -0
  16. package/dist/commands/pull-v4/generators/project-generator.js +125 -0
  17. package/dist/commands/{pull-v3/components → pull-v4/generators}/skill-generator.js +1 -1
  18. package/dist/commands/pull-v4/generators/status-component-generator.js +35 -0
  19. package/dist/commands/pull-v4/generators/sub-agent-generator.js +269 -0
  20. package/dist/commands/pull-v4/generators/trigger-generator.js +58 -0
  21. package/dist/commands/pull-v4/introspect/index.js +365 -0
  22. package/dist/commands/pull-v4/introspect/test-helpers.js +143 -0
  23. package/dist/commands/pull-v4/introspect-generator.js +706 -0
  24. package/dist/commands/pull-v4/module-merge.js +405 -0
  25. package/dist/commands/pull-v4/utils.js +235 -0
  26. package/dist/commands/push.js +1 -1
  27. package/dist/commands/update.js +2 -2
  28. package/dist/index.js +18 -44
  29. package/dist/node_modules/.pnpm/diff@8.0.3/node_modules/diff/libesm/diff/array.js +18 -0
  30. package/dist/node_modules/.pnpm/diff@8.0.3/node_modules/diff/libesm/diff/base.js +180 -0
  31. package/dist/node_modules/.pnpm/diff@8.0.3/node_modules/diff/libesm/diff/character.js +8 -0
  32. package/dist/node_modules/.pnpm/diff@8.0.3/node_modules/diff/libesm/diff/css.js +12 -0
  33. package/dist/node_modules/.pnpm/diff@8.0.3/node_modules/diff/libesm/diff/json.js +60 -0
  34. package/dist/node_modules/.pnpm/diff@8.0.3/node_modules/diff/libesm/diff/line.js +37 -0
  35. package/dist/node_modules/.pnpm/diff@8.0.3/node_modules/diff/libesm/diff/sentence.js +31 -0
  36. package/dist/node_modules/.pnpm/diff@8.0.3/node_modules/diff/libesm/diff/word.js +118 -0
  37. package/dist/node_modules/.pnpm/diff@8.0.3/node_modules/diff/libesm/index.js +11 -0
  38. package/dist/node_modules/.pnpm/diff@8.0.3/node_modules/diff/libesm/patch/create.js +141 -0
  39. package/dist/node_modules/.pnpm/diff@8.0.3/node_modules/diff/libesm/util/string.js +63 -0
  40. package/dist/utils/ci-environment.js +1 -1
  41. package/dist/utils/config.js +1 -1
  42. package/dist/utils/environment-loader.js +1 -1
  43. package/dist/utils/file-finder.js +1 -1
  44. package/dist/utils/mcp-runner.js +1 -1
  45. package/dist/utils/profile-config.js +1 -1
  46. package/dist/utils/profiles/profile-manager.js +1 -1
  47. package/dist/utils/project-directory.js +1 -1
  48. package/dist/utils/project-loader.js +1 -1
  49. package/dist/utils/version-check.js +6 -15
  50. package/package.json +5 -7
  51. package/dist/commands/pull-v3/component-updater.js +0 -768
  52. package/dist/commands/pull-v3/components/agent-generator.js +0 -255
  53. package/dist/commands/pull-v3/components/artifact-component-generator.js +0 -143
  54. package/dist/commands/pull-v3/components/context-config-generator.js +0 -190
  55. package/dist/commands/pull-v3/components/credential-generator.js +0 -89
  56. package/dist/commands/pull-v3/components/data-component-generator.js +0 -102
  57. package/dist/commands/pull-v3/components/environment-generator.js +0 -173
  58. package/dist/commands/pull-v3/components/external-agent-generator.js +0 -75
  59. package/dist/commands/pull-v3/components/function-tool-generator.js +0 -92
  60. package/dist/commands/pull-v3/components/mcp-tool-generator.js +0 -86
  61. package/dist/commands/pull-v3/components/project-generator.js +0 -157
  62. package/dist/commands/pull-v3/components/status-component-generator.js +0 -92
  63. package/dist/commands/pull-v3/components/sub-agent-generator.js +0 -295
  64. package/dist/commands/pull-v3/components/trigger-generator.js +0 -185
  65. package/dist/commands/pull-v3/index.js +0 -510
  66. package/dist/commands/pull-v3/introspect-generator.js +0 -286
  67. package/dist/commands/pull-v3/llm-content-merger.js +0 -192
  68. package/dist/commands/pull-v3/new-component-generator.js +0 -279
  69. package/dist/commands/pull-v3/project-comparator.js +0 -914
  70. package/dist/commands/pull-v3/project-index-generator.js +0 -32
  71. package/dist/commands/pull-v3/project-validator.js +0 -358
  72. package/dist/commands/pull-v3/targeted-typescript-placeholders.js +0 -173
  73. package/dist/commands/pull-v3/utils/component-tracker.js +0 -165
  74. package/dist/commands/pull-v3/utils/generator-utils.js +0 -146
  75. package/dist/commands/pull-v3/utils/model-provider-detector.js +0 -50
  76. package/dist/utils/url.js +0 -26
@@ -0,0 +1,706 @@
1
+ import { collectTemplateVariableNames, createInMemoryProject, isPlainObject, toCamelCase } from "./utils.js";
2
+ import { buildComponentRegistryFromParsing } from "./component-parser.js";
3
+ import { generateAgentDefinition } from "./generators/agent-generator.js";
4
+ import { generateArtifactComponentDefinition } from "./generators/artifact-component-generator.js";
5
+ import { generateContextConfigDefinition } from "./generators/context-config-generator.js";
6
+ import { generateCredentialDefinition } from "./generators/credential-generator.js";
7
+ import { generateDataComponentDefinition } from "./generators/data-component-generator.js";
8
+ import { generateMcpToolDefinition } from "./generators/mcp-tool-generator.js";
9
+ import { generateProjectDefinition } from "./generators/project-generator.js";
10
+ import { generateStatusComponentDefinition } from "./generators/status-component-generator.js";
11
+ import { generateSubAgentDefinition } from "./generators/sub-agent-generator.js";
12
+ import { generateTriggerDefinition } from "./generators/trigger-generator.js";
13
+ import { mergeGeneratedModule } from "./module-merge.js";
14
+ import { dirname, join } from "node:path";
15
+ import { Node, SyntaxKind } from "ts-morph";
16
+ import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
17
+
18
+ //#region src/commands/pull-v4/introspect-generator.ts
19
+ async function introspectGenerate({ project, paths, writeMode = "merge", failOnUnsupportedComponents = false, debug = false }) {
20
+ validateProject(project);
21
+ const skippedAgents = [];
22
+ const context = {
23
+ project,
24
+ paths,
25
+ completeAgentIds: collectCompleteAgentIds(project, skippedAgents),
26
+ existingComponentRegistry: writeMode === "merge" ? buildComponentRegistryFromParsing(paths.projectRoot, debug) : void 0
27
+ };
28
+ const tasks = createGenerationTasks();
29
+ const failures = [];
30
+ const generatedFiles = [];
31
+ for (const task of tasks) {
32
+ const records = task.collect(context);
33
+ for (const record of records) {
34
+ const sourceFile = task.generate(record.payload);
35
+ writeTypeScriptFile(record.filePath, sourceFile.getFullText(), writeMode);
36
+ generatedFiles.push(record.filePath);
37
+ }
38
+ }
39
+ const unsupportedCounts = collectUnsupportedComponentCounts(project);
40
+ if (failOnUnsupportedComponents && hasUnsupportedComponents(unsupportedCounts)) failures.push(formatUnsupportedComponentsError(unsupportedCounts));
41
+ if (failures.length > 0) throw new Error(`Inkeep Pull failed:\n${failures.join("\n")}`);
42
+ if (debug) {
43
+ console.log(`Generated ${generatedFiles.length} files`);
44
+ if (skippedAgents.length > 0) console.log(`Skipped ${skippedAgents.length} agent(s): ${skippedAgents.map((agent) => `${agent.id} (${agent.reason})`).join(", ")}`);
45
+ if (hasUnsupportedComponents(unsupportedCounts)) console.log(formatUnsupportedComponentsWarning(unsupportedCounts));
46
+ }
47
+ }
48
+ function createGenerationTasks() {
49
+ return [
50
+ {
51
+ type: "credential",
52
+ collect: collectCredentialRecords,
53
+ generate: generateCredentialDefinition
54
+ },
55
+ {
56
+ type: "artifact-component",
57
+ collect: collectArtifactComponentRecords,
58
+ generate: generateArtifactComponentDefinition
59
+ },
60
+ {
61
+ type: "data-component",
62
+ collect: collectDataComponentRecords,
63
+ generate: generateDataComponentDefinition
64
+ },
65
+ {
66
+ type: "tool",
67
+ collect: collectToolRecords,
68
+ generate: generateMcpToolDefinition
69
+ },
70
+ {
71
+ type: "context-config",
72
+ collect: collectContextConfigRecords,
73
+ generate: generateContextConfigDefinition
74
+ },
75
+ {
76
+ type: "trigger",
77
+ collect: collectTriggerRecords,
78
+ generate: generateTriggerDefinition
79
+ },
80
+ {
81
+ type: "sub-agent",
82
+ collect: collectSubAgentRecords,
83
+ generate: generateSubAgentDefinition
84
+ },
85
+ {
86
+ type: "status-component",
87
+ collect: collectStatusComponentRecords,
88
+ generate: generateStatusComponentDefinition
89
+ },
90
+ {
91
+ type: "agent",
92
+ collect: collectAgentRecords,
93
+ generate: generateAgentDefinition
94
+ },
95
+ {
96
+ type: "project",
97
+ collect: collectProjectRecord,
98
+ generate: generateProjectDefinition
99
+ }
100
+ ];
101
+ }
102
+ function collectCredentialRecords(context) {
103
+ if (!context.project.credentialReferences) return [];
104
+ return Object.entries(context.project.credentialReferences).map(([credentialId, credentialData]) => ({
105
+ id: credentialId,
106
+ filePath: resolveRecordFilePath(context, "credentials", credentialId, join(context.paths.credentialsDir, `${credentialId}.ts`)),
107
+ payload: {
108
+ credentialId,
109
+ ...credentialData
110
+ }
111
+ }));
112
+ }
113
+ function collectArtifactComponentRecords(context) {
114
+ if (!context.project.artifactComponents) return [];
115
+ return Object.entries(context.project.artifactComponents).map(([artifactComponentId, artifactComponentData]) => ({
116
+ id: artifactComponentId,
117
+ filePath: resolveRecordFilePath(context, "artifactComponents", artifactComponentId, join(context.paths.artifactComponentsDir, `${artifactComponentId}.ts`)),
118
+ payload: {
119
+ artifactComponentId,
120
+ ...artifactComponentData
121
+ }
122
+ }));
123
+ }
124
+ function collectDataComponentRecords(context) {
125
+ if (!context.project.dataComponents) return [];
126
+ return Object.entries(context.project.dataComponents).map(([dataComponentId, dataComponent]) => ({
127
+ id: dataComponentId,
128
+ filePath: resolveRecordFilePath(context, "dataComponents", dataComponentId, join(context.paths.dataComponentsDir, `${dataComponentId}.ts`)),
129
+ payload: {
130
+ dataComponentId,
131
+ ...dataComponent
132
+ }
133
+ }));
134
+ }
135
+ function collectContextConfigRecords(context) {
136
+ if (!context.project.agents) return [];
137
+ const contextConfigRecordsById = /* @__PURE__ */ new Map();
138
+ for (const agentId of context.completeAgentIds) {
139
+ const agentData = context.project.agents[agentId];
140
+ const contextConfig = agentData ? asRecord(agentData.contextConfig) : void 0;
141
+ if (!agentData || !contextConfig) continue;
142
+ const normalizedContextConfig = applyPromptHeaderTemplateSchema(contextConfig, collectHeaderTemplateVariablesFromAgentPrompts(agentData));
143
+ const contextConfigId = typeof normalizedContextConfig.id === "string" ? normalizedContextConfig.id : "";
144
+ if (!contextConfigId) continue;
145
+ if (!contextConfigRecordsById.has(contextConfigId)) {
146
+ const contextConfigFilePath = resolveRecordFilePath(context, "contextConfigs", contextConfigId, join(context.paths.contextConfigsDir, `${contextConfigId}.ts`));
147
+ const credentialReferenceOverrides = collectContextConfigCredentialReferenceOverrides(context, normalizedContextConfig);
148
+ const headersReferenceOverride = collectContextConfigHeadersReferenceOverride(context, contextConfigId, contextConfigFilePath);
149
+ contextConfigRecordsById.set(contextConfigId, {
150
+ id: contextConfigId,
151
+ filePath: contextConfigFilePath,
152
+ payload: {
153
+ contextConfigId,
154
+ ...normalizedContextConfig,
155
+ ...headersReferenceOverride && { headers: headersReferenceOverride },
156
+ ...credentialReferenceOverrides && { referenceOverrides: { credentialReferences: credentialReferenceOverrides } }
157
+ }
158
+ });
159
+ }
160
+ }
161
+ return [...contextConfigRecordsById.values()];
162
+ }
163
+ function collectToolRecords(context) {
164
+ return Object.entries(context.project.tools ?? {}).map(([toolId, toolData]) => ({
165
+ id: toolId,
166
+ filePath: resolveRecordFilePath(context, "tools", toolId, join(context.paths.toolsDir, `${toolId}.ts`)),
167
+ payload: {
168
+ mcpToolId: toolId,
169
+ ...toolData
170
+ }
171
+ }));
172
+ }
173
+ function collectContextConfigCredentialReferenceOverrides(context, contextConfigData) {
174
+ const registry = context.existingComponentRegistry;
175
+ if (!registry) return;
176
+ const contextVariables = asRecord(contextConfigData.contextVariables);
177
+ if (!contextVariables) return;
178
+ const overrides = {};
179
+ for (const contextVariable of Object.values(contextVariables)) {
180
+ const contextVariableRecord = asRecord(contextVariable);
181
+ const credentialReferenceId = contextVariableRecord && typeof contextVariableRecord.credentialReferenceId === "string" ? contextVariableRecord.credentialReferenceId : void 0;
182
+ if (!credentialReferenceId) continue;
183
+ const existingCredential = registry.get(credentialReferenceId, "credentials");
184
+ if (existingCredential?.name) overrides[credentialReferenceId] = existingCredential.name;
185
+ }
186
+ return Object.keys(overrides).length ? overrides : void 0;
187
+ }
188
+ function collectContextConfigHeadersReferenceOverride(context, contextConfigId, filePath) {
189
+ if (!context.existingComponentRegistry || !existsSync(filePath)) return;
190
+ const sourceFile = createInMemoryProject().createSourceFile("existing-context-config.ts", readFileSync(filePath, "utf8"), { overwrite: true });
191
+ for (const declaration of sourceFile.getVariableDeclarations()) {
192
+ const initializer = declaration.getInitializer();
193
+ if (!initializer || !Node.isCallExpression(initializer)) continue;
194
+ const expression = initializer.getExpression();
195
+ if (!Node.isIdentifier(expression) || expression.getText() !== "contextConfig") continue;
196
+ const [configArg] = initializer.getArguments();
197
+ if (!configArg || !Node.isObjectLiteralExpression(configArg)) continue;
198
+ const idProperty = configArg.getProperty("id");
199
+ if (!idProperty || !Node.isPropertyAssignment(idProperty)) continue;
200
+ const idInitializer = idProperty.getInitializer();
201
+ if (!idInitializer || !Node.isStringLiteral(idInitializer)) continue;
202
+ if (idInitializer.getLiteralValue() !== contextConfigId) continue;
203
+ const headersProperty = configArg.getProperty("headers");
204
+ if (!headersProperty) return;
205
+ if (Node.isShorthandPropertyAssignment(headersProperty)) return headersProperty.getName();
206
+ if (!Node.isPropertyAssignment(headersProperty)) return;
207
+ const headersInitializer = headersProperty.getInitializer();
208
+ if (!headersInitializer) return;
209
+ if (Node.isIdentifier(headersInitializer)) return headersInitializer.getText();
210
+ if (Node.isAsExpression(headersInitializer)) {
211
+ const valueExpression = headersInitializer.getExpression();
212
+ if (Node.isIdentifier(valueExpression)) return valueExpression.getText();
213
+ }
214
+ return;
215
+ }
216
+ }
217
+ function collectTriggerRecords(context) {
218
+ if (!context.project.agents) return [];
219
+ const records = [];
220
+ for (const agentId of context.completeAgentIds) {
221
+ const agentData = context.project.agents[agentId];
222
+ if (!agentData?.triggers) continue;
223
+ for (const [triggerId, triggerData] of Object.entries(agentData.triggers)) records.push({
224
+ id: triggerId,
225
+ filePath: resolveRecordFilePath(context, "triggers", triggerId, join(context.paths.agentsDir, "triggers", `${triggerId}.ts`)),
226
+ payload: {
227
+ triggerId,
228
+ ...triggerData
229
+ }
230
+ });
231
+ }
232
+ return records;
233
+ }
234
+ function collectAgentRecords(context) {
235
+ if (!context.project.agents) return [];
236
+ const records = [];
237
+ for (const agentId of context.completeAgentIds) {
238
+ const agentData = context.project.agents[agentId];
239
+ if (!agentData) continue;
240
+ const agentFilePath = resolveRecordFilePath(context, "agents", agentId, join(context.paths.agentsDir, `${agentId}.ts`));
241
+ const existingAgent = context.existingComponentRegistry?.get(agentId, "agents");
242
+ const subAgentReferences = collectSubAgentReferenceOverrides(context, agentData, agentFilePath);
243
+ const statusUpdates = asRecord(agentData.statusUpdates);
244
+ const contextTemplateReferences = collectContextTemplateReferences(context, agentData, agentFilePath, [typeof agentData.prompt === "string" ? agentData.prompt : void 0, typeof statusUpdates?.prompt === "string" ? statusUpdates.prompt : void 0]);
245
+ records.push({
246
+ id: agentId,
247
+ filePath: agentFilePath,
248
+ payload: {
249
+ agentId,
250
+ ...agentData,
251
+ ...existingAgent?.name?.length && { agentVariableName: existingAgent.name },
252
+ ...Object.keys(subAgentReferences).length > 0 ? { subAgentReferences } : {},
253
+ ...contextTemplateReferences && { contextConfigReference: contextTemplateReferences.contextConfigReference },
254
+ ...contextTemplateReferences?.contextConfigHeadersReference && { contextConfigHeadersReference: contextTemplateReferences.contextConfigHeadersReference }
255
+ }
256
+ });
257
+ }
258
+ return records;
259
+ }
260
+ function collectSubAgentRecords(context) {
261
+ if (!context.project.agents) return [];
262
+ const records = [];
263
+ for (const agentId of context.completeAgentIds) {
264
+ const agentData = context.project.agents[agentId];
265
+ const subAgents = asRecord(agentData?.subAgents);
266
+ if (!subAgents) continue;
267
+ for (const [subAgentId, subAgentData] of Object.entries(subAgents)) {
268
+ const payload = asRecord(subAgentData);
269
+ if (!payload) continue;
270
+ const referenceOverrides = collectSubAgentDependencyReferenceOverrides(context, payload);
271
+ const subAgentFilePath = resolveRecordFilePath(context, "subAgents", subAgentId, join(context.paths.agentsDir, "sub-agents", `${subAgentId}.ts`));
272
+ const contextTemplateReferences = collectContextTemplateReferences(context, agentData, subAgentFilePath, [typeof payload.prompt === "string" ? payload.prompt : void 0]);
273
+ records.push({
274
+ id: subAgentId,
275
+ filePath: subAgentFilePath,
276
+ payload: {
277
+ subAgentId,
278
+ ...payload,
279
+ ...referenceOverrides && { referenceOverrides },
280
+ ...contextTemplateReferences && {
281
+ contextConfigId: contextTemplateReferences.contextConfigId,
282
+ contextConfigReference: contextTemplateReferences.contextConfigReference
283
+ },
284
+ ...contextTemplateReferences?.contextConfigHeadersReference && { contextConfigHeadersReference: contextTemplateReferences.contextConfigHeadersReference }
285
+ }
286
+ });
287
+ }
288
+ }
289
+ return records;
290
+ }
291
+ function collectStatusComponentRecords(context) {
292
+ if (!context.project.agents) return [];
293
+ const statusComponentRecordsById = /* @__PURE__ */ new Map();
294
+ for (const agentId of context.completeAgentIds) {
295
+ const agentData = context.project.agents[agentId];
296
+ const statusUpdates = asRecord(agentData?.statusUpdates);
297
+ const statusComponents = Array.isArray(statusUpdates?.statusComponents) ? statusUpdates.statusComponents : [];
298
+ for (const statusComponentData of statusComponents) {
299
+ const payload = asRecord(statusComponentData);
300
+ if (!payload) continue;
301
+ const statusComponentId = resolveStatusComponentId(payload);
302
+ if (!statusComponentId || statusComponentRecordsById.has(statusComponentId)) continue;
303
+ statusComponentRecordsById.set(statusComponentId, {
304
+ id: statusComponentId,
305
+ filePath: resolveRecordFilePath(context, "statusComponents", statusComponentId, join(context.paths.statusComponentsDir, `${statusComponentId}.ts`)),
306
+ payload: {
307
+ statusComponentId,
308
+ ...payload
309
+ }
310
+ });
311
+ }
312
+ }
313
+ return [...statusComponentRecordsById.values()];
314
+ }
315
+ function collectProjectRecord(context) {
316
+ const referenceOverrides = collectProjectReferenceOverrides(context);
317
+ return [{
318
+ id: context.project.id,
319
+ filePath: resolveRecordFilePath(context, "project", context.project.id, join(context.paths.projectRoot, "index.ts")),
320
+ payload: {
321
+ projectId: context.project.id,
322
+ name: context.project.name,
323
+ description: context.project.description,
324
+ models: context.project.models,
325
+ stopWhen: context.project.stopWhen,
326
+ skills: getObjectKeys(context.project.skills),
327
+ agents: [...context.completeAgentIds],
328
+ tools: getObjectKeys(context.project.tools),
329
+ externalAgents: getObjectKeys(context.project.externalAgents),
330
+ dataComponents: getObjectKeys(context.project.dataComponents),
331
+ artifactComponents: getObjectKeys(context.project.artifactComponents),
332
+ credentialReferences: getObjectKeys(context.project.credentialReferences),
333
+ ...referenceOverrides && { referenceOverrides }
334
+ }
335
+ }];
336
+ }
337
+ function validateProject(project) {
338
+ if (!project || typeof project !== "object") throw new Error("Project data is required");
339
+ if (!project.id) throw new Error("Project id is required");
340
+ if (!project.name) throw new Error("Project name is required");
341
+ }
342
+ function collectCompleteAgentIds(project, skippedAgents) {
343
+ const completeAgentIds = /* @__PURE__ */ new Set();
344
+ for (const [agentId, agentData] of Object.entries(project.agents ?? {})) {
345
+ const completeness = isAgentComplete(agentData);
346
+ if (!completeness.complete) {
347
+ skippedAgents.push({
348
+ id: agentId,
349
+ reason: completeness.reason ?? "incomplete"
350
+ });
351
+ continue;
352
+ }
353
+ completeAgentIds.add(agentId);
354
+ }
355
+ return completeAgentIds;
356
+ }
357
+ function isAgentComplete(agentData) {
358
+ const data = asRecord(agentData);
359
+ if (!data) return {
360
+ complete: false,
361
+ reason: "invalid agent object"
362
+ };
363
+ if (!data.name || typeof data.name !== "string") return {
364
+ complete: false,
365
+ reason: "missing name"
366
+ };
367
+ if (!data.defaultSubAgentId || typeof data.defaultSubAgentId !== "string") return {
368
+ complete: false,
369
+ reason: "missing defaultSubAgentId"
370
+ };
371
+ if (!asRecord(data.subAgents) || !Object.keys(data.subAgents).length) return {
372
+ complete: false,
373
+ reason: "no sub-agents defined"
374
+ };
375
+ return { complete: true };
376
+ }
377
+ function collectUnsupportedComponentCounts(project) {
378
+ return {
379
+ functionTools: getObjectKeys(project.functionTools).length,
380
+ functions: getObjectKeys(project.functions).length,
381
+ externalAgents: getObjectKeys(project.externalAgents).length
382
+ };
383
+ }
384
+ function hasUnsupportedComponents(counts) {
385
+ return Object.values(counts).some((value) => value > 0);
386
+ }
387
+ function formatUnsupportedComponentsError(counts) {
388
+ return `Unsupported components for v4 introspect: ${formatUnsupportedCounts(counts)}`;
389
+ }
390
+ function formatUnsupportedComponentsWarning(counts) {
391
+ return `Skipped unsupported components for v4 introspect: ${formatUnsupportedCounts(counts)}`;
392
+ }
393
+ function formatUnsupportedCounts(counts) {
394
+ return Object.entries(counts).filter(([, value]) => value > 0).map(([name, value]) => `${name}=${value}`).join(", ");
395
+ }
396
+ function getObjectKeys(value) {
397
+ const record = asRecord(value);
398
+ if (!record) return [];
399
+ return Object.keys(record);
400
+ }
401
+ function resolveStatusComponentId(statusComponentData) {
402
+ if (typeof statusComponentData.id === "string") return statusComponentData.id;
403
+ if (typeof statusComponentData.type === "string") return statusComponentData.type;
404
+ if (typeof statusComponentData.name === "string") return statusComponentData.name;
405
+ }
406
+ function asRecord(value) {
407
+ if (!value || typeof value !== "object" || Array.isArray(value)) return;
408
+ return value;
409
+ }
410
+ function collectSubAgentReferenceOverrides(context, agentData, agentFilePath) {
411
+ const subAgentIds = new Set(extractReferenceIds(agentData.subAgents));
412
+ if (typeof agentData.defaultSubAgentId === "string" && agentData.defaultSubAgentId.length > 0) subAgentIds.add(agentData.defaultSubAgentId);
413
+ if (!subAgentIds.size) return {};
414
+ const overrides = {};
415
+ for (const subAgentId of subAgentIds) {
416
+ const existingSubAgent = context.existingComponentRegistry?.get(subAgentId, "subAgents");
417
+ if (!existingSubAgent?.name) continue;
418
+ overrides[subAgentId] = normalizeFilePath(resolveProjectFilePath(context.paths.projectRoot, existingSubAgent.filePath)) === normalizeFilePath(agentFilePath) ? {
419
+ name: existingSubAgent.name,
420
+ local: true
421
+ } : { name: existingSubAgent.name };
422
+ }
423
+ return overrides;
424
+ }
425
+ function collectAgentContextConfigReferenceOverride(context, agentData, agentFilePath) {
426
+ const contextConfigId = extractContextConfigData(agentData)?.id;
427
+ if (!contextConfigId) return;
428
+ const existingContextConfig = context.existingComponentRegistry?.get(contextConfigId, "contextConfigs");
429
+ if (!existingContextConfig?.name) return;
430
+ return normalizeFilePath(resolveProjectFilePath(context.paths.projectRoot, existingContextConfig.filePath)) === normalizeFilePath(agentFilePath) ? {
431
+ name: existingContextConfig.name,
432
+ local: true
433
+ } : { name: existingContextConfig.name };
434
+ }
435
+ function collectContextTemplateReferences(context, agentData, targetFilePath, promptValues) {
436
+ const contextConfig = extractContextConfigData(agentData);
437
+ const contextConfigId = contextConfig?.id;
438
+ if (!contextConfigId) return;
439
+ const contextConfigFilePath = resolveRecordFilePath(context, "contextConfigs", contextConfigId, join(context.paths.contextConfigsDir, `${contextConfigId}.ts`));
440
+ const isLocal = normalizeFilePath(contextConfigFilePath) === normalizeFilePath(targetFilePath);
441
+ const contextConfigReference = collectAgentContextConfigReferenceOverride(context, agentData, targetFilePath) ?? (isLocal ? {
442
+ name: toCamelCase(contextConfigId),
443
+ local: true
444
+ } : { name: toCamelCase(contextConfigId) });
445
+ const hasHeadersTemplateVariables = collectTemplateVariablesFromValues(promptValues).some((variableName) => variableName.startsWith("headers."));
446
+ let headersReferenceName = collectContextConfigHeadersReferenceOverride(context, contextConfigId, contextConfigFilePath) ?? inferHeadersReferenceFromContextConfig(contextConfig, contextConfigId);
447
+ if (!headersReferenceName && hasHeadersTemplateVariables) headersReferenceName = `${toCamelCase(contextConfigId)}Headers`;
448
+ return {
449
+ contextConfigId,
450
+ contextConfigReference,
451
+ ...headersReferenceName && { contextConfigHeadersReference: isLocal ? {
452
+ name: headersReferenceName,
453
+ local: true
454
+ } : { name: headersReferenceName } }
455
+ };
456
+ }
457
+ function extractContextConfigData(agentData) {
458
+ const contextConfig = typeof agentData.contextConfig === "string" ? { id: agentData.contextConfig } : asRecord(agentData.contextConfig);
459
+ const contextConfigId = contextConfig && typeof contextConfig.id === "string" ? contextConfig.id : void 0;
460
+ if (!contextConfigId || !contextConfig) return;
461
+ return {
462
+ id: contextConfigId,
463
+ value: contextConfig
464
+ };
465
+ }
466
+ function inferHeadersReferenceFromContextConfig(contextConfig, contextConfigId) {
467
+ const headers = contextConfig.value.headers;
468
+ if (typeof headers === "string" && headers.length > 0) return toCamelCase(headers);
469
+ const headersRecord = asRecord(headers);
470
+ if (headersRecord) {
471
+ if (typeof headersRecord.id === "string" && headersRecord.id.length > 0) return toCamelCase(headersRecord.id);
472
+ if (typeof headersRecord.name === "string" && headersRecord.name.length > 0) return toCamelCase(headersRecord.name);
473
+ }
474
+ if (isPlainObject(contextConfig.value.headersSchema)) return `${toCamelCase(contextConfigId)}Headers`;
475
+ }
476
+ function collectTemplateVariablesFromValues(values) {
477
+ const variables = [];
478
+ for (const value of values) {
479
+ if (typeof value !== "string") continue;
480
+ variables.push(...collectTemplateVariableNames(value));
481
+ }
482
+ return variables;
483
+ }
484
+ function collectHeaderTemplateVariablesFromAgentPrompts(agentData) {
485
+ const variables = /* @__PURE__ */ new Set();
486
+ addHeaderTemplateVariablesFromString(typeof agentData.prompt === "string" ? agentData.prompt : void 0, variables);
487
+ const statusUpdates = asRecord(agentData.statusUpdates);
488
+ addHeaderTemplateVariablesFromString(typeof statusUpdates?.prompt === "string" ? statusUpdates.prompt : void 0, variables);
489
+ const subAgents = asRecord(agentData.subAgents);
490
+ if (!subAgents) return variables;
491
+ for (const subAgentData of Object.values(subAgents)) {
492
+ const subAgent = asRecord(subAgentData);
493
+ addHeaderTemplateVariablesFromString(typeof subAgent?.prompt === "string" ? subAgent.prompt : void 0, variables);
494
+ }
495
+ return variables;
496
+ }
497
+ function addHeaderTemplateVariablesFromString(value, variables) {
498
+ if (typeof value !== "string") return;
499
+ for (const variableName of collectTemplateVariableNames(value)) {
500
+ if (!variableName.startsWith("headers.")) continue;
501
+ const headerPath = variableName.slice(8);
502
+ if (headerPath) variables.add(headerPath);
503
+ }
504
+ }
505
+ function applyPromptHeaderTemplateSchema(contextConfig, headerTemplateVariables) {
506
+ if (!headerTemplateVariables.size) return contextConfig;
507
+ if (typeof contextConfig.headers === "string" || isPlainObject(contextConfig.headers) || isPlainObject(contextConfig.headersSchema)) return contextConfig;
508
+ const variableNames = [...headerTemplateVariables].sort();
509
+ const properties = Object.fromEntries(variableNames.map((variableName) => [variableName, { type: "string" }]));
510
+ return {
511
+ ...contextConfig,
512
+ headersSchema: {
513
+ type: "object",
514
+ properties,
515
+ required: variableNames,
516
+ additionalProperties: false
517
+ }
518
+ };
519
+ }
520
+ function collectSubAgentDependencyReferenceOverrides(context, subAgentData) {
521
+ const registry = context.existingComponentRegistry;
522
+ if (!registry) return;
523
+ const overrides = {};
524
+ const canUse = Array.isArray(subAgentData.canUse) ? subAgentData.canUse : [];
525
+ for (const item of canUse) {
526
+ if (typeof item === "string") {
527
+ assignComponentReferenceOverride(registry, overrides, "tools", item, "tools");
528
+ assignComponentReferenceOverride(registry, overrides, "tools", item, "functionTools");
529
+ continue;
530
+ }
531
+ const canUseRecord = asRecord(item);
532
+ if (!canUseRecord || typeof canUseRecord.toolId !== "string") continue;
533
+ assignComponentReferenceOverride(registry, overrides, "tools", canUseRecord.toolId, "tools");
534
+ assignComponentReferenceOverride(registry, overrides, "tools", canUseRecord.toolId, "functionTools");
535
+ }
536
+ const canDelegateTo = Array.isArray(subAgentData.canDelegateTo) ? subAgentData.canDelegateTo : [];
537
+ for (const item of canDelegateTo) {
538
+ if (typeof item === "string") {
539
+ assignFirstMatchingComponentReferenceOverride(registry, overrides, item, [
540
+ ["subAgents", "subAgents"],
541
+ ["agents", "agents"],
542
+ ["externalAgents", "externalAgents"]
543
+ ]);
544
+ continue;
545
+ }
546
+ const canDelegateRecord = asRecord(item);
547
+ if (!canDelegateRecord) continue;
548
+ if (typeof canDelegateRecord.subAgentId === "string") {
549
+ assignComponentReferenceOverride(registry, overrides, "subAgents", canDelegateRecord.subAgentId, "subAgents");
550
+ continue;
551
+ }
552
+ if (typeof canDelegateRecord.agentId === "string") {
553
+ assignComponentReferenceOverride(registry, overrides, "agents", canDelegateRecord.agentId, "agents");
554
+ continue;
555
+ }
556
+ if (typeof canDelegateRecord.externalAgentId === "string") assignComponentReferenceOverride(registry, overrides, "externalAgents", canDelegateRecord.externalAgentId, "externalAgents");
557
+ }
558
+ const canTransferTo = extractReferenceIds(subAgentData.canTransferTo);
559
+ for (const transferTargetId of canTransferTo) assignFirstMatchingComponentReferenceOverride(registry, overrides, transferTargetId, [
560
+ ["subAgents", "subAgents"],
561
+ ["agents", "agents"],
562
+ ["externalAgents", "externalAgents"]
563
+ ]);
564
+ const dataComponentIds = extractReferenceIds(subAgentData.dataComponents);
565
+ for (const dataComponentId of dataComponentIds) assignComponentReferenceOverride(registry, overrides, "dataComponents", dataComponentId, "dataComponents");
566
+ const artifactComponentIds = extractReferenceIds(subAgentData.artifactComponents);
567
+ for (const artifactComponentId of artifactComponentIds) assignComponentReferenceOverride(registry, overrides, "artifactComponents", artifactComponentId, "artifactComponents");
568
+ return Object.keys(overrides).length > 0 ? overrides : void 0;
569
+ }
570
+ function assignFirstMatchingComponentReferenceOverride(registry, overrides, componentId, candidates) {
571
+ for (const [overrideType, componentType] of candidates) {
572
+ const component = registry.get(componentId, componentType);
573
+ if (!component?.name) continue;
574
+ assignReferenceOverride(overrides, overrideType, componentId, component.name);
575
+ return;
576
+ }
577
+ }
578
+ function assignComponentReferenceOverride(registry, overrides, overrideType, componentId, componentType) {
579
+ const component = registry.get(componentId, componentType);
580
+ if (!component?.name) return;
581
+ assignReferenceOverride(overrides, overrideType, componentId, component.name);
582
+ }
583
+ function assignReferenceOverride(overrides, overrideType, componentId, referenceName) {
584
+ const overrideMap = overrides[overrideType] ?? {};
585
+ overrideMap[componentId] = referenceName;
586
+ overrides[overrideType] = overrideMap;
587
+ }
588
+ function collectProjectReferenceOverrides(context) {
589
+ const registry = context.existingComponentRegistry;
590
+ if (!registry) return;
591
+ const overrides = {};
592
+ for (const agentId of context.completeAgentIds) assignComponentReferenceOverrideForProject(registry, overrides, "agents", agentId, "agents");
593
+ const toolIds = getObjectKeys(context.project.tools);
594
+ for (const toolId of toolIds) {
595
+ if (assignComponentReferenceOverrideForProject(registry, overrides, "tools", toolId, "functionTools")) continue;
596
+ assignComponentReferenceOverrideForProject(registry, overrides, "tools", toolId, "tools");
597
+ }
598
+ const externalAgentIds = getObjectKeys(context.project.externalAgents);
599
+ for (const externalAgentId of externalAgentIds) assignComponentReferenceOverrideForProject(registry, overrides, "externalAgents", externalAgentId, "externalAgents");
600
+ const dataComponentIds = getObjectKeys(context.project.dataComponents);
601
+ for (const dataComponentId of dataComponentIds) assignComponentReferenceOverrideForProject(registry, overrides, "dataComponents", dataComponentId, "dataComponents");
602
+ const artifactComponentIds = getObjectKeys(context.project.artifactComponents);
603
+ for (const artifactComponentId of artifactComponentIds) assignComponentReferenceOverrideForProject(registry, overrides, "artifactComponents", artifactComponentId, "artifactComponents");
604
+ const credentialIds = getObjectKeys(context.project.credentialReferences);
605
+ for (const credentialId of credentialIds) assignComponentReferenceOverrideForProject(registry, overrides, "credentialReferences", credentialId, "credentials");
606
+ return Object.keys(overrides).length > 0 ? overrides : void 0;
607
+ }
608
+ function assignComponentReferenceOverrideForProject(registry, overrides, overrideType, componentId, componentType) {
609
+ const component = registry.get(componentId, componentType);
610
+ if (!component?.name) return false;
611
+ const overrideMap = overrides[overrideType] ?? {};
612
+ overrideMap[componentId] = component.name;
613
+ overrides[overrideType] = overrideMap;
614
+ return true;
615
+ }
616
+ function extractReferenceIds(value) {
617
+ if (Array.isArray(value)) return value.map((item) => {
618
+ if (typeof item === "string") return item;
619
+ const record$1 = asRecord(item);
620
+ if (record$1 && typeof record$1.id === "string") return record$1.id;
621
+ }).filter((id) => !!id);
622
+ const record = asRecord(value);
623
+ if (!record) return [];
624
+ return Object.keys(record);
625
+ }
626
+ function resolveRecordFilePath(context, componentType, componentId, fallbackFilePath) {
627
+ const existingComponent = context.existingComponentRegistry?.get(componentId, componentType);
628
+ if (!existingComponent?.filePath) return fallbackFilePath;
629
+ return resolveProjectFilePath(context.paths.projectRoot, existingComponent.filePath);
630
+ }
631
+ function resolveProjectFilePath(projectRoot, filePath) {
632
+ if (filePath.startsWith("/")) return filePath;
633
+ return join(projectRoot, filePath);
634
+ }
635
+ function normalizeFilePath(filePath) {
636
+ return filePath.replaceAll("\\", "/");
637
+ }
638
+ function writeTypeScriptFile(filePath, content, writeMode) {
639
+ mkdirSync(dirname(filePath), { recursive: true });
640
+ const processedContent = writeMode === "merge" && existsSync(filePath) ? mergeSafely(readFileSync(filePath, "utf8"), content) : content;
641
+ const sourceFile = createInMemoryProject().createSourceFile("generated.ts", processedContent, { overwrite: true });
642
+ const normalizedSourceFile = moveVariableDeclarationsBeforeUsage(applyObjectShorthand(sourceFile));
643
+ sourceFile.formatText();
644
+ writeFileSync(filePath, `${normalizedSourceFile.getFullText().trimEnd()}\n`);
645
+ }
646
+ function mergeSafely(existingContent, generatedContent) {
647
+ try {
648
+ return mergeGeneratedModule(existingContent, generatedContent);
649
+ } catch (error) {
650
+ console.warn(`Warning: Failed to merge file, using generated content. Manual changes may be lost. Reason: ${error instanceof Error ? error.message : String(error)}`);
651
+ return generatedContent;
652
+ }
653
+ }
654
+ function applyObjectShorthand(sourceFile) {
655
+ for (const objectLiteral of sourceFile.getDescendantsOfKind(SyntaxKind.ObjectLiteralExpression)) for (const property of objectLiteral.getProperties()) {
656
+ if (!Node.isPropertyAssignment(property)) continue;
657
+ const nameNode = property.getNameNode();
658
+ const initializer = property.getInitializer();
659
+ if (!Node.isIdentifier(nameNode) || !initializer || !Node.isIdentifier(initializer)) continue;
660
+ if (nameNode.getText() !== initializer.getText()) continue;
661
+ property.replaceWithText(nameNode.getText());
662
+ }
663
+ return sourceFile;
664
+ }
665
+ function moveVariableDeclarationsBeforeUsage(sourceFile) {
666
+ let moved = true;
667
+ while (moved) {
668
+ moved = false;
669
+ const variableStatements = sourceFile.getVariableStatements();
670
+ for (const variableStatement of variableStatements) {
671
+ const statementStart = variableStatement.getStart();
672
+ const sourceStatements = sourceFile.getStatements();
673
+ const statementIndex = sourceStatements.indexOf(variableStatement);
674
+ if (statementIndex <= 0) continue;
675
+ let targetIndex;
676
+ for (const declaration of variableStatement.getDeclarations()) for (const referenceNode of declaration.findReferencesAsNodes()) {
677
+ if (referenceNode.getSourceFile() !== sourceFile) continue;
678
+ if (referenceNode.getParent() === declaration) continue;
679
+ if (referenceNode.getStart() >= statementStart) continue;
680
+ if (isReferenceInsideFunctionLike(referenceNode)) continue;
681
+ const topLevelStatement = referenceNode.getFirstAncestor((ancestor) => {
682
+ return Node.isStatement(ancestor) && ancestor.getParentIfKind(SyntaxKind.SourceFile);
683
+ });
684
+ if (!topLevelStatement) continue;
685
+ const topLevelStatementIndex = sourceStatements.indexOf(topLevelStatement);
686
+ if (topLevelStatementIndex === -1 || topLevelStatementIndex >= statementIndex) continue;
687
+ targetIndex = targetIndex === void 0 ? topLevelStatementIndex : Math.min(targetIndex, topLevelStatementIndex);
688
+ }
689
+ if (targetIndex === void 0) continue;
690
+ const statementText = variableStatement.getText();
691
+ variableStatement.remove();
692
+ sourceFile.insertStatements(targetIndex, [statementText]);
693
+ moved = true;
694
+ break;
695
+ }
696
+ }
697
+ return sourceFile;
698
+ }
699
+ function isReferenceInsideFunctionLike(referenceNode) {
700
+ return Boolean(referenceNode.getFirstAncestor((ancestor) => {
701
+ return Node.isArrowFunction(ancestor) || Node.isFunctionDeclaration(ancestor) || Node.isFunctionExpression(ancestor) || Node.isMethodDeclaration(ancestor) || Node.isGetAccessorDeclaration(ancestor) || Node.isSetAccessorDeclaration(ancestor);
702
+ }));
703
+ }
704
+
705
+ //#endregion
706
+ export { introspectGenerate };