create-cogitator-app 0.3.0 → 0.4.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/README.md +42 -10
- package/dist/index.js +655 -273
- package/dist/index.js.map +1 -1
- package/dist/lib.d.ts +42 -4
- package/dist/lib.js +554 -263
- package/dist/lib.js.map +1 -1
- package/package.json +23 -1
package/dist/lib.js
CHANGED
|
@@ -1,15 +1,18 @@
|
|
|
1
1
|
// src/scaffold.ts
|
|
2
2
|
import fs from "fs";
|
|
3
|
-
import
|
|
3
|
+
import path3 from "path";
|
|
4
4
|
import * as p from "@clack/prompts";
|
|
5
5
|
|
|
6
6
|
// src/utils/providers.ts
|
|
7
7
|
var defaultModels = {
|
|
8
|
-
ollama: "qwen3:
|
|
8
|
+
ollama: "qwen3.5:9b",
|
|
9
9
|
openai: "gpt-6.1-sol",
|
|
10
10
|
anthropic: "claude-sonnet-5-5",
|
|
11
11
|
google: "gemini-3.8-flash"
|
|
12
12
|
};
|
|
13
|
+
function modelFor(options) {
|
|
14
|
+
return options.model?.trim() || defaultModels[options.provider];
|
|
15
|
+
}
|
|
13
16
|
function providerEnvKey(provider) {
|
|
14
17
|
const map = {
|
|
15
18
|
ollama: "OLLAMA_BASE_URL",
|
|
@@ -19,65 +22,149 @@ function providerEnvKey(provider) {
|
|
|
19
22
|
};
|
|
20
23
|
return map[provider];
|
|
21
24
|
}
|
|
22
|
-
function
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
` llm: {`,
|
|
36
|
-
` defaultProvider: 'openai',`,
|
|
37
|
-
` providers: {`,
|
|
38
|
-
` openai: { apiKey: process.env.OPENAI_API_KEY! },`,
|
|
39
|
-
` },`,
|
|
40
|
-
` },`
|
|
41
|
-
].join("\n");
|
|
42
|
-
case "anthropic":
|
|
43
|
-
return [
|
|
44
|
-
` llm: {`,
|
|
45
|
-
` defaultProvider: 'anthropic',`,
|
|
46
|
-
` providers: {`,
|
|
47
|
-
` anthropic: { apiKey: process.env.ANTHROPIC_API_KEY! },`,
|
|
48
|
-
` },`,
|
|
49
|
-
` },`
|
|
50
|
-
].join("\n");
|
|
51
|
-
case "google":
|
|
52
|
-
return [
|
|
53
|
-
` llm: {`,
|
|
54
|
-
` defaultProvider: 'google',`,
|
|
55
|
-
` providers: {`,
|
|
56
|
-
` google: { apiKey: process.env.GOOGLE_API_KEY! },`,
|
|
57
|
-
` },`,
|
|
58
|
-
` },`
|
|
59
|
-
].join("\n");
|
|
25
|
+
function apiKeyExpression(envKey, access) {
|
|
26
|
+
return access === "requireEnv" ? `requireEnv('${envKey}')` : `process.env.${envKey} ?? ''`;
|
|
27
|
+
}
|
|
28
|
+
function providerConfig(provider, access = "process-env") {
|
|
29
|
+
if (provider === "ollama") {
|
|
30
|
+
return [
|
|
31
|
+
` llm: {`,
|
|
32
|
+
` defaultProvider: 'ollama',`,
|
|
33
|
+
` providers: {`,
|
|
34
|
+
` ollama: { baseUrl: process.env.OLLAMA_BASE_URL || 'http://localhost:11434' },`,
|
|
35
|
+
` },`,
|
|
36
|
+
` },`
|
|
37
|
+
].join("\n");
|
|
60
38
|
}
|
|
39
|
+
return [
|
|
40
|
+
` llm: {`,
|
|
41
|
+
` defaultProvider: '${provider}',`,
|
|
42
|
+
` providers: {`,
|
|
43
|
+
` ${provider}: { apiKey: ${apiKeyExpression(providerEnvKey(provider), access)} },`,
|
|
44
|
+
` },`,
|
|
45
|
+
` },`
|
|
46
|
+
].join("\n");
|
|
61
47
|
}
|
|
62
48
|
|
|
63
49
|
// src/templates/versions.ts
|
|
50
|
+
import { existsSync, readFileSync } from "fs";
|
|
51
|
+
import path from "path";
|
|
52
|
+
import { fileURLToPath } from "url";
|
|
64
53
|
var ZOD_VERSION = "^4.6.5";
|
|
54
|
+
var IOREDIS_VERSION = "^6.0.0";
|
|
55
|
+
var OWN_NAME = "create-cogitator-app";
|
|
56
|
+
var SCOPE = "@cogitator-ai/";
|
|
57
|
+
function isRecord(value) {
|
|
58
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
59
|
+
}
|
|
60
|
+
function readManifest(file) {
|
|
61
|
+
const parsed = JSON.parse(readFileSync(file, "utf-8"));
|
|
62
|
+
if (!isRecord(parsed)) throw new Error(`${file} is not a package manifest`);
|
|
63
|
+
return parsed;
|
|
64
|
+
}
|
|
65
|
+
function findOwnRoot(from) {
|
|
66
|
+
let dir = from;
|
|
67
|
+
while (true) {
|
|
68
|
+
const manifest = path.join(dir, "package.json");
|
|
69
|
+
if (existsSync(manifest) && readManifest(manifest).name === OWN_NAME) return dir;
|
|
70
|
+
const parent = path.dirname(dir);
|
|
71
|
+
if (parent === dir) throw new Error(`Cannot find the ${OWN_NAME} package.json above ${from}`);
|
|
72
|
+
dir = parent;
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
function linkedVersion(packageRoot, name) {
|
|
76
|
+
const manifest = path.join(packageRoot, "node_modules", name, "package.json");
|
|
77
|
+
if (!existsSync(manifest)) {
|
|
78
|
+
throw new Error(`Cannot resolve the version of ${name}: ${manifest} does not exist`);
|
|
79
|
+
}
|
|
80
|
+
const version = readManifest(manifest).version;
|
|
81
|
+
if (typeof version !== "string") throw new Error(`${manifest} has no version`);
|
|
82
|
+
return version;
|
|
83
|
+
}
|
|
84
|
+
function readCogitatorVersions(packageRoot) {
|
|
85
|
+
const devDependencies = readManifest(path.join(packageRoot, "package.json")).devDependencies;
|
|
86
|
+
const versions = {};
|
|
87
|
+
if (!isRecord(devDependencies)) return versions;
|
|
88
|
+
for (const [name, range] of Object.entries(devDependencies)) {
|
|
89
|
+
if (!name.startsWith(SCOPE) || typeof range !== "string") continue;
|
|
90
|
+
versions[name] = range.startsWith("workspace:") ? `^${linkedVersion(packageRoot, name)}` : range;
|
|
91
|
+
}
|
|
92
|
+
return versions;
|
|
93
|
+
}
|
|
94
|
+
var resolved;
|
|
95
|
+
function cogitatorVersion(name) {
|
|
96
|
+
resolved ??= readCogitatorVersions(findOwnRoot(path.dirname(fileURLToPath(import.meta.url))));
|
|
97
|
+
const range = resolved[name];
|
|
98
|
+
if (!range) {
|
|
99
|
+
throw new Error(`${name} is not a devDependency of ${OWN_NAME}, so its version is unknown`);
|
|
100
|
+
}
|
|
101
|
+
return range;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
// src/templates/shared.ts
|
|
105
|
+
function tsString(value) {
|
|
106
|
+
const escaped = value.replace(/\\/g, "\\\\").replace(/'/g, "\\'").replace(/\r/g, "\\r").replace(/\n/g, "\\n").replace(/\p{Zl}/gu, "\\u2028").replace(/\p{Zp}/gu, "\\u2029");
|
|
107
|
+
return `'${escaped}'`;
|
|
108
|
+
}
|
|
109
|
+
function needsApiKey(provider) {
|
|
110
|
+
return provider !== "ollama";
|
|
111
|
+
}
|
|
112
|
+
function envHelperFiles(provider) {
|
|
113
|
+
if (!needsApiKey(provider)) return [];
|
|
114
|
+
const content = [
|
|
115
|
+
`export function requireEnv(name: string): string {`,
|
|
116
|
+
` const value = process.env[name]`,
|
|
117
|
+
` if (!value) {`,
|
|
118
|
+
` throw new Error(\`\${name} is not set. Copy .env.example to .env and fill it in.\`)`,
|
|
119
|
+
` }`,
|
|
120
|
+
` return value`,
|
|
121
|
+
`}`,
|
|
122
|
+
``
|
|
123
|
+
].join("\n");
|
|
124
|
+
return [{ path: "src/env.ts", content }];
|
|
125
|
+
}
|
|
126
|
+
function envHelperImport(provider) {
|
|
127
|
+
return needsApiKey(provider) ? [`import { requireEnv } from './env.js'`] : [];
|
|
128
|
+
}
|
|
129
|
+
var RUN_MAIN = [
|
|
130
|
+
`main().catch((error: unknown) => {`,
|
|
131
|
+
` console.error(error)`,
|
|
132
|
+
` process.exitCode = 1`,
|
|
133
|
+
`})`,
|
|
134
|
+
``
|
|
135
|
+
];
|
|
136
|
+
function scriptTemplateScripts() {
|
|
137
|
+
return {
|
|
138
|
+
dev: "tsx watch --env-file-if-exists=.env src/index.ts",
|
|
139
|
+
start: "tsx --env-file-if-exists=.env src/index.ts",
|
|
140
|
+
build: "tsc",
|
|
141
|
+
typecheck: "tsc --noEmit"
|
|
142
|
+
};
|
|
143
|
+
}
|
|
144
|
+
function scriptTemplateDevDependencies() {
|
|
145
|
+
return {
|
|
146
|
+
typescript: "^5.8.0",
|
|
147
|
+
tsx: "^4.19.0",
|
|
148
|
+
"@types/node": "^22.0.0"
|
|
149
|
+
};
|
|
150
|
+
}
|
|
65
151
|
|
|
66
152
|
// src/templates/basic.ts
|
|
67
153
|
var basicTemplate = {
|
|
68
154
|
files(options) {
|
|
69
|
-
const model =
|
|
155
|
+
const model = modelFor(options);
|
|
70
156
|
const indexTs = [
|
|
71
157
|
`import { Cogitator, Agent } from '@cogitator-ai/core'`,
|
|
72
158
|
`import { searchTool, summarizeTool } from './tools.js'`,
|
|
159
|
+
...envHelperImport(options.provider),
|
|
73
160
|
``,
|
|
74
161
|
`const cogitator = new Cogitator({`,
|
|
75
|
-
providerConfig(options.provider),
|
|
162
|
+
providerConfig(options.provider, "requireEnv"),
|
|
76
163
|
`})`,
|
|
77
164
|
``,
|
|
78
165
|
`const agent = new Agent({`,
|
|
79
|
-
` name:
|
|
80
|
-
` model:
|
|
166
|
+
` name: ${tsString(`${options.name}-agent`)},`,
|
|
167
|
+
` model: ${tsString(model)},`,
|
|
81
168
|
` instructions: 'You are a helpful AI assistant. Use your tools to help the user.',`,
|
|
82
169
|
` tools: [searchTool, summarizeTool],`,
|
|
83
170
|
` temperature: 0.7,`,
|
|
@@ -91,8 +178,7 @@ var basicTemplate = {
|
|
|
91
178
|
` console.log(result.output)`,
|
|
92
179
|
`}`,
|
|
93
180
|
``,
|
|
94
|
-
|
|
95
|
-
``
|
|
181
|
+
...RUN_MAIN
|
|
96
182
|
].join("\n");
|
|
97
183
|
const toolsTs = [
|
|
98
184
|
`import { tool } from '@cogitator-ai/core'`,
|
|
@@ -125,42 +211,36 @@ var basicTemplate = {
|
|
|
125
211
|
].join("\n");
|
|
126
212
|
return [
|
|
127
213
|
{ path: "src/index.ts", content: indexTs },
|
|
128
|
-
{ path: "src/tools.ts", content: toolsTs }
|
|
214
|
+
{ path: "src/tools.ts", content: toolsTs },
|
|
215
|
+
...envHelperFiles(options.provider)
|
|
129
216
|
];
|
|
130
217
|
},
|
|
131
218
|
dependencies() {
|
|
132
219
|
return {
|
|
133
|
-
"@cogitator-ai/core": "
|
|
220
|
+
"@cogitator-ai/core": cogitatorVersion("@cogitator-ai/core"),
|
|
134
221
|
zod: ZOD_VERSION
|
|
135
222
|
};
|
|
136
223
|
},
|
|
137
224
|
devDependencies() {
|
|
138
|
-
return
|
|
139
|
-
typescript: "^5.8.0",
|
|
140
|
-
tsx: "^4.19.0",
|
|
141
|
-
"@types/node": "^22.0.0"
|
|
142
|
-
};
|
|
225
|
+
return scriptTemplateDevDependencies();
|
|
143
226
|
},
|
|
144
227
|
scripts() {
|
|
145
|
-
return
|
|
146
|
-
dev: "tsx watch src/index.ts",
|
|
147
|
-
start: "tsx src/index.ts",
|
|
148
|
-
build: "tsc",
|
|
149
|
-
typecheck: "tsc --noEmit"
|
|
150
|
-
};
|
|
228
|
+
return scriptTemplateScripts();
|
|
151
229
|
}
|
|
152
230
|
};
|
|
153
231
|
|
|
154
232
|
// src/templates/memory.ts
|
|
155
233
|
var memoryTemplate = {
|
|
234
|
+
memoryAdapter: "redis",
|
|
156
235
|
files(options) {
|
|
157
|
-
const model =
|
|
236
|
+
const model = modelFor(options);
|
|
158
237
|
const indexTs = [
|
|
159
238
|
`import { Cogitator, Agent } from '@cogitator-ai/core'`,
|
|
160
239
|
`import { searchTool, noteTool } from './tools.js'`,
|
|
240
|
+
...envHelperImport(options.provider),
|
|
161
241
|
``,
|
|
162
242
|
`const cogitator = new Cogitator({`,
|
|
163
|
-
providerConfig(options.provider),
|
|
243
|
+
providerConfig(options.provider, "requireEnv"),
|
|
164
244
|
` memory: {`,
|
|
165
245
|
` adapter: 'redis',`,
|
|
166
246
|
` redis: { url: process.env.REDIS_URL || 'redis://localhost:6379' },`,
|
|
@@ -168,8 +248,8 @@ var memoryTemplate = {
|
|
|
168
248
|
`})`,
|
|
169
249
|
``,
|
|
170
250
|
`const agent = new Agent({`,
|
|
171
|
-
` name:
|
|
172
|
-
` model:
|
|
251
|
+
` name: ${tsString(`${options.name}-agent`)},`,
|
|
252
|
+
` model: ${tsString(model)},`,
|
|
173
253
|
` instructions: [`,
|
|
174
254
|
` 'You are an AI assistant with persistent memory.',`,
|
|
175
255
|
` 'You remember past conversations and user preferences.',`,
|
|
@@ -182,25 +262,26 @@ var memoryTemplate = {
|
|
|
182
262
|
`async function main() {`,
|
|
183
263
|
` const threadId = 'demo-thread'`,
|
|
184
264
|
``,
|
|
185
|
-
`
|
|
186
|
-
`
|
|
187
|
-
`
|
|
188
|
-
`
|
|
189
|
-
`
|
|
190
|
-
`
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
`
|
|
194
|
-
`
|
|
195
|
-
`
|
|
196
|
-
`
|
|
197
|
-
`
|
|
198
|
-
|
|
199
|
-
`
|
|
265
|
+
` try {`,
|
|
266
|
+
` const result1 = await cogitator.run(agent, {`,
|
|
267
|
+
` input: 'My name is Alex and I prefer TypeScript.',`,
|
|
268
|
+
` threadId,`,
|
|
269
|
+
` useMemory: true,`,
|
|
270
|
+
` })`,
|
|
271
|
+
` console.log('Response 1:', result1.output)`,
|
|
272
|
+
``,
|
|
273
|
+
` const result2 = await cogitator.run(agent, {`,
|
|
274
|
+
` input: 'What is my name and preferred language?',`,
|
|
275
|
+
` threadId,`,
|
|
276
|
+
` useMemory: true,`,
|
|
277
|
+
` })`,
|
|
278
|
+
` console.log('Response 2:', result2.output)`,
|
|
279
|
+
` } finally {`,
|
|
280
|
+
` await cogitator.close()`,
|
|
281
|
+
` }`,
|
|
200
282
|
`}`,
|
|
201
283
|
``,
|
|
202
|
-
|
|
203
|
-
``
|
|
284
|
+
...RUN_MAIN
|
|
204
285
|
].join("\n");
|
|
205
286
|
const toolsTs = [
|
|
206
287
|
`import { tool } from '@cogitator-ai/core'`,
|
|
@@ -232,45 +313,38 @@ var memoryTemplate = {
|
|
|
232
313
|
].join("\n");
|
|
233
314
|
return [
|
|
234
315
|
{ path: "src/index.ts", content: indexTs },
|
|
235
|
-
{ path: "src/tools.ts", content: toolsTs }
|
|
316
|
+
{ path: "src/tools.ts", content: toolsTs },
|
|
317
|
+
...envHelperFiles(options.provider)
|
|
236
318
|
];
|
|
237
319
|
},
|
|
238
320
|
dependencies() {
|
|
239
321
|
return {
|
|
240
|
-
"@cogitator-ai/core": "
|
|
241
|
-
"@cogitator-ai/memory": "
|
|
242
|
-
"@cogitator-ai/redis": "
|
|
322
|
+
"@cogitator-ai/core": cogitatorVersion("@cogitator-ai/core"),
|
|
323
|
+
"@cogitator-ai/memory": cogitatorVersion("@cogitator-ai/memory"),
|
|
324
|
+
"@cogitator-ai/redis": cogitatorVersion("@cogitator-ai/redis"),
|
|
325
|
+
ioredis: IOREDIS_VERSION,
|
|
243
326
|
zod: ZOD_VERSION
|
|
244
327
|
};
|
|
245
328
|
},
|
|
246
329
|
devDependencies() {
|
|
247
|
-
return
|
|
248
|
-
typescript: "^5.8.0",
|
|
249
|
-
tsx: "^4.19.0",
|
|
250
|
-
"@types/node": "^22.0.0"
|
|
251
|
-
};
|
|
330
|
+
return scriptTemplateDevDependencies();
|
|
252
331
|
},
|
|
253
332
|
scripts() {
|
|
254
|
-
return
|
|
255
|
-
dev: "tsx watch src/index.ts",
|
|
256
|
-
start: "tsx src/index.ts",
|
|
257
|
-
build: "tsc",
|
|
258
|
-
typecheck: "tsc --noEmit"
|
|
259
|
-
};
|
|
333
|
+
return scriptTemplateScripts();
|
|
260
334
|
}
|
|
261
335
|
};
|
|
262
336
|
|
|
263
337
|
// src/templates/swarm.ts
|
|
264
338
|
var swarmTemplate = {
|
|
265
339
|
files(options) {
|
|
266
|
-
const model =
|
|
340
|
+
const model = modelFor(options);
|
|
267
341
|
const researcherTs = [
|
|
268
342
|
`import { Agent } from '@cogitator-ai/core'`,
|
|
269
343
|
`import { searchTool } from '../tools.js'`,
|
|
270
344
|
``,
|
|
271
345
|
`export const researcher = new Agent({`,
|
|
272
346
|
` name: 'researcher',`,
|
|
273
|
-
` model:
|
|
347
|
+
` model: ${tsString(model)},`,
|
|
274
348
|
` instructions: [`,
|
|
275
349
|
` 'You are a research specialist.',`,
|
|
276
350
|
` 'Use the search tool to find information.',`,
|
|
@@ -286,7 +360,7 @@ var swarmTemplate = {
|
|
|
286
360
|
``,
|
|
287
361
|
`export const writer = new Agent({`,
|
|
288
362
|
` name: 'writer',`,
|
|
289
|
-
` model:
|
|
363
|
+
` model: ${tsString(model)},`,
|
|
290
364
|
` instructions: [`,
|
|
291
365
|
` 'You are a skilled content writer.',`,
|
|
292
366
|
` 'Take research findings and craft well-structured, engaging content.',`,
|
|
@@ -301,7 +375,7 @@ var swarmTemplate = {
|
|
|
301
375
|
``,
|
|
302
376
|
`export const reviewer = new Agent({`,
|
|
303
377
|
` name: 'reviewer',`,
|
|
304
|
-
` model:
|
|
378
|
+
` model: ${tsString(model)},`,
|
|
305
379
|
` instructions: [`,
|
|
306
380
|
` 'You are a meticulous content reviewer.',`,
|
|
307
381
|
` 'Check for accuracy, grammar, and overall quality.',`,
|
|
@@ -333,13 +407,14 @@ var swarmTemplate = {
|
|
|
333
407
|
`import { researcher } from './agents/researcher.js'`,
|
|
334
408
|
`import { writer } from './agents/writer.js'`,
|
|
335
409
|
`import { reviewer } from './agents/reviewer.js'`,
|
|
410
|
+
...envHelperImport(options.provider),
|
|
336
411
|
``,
|
|
337
412
|
`const cogitator = new Cogitator({`,
|
|
338
|
-
providerConfig(options.provider),
|
|
413
|
+
providerConfig(options.provider, "requireEnv"),
|
|
339
414
|
`})`,
|
|
340
415
|
``,
|
|
341
416
|
`const team = new Swarm(cogitator, {`,
|
|
342
|
-
` name:
|
|
417
|
+
` name: ${tsString(`${options.name}-team`)},`,
|
|
343
418
|
` strategy: 'hierarchical',`,
|
|
344
419
|
` supervisor: reviewer,`,
|
|
345
420
|
` workers: [researcher, writer],`,
|
|
@@ -356,75 +431,68 @@ var swarmTemplate = {
|
|
|
356
431
|
`async function main() {`,
|
|
357
432
|
` console.log('Starting swarm...')`,
|
|
358
433
|
``,
|
|
359
|
-
`
|
|
360
|
-
`
|
|
361
|
-
`
|
|
362
|
-
|
|
363
|
-
` console.log('Result:', result.output)`,
|
|
364
|
-
` console.log('Strategy:', team.strategyType)`,
|
|
434
|
+
` try {`,
|
|
435
|
+
` const result = await team.run({`,
|
|
436
|
+
` input: 'Write a comprehensive article about AI agent orchestration.',`,
|
|
437
|
+
` })`,
|
|
365
438
|
``,
|
|
366
|
-
`
|
|
439
|
+
` console.log('Result:', result.output)`,
|
|
440
|
+
` console.log('Strategy:', team.strategyType)`,
|
|
441
|
+
` } finally {`,
|
|
442
|
+
` await team.close()`,
|
|
443
|
+
` }`,
|
|
367
444
|
`}`,
|
|
368
445
|
``,
|
|
369
|
-
|
|
370
|
-
``
|
|
446
|
+
...RUN_MAIN
|
|
371
447
|
].join("\n");
|
|
372
448
|
return [
|
|
373
449
|
{ path: "src/index.ts", content: indexTs },
|
|
374
450
|
{ path: "src/tools.ts", content: toolsTs },
|
|
375
451
|
{ path: "src/agents/researcher.ts", content: researcherTs },
|
|
376
452
|
{ path: "src/agents/writer.ts", content: writerTs },
|
|
377
|
-
{ path: "src/agents/reviewer.ts", content: reviewerTs }
|
|
453
|
+
{ path: "src/agents/reviewer.ts", content: reviewerTs },
|
|
454
|
+
...envHelperFiles(options.provider)
|
|
378
455
|
];
|
|
379
456
|
},
|
|
380
457
|
dependencies() {
|
|
381
458
|
return {
|
|
382
|
-
"@cogitator-ai/core": "
|
|
383
|
-
"@cogitator-ai/swarms": "
|
|
459
|
+
"@cogitator-ai/core": cogitatorVersion("@cogitator-ai/core"),
|
|
460
|
+
"@cogitator-ai/swarms": cogitatorVersion("@cogitator-ai/swarms"),
|
|
384
461
|
zod: ZOD_VERSION
|
|
385
462
|
};
|
|
386
463
|
},
|
|
387
464
|
devDependencies() {
|
|
388
|
-
return
|
|
389
|
-
typescript: "^5.8.0",
|
|
390
|
-
tsx: "^4.19.0",
|
|
391
|
-
"@types/node": "^22.0.0"
|
|
392
|
-
};
|
|
465
|
+
return scriptTemplateDevDependencies();
|
|
393
466
|
},
|
|
394
467
|
scripts() {
|
|
395
|
-
return
|
|
396
|
-
dev: "tsx watch src/index.ts",
|
|
397
|
-
start: "tsx src/index.ts",
|
|
398
|
-
build: "tsc",
|
|
399
|
-
typecheck: "tsc --noEmit"
|
|
400
|
-
};
|
|
468
|
+
return scriptTemplateScripts();
|
|
401
469
|
}
|
|
402
470
|
};
|
|
403
471
|
|
|
404
472
|
// src/templates/workflow.ts
|
|
405
473
|
var workflowTemplate = {
|
|
406
474
|
files(options) {
|
|
407
|
-
const model =
|
|
475
|
+
const model = modelFor(options);
|
|
408
476
|
const agentsTs = [
|
|
409
477
|
`import { Agent } from '@cogitator-ai/core'`,
|
|
410
478
|
``,
|
|
411
479
|
`export const analyzer = new Agent({`,
|
|
412
480
|
` name: 'analyzer',`,
|
|
413
|
-
` model:
|
|
481
|
+
` model: ${tsString(model)},`,
|
|
414
482
|
` instructions: 'You analyze input data and extract key information. Be thorough and structured.',`,
|
|
415
483
|
` temperature: 0.3,`,
|
|
416
484
|
`})`,
|
|
417
485
|
``,
|
|
418
486
|
`export const processor = new Agent({`,
|
|
419
487
|
` name: 'processor',`,
|
|
420
|
-
` model:
|
|
488
|
+
` model: ${tsString(model)},`,
|
|
421
489
|
` instructions: 'You process analyzed data and transform it into actionable insights.',`,
|
|
422
490
|
` temperature: 0.5,`,
|
|
423
491
|
`})`,
|
|
424
492
|
``,
|
|
425
493
|
`export const formatter = new Agent({`,
|
|
426
494
|
` name: 'formatter',`,
|
|
427
|
-
` model:
|
|
495
|
+
` model: ${tsString(model)},`,
|
|
428
496
|
` instructions: 'You format processed data into a clean, readable report.',`,
|
|
429
497
|
` temperature: 0.7,`,
|
|
430
498
|
`})`,
|
|
@@ -439,9 +507,10 @@ var workflowTemplate = {
|
|
|
439
507
|
` functionNode,`,
|
|
440
508
|
`} from '@cogitator-ai/workflows'`,
|
|
441
509
|
`import { analyzer, processor, formatter } from './agents.js'`,
|
|
510
|
+
...envHelperImport(options.provider),
|
|
442
511
|
``,
|
|
443
512
|
`const cogitator = new Cogitator({`,
|
|
444
|
-
providerConfig(options.provider),
|
|
513
|
+
providerConfig(options.provider, "requireEnv"),
|
|
445
514
|
`})`,
|
|
446
515
|
``,
|
|
447
516
|
`type WorkflowState = {`,
|
|
@@ -471,7 +540,7 @@ var workflowTemplate = {
|
|
|
471
540
|
` async (state) => state.report,`,
|
|
472
541
|
`)`,
|
|
473
542
|
``,
|
|
474
|
-
`const workflow = new WorkflowBuilder<WorkflowState>(
|
|
543
|
+
`const workflow = new WorkflowBuilder<WorkflowState>(${tsString(`${options.name}-workflow`)})`,
|
|
475
544
|
` .initialState({ input: '' })`,
|
|
476
545
|
` .entryPoint(analyzeNode.name)`,
|
|
477
546
|
` .addNode(analyzeNode.name, analyzeNode.fn)`,
|
|
@@ -489,48 +558,45 @@ var workflowTemplate = {
|
|
|
489
558
|
` input: 'Analyze the current state of AI agent frameworks and their adoption in enterprise.',`,
|
|
490
559
|
` })`,
|
|
491
560
|
``,
|
|
492
|
-
`
|
|
493
|
-
|
|
561
|
+
` if (result.error) throw result.error`,
|
|
562
|
+
``,
|
|
563
|
+
` console.log(\`Workflow completed in \${result.duration}ms\`)`,
|
|
564
|
+
` console.log('Report:', result.state.report)`,
|
|
565
|
+
` console.log('Nodes:', JSON.stringify(Object.fromEntries(result.nodeResults), null, 2))`,
|
|
494
566
|
`}`,
|
|
495
567
|
``,
|
|
496
|
-
|
|
497
|
-
``
|
|
568
|
+
...RUN_MAIN
|
|
498
569
|
].join("\n");
|
|
499
570
|
return [
|
|
500
571
|
{ path: "src/index.ts", content: indexTs },
|
|
501
|
-
{ path: "src/agents.ts", content: agentsTs }
|
|
572
|
+
{ path: "src/agents.ts", content: agentsTs },
|
|
573
|
+
...envHelperFiles(options.provider)
|
|
502
574
|
];
|
|
503
575
|
},
|
|
504
576
|
dependencies() {
|
|
505
577
|
return {
|
|
506
|
-
"@cogitator-ai/core": "
|
|
507
|
-
"@cogitator-ai/workflows": "
|
|
578
|
+
"@cogitator-ai/core": cogitatorVersion("@cogitator-ai/core"),
|
|
579
|
+
"@cogitator-ai/workflows": cogitatorVersion("@cogitator-ai/workflows"),
|
|
508
580
|
zod: ZOD_VERSION
|
|
509
581
|
};
|
|
510
582
|
},
|
|
511
583
|
devDependencies() {
|
|
512
|
-
return
|
|
513
|
-
typescript: "^5.8.0",
|
|
514
|
-
tsx: "^4.19.0",
|
|
515
|
-
"@types/node": "^22.0.0"
|
|
516
|
-
};
|
|
584
|
+
return scriptTemplateDevDependencies();
|
|
517
585
|
},
|
|
518
586
|
scripts() {
|
|
519
|
-
return
|
|
520
|
-
dev: "tsx watch src/index.ts",
|
|
521
|
-
start: "tsx src/index.ts",
|
|
522
|
-
build: "tsc",
|
|
523
|
-
typecheck: "tsc --noEmit"
|
|
524
|
-
};
|
|
587
|
+
return scriptTemplateScripts();
|
|
525
588
|
}
|
|
526
589
|
};
|
|
527
590
|
|
|
528
591
|
// src/templates/api-server.ts
|
|
529
592
|
var BASE_PATH = "/api";
|
|
593
|
+
var PUBLIC_PATHS = ["/health", "/ready", "/docs", "/openapi.json"];
|
|
530
594
|
var apiServerTemplate = {
|
|
595
|
+
memoryAdapter: "memory",
|
|
596
|
+
secrets: ["API_TOKEN"],
|
|
531
597
|
healthPath: `${BASE_PATH}/health`,
|
|
532
598
|
files(options) {
|
|
533
|
-
const model =
|
|
599
|
+
const model = modelFor(options);
|
|
534
600
|
const agentsTs = [
|
|
535
601
|
`import { Agent, tool } from '@cogitator-ai/core'`,
|
|
536
602
|
`import { z } from 'zod'`,
|
|
@@ -548,7 +614,7 @@ var apiServerTemplate = {
|
|
|
548
614
|
``,
|
|
549
615
|
`export const assistant = new Agent({`,
|
|
550
616
|
` name: 'assistant',`,
|
|
551
|
-
` model:
|
|
617
|
+
` model: ${tsString(model)},`,
|
|
552
618
|
` instructions: 'You are a helpful API assistant. Answer questions clearly and concisely.',`,
|
|
553
619
|
` tools: [searchTool],`,
|
|
554
620
|
` temperature: 0.7,`,
|
|
@@ -556,23 +622,45 @@ var apiServerTemplate = {
|
|
|
556
622
|
``,
|
|
557
623
|
`export const coder = new Agent({`,
|
|
558
624
|
` name: 'coder',`,
|
|
559
|
-
` model:
|
|
625
|
+
` model: ${tsString(model)},`,
|
|
560
626
|
` instructions: 'You are an expert programmer. Write clean, well-structured code.',`,
|
|
561
627
|
` temperature: 0.3,`,
|
|
562
628
|
`})`,
|
|
563
629
|
``
|
|
564
630
|
].join("\n");
|
|
565
631
|
const indexTs = [
|
|
566
|
-
`import
|
|
632
|
+
`import { timingSafeEqual } from 'node:crypto'`,
|
|
633
|
+
`import express, { type Request } from 'express'`,
|
|
567
634
|
`import { Cogitator } from '@cogitator-ai/core'`,
|
|
568
635
|
`import { CogitatorServer } from '@cogitator-ai/express'`,
|
|
569
636
|
`import { assistant, coder } from './agents.js'`,
|
|
637
|
+
...envHelperImport(options.provider),
|
|
638
|
+
``,
|
|
639
|
+
`const production = process.env.NODE_ENV === 'production'`,
|
|
640
|
+
`const port = Number(process.env.PORT ?? 3000)`,
|
|
641
|
+
`const host = process.env.HOST ?? (production ? '0.0.0.0' : '127.0.0.1')`,
|
|
642
|
+
`const apiToken = process.env.API_TOKEN`,
|
|
643
|
+
`const corsOrigin = process.env.CORS_ORIGIN`,
|
|
644
|
+
`const publicPaths = new Set([${PUBLIC_PATHS.map(tsString).join(", ")}])`,
|
|
645
|
+
``,
|
|
646
|
+
`function hasToken(header: string | undefined): boolean {`,
|
|
647
|
+
` if (!apiToken || !header) return false`,
|
|
648
|
+
` const expected = Buffer.from(\`Bearer \${apiToken}\`)`,
|
|
649
|
+
` const given = Buffer.from(header)`,
|
|
650
|
+
` return given.length === expected.length && timingSafeEqual(given, expected)`,
|
|
651
|
+
`}`,
|
|
652
|
+
``,
|
|
653
|
+
`function authenticate(req: Request) {`,
|
|
654
|
+
` if (!apiToken || publicPaths.has(req.path)) return undefined`,
|
|
655
|
+
` if (!hasToken(req.get('authorization'))) throw new Error('Unauthorized')`,
|
|
656
|
+
` return { userId: 'api-token' }`,
|
|
657
|
+
`}`,
|
|
570
658
|
``,
|
|
571
659
|
`const app = express()`,
|
|
572
|
-
`const port = process.env.PORT || 3000`,
|
|
573
660
|
``,
|
|
574
661
|
`const cogitator = new Cogitator({`,
|
|
575
|
-
providerConfig(options.provider),
|
|
662
|
+
providerConfig(options.provider, "requireEnv"),
|
|
663
|
+
` memory: { adapter: 'memory' },`,
|
|
576
664
|
`})`,
|
|
577
665
|
``,
|
|
578
666
|
`const server = new CogitatorServer({`,
|
|
@@ -582,62 +670,62 @@ var apiServerTemplate = {
|
|
|
582
670
|
` config: {`,
|
|
583
671
|
` basePath: '${BASE_PATH}',`,
|
|
584
672
|
` enableSwagger: true,`,
|
|
585
|
-
`
|
|
673
|
+
` auth: authenticate,`,
|
|
674
|
+
` ...(corsOrigin ? { cors: { origin: corsOrigin.split(',').map((o) => o.trim()) } } : {}),`,
|
|
586
675
|
` swagger: {`,
|
|
587
|
-
` title:
|
|
676
|
+
` title: ${tsString(`${options.name} API`)},`,
|
|
588
677
|
` version: '1.0.0',`,
|
|
589
678
|
` },`,
|
|
590
679
|
` },`,
|
|
591
680
|
`})`,
|
|
592
681
|
``,
|
|
593
682
|
`async function main() {`,
|
|
683
|
+
` if (production && !apiToken) {`,
|
|
684
|
+
` throw new Error('Set API_TOKEN in production: it guards every route except health and docs')`,
|
|
685
|
+
` }`,
|
|
686
|
+
``,
|
|
594
687
|
` await server.init()`,
|
|
595
688
|
``,
|
|
596
|
-
` app.listen(port, () => {`,
|
|
597
|
-
` console.log(\`Server running at http
|
|
598
|
-
` console.log(\`Swagger docs at http
|
|
689
|
+
` app.listen(port, host, () => {`,
|
|
690
|
+
` console.log(\`Server running at http://\${host}:\${port}\`)`,
|
|
691
|
+
` console.log(\`Swagger docs at http://\${host}:\${port}${BASE_PATH}/docs\`)`,
|
|
692
|
+
` if (!apiToken) console.log('API_TOKEN is not set, so the API is open to anyone who can reach it')`,
|
|
599
693
|
` })`,
|
|
600
694
|
`}`,
|
|
601
695
|
``,
|
|
602
|
-
|
|
603
|
-
``
|
|
696
|
+
...RUN_MAIN
|
|
604
697
|
].join("\n");
|
|
605
698
|
return [
|
|
606
699
|
{ path: "src/index.ts", content: indexTs },
|
|
607
|
-
{ path: "src/agents.ts", content: agentsTs }
|
|
700
|
+
{ path: "src/agents.ts", content: agentsTs },
|
|
701
|
+
...envHelperFiles(options.provider)
|
|
608
702
|
];
|
|
609
703
|
},
|
|
610
704
|
dependencies() {
|
|
611
705
|
return {
|
|
612
|
-
"@cogitator-ai/core": "
|
|
613
|
-
"@cogitator-ai/express": "
|
|
706
|
+
"@cogitator-ai/core": cogitatorVersion("@cogitator-ai/core"),
|
|
707
|
+
"@cogitator-ai/express": cogitatorVersion("@cogitator-ai/express"),
|
|
614
708
|
express: "^5.2.1",
|
|
615
709
|
zod: ZOD_VERSION
|
|
616
710
|
};
|
|
617
711
|
},
|
|
618
712
|
devDependencies() {
|
|
619
713
|
return {
|
|
620
|
-
|
|
621
|
-
tsx: "^4.19.0",
|
|
622
|
-
"@types/node": "^22.0.0",
|
|
714
|
+
...scriptTemplateDevDependencies(),
|
|
623
715
|
"@types/express": "^5.0.6"
|
|
624
716
|
};
|
|
625
717
|
},
|
|
626
718
|
scripts() {
|
|
627
|
-
return
|
|
628
|
-
dev: "tsx watch src/index.ts",
|
|
629
|
-
start: "tsx src/index.ts",
|
|
630
|
-
build: "tsc",
|
|
631
|
-
typecheck: "tsc --noEmit"
|
|
632
|
-
};
|
|
719
|
+
return scriptTemplateScripts();
|
|
633
720
|
}
|
|
634
721
|
};
|
|
635
722
|
|
|
636
723
|
// src/templates/nextjs.ts
|
|
637
724
|
var nextjsTemplate = {
|
|
725
|
+
memoryAdapter: "memory",
|
|
638
726
|
healthPath: "/api/health",
|
|
639
727
|
files(options) {
|
|
640
|
-
const model =
|
|
728
|
+
const model = modelFor(options);
|
|
641
729
|
const agentTs = [
|
|
642
730
|
`import { Cogitator, Agent, tool } from '@cogitator-ai/core'`,
|
|
643
731
|
`import { z } from 'zod'`,
|
|
@@ -655,11 +743,12 @@ var nextjsTemplate = {
|
|
|
655
743
|
``,
|
|
656
744
|
`export const cogitator = new Cogitator({`,
|
|
657
745
|
providerConfig(options.provider),
|
|
746
|
+
` memory: { adapter: 'memory' },`,
|
|
658
747
|
`})`,
|
|
659
748
|
``,
|
|
660
749
|
`export const agent = new Agent({`,
|
|
661
|
-
` name:
|
|
662
|
-
` model:
|
|
750
|
+
` name: ${tsString(`${options.name}-chat`)},`,
|
|
751
|
+
` model: ${tsString(model)},`,
|
|
663
752
|
` instructions: 'You are a helpful AI chat assistant. Be conversational and helpful.',`,
|
|
664
753
|
` tools: [searchTool],`,
|
|
665
754
|
` temperature: 0.7,`,
|
|
@@ -686,7 +775,7 @@ var nextjsTemplate = {
|
|
|
686
775
|
`import { useState, useRef, useEffect } from 'react'`,
|
|
687
776
|
``,
|
|
688
777
|
`export default function Home() {`,
|
|
689
|
-
` const { messages, input, setInput, send, isLoading } = useCogitatorChat({`,
|
|
778
|
+
` const { messages, input, setInput, send, stop, isLoading, error } = useCogitatorChat({`,
|
|
690
779
|
` api: '/api/chat',`,
|
|
691
780
|
` })`,
|
|
692
781
|
` const messagesEndRef = useRef<HTMLDivElement>(null)`,
|
|
@@ -706,27 +795,29 @@ var nextjsTemplate = {
|
|
|
706
795
|
` <main className="flex min-h-screen flex-col items-center p-4 bg-gray-950 text-white">`,
|
|
707
796
|
` <div className="w-full max-w-2xl flex flex-col h-screen">`,
|
|
708
797
|
` <header className="py-6 text-center">`,
|
|
709
|
-
` <h1 className="text-2xl font-bold"
|
|
798
|
+
` <h1 className="text-2xl font-bold">{${tsString(options.name)}}</h1>`,
|
|
710
799
|
` <p className="text-gray-400 text-sm mt-1">Powered by Cogitator</p>`,
|
|
711
800
|
` </header>`,
|
|
712
801
|
``,
|
|
713
802
|
` <div className="flex-1 overflow-y-auto space-y-4 pb-4">`,
|
|
714
|
-
` {messages
|
|
715
|
-
`
|
|
716
|
-
`
|
|
717
|
-
` className={\`flex \${msg.role === 'user' ? 'justify-end' : 'justify-start'}\`}`,
|
|
718
|
-
` >`,
|
|
803
|
+
` {messages`,
|
|
804
|
+
` .filter((msg) => msg.content)`,
|
|
805
|
+
` .map((msg) => (`,
|
|
719
806
|
` <div`,
|
|
720
|
-
`
|
|
721
|
-
`
|
|
722
|
-
` ? 'bg-blue-600 text-white'`,
|
|
723
|
-
` : 'bg-gray-800 text-gray-100'`,
|
|
724
|
-
` }\`}`,
|
|
807
|
+
` key={msg.id}`,
|
|
808
|
+
` className={\`flex \${msg.role === 'user' ? 'justify-end' : 'justify-start'}\`}`,
|
|
725
809
|
` >`,
|
|
726
|
-
`
|
|
810
|
+
` <div`,
|
|
811
|
+
` className={\`max-w-[80%] rounded-2xl px-4 py-2 \${`,
|
|
812
|
+
` msg.role === 'user'`,
|
|
813
|
+
` ? 'bg-blue-600 text-white'`,
|
|
814
|
+
` : 'bg-gray-800 text-gray-100'`,
|
|
815
|
+
` }\`}`,
|
|
816
|
+
` >`,
|
|
817
|
+
` {msg.content}`,
|
|
818
|
+
` </div>`,
|
|
727
819
|
` </div>`,
|
|
728
|
-
`
|
|
729
|
-
` ))}`,
|
|
820
|
+
` ))}`,
|
|
730
821
|
` {isLoading && (`,
|
|
731
822
|
` <div className="flex justify-start">`,
|
|
732
823
|
` <div className="bg-gray-800 rounded-2xl px-4 py-2 text-gray-400">`,
|
|
@@ -734,6 +825,11 @@ var nextjsTemplate = {
|
|
|
734
825
|
` </div>`,
|
|
735
826
|
` </div>`,
|
|
736
827
|
` )}`,
|
|
828
|
+
` {error && (`,
|
|
829
|
+
` <div className="rounded-xl border border-red-800 bg-red-950 px-4 py-2 text-sm text-red-200">`,
|
|
830
|
+
` {error.message}`,
|
|
831
|
+
` </div>`,
|
|
832
|
+
` )}`,
|
|
737
833
|
` <div ref={messagesEndRef} />`,
|
|
738
834
|
` </div>`,
|
|
739
835
|
``,
|
|
@@ -744,13 +840,23 @@ var nextjsTemplate = {
|
|
|
744
840
|
` placeholder="Type a message..."`,
|
|
745
841
|
` className="flex-1 bg-gray-800 border border-gray-700 rounded-xl px-4 py-3 text-white placeholder-gray-500 focus:outline-none focus:border-blue-500"`,
|
|
746
842
|
` />`,
|
|
747
|
-
`
|
|
748
|
-
`
|
|
749
|
-
`
|
|
750
|
-
`
|
|
751
|
-
`
|
|
752
|
-
`
|
|
753
|
-
`
|
|
843
|
+
` {isLoading ? (`,
|
|
844
|
+
` <button`,
|
|
845
|
+
` type="button"`,
|
|
846
|
+
` onClick={stop}`,
|
|
847
|
+
` className="bg-gray-700 hover:bg-gray-600 text-white rounded-xl px-6 py-3 font-medium transition-colors"`,
|
|
848
|
+
` >`,
|
|
849
|
+
` Stop`,
|
|
850
|
+
` </button>`,
|
|
851
|
+
` ) : (`,
|
|
852
|
+
` <button`,
|
|
853
|
+
` type="submit"`,
|
|
854
|
+
` disabled={!input.trim()}`,
|
|
855
|
+
` className="bg-blue-600 hover:bg-blue-500 disabled:opacity-50 disabled:cursor-not-allowed text-white rounded-xl px-6 py-3 font-medium transition-colors"`,
|
|
856
|
+
` >`,
|
|
857
|
+
` Send`,
|
|
858
|
+
` </button>`,
|
|
859
|
+
` )}`,
|
|
754
860
|
` </form>`,
|
|
755
861
|
` </div>`,
|
|
756
862
|
` </main>`,
|
|
@@ -763,7 +869,7 @@ var nextjsTemplate = {
|
|
|
763
869
|
`import './globals.css'`,
|
|
764
870
|
``,
|
|
765
871
|
`export const metadata: Metadata = {`,
|
|
766
|
-
` title:
|
|
872
|
+
` title: ${tsString(options.name)},`,
|
|
767
873
|
` description: 'AI chat app powered by Cogitator',`,
|
|
768
874
|
`}`,
|
|
769
875
|
``,
|
|
@@ -857,8 +963,8 @@ var nextjsTemplate = {
|
|
|
857
963
|
},
|
|
858
964
|
dependencies() {
|
|
859
965
|
return {
|
|
860
|
-
"@cogitator-ai/core": "
|
|
861
|
-
"@cogitator-ai/next": "
|
|
966
|
+
"@cogitator-ai/core": cogitatorVersion("@cogitator-ai/core"),
|
|
967
|
+
"@cogitator-ai/next": cogitatorVersion("@cogitator-ai/next"),
|
|
862
968
|
next: "^15.0.0",
|
|
863
969
|
react: "^19.0.0",
|
|
864
970
|
"react-dom": "^19.0.0",
|
|
@@ -881,7 +987,7 @@ var nextjsTemplate = {
|
|
|
881
987
|
dev: "next dev",
|
|
882
988
|
build: "next build",
|
|
883
989
|
start: "next start",
|
|
884
|
-
|
|
990
|
+
typecheck: "tsc --noEmit"
|
|
885
991
|
};
|
|
886
992
|
}
|
|
887
993
|
};
|
|
@@ -947,15 +1053,19 @@ function generateTsconfig() {
|
|
|
947
1053
|
}
|
|
948
1054
|
|
|
949
1055
|
// src/templates/base/gitignore.ts
|
|
950
|
-
|
|
1056
|
+
var NEXT_OUTPUT = [".next/", "out/", "next-env.d.ts"];
|
|
1057
|
+
function generateGitignore(template) {
|
|
951
1058
|
return {
|
|
952
1059
|
path: ".gitignore",
|
|
953
1060
|
content: [
|
|
954
1061
|
"node_modules/",
|
|
955
1062
|
"dist/",
|
|
1063
|
+
...template === "nextjs" ? NEXT_OUTPUT : [],
|
|
956
1064
|
".env",
|
|
957
|
-
".env
|
|
1065
|
+
".env.*",
|
|
1066
|
+
"!.env.example",
|
|
958
1067
|
"*.log",
|
|
1068
|
+
"*.tsbuildinfo",
|
|
959
1069
|
".DS_Store",
|
|
960
1070
|
"coverage/",
|
|
961
1071
|
".turbo/",
|
|
@@ -973,16 +1083,16 @@ function generateEnvExample(provider, template) {
|
|
|
973
1083
|
lines.push("# OLLAMA_BASE_URL=http://localhost:11434");
|
|
974
1084
|
break;
|
|
975
1085
|
case "openai":
|
|
976
|
-
lines.push("# OpenAI");
|
|
977
|
-
lines.push("OPENAI_API_KEY=
|
|
1086
|
+
lines.push("# OpenAI, https://platform.openai.com/api-keys");
|
|
1087
|
+
lines.push("OPENAI_API_KEY=");
|
|
978
1088
|
break;
|
|
979
1089
|
case "anthropic":
|
|
980
|
-
lines.push("# Anthropic");
|
|
981
|
-
lines.push("ANTHROPIC_API_KEY=
|
|
1090
|
+
lines.push("# Anthropic, https://console.anthropic.com/settings/keys");
|
|
1091
|
+
lines.push("ANTHROPIC_API_KEY=");
|
|
982
1092
|
break;
|
|
983
1093
|
case "google":
|
|
984
|
-
lines.push("# Google AI");
|
|
985
|
-
lines.push("GOOGLE_API_KEY
|
|
1094
|
+
lines.push("# Google AI, https://aistudio.google.com/apikey");
|
|
1095
|
+
lines.push("GOOGLE_API_KEY=");
|
|
986
1096
|
break;
|
|
987
1097
|
}
|
|
988
1098
|
if (template === "memory") {
|
|
@@ -990,25 +1100,54 @@ function generateEnvExample(provider, template) {
|
|
|
990
1100
|
lines.push("# Redis");
|
|
991
1101
|
lines.push("REDIS_URL=redis://localhost:6379");
|
|
992
1102
|
}
|
|
1103
|
+
if (template === "api-server") {
|
|
1104
|
+
lines.push("");
|
|
1105
|
+
lines.push("# Bearer token that every API route except health and docs requires.");
|
|
1106
|
+
lines.push("# Optional in development, where the server listens on 127.0.0.1 only,");
|
|
1107
|
+
lines.push("# required in production (NODE_ENV=production), where it listens on 0.0.0.0.");
|
|
1108
|
+
lines.push("API_TOKEN=");
|
|
1109
|
+
lines.push("");
|
|
1110
|
+
lines.push("# Comma-separated browser origins allowed to call the API, CORS is off without it");
|
|
1111
|
+
lines.push("# CORS_ORIGIN=http://localhost:5173");
|
|
1112
|
+
lines.push("");
|
|
1113
|
+
lines.push("# HOST=127.0.0.1");
|
|
1114
|
+
lines.push("# PORT=3000");
|
|
1115
|
+
}
|
|
993
1116
|
lines.push("");
|
|
994
1117
|
return { path: ".env.example", content: lines.join("\n") };
|
|
995
1118
|
}
|
|
996
1119
|
|
|
997
1120
|
// src/templates/base/docker-compose.ts
|
|
998
|
-
function
|
|
1121
|
+
function ollamaServices(model) {
|
|
1122
|
+
return [
|
|
1123
|
+
" ollama:",
|
|
1124
|
+
" image: ollama/ollama:latest",
|
|
1125
|
+
" ports:",
|
|
1126
|
+
' - "11434:11434"',
|
|
1127
|
+
" volumes:",
|
|
1128
|
+
" - ollama_data:/root/.ollama",
|
|
1129
|
+
" healthcheck:",
|
|
1130
|
+
' test: ["CMD", "ollama", "list"]',
|
|
1131
|
+
" interval: 5s",
|
|
1132
|
+
" timeout: 5s",
|
|
1133
|
+
" retries: 20",
|
|
1134
|
+
"",
|
|
1135
|
+
" ollama-pull:",
|
|
1136
|
+
" image: ollama/ollama:latest",
|
|
1137
|
+
" depends_on:",
|
|
1138
|
+
" ollama:",
|
|
1139
|
+
" condition: service_healthy",
|
|
1140
|
+
" environment:",
|
|
1141
|
+
" OLLAMA_HOST: http://ollama:11434",
|
|
1142
|
+
` entrypoint: ["ollama", "pull", ${JSON.stringify(model)}]`,
|
|
1143
|
+
' restart: "no"',
|
|
1144
|
+
""
|
|
1145
|
+
];
|
|
1146
|
+
}
|
|
1147
|
+
function generateDockerCompose(provider, model = defaultModels[provider]) {
|
|
999
1148
|
const services = [];
|
|
1000
1149
|
if (provider === "ollama") {
|
|
1001
|
-
services.push(
|
|
1002
|
-
...[
|
|
1003
|
-
" ollama:",
|
|
1004
|
-
" image: ollama/ollama:latest",
|
|
1005
|
-
" ports:",
|
|
1006
|
-
' - "11434:11434"',
|
|
1007
|
-
" volumes:",
|
|
1008
|
-
" - ollama_data:/root/.ollama",
|
|
1009
|
-
""
|
|
1010
|
-
]
|
|
1011
|
-
);
|
|
1150
|
+
services.push(...ollamaServices(model));
|
|
1012
1151
|
}
|
|
1013
1152
|
services.push(
|
|
1014
1153
|
...[
|
|
@@ -1039,12 +1178,15 @@ function generateDockerCompose(provider) {
|
|
|
1039
1178
|
}
|
|
1040
1179
|
|
|
1041
1180
|
// src/templates/base/cogitator-yml.ts
|
|
1042
|
-
|
|
1043
|
-
|
|
1044
|
-
|
|
1045
|
-
|
|
1046
|
-
|
|
1047
|
-
|
|
1181
|
+
var HEADER = [
|
|
1182
|
+
"# Read by `cogitator run` and `cogitator deploy`: the provider and model, the",
|
|
1183
|
+
"# memory to provision and the deploy settings. The code in src/ configures",
|
|
1184
|
+
"# Cogitator itself, so change the provider, model or memory in both places.",
|
|
1185
|
+
""
|
|
1186
|
+
];
|
|
1187
|
+
function generateCogitatorYml(provider, template, model = defaultModels[provider]) {
|
|
1188
|
+
const generator = template ? getTemplate(template) : void 0;
|
|
1189
|
+
const lines = [...HEADER, "llm:", ` defaultProvider: ${provider}`, ` defaultModel: ${model}`];
|
|
1048
1190
|
if (provider === "ollama") {
|
|
1049
1191
|
lines.push(
|
|
1050
1192
|
" providers:",
|
|
@@ -1052,7 +1194,7 @@ function generateCogitatorYml(provider, template) {
|
|
|
1052
1194
|
" baseUrl: ${OLLAMA_BASE_URL:-http://localhost:11434}"
|
|
1053
1195
|
);
|
|
1054
1196
|
}
|
|
1055
|
-
if (
|
|
1197
|
+
if (generator?.memoryAdapter === "redis") {
|
|
1056
1198
|
lines.push(
|
|
1057
1199
|
"",
|
|
1058
1200
|
"memory:",
|
|
@@ -1060,10 +1202,22 @@ function generateCogitatorYml(provider, template) {
|
|
|
1060
1202
|
" redis:",
|
|
1061
1203
|
" url: ${REDIS_URL:-redis://localhost:6379}"
|
|
1062
1204
|
);
|
|
1205
|
+
} else if (generator?.memoryAdapter === "memory") {
|
|
1206
|
+
lines.push("", "memory:", " adapter: memory");
|
|
1207
|
+
}
|
|
1208
|
+
const deploy = [];
|
|
1209
|
+
if (generator?.healthPath) {
|
|
1210
|
+
deploy.push(" health:", ` path: ${generator.healthPath}`);
|
|
1211
|
+
}
|
|
1212
|
+
if (generator?.secrets?.length) {
|
|
1213
|
+
const secrets = [
|
|
1214
|
+
...provider === "ollama" ? [] : [providerEnvKey(provider)],
|
|
1215
|
+
...generator.secrets
|
|
1216
|
+
];
|
|
1217
|
+
deploy.push(" secrets:", ...secrets.map((name) => ` - ${name}`));
|
|
1063
1218
|
}
|
|
1064
|
-
|
|
1065
|
-
|
|
1066
|
-
lines.push("", "deploy:", " health:", ` path: ${healthPath}`);
|
|
1219
|
+
if (deploy.length > 0) {
|
|
1220
|
+
lines.push("", "deploy:", ...deploy);
|
|
1067
1221
|
}
|
|
1068
1222
|
lines.push("");
|
|
1069
1223
|
return { path: "cogitator.yml", content: lines.join("\n") };
|
|
@@ -1072,12 +1226,8 @@ function generateCogitatorYml(provider, template) {
|
|
|
1072
1226
|
// src/utils/package-manager.ts
|
|
1073
1227
|
import { execSync } from "child_process";
|
|
1074
1228
|
function detectPackageManager() {
|
|
1075
|
-
const
|
|
1076
|
-
if (
|
|
1077
|
-
if (ua.startsWith("pnpm")) return "pnpm";
|
|
1078
|
-
if (ua.startsWith("yarn")) return "yarn";
|
|
1079
|
-
if (ua.startsWith("bun")) return "bun";
|
|
1080
|
-
}
|
|
1229
|
+
const name = process.env.npm_config_user_agent?.split("/")[0];
|
|
1230
|
+
if (name === "npm" || name === "pnpm" || name === "yarn" || name === "bun") return name;
|
|
1081
1231
|
return "pnpm";
|
|
1082
1232
|
}
|
|
1083
1233
|
function installDependencies(cwd, pm) {
|
|
@@ -1088,6 +1238,35 @@ function devCommand(pm) {
|
|
|
1088
1238
|
return `${pm} dev`;
|
|
1089
1239
|
}
|
|
1090
1240
|
|
|
1241
|
+
// src/next-steps.ts
|
|
1242
|
+
function nextSteps(options, state) {
|
|
1243
|
+
const steps = [];
|
|
1244
|
+
if (state.directory) {
|
|
1245
|
+
const dir = /^[\w./-]+$/.test(state.directory) ? state.directory : JSON.stringify(state.directory);
|
|
1246
|
+
steps.push({ command: `cd ${dir}` });
|
|
1247
|
+
}
|
|
1248
|
+
if (!state.installed) {
|
|
1249
|
+
steps.push({ command: `${options.packageManager} install` });
|
|
1250
|
+
}
|
|
1251
|
+
if (options.provider !== "ollama") {
|
|
1252
|
+
steps.push({
|
|
1253
|
+
command: "cp .env.example .env",
|
|
1254
|
+
note: `then set ${providerEnvKey(options.provider)} in .env`
|
|
1255
|
+
});
|
|
1256
|
+
}
|
|
1257
|
+
if (options.provider === "ollama" && !state.modelReady) {
|
|
1258
|
+
steps.push({
|
|
1259
|
+
command: `ollama pull ${modelFor(options)}`,
|
|
1260
|
+
note: options.docker ? "download the model the agents use, or let `docker compose up -d` pull it into the Ollama container" : "download the model the agents use"
|
|
1261
|
+
});
|
|
1262
|
+
}
|
|
1263
|
+
if (options.template === "memory" && options.docker) {
|
|
1264
|
+
steps.push({ command: "docker compose up -d redis", note: "the memory lives in Redis" });
|
|
1265
|
+
}
|
|
1266
|
+
steps.push({ command: devCommand(options.packageManager) });
|
|
1267
|
+
return steps;
|
|
1268
|
+
}
|
|
1269
|
+
|
|
1091
1270
|
// src/utils/links.ts
|
|
1092
1271
|
var DOCS_URL = "https://cogitator.app/docs";
|
|
1093
1272
|
var REPO_URL = "https://github.com/cogitator-ai/Cogitator-AI";
|
|
@@ -1102,24 +1281,33 @@ var templateNames = {
|
|
|
1102
1281
|
nextjs: "Next.js Chat App"
|
|
1103
1282
|
};
|
|
1104
1283
|
function generateReadme(options) {
|
|
1105
|
-
const dev = devCommand(options.packageManager);
|
|
1106
1284
|
const templateName = templateNames[options.template] || options.template;
|
|
1285
|
+
const steps = nextSteps(options, { installed: false, modelReady: false });
|
|
1107
1286
|
const content = [
|
|
1108
1287
|
`# ${options.name}`,
|
|
1109
1288
|
"",
|
|
1110
|
-
`> Created with [create-cogitator-app](${REPO_URL})
|
|
1289
|
+
`> Created with [create-cogitator-app](${REPO_URL}) - ${templateName} template`,
|
|
1111
1290
|
"",
|
|
1112
1291
|
"## Getting Started",
|
|
1113
1292
|
"",
|
|
1114
1293
|
"```bash",
|
|
1115
|
-
|
|
1116
|
-
|
|
1117
|
-
|
|
1118
|
-
|
|
1119
|
-
|
|
1294
|
+
...steps.flatMap((step, i) => [
|
|
1295
|
+
...i > 0 ? [""] : [],
|
|
1296
|
+
...step.note ? [`# ${step.note}`] : [],
|
|
1297
|
+
step.command
|
|
1298
|
+
]),
|
|
1120
1299
|
"```",
|
|
1121
1300
|
"",
|
|
1122
|
-
...options.docker ? [
|
|
1301
|
+
...options.docker ? [
|
|
1302
|
+
"## Docker Services",
|
|
1303
|
+
"",
|
|
1304
|
+
"```bash",
|
|
1305
|
+
"docker compose up -d",
|
|
1306
|
+
"```",
|
|
1307
|
+
"",
|
|
1308
|
+
options.provider === "ollama" ? "Starts Redis, Postgres and Ollama, and pulls the model into the Ollama container." : "Starts Redis and Postgres.",
|
|
1309
|
+
""
|
|
1310
|
+
] : [],
|
|
1123
1311
|
"## Learn More",
|
|
1124
1312
|
"",
|
|
1125
1313
|
`- [Cogitator Documentation](${DOCS_URL})`,
|
|
@@ -1175,10 +1363,28 @@ function initGitRepo(cwd) {
|
|
|
1175
1363
|
});
|
|
1176
1364
|
}
|
|
1177
1365
|
|
|
1366
|
+
// src/utils/project-name.ts
|
|
1367
|
+
import path2 from "path";
|
|
1368
|
+
var PACKAGE_NAME = /^[a-z0-9][a-z0-9._-]*$/;
|
|
1369
|
+
var MAX_LENGTH = 214;
|
|
1370
|
+
function validateProjectName(name) {
|
|
1371
|
+
const trimmed = name.trim();
|
|
1372
|
+
if (!trimmed) return "Project name is required";
|
|
1373
|
+
if (trimmed.length > MAX_LENGTH) return `Use at most ${MAX_LENGTH} characters`;
|
|
1374
|
+
if (!PACKAGE_NAME.test(trimmed)) {
|
|
1375
|
+
return 'Use lowercase letters, digits, ".", "_" or "-", starting with a letter or digit';
|
|
1376
|
+
}
|
|
1377
|
+
return void 0;
|
|
1378
|
+
}
|
|
1379
|
+
function projectNameFromDirectory(dir, cwd = process.cwd()) {
|
|
1380
|
+
return path2.basename(path2.resolve(cwd, dir.trim()));
|
|
1381
|
+
}
|
|
1382
|
+
|
|
1178
1383
|
// src/scaffold.ts
|
|
1384
|
+
var NODE_ENGINES = ">=22.12.0";
|
|
1179
1385
|
function writeFile(basePath, file) {
|
|
1180
|
-
const fullPath =
|
|
1181
|
-
fs.mkdirSync(
|
|
1386
|
+
const fullPath = path3.join(basePath, file.path);
|
|
1387
|
+
fs.mkdirSync(path3.dirname(fullPath), { recursive: true });
|
|
1182
1388
|
fs.writeFileSync(fullPath, file.content, "utf-8");
|
|
1183
1389
|
}
|
|
1184
1390
|
function buildPackageJson(options) {
|
|
@@ -1189,6 +1395,7 @@ function buildPackageJson(options) {
|
|
|
1189
1395
|
version: "0.1.0",
|
|
1190
1396
|
private: true,
|
|
1191
1397
|
...isNextjs ? {} : { type: "module" },
|
|
1398
|
+
engines: { node: NODE_ENGINES },
|
|
1192
1399
|
scripts: template.scripts(),
|
|
1193
1400
|
dependencies: template.dependencies(),
|
|
1194
1401
|
devDependencies: template.devDependencies()
|
|
@@ -1200,9 +1407,9 @@ function collectFiles(options) {
|
|
|
1200
1407
|
const files = [];
|
|
1201
1408
|
files.push({ path: "package.json", content: buildPackageJson(options) });
|
|
1202
1409
|
files.push(...template.files(options));
|
|
1203
|
-
files.push(generateGitignore());
|
|
1410
|
+
files.push(generateGitignore(options.template));
|
|
1204
1411
|
files.push(generateEnvExample(options.provider, options.template));
|
|
1205
|
-
files.push(generateCogitatorYml(options.provider, options.template));
|
|
1412
|
+
files.push(generateCogitatorYml(options.provider, options.template, modelFor(options)));
|
|
1206
1413
|
files.push(generateReadme(options));
|
|
1207
1414
|
if (options.template !== "nextjs") {
|
|
1208
1415
|
files.push(generateTsconfig());
|
|
@@ -1211,7 +1418,7 @@ function collectFiles(options) {
|
|
|
1211
1418
|
files.push(generatePnpmWorkspace());
|
|
1212
1419
|
}
|
|
1213
1420
|
if (options.docker) {
|
|
1214
|
-
files.push(generateDockerCompose(options.provider));
|
|
1421
|
+
files.push(generateDockerCompose(options.provider, modelFor(options)));
|
|
1215
1422
|
}
|
|
1216
1423
|
return files;
|
|
1217
1424
|
}
|
|
@@ -1227,6 +1434,10 @@ function runStep(spinner2, messages, step) {
|
|
|
1227
1434
|
}
|
|
1228
1435
|
}
|
|
1229
1436
|
async function scaffold(options) {
|
|
1437
|
+
const nameError = validateProjectName(options.name);
|
|
1438
|
+
if (nameError) {
|
|
1439
|
+
throw new Error(`Invalid project name "${options.name}": ${nameError}`);
|
|
1440
|
+
}
|
|
1230
1441
|
if (fs.existsSync(options.path) && fs.readdirSync(options.path).length > 0) {
|
|
1231
1442
|
throw new Error(`Directory "${options.path}" already exists and is not empty`);
|
|
1232
1443
|
}
|
|
@@ -1261,7 +1472,46 @@ async function scaffold(options) {
|
|
|
1261
1472
|
|
|
1262
1473
|
// src/prompts.ts
|
|
1263
1474
|
import * as p2 from "@clack/prompts";
|
|
1264
|
-
import
|
|
1475
|
+
import path4 from "path";
|
|
1476
|
+
|
|
1477
|
+
// src/utils/ollama.ts
|
|
1478
|
+
var DEFAULT_OLLAMA_URL = "http://localhost:11434";
|
|
1479
|
+
function isRecord2(value) {
|
|
1480
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
1481
|
+
}
|
|
1482
|
+
function trimTrailingSlashes(value) {
|
|
1483
|
+
let end = value.length;
|
|
1484
|
+
while (end > 0 && value[end - 1] === "/") end--;
|
|
1485
|
+
return value.slice(0, end);
|
|
1486
|
+
}
|
|
1487
|
+
function resolveOllamaUrl(env = process.env) {
|
|
1488
|
+
const raw = env.OLLAMA_BASE_URL?.trim() || env.OLLAMA_HOST?.trim();
|
|
1489
|
+
if (!raw) return DEFAULT_OLLAMA_URL;
|
|
1490
|
+
const withScheme = /^https?:\/\//i.test(raw) ? raw : `http://${raw}`;
|
|
1491
|
+
return trimTrailingSlashes(withScheme);
|
|
1492
|
+
}
|
|
1493
|
+
async function listOllamaModels(baseUrl, timeoutMs = 2e3) {
|
|
1494
|
+
try {
|
|
1495
|
+
const res = await fetch(`${baseUrl}/api/tags`, { signal: AbortSignal.timeout(timeoutMs) });
|
|
1496
|
+
if (!res.ok) return void 0;
|
|
1497
|
+
const data = await res.json();
|
|
1498
|
+
if (!isRecord2(data) || !Array.isArray(data.models)) return void 0;
|
|
1499
|
+
return data.models.flatMap(
|
|
1500
|
+
(model) => isRecord2(model) && typeof model.name === "string" ? [{ name: model.name, size: typeof model.size === "number" ? model.size : 0 }] : []
|
|
1501
|
+
);
|
|
1502
|
+
} catch {
|
|
1503
|
+
return void 0;
|
|
1504
|
+
}
|
|
1505
|
+
}
|
|
1506
|
+
function withTag(name) {
|
|
1507
|
+
return name.includes(":") ? name : `${name}:latest`;
|
|
1508
|
+
}
|
|
1509
|
+
function hasOllamaModel(installed, model) {
|
|
1510
|
+
const wanted = withTag(model);
|
|
1511
|
+
return installed.some((m) => withTag(m.name) === wanted);
|
|
1512
|
+
}
|
|
1513
|
+
|
|
1514
|
+
// src/prompts.ts
|
|
1265
1515
|
var validTemplates = ["basic", "memory", "swarm", "workflow", "api-server", "nextjs"];
|
|
1266
1516
|
var validProviders = ["ollama", "openai", "anthropic", "google"];
|
|
1267
1517
|
var validPMs = ["pnpm", "npm", "yarn", "bun"];
|
|
@@ -1279,6 +1529,12 @@ function parseArgs(args) {
|
|
|
1279
1529
|
const val = args[++i];
|
|
1280
1530
|
if (validProviders.includes(val)) parsed.provider = val;
|
|
1281
1531
|
}
|
|
1532
|
+
} else if (arg === "--model") {
|
|
1533
|
+
const val = args[i + 1];
|
|
1534
|
+
if (val !== void 0 && !val.startsWith("-")) {
|
|
1535
|
+
parsed.model = val;
|
|
1536
|
+
i++;
|
|
1537
|
+
}
|
|
1282
1538
|
} else if (arg === "--pm") {
|
|
1283
1539
|
if (i + 1 < args.length) {
|
|
1284
1540
|
const val = args[++i];
|
|
@@ -1318,22 +1574,54 @@ function unlessCancelled(answer) {
|
|
|
1318
1574
|
}
|
|
1319
1575
|
return answer;
|
|
1320
1576
|
}
|
|
1577
|
+
function validateDirectory(value) {
|
|
1578
|
+
if (!value) return void 0;
|
|
1579
|
+
if (!value.trim()) return "Project name is required";
|
|
1580
|
+
return validateProjectName(projectNameFromDirectory(value));
|
|
1581
|
+
}
|
|
1582
|
+
function formatSize(bytes) {
|
|
1583
|
+
return bytes > 0 ? `${(bytes / 1e9).toFixed(1)} GB` : void 0;
|
|
1584
|
+
}
|
|
1585
|
+
async function promptOllamaModel() {
|
|
1586
|
+
const installed = await listOllamaModels(resolveOllamaUrl());
|
|
1587
|
+
if (!installed) return void 0;
|
|
1588
|
+
const recommended = defaultModels.ollama;
|
|
1589
|
+
const others = installed.filter((model) => !hasOllamaModel([model], recommended));
|
|
1590
|
+
return unlessCancelled(
|
|
1591
|
+
await p2.select({
|
|
1592
|
+
message: "Which Ollama model?",
|
|
1593
|
+
options: [
|
|
1594
|
+
{
|
|
1595
|
+
value: recommended,
|
|
1596
|
+
label: recommended,
|
|
1597
|
+
hint: hasOllamaModel(installed, recommended) ? "recommended, installed" : "recommended, not installed yet"
|
|
1598
|
+
},
|
|
1599
|
+
...others.map((model) => ({
|
|
1600
|
+
value: model.name,
|
|
1601
|
+
label: model.name,
|
|
1602
|
+
hint: formatSize(model.size)
|
|
1603
|
+
}))
|
|
1604
|
+
],
|
|
1605
|
+
initialValue: recommended
|
|
1606
|
+
})
|
|
1607
|
+
);
|
|
1608
|
+
}
|
|
1321
1609
|
async function collectOptions(args) {
|
|
1322
1610
|
const interactive = !args.yes;
|
|
1323
|
-
const
|
|
1611
|
+
const directory = (args.name || (interactive ? unlessCancelled(
|
|
1324
1612
|
await p2.text({
|
|
1325
1613
|
message: "Where should we create your project?",
|
|
1326
1614
|
placeholder: `./${defaultAnswers.name}`,
|
|
1327
1615
|
defaultValue: defaultAnswers.name,
|
|
1328
|
-
validate:
|
|
1329
|
-
if (value && !value.trim()) return "Project name is required";
|
|
1330
|
-
return void 0;
|
|
1331
|
-
}
|
|
1616
|
+
validate: validateDirectory
|
|
1332
1617
|
})
|
|
1333
|
-
) : defaultAnswers.name);
|
|
1334
|
-
const
|
|
1335
|
-
const projectName =
|
|
1336
|
-
const
|
|
1618
|
+
) : defaultAnswers.name)).trim();
|
|
1619
|
+
const projectPath = path4.resolve(process.cwd(), directory);
|
|
1620
|
+
const projectName = projectNameFromDirectory(directory);
|
|
1621
|
+
const nameError = validateProjectName(projectName);
|
|
1622
|
+
if (nameError) {
|
|
1623
|
+
throw new Error(`Invalid project name "${projectName}": ${nameError}`);
|
|
1624
|
+
}
|
|
1337
1625
|
const template = args.template ?? (interactive ? unlessCancelled(
|
|
1338
1626
|
await p2.select({
|
|
1339
1627
|
message: "Which template would you like?",
|
|
@@ -1348,7 +1636,7 @@ async function collectOptions(args) {
|
|
|
1348
1636
|
{
|
|
1349
1637
|
value: "ollama",
|
|
1350
1638
|
label: "Ollama",
|
|
1351
|
-
hint: `${defaultModels.ollama}
|
|
1639
|
+
hint: `${defaultModels.ollama}, local, free, requires Ollama installed`
|
|
1352
1640
|
},
|
|
1353
1641
|
{ value: "openai", label: "OpenAI", hint: defaultModels.openai },
|
|
1354
1642
|
{ value: "anthropic", label: "Anthropic", hint: defaultModels.anthropic },
|
|
@@ -1357,6 +1645,7 @@ async function collectOptions(args) {
|
|
|
1357
1645
|
initialValue: defaultAnswers.provider
|
|
1358
1646
|
})
|
|
1359
1647
|
) : defaultAnswers.provider);
|
|
1648
|
+
const model = args.model ?? (interactive && provider === "ollama" ? await promptOllamaModel() : void 0);
|
|
1360
1649
|
const packageManager = args.packageManager ?? (interactive ? unlessCancelled(
|
|
1361
1650
|
await p2.select({
|
|
1362
1651
|
message: "Package manager?",
|
|
@@ -1386,6 +1675,7 @@ async function collectOptions(args) {
|
|
|
1386
1675
|
path: projectPath,
|
|
1387
1676
|
template,
|
|
1388
1677
|
provider,
|
|
1678
|
+
...model !== void 0 && { model },
|
|
1389
1679
|
packageManager,
|
|
1390
1680
|
docker,
|
|
1391
1681
|
git,
|
|
@@ -1402,6 +1692,7 @@ export {
|
|
|
1402
1692
|
providerConfig,
|
|
1403
1693
|
providerEnvKey,
|
|
1404
1694
|
scaffold,
|
|
1405
|
-
templateChoices
|
|
1695
|
+
templateChoices,
|
|
1696
|
+
validateProjectName
|
|
1406
1697
|
};
|
|
1407
1698
|
//# sourceMappingURL=lib.js.map
|