@inkeep/agents-cli 0.1.4 → 0.1.6
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/SUPPLEMENTAL_TERMS.md +40 -0
- package/dist/commands/create.d.ts +12 -0
- package/dist/commands/create.js +865 -0
- package/dist/config.d.ts +4 -4
- package/dist/index.js +5308 -20409
- package/package.json +15 -6
- package/dist/__tests__/api.test.d.ts +0 -1
- package/dist/__tests__/api.test.js +0 -257
- package/dist/__tests__/cli.test.d.ts +0 -1
- package/dist/__tests__/cli.test.js +0 -153
- package/dist/__tests__/commands/config.test.d.ts +0 -1
- package/dist/__tests__/commands/config.test.js +0 -154
- package/dist/__tests__/commands/init.test.d.ts +0 -1
- package/dist/__tests__/commands/init.test.js +0 -186
- package/dist/__tests__/commands/pull.test.d.ts +0 -1
- package/dist/__tests__/commands/pull.test.js +0 -54
- package/dist/__tests__/commands/push-spinner.test.d.ts +0 -1
- package/dist/__tests__/commands/push-spinner.test.js +0 -127
- package/dist/__tests__/commands/push.test.d.ts +0 -1
- package/dist/__tests__/commands/push.test.js +0 -265
- package/dist/__tests__/config-validation.test.d.ts +0 -1
- package/dist/__tests__/config-validation.test.js +0 -98
- package/dist/__tests__/package.test.d.ts +0 -1
- package/dist/__tests__/package.test.js +0 -82
- package/dist/__tests__/utils/json-comparator.test.d.ts +0 -1
- package/dist/__tests__/utils/json-comparator.test.js +0 -174
- package/dist/__tests__/utils/ts-loader.test.d.ts +0 -1
- package/dist/__tests__/utils/ts-loader.test.js +0 -232
- package/dist/api.d.ts +0 -23
- package/dist/api.js +0 -140
- package/dist/commands/chat-enhanced.d.ts +0 -7
- package/dist/commands/chat-enhanced.js +0 -396
- package/dist/commands/chat.d.ts +0 -5
- package/dist/commands/chat.js +0 -125
- package/dist/commands/config.d.ts +0 -6
- package/dist/commands/config.js +0 -128
- package/dist/commands/init.d.ts +0 -5
- package/dist/commands/init.js +0 -171
- package/dist/commands/list-graphs.d.ts +0 -6
- package/dist/commands/list-graphs.js +0 -131
- package/dist/commands/pull.d.ts +0 -15
- package/dist/commands/pull.js +0 -305
- package/dist/commands/pull.llm-generate.d.ts +0 -10
- package/dist/commands/pull.llm-generate.js +0 -184
- package/dist/commands/push.d.ts +0 -6
- package/dist/commands/push.js +0 -268
- package/dist/exports.d.ts +0 -2
- package/dist/exports.js +0 -2
- package/dist/index.js.map +0 -7
- package/dist/types/config.d.ts +0 -9
- package/dist/types/config.js +0 -3
- package/dist/types/graph.d.ts +0 -10
- package/dist/types/graph.js +0 -1
- package/dist/utils/json-comparator.d.ts +0 -60
- package/dist/utils/json-comparator.js +0 -222
- package/dist/utils/mcp-runner.d.ts +0 -6
- package/dist/utils/mcp-runner.js +0 -147
- package/dist/utils/ts-loader.d.ts +0 -5
- package/dist/utils/ts-loader.js +0 -145
package/dist/commands/push.js
DELETED
|
@@ -1,268 +0,0 @@
|
|
|
1
|
-
import { spawn } from 'node:child_process';
|
|
2
|
-
import { existsSync } from 'node:fs';
|
|
3
|
-
import { dirname, extname, resolve } from 'node:path';
|
|
4
|
-
import { fileURLToPath, pathToFileURL } from 'node:url';
|
|
5
|
-
import chalk from 'chalk';
|
|
6
|
-
import ora from 'ora';
|
|
7
|
-
import inquirer from 'inquirer';
|
|
8
|
-
import { createDatabaseClient, getProject, createProject } from '@inkeep/agents-core';
|
|
9
|
-
import { ManagementApiClient } from '../api.js';
|
|
10
|
-
import { validateConfiguration } from '../config.js';
|
|
11
|
-
export async function pushCommand(graphPath, options) {
|
|
12
|
-
const spinner = ora('Loading graph configuration...').start();
|
|
13
|
-
try {
|
|
14
|
-
// Resolve the absolute path
|
|
15
|
-
const absolutePath = resolve(process.cwd(), graphPath);
|
|
16
|
-
// Check if file exists
|
|
17
|
-
if (!existsSync(absolutePath)) {
|
|
18
|
-
spinner.fail('Graph file not found');
|
|
19
|
-
console.error(chalk.red(`File not found: ${absolutePath}`));
|
|
20
|
-
process.exit(1);
|
|
21
|
-
}
|
|
22
|
-
// Check if this is a TypeScript file
|
|
23
|
-
const ext = extname(absolutePath);
|
|
24
|
-
if (ext === '.ts') {
|
|
25
|
-
// For TypeScript files, we need to use tsx to run this entire command
|
|
26
|
-
// Check if we're already running under tsx
|
|
27
|
-
if (!process.env.TSX_RUNNING) {
|
|
28
|
-
// Stop spinner before spawning child process to avoid conflicts with interactive prompts
|
|
29
|
-
spinner.stop();
|
|
30
|
-
// Re-run this command with tsx
|
|
31
|
-
// Find the inkeep CLI executable
|
|
32
|
-
const __filename = fileURLToPath(import.meta.url);
|
|
33
|
-
const __dirname = dirname(__filename);
|
|
34
|
-
const cliPath = resolve(__dirname, '../index.js');
|
|
35
|
-
const args = [cliPath, 'push', graphPath];
|
|
36
|
-
if (options.tenantId)
|
|
37
|
-
args.push('--tenant-id', options.tenantId);
|
|
38
|
-
if (options.managementApiUrl)
|
|
39
|
-
args.push('--management-api-url', options.managementApiUrl);
|
|
40
|
-
if (options.configFilePath)
|
|
41
|
-
args.push('--config-file-path', options.configFilePath);
|
|
42
|
-
const child = spawn('npx', ['tsx', ...args], {
|
|
43
|
-
cwd: process.cwd(),
|
|
44
|
-
stdio: 'inherit',
|
|
45
|
-
env: { ...process.env, TSX_RUNNING: '1' },
|
|
46
|
-
});
|
|
47
|
-
child.on('error', (error) => {
|
|
48
|
-
console.error(chalk.red('Failed to load TypeScript file'));
|
|
49
|
-
console.error(chalk.red('Error:'), error.message);
|
|
50
|
-
process.exit(1);
|
|
51
|
-
});
|
|
52
|
-
child.on('exit', (code) => {
|
|
53
|
-
process.exit(code || 0);
|
|
54
|
-
});
|
|
55
|
-
return;
|
|
56
|
-
}
|
|
57
|
-
}
|
|
58
|
-
// Now we can import the module (either JS directly, or TS via tsx)
|
|
59
|
-
const fileUrl = pathToFileURL(absolutePath).href;
|
|
60
|
-
const module = await import(fileUrl);
|
|
61
|
-
// Validate that exactly one graph is exported
|
|
62
|
-
const exports = Object.keys(module);
|
|
63
|
-
const graphExports = exports.filter((key) => {
|
|
64
|
-
const value = module[key];
|
|
65
|
-
// Check for AgentGraph-like objects (has required methods)
|
|
66
|
-
return (value &&
|
|
67
|
-
typeof value === 'object' &&
|
|
68
|
-
typeof value.init === 'function' &&
|
|
69
|
-
typeof value.getId === 'function' &&
|
|
70
|
-
typeof value.getName === 'function' &&
|
|
71
|
-
typeof value.getAgents === 'function');
|
|
72
|
-
});
|
|
73
|
-
if (graphExports.length === 0) {
|
|
74
|
-
spinner.fail('No AgentGraph exported from configuration file');
|
|
75
|
-
console.error(chalk.red('Configuration file must export at least one AgentGraph instance'));
|
|
76
|
-
process.exit(1);
|
|
77
|
-
}
|
|
78
|
-
if (graphExports.length > 1) {
|
|
79
|
-
spinner.fail('Multiple AgentGraphs exported from configuration file');
|
|
80
|
-
console.error(chalk.red('Configuration file must export exactly one AgentGraph instance'));
|
|
81
|
-
console.error(chalk.yellow('Found exports:'), graphExports.join(', '));
|
|
82
|
-
process.exit(1);
|
|
83
|
-
}
|
|
84
|
-
// Get the graph instance
|
|
85
|
-
const graphKey = graphExports[0];
|
|
86
|
-
const graph = module[graphKey];
|
|
87
|
-
spinner.text = 'Loading configuration...';
|
|
88
|
-
// Validate configuration
|
|
89
|
-
let config;
|
|
90
|
-
try {
|
|
91
|
-
config = await validateConfiguration(options.tenantId, options.managementApiUrl, undefined, // executionApiUrl not needed for push
|
|
92
|
-
options.configFilePath);
|
|
93
|
-
}
|
|
94
|
-
catch (error) {
|
|
95
|
-
spinner.fail('Configuration validation failed');
|
|
96
|
-
console.error(chalk.red(error.message));
|
|
97
|
-
process.exit(1);
|
|
98
|
-
}
|
|
99
|
-
spinner.succeed('Configuration loaded');
|
|
100
|
-
// Log configuration sources for debugging
|
|
101
|
-
console.log(chalk.gray('Configuration sources:'));
|
|
102
|
-
console.log(chalk.gray(` • Tenant ID: ${config.sources.tenantId}`));
|
|
103
|
-
console.log(chalk.gray(` • Project ID: ${config.sources.projectId}`));
|
|
104
|
-
console.log(chalk.gray(` • API URL: ${config.sources.managementApiUrl}`));
|
|
105
|
-
const tenantId = config.tenantId;
|
|
106
|
-
const projectId = config.projectId;
|
|
107
|
-
const managementApiUrl = config.managementApiUrl;
|
|
108
|
-
// Check if project exists in the database
|
|
109
|
-
spinner.text = 'Validating project...';
|
|
110
|
-
// Use local.db to check if project exists
|
|
111
|
-
let dbUrl = process.env.DB_FILE_NAME || 'local.db';
|
|
112
|
-
// Convert relative path to absolute path for libsql
|
|
113
|
-
if (dbUrl !== ':memory:' &&
|
|
114
|
-
!dbUrl.startsWith('file:') &&
|
|
115
|
-
!dbUrl.startsWith('libsql:') &&
|
|
116
|
-
!dbUrl.startsWith('http')) {
|
|
117
|
-
const absolutePath = resolve(process.cwd(), dbUrl);
|
|
118
|
-
// Validate database file exists
|
|
119
|
-
if (!existsSync(absolutePath)) {
|
|
120
|
-
spinner.fail(`Database file not found: ${absolutePath}`);
|
|
121
|
-
console.error(chalk.red('Please ensure the database file exists or set DB_FILE_NAME environment variable'));
|
|
122
|
-
process.exit(1);
|
|
123
|
-
}
|
|
124
|
-
dbUrl = `file:${absolutePath}`;
|
|
125
|
-
}
|
|
126
|
-
const dbClient = createDatabaseClient({ url: dbUrl });
|
|
127
|
-
const existingProject = await getProject(dbClient)({
|
|
128
|
-
scopes: { tenantId, projectId },
|
|
129
|
-
});
|
|
130
|
-
if (!existingProject) {
|
|
131
|
-
spinner.warn(`Project "${projectId}" does not exist`);
|
|
132
|
-
spinner.stop(); // Stop spinner before prompting
|
|
133
|
-
// Ask user if they want to create the project
|
|
134
|
-
const { shouldCreate } = await inquirer.prompt([
|
|
135
|
-
{
|
|
136
|
-
type: 'confirm',
|
|
137
|
-
name: 'shouldCreate',
|
|
138
|
-
message: `Project "${projectId}" does not exist. Would you like to create it?`,
|
|
139
|
-
default: true,
|
|
140
|
-
},
|
|
141
|
-
]);
|
|
142
|
-
if (!shouldCreate) {
|
|
143
|
-
console.log(chalk.yellow('Push cancelled. Project must exist before pushing a graph.'));
|
|
144
|
-
process.exit(0);
|
|
145
|
-
}
|
|
146
|
-
// Prompt for project details
|
|
147
|
-
const { projectName, projectDescription } = await inquirer.prompt([
|
|
148
|
-
{
|
|
149
|
-
type: 'input',
|
|
150
|
-
name: 'projectName',
|
|
151
|
-
message: 'Enter a name for the project:',
|
|
152
|
-
default: projectId,
|
|
153
|
-
validate: (input) => {
|
|
154
|
-
if (!input || input.trim() === '') {
|
|
155
|
-
return 'Project name is required';
|
|
156
|
-
}
|
|
157
|
-
return true;
|
|
158
|
-
},
|
|
159
|
-
},
|
|
160
|
-
{
|
|
161
|
-
type: 'input',
|
|
162
|
-
name: 'projectDescription',
|
|
163
|
-
message: 'Enter a description for the project (optional):',
|
|
164
|
-
default: '',
|
|
165
|
-
},
|
|
166
|
-
]);
|
|
167
|
-
// Create the project
|
|
168
|
-
spinner.start('Creating project...');
|
|
169
|
-
try {
|
|
170
|
-
await createProject(dbClient)({
|
|
171
|
-
id: projectId,
|
|
172
|
-
tenantId: tenantId,
|
|
173
|
-
name: projectName,
|
|
174
|
-
description: projectDescription || 'No description provided',
|
|
175
|
-
});
|
|
176
|
-
spinner.succeed(`Project "${projectName}" created successfully`);
|
|
177
|
-
}
|
|
178
|
-
catch (error) {
|
|
179
|
-
spinner.fail('Failed to create project');
|
|
180
|
-
console.error(chalk.red('Error:'), error.message);
|
|
181
|
-
process.exit(1);
|
|
182
|
-
}
|
|
183
|
-
}
|
|
184
|
-
else {
|
|
185
|
-
spinner.succeed(`Project "${existingProject.name || projectId}" validated`);
|
|
186
|
-
}
|
|
187
|
-
// Create API client with validated configuration (not used directly since graph handles its own API calls)
|
|
188
|
-
await ManagementApiClient.create(config.managementApiUrl, options.configFilePath, config.tenantId);
|
|
189
|
-
// Inject configuration into the graph
|
|
190
|
-
if (typeof graph.setConfig === 'function') {
|
|
191
|
-
graph.setConfig(tenantId, projectId, managementApiUrl);
|
|
192
|
-
}
|
|
193
|
-
spinner.start('Initializing graph...');
|
|
194
|
-
// Initialize the graph (this will push to the backend)
|
|
195
|
-
await graph.init();
|
|
196
|
-
// Get graph details
|
|
197
|
-
const graphId = graph.getId();
|
|
198
|
-
const graphName = graph.getName();
|
|
199
|
-
const stats = graph.getStats();
|
|
200
|
-
spinner.succeed(`Graph "${graphName}" (${graphId}) pushed successfully`);
|
|
201
|
-
// Validate for dangling resources
|
|
202
|
-
const agents = graph.getAgents();
|
|
203
|
-
const warnings = [];
|
|
204
|
-
// Check for agents not referenced in any relationships
|
|
205
|
-
for (const agent of agents) {
|
|
206
|
-
const agentName = agent.getName();
|
|
207
|
-
let isReferenced = false;
|
|
208
|
-
// Check if this agent is referenced by any other agent
|
|
209
|
-
for (const otherAgent of agents) {
|
|
210
|
-
if (otherAgent === agent)
|
|
211
|
-
continue;
|
|
212
|
-
// Check transfers (only for internal agents)
|
|
213
|
-
if (typeof otherAgent.getTransfers === 'function') {
|
|
214
|
-
const transfers = otherAgent.getTransfers();
|
|
215
|
-
if (transfers.some((h) => h.getName() === agentName)) {
|
|
216
|
-
isReferenced = true;
|
|
217
|
-
break;
|
|
218
|
-
}
|
|
219
|
-
}
|
|
220
|
-
// Check delegates (only for internal agents)
|
|
221
|
-
if (typeof otherAgent.getDelegates === 'function') {
|
|
222
|
-
const delegates = otherAgent.getDelegates();
|
|
223
|
-
if (delegates.some((d) => d.getName() === agentName)) {
|
|
224
|
-
isReferenced = true;
|
|
225
|
-
break;
|
|
226
|
-
}
|
|
227
|
-
}
|
|
228
|
-
}
|
|
229
|
-
// Check if it's the default agent
|
|
230
|
-
const defaultAgent = graph.getDefaultAgent();
|
|
231
|
-
if (defaultAgent && defaultAgent.getName() === agentName) {
|
|
232
|
-
isReferenced = true;
|
|
233
|
-
}
|
|
234
|
-
if (!isReferenced && agents.length > 1) {
|
|
235
|
-
warnings.push(`Agent "${agentName}" is not referenced in any transfer or delegation relationships`);
|
|
236
|
-
}
|
|
237
|
-
}
|
|
238
|
-
// Display warnings if any
|
|
239
|
-
if (warnings.length > 0) {
|
|
240
|
-
console.log(chalk.yellow('\n⚠️ Warnings:'));
|
|
241
|
-
warnings.forEach((warning) => {
|
|
242
|
-
console.log(chalk.yellow(` • ${warning}`));
|
|
243
|
-
});
|
|
244
|
-
}
|
|
245
|
-
// Display summary
|
|
246
|
-
console.log(chalk.cyan('\n📊 Graph Summary:'));
|
|
247
|
-
console.log(chalk.gray(` • Graph ID: ${graphId}`));
|
|
248
|
-
console.log(chalk.gray(` • Name: ${graphName}`));
|
|
249
|
-
console.log(chalk.gray(` • Agents: ${stats.agentCount}`));
|
|
250
|
-
console.log(chalk.gray(` • Tools: ${stats.toolCount}`));
|
|
251
|
-
console.log(chalk.gray(` • Relations: ${stats.relationCount}`));
|
|
252
|
-
// Provide next steps
|
|
253
|
-
console.log(chalk.green('\n✨ Next steps:'));
|
|
254
|
-
console.log(chalk.gray(` • Test your graph: inkeep chat ${graphId}`));
|
|
255
|
-
console.log(chalk.gray(` • View all graphs: inkeep list-graphs`));
|
|
256
|
-
console.log(chalk.gray(` • Get graph details: inkeep get-graph ${graphId}`));
|
|
257
|
-
// Force exit to avoid hanging due to OpenTelemetry or other background tasks
|
|
258
|
-
process.exit(0);
|
|
259
|
-
}
|
|
260
|
-
catch (error) {
|
|
261
|
-
spinner.fail('Failed to push graph');
|
|
262
|
-
console.error(chalk.red('Error:'), error.message);
|
|
263
|
-
if (error.stack && process.env.DEBUG) {
|
|
264
|
-
console.error(chalk.gray(error.stack));
|
|
265
|
-
}
|
|
266
|
-
process.exit(1);
|
|
267
|
-
}
|
|
268
|
-
}
|
package/dist/exports.d.ts
DELETED
package/dist/exports.js
DELETED