@inkeep/agents-cli 0.39.4 → 0.40.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/_virtual/rolldown_runtime.js +7 -0
- package/dist/api.js +185 -0
- package/dist/commands/add.js +139 -0
- package/dist/commands/config.js +86 -0
- package/dist/commands/dev.js +259 -0
- package/dist/commands/init.js +360 -0
- package/dist/commands/list-agents.js +56 -0
- package/dist/commands/login.js +179 -0
- package/dist/commands/logout.js +56 -0
- package/dist/commands/profile.js +276 -0
- package/dist/{component-parser2.js → commands/pull-v3/component-parser.js} +16 -3
- package/dist/commands/pull-v3/component-updater.js +710 -0
- package/dist/commands/pull-v3/components/agent-generator.js +241 -0
- package/dist/commands/pull-v3/components/artifact-component-generator.js +127 -0
- package/dist/commands/pull-v3/components/context-config-generator.js +190 -0
- package/dist/commands/pull-v3/components/credential-generator.js +89 -0
- package/dist/commands/pull-v3/components/data-component-generator.js +102 -0
- package/dist/commands/pull-v3/components/environment-generator.js +170 -0
- package/dist/commands/pull-v3/components/external-agent-generator.js +75 -0
- package/dist/commands/pull-v3/components/function-tool-generator.js +94 -0
- package/dist/commands/pull-v3/components/mcp-tool-generator.js +86 -0
- package/dist/commands/pull-v3/components/project-generator.js +145 -0
- package/dist/commands/pull-v3/components/status-component-generator.js +92 -0
- package/dist/commands/pull-v3/components/sub-agent-generator.js +285 -0
- package/dist/commands/pull-v3/index.js +510 -0
- package/dist/commands/pull-v3/introspect-generator.js +278 -0
- package/dist/commands/pull-v3/llm-content-merger.js +192 -0
- package/dist/{new-component-generator.js → commands/pull-v3/new-component-generator.js} +14 -3
- package/dist/commands/pull-v3/project-comparator.js +914 -0
- package/dist/{project-index-generator.js → commands/pull-v3/project-index-generator.js} +1 -2
- package/dist/{project-validator.js → commands/pull-v3/project-validator.js} +4 -4
- package/dist/commands/pull-v3/targeted-typescript-placeholders.js +173 -0
- package/dist/commands/pull-v3/utils/component-registry.js +369 -0
- package/dist/commands/pull-v3/utils/component-tracker.js +165 -0
- package/dist/commands/pull-v3/utils/generator-utils.js +146 -0
- package/dist/commands/pull-v3/utils/model-provider-detector.js +44 -0
- package/dist/commands/push.js +326 -0
- package/dist/commands/status.js +89 -0
- package/dist/commands/update.js +97 -0
- package/dist/commands/whoami.js +38 -0
- package/dist/config.js +0 -1
- package/dist/env.js +30 -0
- package/dist/exports.js +3 -0
- package/dist/index.js +28 -196514
- package/dist/instrumentation.js +47 -0
- package/dist/types/agent.js +1 -0
- package/dist/types/tsx.d.d.ts +1 -0
- package/dist/utils/background-version-check.js +19 -0
- package/dist/utils/ci-environment.js +87 -0
- package/dist/utils/cli-pipeline.js +158 -0
- package/dist/utils/config.js +290 -0
- package/dist/utils/credentials.js +132 -0
- package/dist/utils/environment-loader.js +28 -0
- package/dist/utils/file-finder.js +62 -0
- package/dist/utils/json-comparator.js +185 -0
- package/dist/utils/json-comparison.js +232 -0
- package/dist/utils/mcp-runner.js +120 -0
- package/dist/utils/model-config.js +182 -0
- package/dist/utils/package-manager.js +58 -0
- package/dist/utils/profile-config.js +85 -0
- package/dist/utils/profiles/index.js +4 -0
- package/dist/utils/profiles/profile-manager.js +219 -0
- package/dist/utils/profiles/types.js +62 -0
- package/dist/utils/project-directory.js +33 -0
- package/dist/utils/project-loader.js +29 -0
- package/dist/utils/schema-introspection.js +44 -0
- package/dist/utils/templates.js +198 -0
- package/dist/utils/tsx-loader.js +27 -0
- package/dist/utils/url.js +26 -0
- package/dist/utils/version-check.js +79 -0
- package/package.json +4 -19
- package/dist/component-parser.js +0 -4
- package/dist/component-updater.js +0 -4
- package/dist/config2.js +0 -4
- package/dist/credential-stores.js +0 -4
- package/dist/environment-generator.js +0 -4
- package/dist/nodefs.js +0 -27
- package/dist/opfs-ahp.js +0 -368
- package/dist/project-loader.js +0 -4
- package/dist/tsx-loader.js +0 -4
|
@@ -0,0 +1,241 @@
|
|
|
1
|
+
import { compareJsonObjects } from "../../../utils/json-comparator.js";
|
|
2
|
+
import { DEFAULT_STYLE, formatPromptWithContext, formatString, generateFileContent, generateImport, hasTemplateVariables, removeTrailingComma, toCamelCase } from "../utils/generator-utils.js";
|
|
3
|
+
|
|
4
|
+
//#region src/commands/pull-v3/components/agent-generator.ts
|
|
5
|
+
/**
|
|
6
|
+
* Agent Generator - Generate top-level agent definitions
|
|
7
|
+
*
|
|
8
|
+
* Generates top-level agents using the agent() builder function from @inkeep/agents-sdk
|
|
9
|
+
* Top-level agents are the main entry points that handle statusUpdates with statusComponents
|
|
10
|
+
*/
|
|
11
|
+
/**
|
|
12
|
+
* Format statusUpdates configuration with statusComponents references
|
|
13
|
+
*/
|
|
14
|
+
function formatStatusUpdates(statusUpdatesConfig, style, indentLevel, registry, contextConfigData, agentId) {
|
|
15
|
+
if (!statusUpdatesConfig) return "";
|
|
16
|
+
const { quotes, indentation } = style;
|
|
17
|
+
const q = quotes === "single" ? "'" : "\"";
|
|
18
|
+
const indent = indentation.repeat(indentLevel);
|
|
19
|
+
const lines = [];
|
|
20
|
+
lines.push(`${indent}statusUpdates: {`);
|
|
21
|
+
if (statusUpdatesConfig.numEvents !== void 0) lines.push(`${indent}${indentation}numEvents: ${statusUpdatesConfig.numEvents},`);
|
|
22
|
+
if (statusUpdatesConfig.timeInSeconds !== void 0) lines.push(`${indent}${indentation}timeInSeconds: ${statusUpdatesConfig.timeInSeconds},`);
|
|
23
|
+
if (statusUpdatesConfig.statusComponents && Array.isArray(statusUpdatesConfig.statusComponents) && statusUpdatesConfig.statusComponents.length > 0) {
|
|
24
|
+
const statusComponentIds = statusUpdatesConfig.statusComponents.map((comp) => {
|
|
25
|
+
if (typeof comp === "string") return comp;
|
|
26
|
+
if (typeof comp === "object" && comp) return comp.id || comp.type || comp.name;
|
|
27
|
+
return null;
|
|
28
|
+
}).filter(Boolean);
|
|
29
|
+
if (statusComponentIds.length > 0) {
|
|
30
|
+
lines.push(`${indent}${indentation}statusComponents: [`);
|
|
31
|
+
for (const statusCompId of statusComponentIds) {
|
|
32
|
+
const statusCompVar = registry?.getVariableName(statusCompId, "statusComponents");
|
|
33
|
+
lines.push(`${indent}${indentation}${indentation}${statusCompVar || "undefined"}.config,`);
|
|
34
|
+
}
|
|
35
|
+
lines.push(`${indent}${indentation}],`);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
if (statusUpdatesConfig.prompt) if (hasTemplateVariables(statusUpdatesConfig.prompt) && contextConfigData && agentId && registry) {
|
|
39
|
+
const contextConfigId = contextConfigData.id;
|
|
40
|
+
const contextVarName = registry.getVariableName(contextConfigId, "contextConfigs");
|
|
41
|
+
if (!contextVarName) throw new Error(`Failed to resolve context config variable name for: ${contextConfigId}`);
|
|
42
|
+
lines.push(`${indent}${indentation}prompt: ${formatPromptWithContext(statusUpdatesConfig.prompt, contextVarName, "headersSchema", contextConfigData, q, true)},`);
|
|
43
|
+
} else lines.push(`${indent}${indentation}prompt: ${formatString(statusUpdatesConfig.prompt, q, true)},`);
|
|
44
|
+
removeTrailingComma(lines);
|
|
45
|
+
lines.push(`${indent}},`);
|
|
46
|
+
return lines.join("\n");
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Format stopWhen configuration for agents (only supports transferCountIs)
|
|
50
|
+
*/
|
|
51
|
+
function formatStopWhen(stopWhenConfig, style, indentLevel) {
|
|
52
|
+
if (!stopWhenConfig || !stopWhenConfig.transferCountIs) return "";
|
|
53
|
+
const { indentation } = style;
|
|
54
|
+
const indent = indentation.repeat(indentLevel);
|
|
55
|
+
return `${indent}stopWhen: {\n${indent}${indentation}transferCountIs: ${stopWhenConfig.transferCountIs} // Max transfers in one conversation\n${indent}},`;
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Check if agent models are different from project models
|
|
59
|
+
*/
|
|
60
|
+
function hasDistinctModels(agentModels, projectModels) {
|
|
61
|
+
if (!agentModels) return false;
|
|
62
|
+
if (!projectModels) return !!agentModels;
|
|
63
|
+
for (const type of [
|
|
64
|
+
"base",
|
|
65
|
+
"structuredOutput",
|
|
66
|
+
"summarizer"
|
|
67
|
+
]) {
|
|
68
|
+
const agentModel = agentModels[type]?.model;
|
|
69
|
+
const projectModel = projectModels[type]?.model;
|
|
70
|
+
if (agentModel !== projectModel) return true;
|
|
71
|
+
if (agentModel && projectModel) {
|
|
72
|
+
const agentOptions = agentModels[type]?.providerOptions;
|
|
73
|
+
const projectOptions = projectModels[type]?.providerOptions;
|
|
74
|
+
if (agentOptions !== projectOptions) {
|
|
75
|
+
if (!agentOptions && !projectOptions) continue;
|
|
76
|
+
if (!agentOptions || !projectOptions) return true;
|
|
77
|
+
if (!compareJsonObjects(agentOptions, projectOptions, {
|
|
78
|
+
ignoreArrayOrder: true,
|
|
79
|
+
showDetails: false
|
|
80
|
+
}).isEqual) return true;
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
return false;
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* Generate Agent Definition using agent() builder function
|
|
88
|
+
*/
|
|
89
|
+
function generateAgentDefinition(agentId, agentData, style = DEFAULT_STYLE, registry, contextConfigData, projectModels) {
|
|
90
|
+
if (!agentId || typeof agentId !== "string") throw new Error("agentId is required and must be a string");
|
|
91
|
+
if (!agentData || typeof agentData !== "object") throw new Error(`agentData is required for agent '${agentId}'`);
|
|
92
|
+
const missingFields = [
|
|
93
|
+
"name",
|
|
94
|
+
"defaultSubAgentId",
|
|
95
|
+
"subAgents"
|
|
96
|
+
].filter((field) => !agentData[field] || agentData[field] === null || agentData[field] === void 0);
|
|
97
|
+
if (missingFields.length > 0) throw new Error(`Missing required fields for agent '${agentId}': ${missingFields.join(", ")}`);
|
|
98
|
+
const { quotes, semicolons, indentation } = style;
|
|
99
|
+
const q = quotes === "single" ? "'" : "\"";
|
|
100
|
+
const semi = semicolons ? ";" : "";
|
|
101
|
+
let agentVarName = toCamelCase(agentId);
|
|
102
|
+
if (registry) {
|
|
103
|
+
const registryVarName = registry.getVariableName(agentId, "agents");
|
|
104
|
+
if (registryVarName) agentVarName = registryVarName;
|
|
105
|
+
}
|
|
106
|
+
const lines = [];
|
|
107
|
+
lines.push(`export const ${agentVarName} = agent({`);
|
|
108
|
+
lines.push(`${indentation}id: ${formatString(agentId, q)},`);
|
|
109
|
+
lines.push(`${indentation}name: ${formatString(agentData.name, q)},`);
|
|
110
|
+
if (agentData.description !== void 0 && agentData.description !== null) lines.push(`${indentation}description: ${formatString(agentData.description, q, true)},`);
|
|
111
|
+
if (agentData.prompt !== void 0 && agentData.prompt !== null) if (hasTemplateVariables(agentData.prompt) && contextConfigData && registry) {
|
|
112
|
+
const contextConfigId = contextConfigData.id;
|
|
113
|
+
const contextVarName = registry.getVariableName(contextConfigId, "contextConfigs");
|
|
114
|
+
if (!contextVarName) throw new Error(`Failed to resolve context config variable name for: ${contextConfigId}`);
|
|
115
|
+
lines.push(`${indentation}prompt: ${formatPromptWithContext(agentData.prompt, contextVarName, "headersSchema", contextConfigData, q, true)},`);
|
|
116
|
+
} else lines.push(`${indentation}prompt: ${formatString(agentData.prompt, q, true)},`);
|
|
117
|
+
if (agentData.models && hasDistinctModels(agentData.models, projectModels)) {
|
|
118
|
+
lines.push(`${indentation}models: {`);
|
|
119
|
+
if (agentData.models.base?.model) {
|
|
120
|
+
lines.push(`${indentation}${indentation}base: {`);
|
|
121
|
+
lines.push(`${indentation}${indentation}${indentation}model: ${formatString(agentData.models.base.model, q)}`);
|
|
122
|
+
if (agentData.models.base.providerOptions) {
|
|
123
|
+
lines.push(`${indentation}${indentation}${indentation},`);
|
|
124
|
+
lines.push(`${indentation}${indentation}${indentation}providerOptions: ${JSON.stringify(agentData.models.base.providerOptions)}`);
|
|
125
|
+
}
|
|
126
|
+
lines.push(`${indentation}${indentation}},`);
|
|
127
|
+
}
|
|
128
|
+
if (agentData.models.structuredOutput?.model) {
|
|
129
|
+
lines.push(`${indentation}${indentation}structuredOutput: {`);
|
|
130
|
+
lines.push(`${indentation}${indentation}${indentation}model: ${formatString(agentData.models.structuredOutput.model, q)}`);
|
|
131
|
+
if (agentData.models.structuredOutput.providerOptions) {
|
|
132
|
+
lines.push(`${indentation}${indentation}${indentation},`);
|
|
133
|
+
lines.push(`${indentation}${indentation}${indentation}providerOptions: ${JSON.stringify(agentData.models.structuredOutput.providerOptions)}`);
|
|
134
|
+
}
|
|
135
|
+
lines.push(`${indentation}${indentation}},`);
|
|
136
|
+
}
|
|
137
|
+
if (agentData.models.summarizer?.model) {
|
|
138
|
+
lines.push(`${indentation}${indentation}summarizer: {`);
|
|
139
|
+
lines.push(`${indentation}${indentation}${indentation}model: ${formatString(agentData.models.summarizer.model, q)}`);
|
|
140
|
+
if (agentData.models.summarizer.providerOptions) {
|
|
141
|
+
lines.push(`${indentation}${indentation}${indentation},`);
|
|
142
|
+
lines.push(`${indentation}${indentation}${indentation}providerOptions: ${JSON.stringify(agentData.models.summarizer.providerOptions)}`);
|
|
143
|
+
}
|
|
144
|
+
lines.push(`${indentation}${indentation}},`);
|
|
145
|
+
}
|
|
146
|
+
removeTrailingComma(lines);
|
|
147
|
+
lines.push(`${indentation}},`);
|
|
148
|
+
}
|
|
149
|
+
if (agentData.defaultSubAgentId) {
|
|
150
|
+
if (!registry) throw new Error("Registry is required for defaultSubAgent generation");
|
|
151
|
+
const defaultSubAgentVar = registry.getVariableName(agentData.defaultSubAgentId, "subAgents");
|
|
152
|
+
if (!defaultSubAgentVar) throw new Error(`Failed to resolve variable name for default sub-agent: ${agentData.defaultSubAgentId}`);
|
|
153
|
+
lines.push(`${indentation}defaultSubAgent: ${defaultSubAgentVar},`);
|
|
154
|
+
}
|
|
155
|
+
if (agentData.subAgents && typeof agentData.subAgents === "object" && Object.keys(agentData.subAgents).length > 0) {
|
|
156
|
+
if (!registry) throw new Error("Registry is required for subAgents generation");
|
|
157
|
+
const subAgentIds = Object.keys(agentData.subAgents);
|
|
158
|
+
const subAgentsArray = registry.formatReferencesForCode(subAgentIds, "subAgents", style, 2);
|
|
159
|
+
if (!subAgentsArray) throw new Error(`Failed to resolve variable names for sub-agents: ${subAgentIds.join(", ")}`);
|
|
160
|
+
lines.push(`${indentation}subAgents: () => ${subAgentsArray},`);
|
|
161
|
+
}
|
|
162
|
+
if (agentData.contextConfig && registry && agentData.contextConfig.id) {
|
|
163
|
+
const contextConfigVar = registry.getVariableName(agentData.contextConfig.id, "contextConfigs");
|
|
164
|
+
if (contextConfigVar) lines.push(`${indentation}contextConfig: ${contextConfigVar},`);
|
|
165
|
+
else lines.push(`${indentation}contextConfig: undefined,`);
|
|
166
|
+
}
|
|
167
|
+
if (agentData.credentials && Array.isArray(agentData.credentials) && agentData.credentials.length > 0) {
|
|
168
|
+
if (!registry) throw new Error("Registry is required for credentials generation");
|
|
169
|
+
const credentialsArray = `[${agentData.credentials.map((cred) => {
|
|
170
|
+
const credVarName = registry.getVariableName(cred.id, "credentials");
|
|
171
|
+
if (!credVarName) throw new Error(`Failed to resolve variable name for credential: ${cred.id}`);
|
|
172
|
+
return credVarName;
|
|
173
|
+
}).join(", ")}]`;
|
|
174
|
+
lines.push(`${indentation}credentials: () => ${credentialsArray},`);
|
|
175
|
+
}
|
|
176
|
+
if (agentData.stopWhen) {
|
|
177
|
+
const stopWhenFormatted = formatStopWhen(agentData.stopWhen, style, 1);
|
|
178
|
+
if (stopWhenFormatted) lines.push(stopWhenFormatted);
|
|
179
|
+
}
|
|
180
|
+
if (agentData.statusUpdates) {
|
|
181
|
+
const statusUpdatesFormatted = formatStatusUpdates(agentData.statusUpdates, style, 1, registry, contextConfigData, agentId);
|
|
182
|
+
if (statusUpdatesFormatted) lines.push(statusUpdatesFormatted);
|
|
183
|
+
}
|
|
184
|
+
removeTrailingComma(lines);
|
|
185
|
+
lines.push(`})${semi}`);
|
|
186
|
+
return lines.join("\n");
|
|
187
|
+
}
|
|
188
|
+
/**
|
|
189
|
+
* Generate imports needed for an agent file
|
|
190
|
+
*/
|
|
191
|
+
function generateAgentImports(agentId, agentData, style = DEFAULT_STYLE, registry, contextConfigData, actualFilePath) {
|
|
192
|
+
const imports = [];
|
|
193
|
+
imports.push(generateImport(["agent"], "@inkeep/agents-sdk", style));
|
|
194
|
+
if (registry) {
|
|
195
|
+
const currentFilePath = actualFilePath || `agents/${agentId}.ts`;
|
|
196
|
+
const referencedComponents = [];
|
|
197
|
+
if (agentData.subAgents && typeof agentData.subAgents === "object") {
|
|
198
|
+
const subAgentIds = Object.keys(agentData.subAgents);
|
|
199
|
+
referencedComponents.push(...subAgentIds.map((id) => ({
|
|
200
|
+
id,
|
|
201
|
+
type: "subAgents"
|
|
202
|
+
})));
|
|
203
|
+
}
|
|
204
|
+
if (agentData.statusUpdates && agentData.statusUpdates.statusComponents && Array.isArray(agentData.statusUpdates.statusComponents)) {
|
|
205
|
+
for (const comp of agentData.statusUpdates.statusComponents) if (typeof comp === "string") referencedComponents.push({
|
|
206
|
+
id: comp,
|
|
207
|
+
type: "statusComponents"
|
|
208
|
+
});
|
|
209
|
+
else if (typeof comp === "object" && comp) {
|
|
210
|
+
const statusId = comp.id || comp.type || comp.name;
|
|
211
|
+
if (statusId) referencedComponents.push({
|
|
212
|
+
id: statusId,
|
|
213
|
+
type: "statusComponents"
|
|
214
|
+
});
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
if (agentData.contextConfig) {
|
|
218
|
+
const contextConfigId = agentData.contextConfig.id;
|
|
219
|
+
referencedComponents.push({
|
|
220
|
+
id: contextConfigId,
|
|
221
|
+
type: "contextConfigs"
|
|
222
|
+
});
|
|
223
|
+
}
|
|
224
|
+
if (agentData.defaultSubAgentId) referencedComponents.push({
|
|
225
|
+
id: agentData.defaultSubAgentId,
|
|
226
|
+
type: "subAgents"
|
|
227
|
+
});
|
|
228
|
+
const componentImports = registry.getImportsForFile(currentFilePath, referencedComponents);
|
|
229
|
+
imports.push(...componentImports);
|
|
230
|
+
}
|
|
231
|
+
return imports;
|
|
232
|
+
}
|
|
233
|
+
/**
|
|
234
|
+
* Generate complete agent file (imports + definition)
|
|
235
|
+
*/
|
|
236
|
+
function generateAgentFile(agentId, agentData, style = DEFAULT_STYLE, registry, contextConfigData, projectModels, actualFilePath) {
|
|
237
|
+
return generateFileContent(generateAgentImports(agentId, agentData, style, registry, contextConfigData, actualFilePath), [generateAgentDefinition(agentId, agentData, style, registry, contextConfigData, projectModels)]);
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
//#endregion
|
|
241
|
+
export { generateAgentDefinition, generateAgentFile, generateAgentImports };
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
import { jsonSchemaToZod } from "json-schema-to-zod";
|
|
2
|
+
|
|
3
|
+
//#region src/commands/pull-v3/components/artifact-component-generator.ts
|
|
4
|
+
/**
|
|
5
|
+
* Artifact Component Generator - Generate artifact component definitions
|
|
6
|
+
*
|
|
7
|
+
* Generates artifact components using the artifactComponent() builder function from @inkeep/agents-sdk
|
|
8
|
+
* Handles isPreview flag with preview() function wrapper from @inkeep/agents-core
|
|
9
|
+
*/
|
|
10
|
+
const DEFAULT_STYLE = {
|
|
11
|
+
quotes: "single",
|
|
12
|
+
semicolons: true,
|
|
13
|
+
indentation: " "
|
|
14
|
+
};
|
|
15
|
+
/**
|
|
16
|
+
* Utility functions
|
|
17
|
+
*/
|
|
18
|
+
function toCamelCase(str) {
|
|
19
|
+
return str.toLowerCase().replace(/[-_](.)/g, (_, char) => char.toUpperCase()).replace(/[^a-zA-Z0-9]/g, "").replace(/^[0-9]/, "_$&");
|
|
20
|
+
}
|
|
21
|
+
function formatString(str, quote = "'", multiline = false) {
|
|
22
|
+
if (!str) return `${quote}${quote}`;
|
|
23
|
+
if (multiline && (str.includes("\n") || str.length > 80)) return `\`${str.replace(/`/g, "\\`")}\``;
|
|
24
|
+
return `${quote}${str.replace(new RegExp(quote, "g"), "\\" + quote)}${quote}`;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Check if schema has any properties with inPreview: true
|
|
28
|
+
*/
|
|
29
|
+
function hasInPreviewFields(schema) {
|
|
30
|
+
if (!schema || typeof schema !== "object" || schema.type !== "object" || !schema.properties) return false;
|
|
31
|
+
for (const prop of Object.values(schema.properties)) if (prop.inPreview === true) return true;
|
|
32
|
+
return false;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Format artifact schema with preview() wrappers based on inPreview: true in properties
|
|
36
|
+
*/
|
|
37
|
+
function formatArtifactSchema(schema, style) {
|
|
38
|
+
if (!schema || typeof schema !== "object") return "z.any()";
|
|
39
|
+
if (schema.type === "object" && schema.properties) {
|
|
40
|
+
const { indentation } = style;
|
|
41
|
+
const lines = ["z.object({"];
|
|
42
|
+
for (const [key, prop] of Object.entries(schema.properties)) {
|
|
43
|
+
const propCopy = { ...prop };
|
|
44
|
+
delete propCopy.inPreview;
|
|
45
|
+
const baseZodType = convertJsonSchemaToZod(propCopy);
|
|
46
|
+
const finalZodType = prop.inPreview === true ? `preview(${baseZodType})` : baseZodType;
|
|
47
|
+
lines.push(`${indentation}${key}: ${finalZodType},`);
|
|
48
|
+
}
|
|
49
|
+
lines.push("})");
|
|
50
|
+
if (schema.description) return lines.join("\n") + `.describe(\`${schema.description}\`)`;
|
|
51
|
+
return lines.join("\n");
|
|
52
|
+
}
|
|
53
|
+
return convertJsonSchemaToZod(schema);
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Convert JSON Schema to Zod schema using existing utility
|
|
57
|
+
*/
|
|
58
|
+
function convertJsonSchemaToZod(schema) {
|
|
59
|
+
if (!schema || typeof schema !== "object") return "z.any()";
|
|
60
|
+
try {
|
|
61
|
+
return jsonSchemaToZod(schema);
|
|
62
|
+
} catch (error) {
|
|
63
|
+
console.warn("Failed to convert JSON schema to Zod:", error);
|
|
64
|
+
return "z.any()";
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Generate Artifact Component Definition using artifactComponent() builder function
|
|
69
|
+
*/
|
|
70
|
+
function generateArtifactComponentDefinition(componentId, componentData, style = DEFAULT_STYLE) {
|
|
71
|
+
if (!componentId || typeof componentId !== "string") throw new Error("componentId is required and must be a string");
|
|
72
|
+
if (!componentData || typeof componentData !== "object") throw new Error(`componentData is required for artifact component '${componentId}'`);
|
|
73
|
+
const missingFields = ["name"].filter((field) => !componentData[field] || componentData[field] === null || componentData[field] === void 0);
|
|
74
|
+
if (!componentData.props) missingFields.push("props");
|
|
75
|
+
if (missingFields.length > 0) throw new Error(`Missing required fields for artifact component '${componentId}': ${missingFields.join(", ")}`);
|
|
76
|
+
const { quotes, semicolons, indentation } = style;
|
|
77
|
+
const q = quotes === "single" ? "'" : "\"";
|
|
78
|
+
const semi = semicolons ? ";" : "";
|
|
79
|
+
const componentVarName = toCamelCase(componentId);
|
|
80
|
+
const lines = [];
|
|
81
|
+
lines.push(`export const ${componentVarName} = artifactComponent({`);
|
|
82
|
+
lines.push(`${indentation}id: ${formatString(componentId, q)},`);
|
|
83
|
+
lines.push(`${indentation}name: ${formatString(componentData.name, q)},`);
|
|
84
|
+
lines.push(`${indentation}description: ${formatString(componentData.description, q, true)},`);
|
|
85
|
+
const schema = componentData.props || componentData.schema;
|
|
86
|
+
if (schema) {
|
|
87
|
+
const zodSchema = formatArtifactSchema(schema, style);
|
|
88
|
+
if (zodSchema.includes("\n")) {
|
|
89
|
+
const schemaLines = zodSchema.split("\n");
|
|
90
|
+
lines.push(`${indentation}props: ${schemaLines[0]}`);
|
|
91
|
+
schemaLines.slice(1, -1).forEach((line) => {
|
|
92
|
+
lines[lines.length - 1] += "\n" + indentation + line;
|
|
93
|
+
});
|
|
94
|
+
lines[lines.length - 1] += "\n" + indentation + schemaLines[schemaLines.length - 1] + ",";
|
|
95
|
+
} else lines.push(`${indentation}props: ${zodSchema},`);
|
|
96
|
+
}
|
|
97
|
+
if (componentData.template) lines.push(`${indentation}template: ${formatString(componentData.template, q, true)},`);
|
|
98
|
+
if (componentData.contentType) lines.push(`${indentation}contentType: ${formatString(componentData.contentType, q)},`);
|
|
99
|
+
if (lines.length > 0 && lines[lines.length - 1].endsWith(",")) lines[lines.length - 1] = lines[lines.length - 1].slice(0, -1);
|
|
100
|
+
lines.push(`})${semi}`);
|
|
101
|
+
return lines.join("\n");
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* Generate imports needed for an artifact component file
|
|
105
|
+
*/
|
|
106
|
+
function generateArtifactComponentImports(componentId, componentData, style = DEFAULT_STYLE) {
|
|
107
|
+
const { quotes, semicolons } = style;
|
|
108
|
+
const q = quotes === "single" ? "'" : "\"";
|
|
109
|
+
const semi = semicolons ? ";" : "";
|
|
110
|
+
const imports = [];
|
|
111
|
+
const schema = componentData.props || componentData.schema;
|
|
112
|
+
if (hasInPreviewFields(schema)) imports.push(`import { preview } from ${q}@inkeep/agents-core${q}${semi}`);
|
|
113
|
+
imports.push(`import { artifactComponent } from ${q}@inkeep/agents-sdk${q}${semi}`);
|
|
114
|
+
if (schema) imports.push(`import { z } from ${q}zod${q}${semi}`);
|
|
115
|
+
return imports;
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* Generate complete artifact component file (imports + definition)
|
|
119
|
+
*/
|
|
120
|
+
function generateArtifactComponentFile(componentId, componentData, style = DEFAULT_STYLE) {
|
|
121
|
+
const imports = generateArtifactComponentImports(componentId, componentData, style);
|
|
122
|
+
const definition = generateArtifactComponentDefinition(componentId, componentData, style);
|
|
123
|
+
return imports.join("\n") + "\n\n" + definition + "\n";
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
//#endregion
|
|
127
|
+
export { generateArtifactComponentDefinition, generateArtifactComponentFile, generateArtifactComponentImports };
|
|
@@ -0,0 +1,190 @@
|
|
|
1
|
+
import { DEFAULT_STYLE, formatString, generateFileContent, generateImport, hasTemplateVariables, removeTrailingComma, toCamelCase } from "../utils/generator-utils.js";
|
|
2
|
+
import { jsonSchemaToZod } from "json-schema-to-zod";
|
|
3
|
+
|
|
4
|
+
//#region src/commands/pull-v3/components/context-config-generator.ts
|
|
5
|
+
/**
|
|
6
|
+
* Context Config Generator - Generate contextConfig definitions
|
|
7
|
+
*
|
|
8
|
+
* Generates contextConfig using contextConfig(), headers(), and fetchDefinition()
|
|
9
|
+
* builder functions from @inkeep/agents-core
|
|
10
|
+
*/
|
|
11
|
+
/**
|
|
12
|
+
* Process template variables in fetchConfig objects
|
|
13
|
+
*/
|
|
14
|
+
function processFetchConfigTemplates(fetchConfig, headersVarName) {
|
|
15
|
+
const processValue = (value) => {
|
|
16
|
+
if (typeof value === "string") {
|
|
17
|
+
if (hasTemplateVariables(value)) return `\`${value.replace(/\{\{headers\.([^}]+)\}\}/g, `\${${headersVarName}.toTemplate("$1")}`).replace(/`/g, "\\`")}\``;
|
|
18
|
+
if (value.includes("\n") || value.length > 80) return `\`${value.replace(/`/g, "\\`")}\``;
|
|
19
|
+
return `'${value.replace(/'/g, "\\'")}'`;
|
|
20
|
+
}
|
|
21
|
+
if (typeof value === "object" && value !== null) return processObject(value);
|
|
22
|
+
return JSON.stringify(value);
|
|
23
|
+
};
|
|
24
|
+
const processObject = (obj) => {
|
|
25
|
+
if (Array.isArray(obj)) return `[${obj.map((item) => processValue(item)).join(", ")}]`;
|
|
26
|
+
return `{\n ${Object.entries(obj).filter(([key, val]) => val !== void 0 && val !== null).map(([key, val]) => {
|
|
27
|
+
return `${/^[a-zA-Z_$][a-zA-Z0-9_$]*$/.test(key) ? key : `'${key}'`}: ${processValue(val)}`;
|
|
28
|
+
}).join(",\n ")}\n }`;
|
|
29
|
+
};
|
|
30
|
+
return processObject(fetchConfig);
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Generate Headers Definition using headers() builder function
|
|
34
|
+
*/
|
|
35
|
+
function generateHeadersDefinition(headersId, headersData, style = DEFAULT_STYLE) {
|
|
36
|
+
const { quotes, semicolons, indentation } = style;
|
|
37
|
+
const semi = semicolons ? ";" : "";
|
|
38
|
+
const headersVarName = toCamelCase(headersId);
|
|
39
|
+
const lines = [];
|
|
40
|
+
lines.push(`const ${headersVarName} = headers({`);
|
|
41
|
+
if (headersData.schema) {
|
|
42
|
+
const zodSchema = jsonSchemaToZod(headersData.schema, { module: "none" });
|
|
43
|
+
lines.push(`${indentation}schema: ${zodSchema},`);
|
|
44
|
+
}
|
|
45
|
+
removeTrailingComma(lines);
|
|
46
|
+
lines.push(`})${semi}`);
|
|
47
|
+
return lines.join("\n");
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Generate Fetch Definition using fetchDefinition() builder function
|
|
51
|
+
*/
|
|
52
|
+
function generateFetchDefinitionDefinition(fetchId, fetchData, style = DEFAULT_STYLE, headersVarName, registry) {
|
|
53
|
+
const { quotes, semicolons, indentation } = style;
|
|
54
|
+
const q = quotes === "single" ? "'" : "\"";
|
|
55
|
+
const semi = semicolons ? ";" : "";
|
|
56
|
+
const fetchVarName = toCamelCase(fetchId);
|
|
57
|
+
const lines = [];
|
|
58
|
+
lines.push(`const ${fetchVarName} = fetchDefinition({`);
|
|
59
|
+
lines.push(`${indentation}id: ${formatString(fetchData.id || fetchId, q)},`);
|
|
60
|
+
if (fetchData.name) lines.push(`${indentation}name: ${formatString(fetchData.name, q)},`);
|
|
61
|
+
if (fetchData.trigger) lines.push(`${indentation}trigger: ${formatString(fetchData.trigger, q)},`);
|
|
62
|
+
if (fetchData.fetchConfig) {
|
|
63
|
+
const processedFetchConfig = processFetchConfigTemplates(fetchData.fetchConfig, headersVarName || "headers");
|
|
64
|
+
lines.push(`${indentation}fetchConfig: ${processedFetchConfig},`);
|
|
65
|
+
}
|
|
66
|
+
if (fetchData.responseSchema) {
|
|
67
|
+
const zodSchema = jsonSchemaToZod(fetchData.responseSchema, { module: "none" });
|
|
68
|
+
lines.push(`${indentation}responseSchema: ${zodSchema},`);
|
|
69
|
+
}
|
|
70
|
+
if (fetchData.defaultValue) if (typeof fetchData.defaultValue === "string") {
|
|
71
|
+
const isMultiline = fetchData.defaultValue.includes("\n") || fetchData.defaultValue.length > 80;
|
|
72
|
+
lines.push(`${indentation}defaultValue: ${formatString(fetchData.defaultValue, q, isMultiline)},`);
|
|
73
|
+
} else lines.push(`${indentation}defaultValue: ${JSON.stringify(fetchData.defaultValue)},`);
|
|
74
|
+
if (fetchData.credentialReferenceId && registry) {
|
|
75
|
+
const validKey = registry.getVariableName(fetchData.credentialReferenceId, "credentials");
|
|
76
|
+
lines.push(`${indentation}credentialReference: ${validKey},`);
|
|
77
|
+
}
|
|
78
|
+
removeTrailingComma(lines);
|
|
79
|
+
lines.push(`})${semi}`);
|
|
80
|
+
return lines.join("\n");
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* Generate Context Config Definition using contextConfig() builder function
|
|
84
|
+
*/
|
|
85
|
+
function generateContextConfigDefinition(contextId, contextData, style = DEFAULT_STYLE, registry, agentId, headersVarName) {
|
|
86
|
+
if (!contextId || typeof contextId !== "string") throw new Error("contextId is required and must be a string");
|
|
87
|
+
if (!contextData || typeof contextData !== "object") throw new Error(`contextData is required for context config '${contextId}'`);
|
|
88
|
+
const { quotes, semicolons, indentation } = style;
|
|
89
|
+
const q = quotes === "single" ? "'" : "\"";
|
|
90
|
+
const semi = semicolons ? ";" : "";
|
|
91
|
+
const contextVarName = (() => {
|
|
92
|
+
if (!registry) throw new Error("Registry is required for context config variable name generation");
|
|
93
|
+
const varName = registry.getVariableName(contextId, "contextConfigs");
|
|
94
|
+
if (!varName) throw new Error(`Failed to resolve variable name for context config: ${contextId}`);
|
|
95
|
+
return varName;
|
|
96
|
+
})();
|
|
97
|
+
const lines = [];
|
|
98
|
+
lines.push(`const ${contextVarName} = contextConfig({`);
|
|
99
|
+
if (contextData.id) lines.push(`${indentation}id: ${formatString(contextData.id, q)},`);
|
|
100
|
+
if (headersVarName) lines.push(`${indentation}headers: ${headersVarName},`);
|
|
101
|
+
else if (contextData.headers) lines.push(`${indentation}headers: ${contextData.headers},`);
|
|
102
|
+
if (contextData.contextVariables) {
|
|
103
|
+
const contextVarLines = [`${indentation}contextVariables: {`];
|
|
104
|
+
for (const [varName, varData] of Object.entries(contextData.contextVariables)) if (typeof varData === "string") contextVarLines.push(`${indentation} ${varName}: ${varData},`);
|
|
105
|
+
else if (varData && typeof varData === "object" && (varData.fetchConfig || varData.responseSchema)) contextVarLines.push(`${indentation} ${varName},`);
|
|
106
|
+
if (contextVarLines[contextVarLines.length - 1].endsWith(",")) contextVarLines[contextVarLines.length - 1] = contextVarLines[contextVarLines.length - 1].slice(0, -1);
|
|
107
|
+
contextVarLines.push(`${indentation}},`);
|
|
108
|
+
lines.push(...contextVarLines);
|
|
109
|
+
}
|
|
110
|
+
removeTrailingComma(lines);
|
|
111
|
+
lines.push(`})${semi}`);
|
|
112
|
+
return lines.join("\n");
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* Generate imports needed for a context config file
|
|
116
|
+
*/
|
|
117
|
+
function generateContextConfigImports(contextId, contextData, style = DEFAULT_STYLE, registry) {
|
|
118
|
+
const imports = [];
|
|
119
|
+
const coreImports = [];
|
|
120
|
+
if (contextData.headers || hasHeadersInData(contextData)) coreImports.push("headers");
|
|
121
|
+
if (contextData.contextVariables && hasFetchDefinitionsInData(contextData)) coreImports.push("fetchDefinition");
|
|
122
|
+
coreImports.push("contextConfig");
|
|
123
|
+
if (coreImports.length > 0) imports.push(generateImport(coreImports, "@inkeep/agents-core", style));
|
|
124
|
+
if (hasSchemas(contextData)) imports.push(generateImport(["z"], "zod", style));
|
|
125
|
+
if (registry && contextData.contextVariables) {
|
|
126
|
+
const credentialRefs = [];
|
|
127
|
+
for (const [varName, varData] of Object.entries(contextData.contextVariables)) if (varData && typeof varData === "object" && varData.credentialReferenceId) credentialRefs.push({
|
|
128
|
+
id: varData.credentialReferenceId,
|
|
129
|
+
type: "credentials"
|
|
130
|
+
});
|
|
131
|
+
if (credentialRefs.length > 0) {
|
|
132
|
+
const contextComponent = registry.get(contextId, "contextConfigs");
|
|
133
|
+
if (contextComponent) {
|
|
134
|
+
const credentialImports = registry.getImportsForFile(contextComponent.filePath, credentialRefs);
|
|
135
|
+
imports.push(...credentialImports);
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
return imports;
|
|
140
|
+
}
|
|
141
|
+
/**
|
|
142
|
+
* Helper functions to detect what imports are needed
|
|
143
|
+
*/
|
|
144
|
+
function hasHeadersInData(contextData) {
|
|
145
|
+
return !!contextData.headers || JSON.stringify(contextData).includes("headers");
|
|
146
|
+
}
|
|
147
|
+
function hasFetchDefinitionsInData(contextData) {
|
|
148
|
+
return JSON.stringify(contextData).includes("fetchDefinition") || contextData.contextVariables && Object.values(contextData.contextVariables).some((v) => v && typeof v === "object" && (v.fetchConfig || v.responseSchema));
|
|
149
|
+
}
|
|
150
|
+
function hasSchemas(contextData) {
|
|
151
|
+
const dataStr = JSON.stringify(contextData).toLowerCase();
|
|
152
|
+
return dataStr.includes("schema") || dataStr.includes("responseschema");
|
|
153
|
+
}
|
|
154
|
+
/**
|
|
155
|
+
* Generate complete context config file (imports + all definitions)
|
|
156
|
+
*/
|
|
157
|
+
function generateContextConfigFile(contextId, contextData, style = DEFAULT_STYLE, registry, agentId) {
|
|
158
|
+
const imports = generateContextConfigImports(contextId, contextData, style, registry);
|
|
159
|
+
const definitions = [];
|
|
160
|
+
let headersVarName;
|
|
161
|
+
if (contextData.headersSchema) {
|
|
162
|
+
if (typeof contextData.headers === "string") headersVarName = contextData.headers;
|
|
163
|
+
else headersVarName = `${toCamelCase(contextId)}Headers`;
|
|
164
|
+
const headersDefinition = generateHeadersDefinition(headersVarName || "headers", { schema: contextData.headersSchema }, style);
|
|
165
|
+
definitions.push(headersDefinition);
|
|
166
|
+
}
|
|
167
|
+
if (contextData.contextVariables) {
|
|
168
|
+
for (const [varName, varData] of Object.entries(contextData.contextVariables)) if (varData && typeof varData === "object" && (varData.fetchConfig || varData.responseSchema)) {
|
|
169
|
+
const fetchDefinition = generateFetchDefinitionDefinition(varName, varData, style, headersVarName, registry);
|
|
170
|
+
definitions.push(fetchDefinition);
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
const contextDefinition = generateContextConfigDefinition(contextId, contextData, style, registry, agentId, headersVarName);
|
|
174
|
+
definitions.push(contextDefinition);
|
|
175
|
+
const exports = [(() => {
|
|
176
|
+
if (!registry) throw new Error("Registry is required for context config variable name generation");
|
|
177
|
+
const varName = registry.getVariableName(contextId, "contextConfigs");
|
|
178
|
+
if (!varName) throw new Error(`Failed to resolve variable name for context config: ${contextId}`);
|
|
179
|
+
return varName;
|
|
180
|
+
})()];
|
|
181
|
+
if (headersVarName) exports.push(headersVarName);
|
|
182
|
+
if (contextData.contextVariables) {
|
|
183
|
+
for (const [varName, varData] of Object.entries(contextData.contextVariables)) if (varData && typeof varData === "object" && (varData.fetchConfig || varData.responseSchema)) exports.push(varName);
|
|
184
|
+
}
|
|
185
|
+
definitions.push(`export { ${exports.join(", ")} };`);
|
|
186
|
+
return generateFileContent(imports, definitions);
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
//#endregion
|
|
190
|
+
export { generateContextConfigDefinition, generateContextConfigFile, generateContextConfigImports, generateFetchDefinitionDefinition, generateHeadersDefinition };
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
//#region src/commands/pull-v3/components/credential-generator.ts
|
|
2
|
+
const DEFAULT_STYLE = {
|
|
3
|
+
quotes: "single",
|
|
4
|
+
semicolons: true,
|
|
5
|
+
indentation: " "
|
|
6
|
+
};
|
|
7
|
+
/**
|
|
8
|
+
* Utility functions
|
|
9
|
+
*/
|
|
10
|
+
function toCamelCase(str) {
|
|
11
|
+
return str.toLowerCase().replace(/[-_](.)/g, (_, char) => char.toUpperCase()).replace(/[^a-zA-Z0-9]/g, "").replace(/^[0-9]/, "_$&");
|
|
12
|
+
}
|
|
13
|
+
function formatString(str, quote = "'", multiline = false) {
|
|
14
|
+
if (!str) return `${quote}${quote}`;
|
|
15
|
+
if (multiline && (str.includes("\n") || str.length > 80)) return `\`${str.replace(/`/g, "\\`")}\``;
|
|
16
|
+
return `${quote}${str.replace(new RegExp(quote, "g"), "\\" + quote)}${quote}`;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Format retrieval params object
|
|
20
|
+
*/
|
|
21
|
+
function formatRetrievalParams(retrievalParams, style, indentLevel) {
|
|
22
|
+
if (!retrievalParams || typeof retrievalParams !== "object") return "{}";
|
|
23
|
+
const { quotes, indentation } = style;
|
|
24
|
+
const q = quotes === "single" ? "'" : "\"";
|
|
25
|
+
const baseIndent = indentation.repeat(indentLevel);
|
|
26
|
+
const indent = indentation.repeat(indentLevel + 1);
|
|
27
|
+
const lines = ["{"];
|
|
28
|
+
for (const [key, value] of Object.entries(retrievalParams)) {
|
|
29
|
+
const formattedKey = /^[a-zA-Z_$][a-zA-Z0-9_$]*$/.test(key) ? key : `${q}${key}${q}`;
|
|
30
|
+
if (typeof value === "string") lines.push(`${indent}${formattedKey}: ${formatString(value, q)},`);
|
|
31
|
+
else if (typeof value === "number" || typeof value === "boolean") lines.push(`${indent}${formattedKey}: ${JSON.stringify(value)},`);
|
|
32
|
+
else if (typeof value === "object" && value !== null) lines.push(`${indent}${formattedKey}: ${formatRetrievalParams(value, style, indentLevel + 1)},`);
|
|
33
|
+
}
|
|
34
|
+
if (lines.length > 1 && lines[lines.length - 1].endsWith(",")) lines[lines.length - 1] = lines[lines.length - 1].slice(0, -1);
|
|
35
|
+
lines.push(`${baseIndent}}`);
|
|
36
|
+
return lines.join("\n");
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Generate Credential Definition using credential() builder function
|
|
40
|
+
*/
|
|
41
|
+
function generateCredentialDefinition(credentialId, credentialData, style = DEFAULT_STYLE) {
|
|
42
|
+
const { quotes, semicolons, indentation } = style;
|
|
43
|
+
const q = quotes === "single" ? "'" : "\"";
|
|
44
|
+
const semi = semicolons ? ";" : "";
|
|
45
|
+
const credentialVarName = toCamelCase(credentialId);
|
|
46
|
+
const lines = [];
|
|
47
|
+
lines.push(`export const ${credentialVarName} = credential({`);
|
|
48
|
+
lines.push(`${indentation}id: ${formatString(credentialId, q)},`);
|
|
49
|
+
const missingFields = [
|
|
50
|
+
"name",
|
|
51
|
+
"type",
|
|
52
|
+
"credentialStoreId"
|
|
53
|
+
].filter((field) => !credentialData[field] || credentialData[field] === null || credentialData[field] === void 0);
|
|
54
|
+
if (missingFields.length > 0) throw new Error(`Missing required fields for credential '${credentialId}': ${missingFields.join(", ")}`);
|
|
55
|
+
lines.push(`${indentation}name: ${formatString(credentialData.name, q)},`);
|
|
56
|
+
lines.push(`${indentation}type: ${formatString(credentialData.type, q)},`);
|
|
57
|
+
lines.push(`${indentation}credentialStoreId: ${formatString(credentialData.credentialStoreId, q)},`);
|
|
58
|
+
if (credentialData.description) lines.push(`${indentation}description: ${formatString(credentialData.description, q, true)},`);
|
|
59
|
+
if (credentialData.retrievalParams) {
|
|
60
|
+
const formattedParams = formatRetrievalParams(credentialData.retrievalParams, style, 1);
|
|
61
|
+
if (formattedParams.includes("\n")) lines.push(`${indentation}retrievalParams: ${formattedParams},`);
|
|
62
|
+
else lines.push(`${indentation}retrievalParams: ${formattedParams},`);
|
|
63
|
+
}
|
|
64
|
+
if (lines.length > 0 && lines[lines.length - 1].endsWith(",")) lines[lines.length - 1] = lines[lines.length - 1].slice(0, -1);
|
|
65
|
+
lines.push(`})${semi}`);
|
|
66
|
+
return lines.join("\n");
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Generate imports needed for a credential file
|
|
70
|
+
*/
|
|
71
|
+
function generateCredentialImports(credentialId, credentialData, style = DEFAULT_STYLE) {
|
|
72
|
+
const { quotes, semicolons } = style;
|
|
73
|
+
const q = quotes === "single" ? "'" : "\"";
|
|
74
|
+
const semi = semicolons ? ";" : "";
|
|
75
|
+
const imports = [];
|
|
76
|
+
imports.push(`import { credential } from ${q}@inkeep/agents-sdk${q}${semi}`);
|
|
77
|
+
return imports;
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Generate complete credential file (imports + definition)
|
|
81
|
+
*/
|
|
82
|
+
function generateCredentialFile(credentialId, credentialData, style = DEFAULT_STYLE) {
|
|
83
|
+
const imports = generateCredentialImports(credentialId, credentialData, style);
|
|
84
|
+
const definition = generateCredentialDefinition(credentialId, credentialData, style);
|
|
85
|
+
return imports.join("\n") + "\n\n" + definition + "\n";
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
//#endregion
|
|
89
|
+
export { generateCredentialDefinition, generateCredentialFile, generateCredentialImports };
|