@inkeep/create-agents 0.0.0-dev-20250919192523 → 0.0.0-dev-20250920001717
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/__tests__/utils.test.js +18 -14
- package/dist/templates.js +4 -6
- package/dist/utils.js +11 -11
- package/package.json +1 -1
|
@@ -49,17 +49,17 @@ describe('createAgents - Template and Project ID Logic', () => {
|
|
|
49
49
|
vi.mocked(fs.remove).mockResolvedValue(undefined);
|
|
50
50
|
// Mock templates
|
|
51
51
|
vi.mocked(getAvailableTemplates).mockResolvedValue([
|
|
52
|
-
'weather-
|
|
52
|
+
'weather-project',
|
|
53
53
|
'chatbot',
|
|
54
54
|
'data-analysis',
|
|
55
55
|
]);
|
|
56
56
|
vi.mocked(cloneTemplate).mockResolvedValue(undefined);
|
|
57
57
|
// Mock util.promisify to return a mock exec function
|
|
58
58
|
const mockExecAsync = vi.fn().mockResolvedValue({ stdout: '', stderr: '' });
|
|
59
|
-
const util = require('util');
|
|
59
|
+
const util = require('node:util');
|
|
60
60
|
util.promisify = vi.fn(() => mockExecAsync);
|
|
61
61
|
// Mock child_process.spawn
|
|
62
|
-
const childProcess = require('child_process');
|
|
62
|
+
const childProcess = require('node:child_process');
|
|
63
63
|
childProcess.spawn = vi.fn(() => ({
|
|
64
64
|
pid: 12345,
|
|
65
65
|
stdio: ['pipe', 'pipe', 'pipe'],
|
|
@@ -72,27 +72,27 @@ describe('createAgents - Template and Project ID Logic', () => {
|
|
|
72
72
|
processChdirSpy.mockRestore();
|
|
73
73
|
});
|
|
74
74
|
describe('Default behavior (no template or customProjectId)', () => {
|
|
75
|
-
it('should use weather-
|
|
75
|
+
it('should use weather-project as default template and project ID', async () => {
|
|
76
76
|
await createAgents({
|
|
77
77
|
dirName: 'test-dir',
|
|
78
78
|
openAiKey: 'test-openai-key',
|
|
79
79
|
anthropicKey: 'test-anthropic-key',
|
|
80
80
|
});
|
|
81
|
-
// Should clone base template and weather-
|
|
81
|
+
// Should clone base template and weather-project template
|
|
82
82
|
expect(cloneTemplate).toHaveBeenCalledTimes(2);
|
|
83
83
|
expect(cloneTemplate).toHaveBeenCalledWith('https://github.com/inkeep/create-agents-template', expect.any(String));
|
|
84
|
-
expect(cloneTemplate).toHaveBeenCalledWith('https://github.com/inkeep/agents-cookbook/
|
|
84
|
+
expect(cloneTemplate).toHaveBeenCalledWith('https://github.com/inkeep/agents-cookbook/template-projects/weather-project', 'src/weather-project');
|
|
85
85
|
// Should not call getAvailableTemplates since no template validation needed
|
|
86
86
|
expect(getAvailableTemplates).not.toHaveBeenCalled();
|
|
87
87
|
});
|
|
88
|
-
it('should create project with weather-
|
|
88
|
+
it('should create project with weather-project as project ID', async () => {
|
|
89
89
|
await createAgents({
|
|
90
90
|
dirName: 'test-dir',
|
|
91
91
|
openAiKey: 'test-openai-key',
|
|
92
92
|
anthropicKey: 'test-anthropic-key',
|
|
93
93
|
});
|
|
94
94
|
// Check that inkeep.config.ts is created with correct project ID
|
|
95
|
-
expect(fs.writeFile).toHaveBeenCalledWith('src/weather-
|
|
95
|
+
expect(fs.writeFile).toHaveBeenCalledWith('src/weather-project/inkeep.config.ts', expect.stringContaining('projectId: "weather-project"'));
|
|
96
96
|
});
|
|
97
97
|
});
|
|
98
98
|
describe('Template provided', () => {
|
|
@@ -108,11 +108,11 @@ describe('createAgents - Template and Project ID Logic', () => {
|
|
|
108
108
|
// Should clone base template and the specified template
|
|
109
109
|
expect(cloneTemplate).toHaveBeenCalledTimes(2);
|
|
110
110
|
expect(cloneTemplate).toHaveBeenCalledWith('https://github.com/inkeep/create-agents-template', expect.any(String));
|
|
111
|
-
expect(cloneTemplate).toHaveBeenCalledWith('https://github.com/inkeep/agents-cookbook/
|
|
111
|
+
expect(cloneTemplate).toHaveBeenCalledWith('https://github.com/inkeep/agents-cookbook/template-projects/chatbot', 'src/chatbot');
|
|
112
112
|
expect(fs.writeFile).toHaveBeenCalledWith('src/chatbot/inkeep.config.ts', expect.stringContaining('projectId: "chatbot"'));
|
|
113
113
|
});
|
|
114
114
|
it('should exit with error when template does not exist', async () => {
|
|
115
|
-
vi.mocked(getAvailableTemplates).mockResolvedValue(['weather-
|
|
115
|
+
vi.mocked(getAvailableTemplates).mockResolvedValue(['weather-project', 'chatbot']);
|
|
116
116
|
await expect(createAgents({
|
|
117
117
|
dirName: 'test-dir',
|
|
118
118
|
template: 'non-existent-template',
|
|
@@ -123,7 +123,7 @@ describe('createAgents - Template and Project ID Logic', () => {
|
|
|
123
123
|
});
|
|
124
124
|
it('should show available templates when invalid template is provided', async () => {
|
|
125
125
|
vi.mocked(getAvailableTemplates).mockResolvedValue([
|
|
126
|
-
'weather-
|
|
126
|
+
'weather-project',
|
|
127
127
|
'chatbot',
|
|
128
128
|
'data-analysis',
|
|
129
129
|
]);
|
|
@@ -133,7 +133,7 @@ describe('createAgents - Template and Project ID Logic', () => {
|
|
|
133
133
|
openAiKey: 'test-openai-key',
|
|
134
134
|
})).rejects.toThrow('process.exit called');
|
|
135
135
|
const cancelCall = vi.mocked(p.cancel).mock.calls[0][0];
|
|
136
|
-
expect(cancelCall).toContain('weather-
|
|
136
|
+
expect(cancelCall).toContain('weather-project');
|
|
137
137
|
expect(cancelCall).toContain('chatbot');
|
|
138
138
|
expect(cancelCall).toContain('data-analysis');
|
|
139
139
|
});
|
|
@@ -185,7 +185,7 @@ describe('createAgents - Template and Project ID Logic', () => {
|
|
|
185
185
|
anthropicKey: 'test-key',
|
|
186
186
|
});
|
|
187
187
|
expect(cloneTemplate).toHaveBeenCalledTimes(2);
|
|
188
|
-
expect(cloneTemplate).toHaveBeenCalledWith('https://github.com/inkeep/agents-cookbook/
|
|
188
|
+
expect(cloneTemplate).toHaveBeenCalledWith('https://github.com/inkeep/agents-cookbook/template-projects/my-complex-template', 'src/my-complex-template');
|
|
189
189
|
});
|
|
190
190
|
it('should handle custom project IDs with special characters', async () => {
|
|
191
191
|
await createAgents({
|
|
@@ -237,6 +237,10 @@ function setupDefaultMocks() {
|
|
|
237
237
|
vi.mocked(fs.pathExists).mockResolvedValue(false);
|
|
238
238
|
vi.mocked(fs.ensureDir).mockResolvedValue(undefined);
|
|
239
239
|
vi.mocked(fs.writeFile).mockResolvedValue(undefined);
|
|
240
|
-
vi.mocked(getAvailableTemplates).mockResolvedValue([
|
|
240
|
+
vi.mocked(getAvailableTemplates).mockResolvedValue([
|
|
241
|
+
'weather-project',
|
|
242
|
+
'chatbot',
|
|
243
|
+
'data-analysis',
|
|
244
|
+
]);
|
|
241
245
|
vi.mocked(cloneTemplate).mockResolvedValue(undefined);
|
|
242
246
|
}
|
package/dist/templates.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import fs from 'fs-extra';
|
|
2
1
|
import degit from 'degit';
|
|
2
|
+
import fs from 'fs-extra';
|
|
3
3
|
//Duplicating function here so we dont have to add a dependency on the agents-cli package
|
|
4
4
|
export async function cloneTemplate(templatePath, targetPath) {
|
|
5
5
|
await fs.mkdir(targetPath, { recursive: true });
|
|
@@ -8,15 +8,13 @@ export async function cloneTemplate(templatePath, targetPath) {
|
|
|
8
8
|
try {
|
|
9
9
|
await emitter.clone(targetPath);
|
|
10
10
|
}
|
|
11
|
-
catch (
|
|
11
|
+
catch (_error) {
|
|
12
12
|
process.exit(1);
|
|
13
13
|
}
|
|
14
14
|
}
|
|
15
15
|
export async function getAvailableTemplates() {
|
|
16
16
|
// Fetch the list of templates from your repo
|
|
17
|
-
const response = await fetch('https://api.github.com/repos/inkeep/agents-cookbook/contents/
|
|
17
|
+
const response = await fetch('https://api.github.com/repos/inkeep/agents-cookbook/contents/template-projects');
|
|
18
18
|
const contents = await response.json();
|
|
19
|
-
return contents
|
|
20
|
-
.filter((item) => item.type === 'dir')
|
|
21
|
-
.map((item) => item.name);
|
|
19
|
+
return contents.filter((item) => item.type === 'dir').map((item) => item.name);
|
|
22
20
|
}
|
package/dist/utils.js
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import * as p from '@clack/prompts';
|
|
2
|
-
import { exec } from 'child_process';
|
|
2
|
+
import { exec } from 'node:child_process';
|
|
3
3
|
import fs from 'fs-extra';
|
|
4
|
-
import path from 'path';
|
|
4
|
+
import path from 'node:path';
|
|
5
5
|
import color from 'picocolors';
|
|
6
|
-
import { promisify } from 'util';
|
|
6
|
+
import { promisify } from 'node:util';
|
|
7
7
|
import { cloneTemplate, getAvailableTemplates } from './templates.js';
|
|
8
8
|
const execAsync = promisify(exec);
|
|
9
9
|
export const defaultGoogleModelConfigurations = {
|
|
@@ -66,8 +66,8 @@ export const createAgents = async (args = {}) => {
|
|
|
66
66
|
}
|
|
67
67
|
else {
|
|
68
68
|
// No template or custom project ID provided - use defaults
|
|
69
|
-
projectId = 'weather-
|
|
70
|
-
templateName = 'weather-
|
|
69
|
+
projectId = 'weather-project';
|
|
70
|
+
templateName = 'weather-project';
|
|
71
71
|
}
|
|
72
72
|
p.intro(color.inverse(' Create Agents Directory '));
|
|
73
73
|
// Prompt for directory name if not provided
|
|
@@ -172,7 +172,7 @@ export const createAgents = async (args = {}) => {
|
|
|
172
172
|
try {
|
|
173
173
|
const agentsTemplateRepo = 'https://github.com/inkeep/create-agents-template';
|
|
174
174
|
const projectTemplateRepo = templateName
|
|
175
|
-
? `https://github.com/inkeep/agents-cookbook/
|
|
175
|
+
? `https://github.com/inkeep/agents-cookbook/template-projects/${templateName}`
|
|
176
176
|
: null;
|
|
177
177
|
const directoryPath = path.resolve(process.cwd(), dirName);
|
|
178
178
|
// Check if directory already exists
|
|
@@ -203,7 +203,7 @@ export const createAgents = async (args = {}) => {
|
|
|
203
203
|
manageApiPort: manageApiPort || '3002',
|
|
204
204
|
runApiPort: runApiPort || '3003',
|
|
205
205
|
modelSettings: defaultModelSettings,
|
|
206
|
-
customProject: customProjectId
|
|
206
|
+
customProject: !!customProjectId,
|
|
207
207
|
};
|
|
208
208
|
// Create workspace structure for project-specific files
|
|
209
209
|
s.message('Setting up project structure...');
|
|
@@ -324,7 +324,7 @@ async function installDependencies() {
|
|
|
324
324
|
}
|
|
325
325
|
async function setupProjectInDatabase(config) {
|
|
326
326
|
// Start development servers in background
|
|
327
|
-
const { spawn } = await import('child_process');
|
|
327
|
+
const { spawn } = await import('node:child_process');
|
|
328
328
|
const devProcess = spawn('pnpm', ['dev:apis'], {
|
|
329
329
|
stdio: ['pipe', 'pipe', 'pipe'],
|
|
330
330
|
detached: true, // Detach so we can kill the process group
|
|
@@ -335,9 +335,9 @@ async function setupProjectInDatabase(config) {
|
|
|
335
335
|
// Run inkeep push
|
|
336
336
|
try {
|
|
337
337
|
// Suppress all output
|
|
338
|
-
|
|
338
|
+
await execAsync(`pnpm inkeep push --project src/${config.projectId}`);
|
|
339
339
|
}
|
|
340
|
-
catch (
|
|
340
|
+
catch (_error) {
|
|
341
341
|
//Continue despite error - user can setup project manually
|
|
342
342
|
}
|
|
343
343
|
finally {
|
|
@@ -356,7 +356,7 @@ async function setupProjectInDatabase(config) {
|
|
|
356
356
|
// Process already terminated
|
|
357
357
|
}
|
|
358
358
|
}
|
|
359
|
-
catch (
|
|
359
|
+
catch (_error) {
|
|
360
360
|
// Process might already be dead, that's fine
|
|
361
361
|
console.log('Note: Dev servers may still be running in background');
|
|
362
362
|
}
|