@voltx/cli 0.3.2 → 0.3.4
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 +31 -9
- package/dist/chunk-4T26KROZ.mjs +456 -0
- package/dist/chunk-5RN2FYST.mjs +494 -0
- package/dist/chunk-CFWXMM7Q.mjs +450 -0
- package/dist/chunk-EXMRIKIX.mjs +404 -0
- package/dist/chunk-FN7KZJ6H.mjs +363 -0
- package/dist/chunk-HAFJKS2O.mjs +141 -0
- package/dist/chunk-HM7F67C2.mjs +405 -0
- package/dist/chunk-P5FSO2UH.mjs +497 -0
- package/dist/chunk-UO43CY7Y.mjs +497 -0
- package/dist/cli.js +242 -150
- package/dist/create.js +239 -147
- package/dist/create.mjs +1 -1
- package/dist/generate.js +1 -1
- package/dist/generate.mjs +1 -1
- package/dist/index.d.mts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +241 -149
- package/dist/index.mjs +3 -3
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -148,6 +148,13 @@ function printWelcomeBanner(projectName) {
|
|
|
148
148
|
}
|
|
149
149
|
|
|
150
150
|
// src/create.ts
|
|
151
|
+
var V = "^0.3.0";
|
|
152
|
+
var TEMPLATE_DEPS = {
|
|
153
|
+
blank: { "@voltx/core": V, "@voltx/server": V },
|
|
154
|
+
chatbot: { "@voltx/core": V, "@voltx/ai": V, "@voltx/server": V, "@voltx/memory": V },
|
|
155
|
+
"rag-app": { "@voltx/core": V, "@voltx/ai": V, "@voltx/server": V, "@voltx/rag": V, "@voltx/db": V },
|
|
156
|
+
"agent-app": { "@voltx/core": V, "@voltx/ai": V, "@voltx/server": V, "@voltx/agents": V, "@voltx/memory": V }
|
|
157
|
+
};
|
|
151
158
|
async function createProject(options) {
|
|
152
159
|
const { name, template = "blank", auth = "none" } = options;
|
|
153
160
|
const targetDir = path.resolve(process.cwd(), name);
|
|
@@ -156,62 +163,26 @@ async function createProject(options) {
|
|
|
156
163
|
process.exit(1);
|
|
157
164
|
}
|
|
158
165
|
fs.mkdirSync(targetDir, { recursive: true });
|
|
159
|
-
const
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
"@voltx/core": "^0.3.0",
|
|
172
|
-
"@voltx/ai": "^0.3.0",
|
|
173
|
-
"@voltx/server": "^0.3.0",
|
|
174
|
-
"@voltx/rag": "^0.3.0",
|
|
175
|
-
"@voltx/db": "^0.3.0"
|
|
176
|
-
},
|
|
177
|
-
"agent-app": {
|
|
178
|
-
"@voltx/core": "^0.3.0",
|
|
179
|
-
"@voltx/ai": "^0.3.0",
|
|
180
|
-
"@voltx/server": "^0.3.0",
|
|
181
|
-
"@voltx/agents": "^0.3.0",
|
|
182
|
-
"@voltx/memory": "^0.3.0"
|
|
183
|
-
}
|
|
184
|
-
};
|
|
185
|
-
const packageJson = {
|
|
166
|
+
const provider = template === "rag-app" ? "openai" : "cerebras";
|
|
167
|
+
const model = template === "rag-app" ? "gpt-4o" : "llama3.1-8b";
|
|
168
|
+
const hasDb = template === "rag-app" || template === "agent-app" || auth === "better-auth";
|
|
169
|
+
const deps = { ...TEMPLATE_DEPS[template] ?? TEMPLATE_DEPS["blank"], "@voltx/cli": V };
|
|
170
|
+
if (auth === "better-auth") {
|
|
171
|
+
deps["@voltx/auth"] = V;
|
|
172
|
+
deps["better-auth"] = "^1.5.0";
|
|
173
|
+
} else if (auth === "jwt") {
|
|
174
|
+
deps["@voltx/auth"] = V;
|
|
175
|
+
deps["jose"] = "^6.0.0";
|
|
176
|
+
}
|
|
177
|
+
fs.writeFileSync(path.join(targetDir, "package.json"), JSON.stringify({
|
|
186
178
|
name,
|
|
187
179
|
version: "0.1.0",
|
|
188
180
|
private: true,
|
|
189
|
-
scripts: {
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
dependencies: {
|
|
195
|
-
...templateDeps[template] ?? templateDeps["blank"],
|
|
196
|
-
"@voltx/cli": "^0.3.0",
|
|
197
|
-
...auth === "better-auth" ? { "@voltx/auth": "^0.3.0", "better-auth": "^1.5.0" } : {},
|
|
198
|
-
...auth === "jwt" ? { "@voltx/auth": "^0.3.0", "jose": "^6.0.0" } : {}
|
|
199
|
-
},
|
|
200
|
-
devDependencies: {
|
|
201
|
-
typescript: "^5.7.0",
|
|
202
|
-
tsx: "^4.21.0",
|
|
203
|
-
tsup: "^8.0.0",
|
|
204
|
-
"@types/node": "^22.0.0"
|
|
205
|
-
}
|
|
206
|
-
};
|
|
207
|
-
fs.writeFileSync(
|
|
208
|
-
path.join(targetDir, "package.json"),
|
|
209
|
-
JSON.stringify(packageJson, null, 2)
|
|
210
|
-
);
|
|
211
|
-
const hasDb = template === "rag-app" || template === "agent-app" || auth === "better-auth";
|
|
212
|
-
const provider = template === "rag-app" ? "openai" : "cerebras";
|
|
213
|
-
const model = template === "rag-app" ? "gpt-4o" : "llama-4-scout-17b-16e";
|
|
214
|
-
let configContent = `import { defineConfig } from "@voltx/core";
|
|
181
|
+
scripts: { dev: "voltx dev", build: "voltx build", start: "voltx start" },
|
|
182
|
+
dependencies: deps,
|
|
183
|
+
devDependencies: { typescript: "^5.7.0", tsx: "^4.21.0", tsup: "^8.0.0", "@types/node": "^22.0.0" }
|
|
184
|
+
}, null, 2));
|
|
185
|
+
let config = `import { defineConfig } from "@voltx/core";
|
|
215
186
|
|
|
216
187
|
export default defineConfig({
|
|
217
188
|
name: "${name}",
|
|
@@ -220,19 +191,15 @@ export default defineConfig({
|
|
|
220
191
|
provider: "${provider}",
|
|
221
192
|
model: "${model}",
|
|
222
193
|
},`;
|
|
223
|
-
if (hasDb)
|
|
224
|
-
configContent += `
|
|
194
|
+
if (hasDb) config += `
|
|
225
195
|
db: {
|
|
226
196
|
url: process.env.DATABASE_URL,
|
|
227
197
|
},`;
|
|
228
|
-
|
|
229
|
-
if (auth !== "none") {
|
|
230
|
-
configContent += `
|
|
198
|
+
if (auth !== "none") config += `
|
|
231
199
|
auth: {
|
|
232
200
|
provider: "${auth}",
|
|
233
201
|
},`;
|
|
234
|
-
|
|
235
|
-
configContent += `
|
|
202
|
+
config += `
|
|
236
203
|
server: {
|
|
237
204
|
routesDir: "src/routes",
|
|
238
205
|
staticDir: "public",
|
|
@@ -240,9 +207,13 @@ export default defineConfig({
|
|
|
240
207
|
},
|
|
241
208
|
});
|
|
242
209
|
`;
|
|
243
|
-
fs.writeFileSync(path.join(targetDir, "voltx.config.ts"),
|
|
210
|
+
fs.writeFileSync(path.join(targetDir, "voltx.config.ts"), config);
|
|
244
211
|
fs.mkdirSync(path.join(targetDir, "src", "routes", "api"), { recursive: true });
|
|
245
212
|
fs.mkdirSync(path.join(targetDir, "public"), { recursive: true });
|
|
213
|
+
fs.writeFileSync(path.join(targetDir, "tsconfig.json"), JSON.stringify({
|
|
214
|
+
compilerOptions: { target: "ES2022", module: "ESNext", moduleResolution: "bundler", strict: true, esModuleInterop: true, skipLibCheck: true, outDir: "dist" },
|
|
215
|
+
include: ["src", "voltx.config.ts"]
|
|
216
|
+
}, null, 2));
|
|
246
217
|
fs.writeFileSync(
|
|
247
218
|
path.join(targetDir, "src", "index.ts"),
|
|
248
219
|
`import { createApp } from "@voltx/core";
|
|
@@ -270,19 +241,16 @@ import type { Context } from "@voltx/server";
|
|
|
270
241
|
import { streamText } from "@voltx/ai";
|
|
271
242
|
import { createMemory } from "@voltx/memory";
|
|
272
243
|
|
|
273
|
-
// In-memory for dev; swap to createMemory("postgres", { url }) for production
|
|
274
244
|
const memory = createMemory({ maxMessages: 50 });
|
|
275
245
|
|
|
276
246
|
export async function POST(c: Context) {
|
|
277
247
|
const { messages, conversationId = "default" } = await c.req.json();
|
|
278
248
|
|
|
279
|
-
// Store the latest user message
|
|
280
249
|
const lastMessage = messages[messages.length - 1];
|
|
281
250
|
if (lastMessage?.role === "user") {
|
|
282
251
|
await memory.add(conversationId, { role: "user", content: lastMessage.content });
|
|
283
252
|
}
|
|
284
253
|
|
|
285
|
-
// Get conversation history from memory
|
|
286
254
|
const history = await memory.get(conversationId);
|
|
287
255
|
|
|
288
256
|
const result = await streamText({
|
|
@@ -291,7 +259,6 @@ export async function POST(c: Context) {
|
|
|
291
259
|
messages: history.map((m) => ({ role: m.role, content: m.content })),
|
|
292
260
|
});
|
|
293
261
|
|
|
294
|
-
// Store assistant response after stream completes
|
|
295
262
|
result.text.then(async (text) => {
|
|
296
263
|
await memory.add(conversationId, { role: "assistant", content: text });
|
|
297
264
|
});
|
|
@@ -304,41 +271,69 @@ export async function POST(c: Context) {
|
|
|
304
271
|
if (template === "agent-app") {
|
|
305
272
|
fs.mkdirSync(path.join(targetDir, "src", "agents"), { recursive: true });
|
|
306
273
|
fs.mkdirSync(path.join(targetDir, "src", "tools"), { recursive: true });
|
|
307
|
-
fs.writeFileSync(
|
|
308
|
-
|
|
309
|
-
`import { createAgent } from "@voltx/agents";
|
|
310
|
-
import { searchTool } from "../tools/search";
|
|
274
|
+
fs.writeFileSync(path.join(targetDir, "src", "tools", "calculator.ts"), `// Calculator tool \u2014 evaluates math expressions (no API key needed)
|
|
275
|
+
import type { Tool } from "@voltx/agents";
|
|
311
276
|
|
|
312
|
-
export const
|
|
313
|
-
name: "
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
277
|
+
export const calculatorTool: Tool = {
|
|
278
|
+
name: "calculator",
|
|
279
|
+
description: "Evaluate a math expression. Supports +, -, *, /, %, parentheses, and Math functions.",
|
|
280
|
+
parameters: {
|
|
281
|
+
type: "object",
|
|
282
|
+
properties: { expression: { type: "string", description: "The math expression to evaluate" } },
|
|
283
|
+
required: ["expression"],
|
|
284
|
+
},
|
|
285
|
+
async execute(args: { expression: string }) {
|
|
286
|
+
try {
|
|
287
|
+
const safe = args.expression.replace(/[^0-9+\\-*/.()%\\s,]|(?<!Math)\\.[a-z]/gi, (match) => {
|
|
288
|
+
if (args.expression.includes("Math.")) return match;
|
|
289
|
+
throw new Error("Invalid character: " + match);
|
|
290
|
+
});
|
|
291
|
+
const result = new Function("return " + safe)();
|
|
292
|
+
return \`\${args.expression} = \${result}\`;
|
|
293
|
+
} catch (err) {
|
|
294
|
+
return \`Error: \${err instanceof Error ? err.message : String(err)}\`;
|
|
295
|
+
}
|
|
296
|
+
},
|
|
297
|
+
};
|
|
298
|
+
`);
|
|
299
|
+
fs.writeFileSync(path.join(targetDir, "src", "tools", "datetime.ts"), `// Date & time tool \u2014 returns current date, time, timezone (no API key needed)
|
|
300
|
+
import type { Tool } from "@voltx/agents";
|
|
324
301
|
|
|
325
|
-
export const
|
|
326
|
-
name: "
|
|
327
|
-
description: "
|
|
302
|
+
export const datetimeTool: Tool = {
|
|
303
|
+
name: "datetime",
|
|
304
|
+
description: "Get the current date, time, day of week, and timezone.",
|
|
328
305
|
parameters: {
|
|
329
306
|
type: "object",
|
|
330
|
-
properties: {
|
|
331
|
-
required: ["query"],
|
|
307
|
+
properties: { timezone: { type: "string", description: "Optional IANA timezone. Defaults to server timezone." } },
|
|
332
308
|
},
|
|
333
|
-
async execute(args: {
|
|
334
|
-
|
|
309
|
+
async execute(args: { timezone?: string }) {
|
|
310
|
+
const now = new Date();
|
|
311
|
+
const tz = args.timezone || Intl.DateTimeFormat().resolvedOptions().timeZone;
|
|
312
|
+
const formatted = now.toLocaleString("en-US", {
|
|
313
|
+
timeZone: tz, weekday: "long", year: "numeric", month: "long", day: "numeric",
|
|
314
|
+
hour: "2-digit", minute: "2-digit", second: "2-digit", hour12: true,
|
|
315
|
+
});
|
|
316
|
+
return \`Current date/time (\${tz}): \${formatted}\`;
|
|
335
317
|
},
|
|
336
318
|
};
|
|
337
|
-
`
|
|
338
|
-
)
|
|
319
|
+
`);
|
|
320
|
+
fs.writeFileSync(path.join(targetDir, "src", "agents", "assistant.ts"), `// AI Agent \u2014 autonomous assistant with tools
|
|
321
|
+
import { createAgent } from "@voltx/agents";
|
|
322
|
+
import { calculatorTool } from "../tools/calculator";
|
|
323
|
+
import { datetimeTool } from "../tools/datetime";
|
|
324
|
+
|
|
325
|
+
export const assistant = createAgent({
|
|
326
|
+
name: "assistant",
|
|
327
|
+
model: "${provider}:${model}",
|
|
328
|
+
instructions: "You are a helpful AI assistant with access to tools: Calculator, Date & Time. Use them when needed to answer questions accurately.",
|
|
329
|
+
tools: [calculatorTool, datetimeTool],
|
|
330
|
+
maxIterations: 5,
|
|
331
|
+
});
|
|
332
|
+
`);
|
|
339
333
|
fs.writeFileSync(
|
|
340
334
|
path.join(targetDir, "src", "routes", "api", "agent.ts"),
|
|
341
|
-
|
|
335
|
+
`// POST /api/agent \u2014 Run the AI agent
|
|
336
|
+
import type { Context } from "@voltx/server";
|
|
342
337
|
import { assistant } from "../../agents/assistant";
|
|
343
338
|
|
|
344
339
|
export async function POST(c: Context) {
|
|
@@ -361,21 +356,18 @@ import { streamText } from "@voltx/ai";
|
|
|
361
356
|
import { createRAGPipeline, createEmbedder } from "@voltx/rag";
|
|
362
357
|
import { createVectorStore } from "@voltx/db";
|
|
363
358
|
|
|
364
|
-
const vectorStore = createVectorStore();
|
|
359
|
+
const vectorStore = createVectorStore();
|
|
365
360
|
const embedder = createEmbedder({ model: "${embedModel}" });
|
|
366
361
|
const rag = createRAGPipeline({ embedder, vectorStore });
|
|
367
362
|
|
|
368
363
|
export async function POST(c: Context) {
|
|
369
364
|
const { question } = await c.req.json();
|
|
370
|
-
|
|
371
365
|
const context = await rag.getContext(question, { topK: 5 });
|
|
372
|
-
|
|
373
366
|
const result = await streamText({
|
|
374
367
|
model: "${provider}:${model}",
|
|
375
|
-
system: \`Answer
|
|
368
|
+
system: \`Answer based on context. If not relevant, say so.\\n\\nContext:\\n\${context}\`,
|
|
376
369
|
messages: [{ role: "user", content: question }],
|
|
377
370
|
});
|
|
378
|
-
|
|
379
371
|
return result.toSSEResponse();
|
|
380
372
|
}
|
|
381
373
|
`
|
|
@@ -393,11 +385,7 @@ const rag = createRAGPipeline({ embedder, vectorStore });
|
|
|
393
385
|
|
|
394
386
|
export async function POST(c: Context) {
|
|
395
387
|
const { text, idPrefix } = await c.req.json();
|
|
396
|
-
|
|
397
|
-
if (!text || typeof text !== "string") {
|
|
398
|
-
return c.json({ error: "Missing 'text' field" }, 400);
|
|
399
|
-
}
|
|
400
|
-
|
|
388
|
+
if (!text || typeof text !== "string") return c.json({ error: "Missing 'text' field" }, 400);
|
|
401
389
|
const result = await rag.ingest(text, idPrefix ?? "doc");
|
|
402
390
|
return c.json({ status: "ok", chunks: result.chunks, ids: result.ids });
|
|
403
391
|
}
|
|
@@ -422,8 +410,7 @@ export const POST = (c: Context) => handler(c);
|
|
|
422
410
|
fs.mkdirSync(path.join(targetDir, "src", "lib"), { recursive: true });
|
|
423
411
|
fs.writeFileSync(
|
|
424
412
|
path.join(targetDir, "src", "lib", "auth.ts"),
|
|
425
|
-
|
|
426
|
-
import { createAuth, createAuthMiddleware } from "@voltx/auth";
|
|
413
|
+
`import { createAuth, createAuthMiddleware } from "@voltx/auth";
|
|
427
414
|
|
|
428
415
|
export const auth = createAuth("better-auth", {
|
|
429
416
|
database: process.env.DATABASE_URL!,
|
|
@@ -440,8 +427,7 @@ export const authMiddleware = createAuthMiddleware({
|
|
|
440
427
|
fs.mkdirSync(path.join(targetDir, "src", "lib"), { recursive: true });
|
|
441
428
|
fs.writeFileSync(
|
|
442
429
|
path.join(targetDir, "src", "lib", "auth.ts"),
|
|
443
|
-
|
|
444
|
-
import { createAuth, createAuthMiddleware } from "@voltx/auth";
|
|
430
|
+
`import { createAuth, createAuthMiddleware } from "@voltx/auth";
|
|
445
431
|
|
|
446
432
|
export const jwt = createAuth("jwt", {
|
|
447
433
|
secret: process.env.JWT_SECRET!,
|
|
@@ -456,17 +442,12 @@ export const authMiddleware = createAuthMiddleware({
|
|
|
456
442
|
);
|
|
457
443
|
fs.writeFileSync(
|
|
458
444
|
path.join(targetDir, "src", "routes", "api", "auth.ts"),
|
|
459
|
-
|
|
460
|
-
import type { Context } from "@voltx/server";
|
|
445
|
+
`import type { Context } from "@voltx/server";
|
|
461
446
|
import { jwt } from "../../lib/auth";
|
|
462
447
|
|
|
463
448
|
export async function POST(c: Context) {
|
|
464
449
|
const { email, password } = await c.req.json();
|
|
465
|
-
|
|
466
|
-
if (!email || !password) {
|
|
467
|
-
return c.json({ error: "Email and password are required" }, 400);
|
|
468
|
-
}
|
|
469
|
-
|
|
450
|
+
if (!email || !password) return c.json({ error: "Email and password are required" }, 400);
|
|
470
451
|
const token = await jwt.sign({ sub: email, email });
|
|
471
452
|
return c.json({ token });
|
|
472
453
|
}
|
|
@@ -476,55 +457,166 @@ export async function POST(c: Context) {
|
|
|
476
457
|
let envContent = "";
|
|
477
458
|
if (template === "rag-app") {
|
|
478
459
|
envContent += "# \u2500\u2500\u2500 LLM Provider \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\nOPENAI_API_KEY=sk-...\n\n";
|
|
479
|
-
envContent += "# \u2500\u2500\u2500 Database
|
|
480
|
-
envContent += "# \u2500\u2500\u2500 Vector Database (Pinecone) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\nPINECONE_API_KEY=pc-...\nPINECONE_INDEX=voltx-embeddings\n\n";
|
|
460
|
+
envContent += "# \u2500\u2500\u2500 Database \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\nDATABASE_URL=\n\n";
|
|
481
461
|
} else if (template === "chatbot" || template === "agent-app") {
|
|
482
462
|
envContent += "# \u2500\u2500\u2500 LLM Provider \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\nCEREBRAS_API_KEY=csk-...\n\n";
|
|
483
463
|
if (template === "agent-app") {
|
|
484
|
-
envContent += "# \u2500\u2500\u2500 Database (
|
|
464
|
+
envContent += "# \u2500\u2500\u2500 Database (optional) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\nDATABASE_URL=\n\n";
|
|
465
|
+
envContent += "# \u2500\u2500\u2500 Tool API Keys (add keys for tools you use) \u2500\u2500\n";
|
|
466
|
+
envContent += "# TAVILY_API_KEY=tvly-... (Web Search \u2014 https://tavily.com)\n";
|
|
467
|
+
envContent += "# SERPER_API_KEY= (Google Search \u2014 https://serper.dev)\n";
|
|
468
|
+
envContent += "# OPENWEATHER_API_KEY= (Weather \u2014 https://openweathermap.org/api)\n";
|
|
469
|
+
envContent += "# NEWS_API_KEY= (News \u2014 https://newsapi.org)\n\n";
|
|
485
470
|
}
|
|
486
471
|
} else {
|
|
487
|
-
envContent += "# \u2500\u2500\u2500 LLM Provider
|
|
472
|
+
envContent += "# \u2500\u2500\u2500 LLM Provider \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n# OPENAI_API_KEY=sk-...\n# CEREBRAS_API_KEY=csk-...\n\n";
|
|
488
473
|
}
|
|
489
474
|
if (auth === "better-auth") {
|
|
490
|
-
envContent += "# \u2500\u2500\u2500 Auth (Better Auth) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\nBETTER_AUTH_SECRET=your-secret-key-min-32-chars-here\nBETTER_AUTH_URL=http://localhost:3000\n";
|
|
491
|
-
if (template !== "rag-app" && template !== "agent-app") {
|
|
492
|
-
envContent += "DATABASE_URL=postgresql://user:pass@ep-xxx.us-east-2.aws.neon.tech/dbname?sslmode=require\n";
|
|
493
|
-
}
|
|
494
|
-
envContent += "# GITHUB_CLIENT_ID=\n# GITHUB_CLIENT_SECRET=\n\n";
|
|
475
|
+
envContent += "# \u2500\u2500\u2500 Auth (Better Auth) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\nBETTER_AUTH_SECRET=your-secret-key-min-32-chars-here\nBETTER_AUTH_URL=http://localhost:3000\n\n";
|
|
495
476
|
} else if (auth === "jwt") {
|
|
496
477
|
envContent += "# \u2500\u2500\u2500 Auth (JWT) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\nJWT_SECRET=your-jwt-secret-key\n\n";
|
|
497
478
|
}
|
|
498
479
|
envContent += "# \u2500\u2500\u2500 App \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\nPORT=3000\nNODE_ENV=development\n";
|
|
499
480
|
fs.writeFileSync(path.join(targetDir, ".env.example"), envContent);
|
|
500
|
-
|
|
501
|
-
path.join(targetDir, ".
|
|
502
|
-
|
|
503
|
-
);
|
|
504
|
-
fs.writeFileSync(
|
|
505
|
-
path.join(targetDir, "tsconfig.json"),
|
|
506
|
-
JSON.stringify(
|
|
507
|
-
{
|
|
508
|
-
compilerOptions: {
|
|
509
|
-
target: "ES2022",
|
|
510
|
-
module: "ESNext",
|
|
511
|
-
moduleResolution: "bundler",
|
|
512
|
-
strict: true,
|
|
513
|
-
esModuleInterop: true,
|
|
514
|
-
skipLibCheck: true,
|
|
515
|
-
outDir: "dist",
|
|
516
|
-
rootDir: "src"
|
|
517
|
-
},
|
|
518
|
-
include: ["src"]
|
|
519
|
-
},
|
|
520
|
-
null,
|
|
521
|
-
2
|
|
522
|
-
)
|
|
523
|
-
);
|
|
481
|
+
if (template !== "blank") {
|
|
482
|
+
fs.writeFileSync(path.join(targetDir, "public", "index.html"), generateFrontendHTML(name, template));
|
|
483
|
+
}
|
|
484
|
+
fs.writeFileSync(path.join(targetDir, ".gitignore"), "node_modules\ndist\n.env\n");
|
|
524
485
|
printWelcomeBanner(name);
|
|
525
486
|
}
|
|
526
|
-
|
|
527
|
-
|
|
487
|
+
function generateFrontendHTML(projectName, template) {
|
|
488
|
+
const badge = template === "chatbot" ? "Chatbot" : template === "rag-app" ? "RAG App" : "Agent App";
|
|
489
|
+
const accentClass = template === "rag-app" ? "emerald" : template === "agent-app" ? "purple" : "blue";
|
|
490
|
+
const shell = (body) => `<!DOCTYPE html>
|
|
491
|
+
<html lang="en" class="h-full">
|
|
492
|
+
<head>
|
|
493
|
+
<meta charset="UTF-8" />
|
|
494
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
495
|
+
<title>${projectName}</title>
|
|
496
|
+
<script src="https://cdn.tailwindcss.com/3.4.17"></script>
|
|
497
|
+
<style>
|
|
498
|
+
@import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap');
|
|
499
|
+
body { font-family: 'Inter', system-ui, sans-serif; }
|
|
500
|
+
.msg-enter { animation: msgIn 0.25s ease-out; }
|
|
501
|
+
@keyframes msgIn { from { opacity: 0; transform: translateY(8px); } to { opacity: 1; transform: translateY(0); } }
|
|
502
|
+
.typing-dot { animation: blink 1.4s infinite both; }
|
|
503
|
+
.typing-dot:nth-child(2) { animation-delay: 0.2s; }
|
|
504
|
+
.typing-dot:nth-child(3) { animation-delay: 0.4s; }
|
|
505
|
+
@keyframes blink { 0%, 80%, 100% { opacity: 0.2; } 40% { opacity: 1; } }
|
|
506
|
+
::-webkit-scrollbar { width: 6px; }
|
|
507
|
+
::-webkit-scrollbar-track { background: transparent; }
|
|
508
|
+
::-webkit-scrollbar-thumb { background: #334155; border-radius: 3px; }
|
|
509
|
+
</style>
|
|
510
|
+
</head>
|
|
511
|
+
<body class="h-full bg-gray-950 text-gray-100">
|
|
512
|
+
<div id="app" class="h-full flex flex-col">
|
|
513
|
+
<header class="flex-shrink-0 border-b border-gray-800 bg-gray-950/80 backdrop-blur-sm px-4 py-3">
|
|
514
|
+
<div class="max-w-4xl mx-auto flex items-center justify-between">
|
|
515
|
+
<div class="flex items-center gap-3">
|
|
516
|
+
<div class="w-8 h-8 rounded-lg bg-gradient-to-br from-blue-500 to-purple-600 flex items-center justify-center text-sm font-bold">V</div>
|
|
517
|
+
<h1 class="text-lg font-semibold text-white">${projectName}</h1>
|
|
518
|
+
<span class="text-xs px-2 py-0.5 rounded-full bg-gray-800 text-gray-400">${badge}</span>
|
|
519
|
+
</div>
|
|
520
|
+
<a href="https://github.com/codewithshail/voltx" target="_blank" class="text-gray-500 hover:text-gray-300 transition-colors text-sm">Built with VoltX</a>
|
|
521
|
+
</div>
|
|
522
|
+
</header>
|
|
523
|
+
<main class="flex-1 overflow-hidden"><div class="h-full max-w-4xl mx-auto">
|
|
524
|
+
${body}
|
|
525
|
+
</div></main>
|
|
526
|
+
</div>
|
|
527
|
+
</body>
|
|
528
|
+
</html>`;
|
|
529
|
+
if (template === "chatbot") return shell(chatbotBody());
|
|
530
|
+
if (template === "rag-app") return shell(ragAppBody());
|
|
531
|
+
if (template === "agent-app") return shell(agentAppBody());
|
|
532
|
+
return "";
|
|
533
|
+
}
|
|
534
|
+
function chatbotBody() {
|
|
535
|
+
return ` <div class="h-full flex flex-col">
|
|
536
|
+
<div id="messages" class="flex-1 overflow-y-auto px-4 py-6 space-y-4">
|
|
537
|
+
<div class="text-center py-12">
|
|
538
|
+
<div class="w-16 h-16 mx-auto mb-4 rounded-2xl bg-gradient-to-br from-blue-500/20 to-purple-600/20 border border-blue-500/20 flex items-center justify-center">
|
|
539
|
+
<svg class="w-8 h-8 text-blue-400" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5" d="M8 12h.01M12 12h.01M16 12h.01M21 12c0 4.418-4.03 8-9 8a9.863 9.863 0 01-4.255-.949L3 20l1.395-3.72C3.512 15.042 3 13.574 3 12c0-4.418 4.03-8 9-8s9 3.582 9 8z"/></svg>
|
|
540
|
+
</div>
|
|
541
|
+
<h2 class="text-xl font-semibold text-white mb-2">Start a conversation</h2>
|
|
542
|
+
<p class="text-gray-500 text-sm">Type a message below to chat with your AI assistant.</p>
|
|
543
|
+
</div>
|
|
544
|
+
</div>
|
|
545
|
+
<div class="flex-shrink-0 border-t border-gray-800 px-4 py-4">
|
|
546
|
+
<form id="chatForm" class="flex gap-3">
|
|
547
|
+
<input id="chatInput" type="text" placeholder="Type your message..." autocomplete="off" class="flex-1 bg-gray-900 border border-gray-700 rounded-xl px-4 py-3 text-sm text-white placeholder-gray-500 focus:outline-none focus:border-blue-500 focus:ring-1 focus:ring-blue-500 transition-colors" />
|
|
548
|
+
<button type="submit" id="sendBtn" class="px-5 py-3 bg-blue-600 hover:bg-blue-500 disabled:bg-gray-700 disabled:text-gray-500 text-white text-sm font-medium rounded-xl transition-colors">Send</button>
|
|
549
|
+
</form>
|
|
550
|
+
</div>
|
|
551
|
+
</div>
|
|
552
|
+
<script>
|
|
553
|
+
const messages=[], messagesEl=document.getElementById("messages"), form=document.getElementById("chatForm"), input=document.getElementById("chatInput"), sendBtn=document.getElementById("sendBtn");
|
|
554
|
+
function addMsg(role,content){const d=document.createElement("div");d.className="msg-enter flex "+(role==="user"?"justify-end":"justify-start");const b=document.createElement("div");b.className=role==="user"?"max-w-[75%] px-4 py-2.5 rounded-2xl rounded-br-md bg-blue-600 text-white text-sm leading-relaxed":"max-w-[75%] px-4 py-2.5 rounded-2xl rounded-bl-md bg-gray-800 text-gray-200 text-sm leading-relaxed";b.textContent=content;d.appendChild(b);const w=messagesEl.querySelector(".text-center.py-12");if(w)w.remove();messagesEl.appendChild(d);messagesEl.scrollTop=messagesEl.scrollHeight;return b}
|
|
555
|
+
form.addEventListener("submit",async e=>{e.preventDefault();const text=input.value.trim();if(!text)return;messages.push({role:"user",content:text});addMsg("user",text);input.value="";sendBtn.disabled=true;try{const res=await fetch("/api/chat",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({messages,conversationId:"default"})});if(!res.ok){addMsg("assistant","Error: "+res.status);sendBtn.disabled=false;return}const bubble=addMsg("assistant","");const reader=res.body.getReader();const dec=new TextDecoder();let full="";while(true){const{done,value}=await reader.read();if(done)break;const chunk=dec.decode(value,{stream:true});for(const line of chunk.split("\\n")){if(line.startsWith("data: ")){const d=line.slice(6);if(d==="[DONE]")continue;try{const p=JSON.parse(d);const t=p.textDelta||p.choices?.[0]?.delta?.content||p.content||p.text||"";full+=t;bubble.textContent=full;messagesEl.scrollTop=messagesEl.scrollHeight}catch{}}}}messages.push({role:"assistant",content:full})}catch(err){addMsg("assistant","Error: "+err.message)}sendBtn.disabled=false;input.focus()});
|
|
556
|
+
input.focus();
|
|
557
|
+
</script>`;
|
|
558
|
+
}
|
|
559
|
+
function ragAppBody() {
|
|
560
|
+
return ` <div class="h-full flex flex-col md:flex-row">
|
|
561
|
+
<div class="md:w-80 flex-shrink-0 border-b md:border-b-0 md:border-r border-gray-800 flex flex-col">
|
|
562
|
+
<div class="px-4 py-3 border-b border-gray-800"><h2 class="text-sm font-semibold text-white flex items-center gap-2"><svg class="w-4 h-4 text-emerald-400" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M7 16a4 4 0 01-.88-7.903A5 5 0 1115.9 6L16 6a5 5 0 011 9.9M15 13l-3-3m0 0l-3 3m3-3v12"/></svg>Ingest Documents</h2></div>
|
|
563
|
+
<div class="flex-1 p-4 flex flex-col gap-3">
|
|
564
|
+
<textarea id="ingestText" rows="6" placeholder="Paste text to ingest..." class="w-full bg-gray-900 border border-gray-700 rounded-lg px-3 py-2 text-sm text-white placeholder-gray-500 focus:outline-none focus:border-emerald-500 resize-none"></textarea>
|
|
565
|
+
<button id="ingestBtn" onclick="ingestDoc()" class="w-full py-2.5 bg-emerald-600 hover:bg-emerald-500 disabled:bg-gray-700 disabled:text-gray-500 text-white text-sm font-medium rounded-lg transition-colors">Ingest</button>
|
|
566
|
+
<div id="ingestStatus" class="text-xs text-gray-500 hidden"></div>
|
|
567
|
+
<div class="mt-auto pt-3 border-t border-gray-800"><p class="text-xs text-gray-600">Documents are chunked, embedded, and stored for retrieval.</p></div>
|
|
568
|
+
</div>
|
|
569
|
+
</div>
|
|
570
|
+
<div class="flex-1 flex flex-col min-w-0">
|
|
571
|
+
<div id="ragMessages" class="flex-1 overflow-y-auto px-4 py-6 space-y-4">
|
|
572
|
+
<div class="text-center py-12">
|
|
573
|
+
<div class="w-16 h-16 mx-auto mb-4 rounded-2xl bg-gradient-to-br from-emerald-500/20 to-blue-600/20 border border-emerald-500/20 flex items-center justify-center"><svg class="w-8 h-8 text-emerald-400" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5" d="M9 12h6m-6 4h6m2 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z"/></svg></div>
|
|
574
|
+
<h2 class="text-xl font-semibold text-white mb-2">Ask your documents</h2>
|
|
575
|
+
<p class="text-gray-500 text-sm">Ingest documents on the left, then ask questions here.</p>
|
|
576
|
+
</div>
|
|
577
|
+
</div>
|
|
578
|
+
<div class="flex-shrink-0 border-t border-gray-800 px-4 py-4">
|
|
579
|
+
<form id="ragForm" class="flex gap-3">
|
|
580
|
+
<input id="ragInput" type="text" placeholder="Ask about your documents..." autocomplete="off" class="flex-1 bg-gray-900 border border-gray-700 rounded-xl px-4 py-3 text-sm text-white placeholder-gray-500 focus:outline-none focus:border-emerald-500 focus:ring-1 focus:ring-emerald-500 transition-colors" />
|
|
581
|
+
<button type="submit" id="ragSendBtn" class="px-5 py-3 bg-emerald-600 hover:bg-emerald-500 disabled:bg-gray-700 disabled:text-gray-500 text-white text-sm font-medium rounded-xl transition-colors">Ask</button>
|
|
582
|
+
</form>
|
|
583
|
+
</div>
|
|
584
|
+
</div>
|
|
585
|
+
</div>
|
|
586
|
+
<script>
|
|
587
|
+
const ragEl=document.getElementById("ragMessages");
|
|
588
|
+
function addRagMsg(role,c){const d=document.createElement("div");d.className="msg-enter flex "+(role==="user"?"justify-end":"justify-start");const b=document.createElement("div");b.className=role==="user"?"max-w-[75%] px-4 py-2.5 rounded-2xl rounded-br-md bg-emerald-600 text-white text-sm leading-relaxed":"max-w-[75%] px-4 py-2.5 rounded-2xl rounded-bl-md bg-gray-800 text-gray-200 text-sm leading-relaxed";b.textContent=c;d.appendChild(b);const w=ragEl.querySelector(".text-center.py-12");if(w)w.remove();ragEl.appendChild(d);ragEl.scrollTop=ragEl.scrollHeight;return b}
|
|
589
|
+
async function ingestDoc(){const text=document.getElementById("ingestText").value.trim();if(!text)return;const btn=document.getElementById("ingestBtn"),st=document.getElementById("ingestStatus");btn.disabled=true;btn.textContent="Ingesting...";st.className="text-xs text-yellow-400";st.textContent="Processing...";st.classList.remove("hidden");try{const res=await fetch("/api/rag/ingest",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({text})});const data=await res.json();if(res.ok){st.className="text-xs text-emerald-400";st.textContent="Ingested "+(data.chunks||0)+" chunks.";document.getElementById("ingestText").value=""}else{st.className="text-xs text-red-400";st.textContent="Error: "+(data.error||res.statusText)}}catch(e){st.className="text-xs text-red-400";st.textContent="Error: "+e.message}btn.disabled=false;btn.textContent="Ingest"}
|
|
590
|
+
document.getElementById("ragForm").addEventListener("submit",async e=>{e.preventDefault();const input=document.getElementById("ragInput"),text=input.value.trim();if(!text)return;addRagMsg("user",text);input.value="";document.getElementById("ragSendBtn").disabled=true;try{const res=await fetch("/api/rag/query",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({question:text})});if(!res.ok){addRagMsg("assistant","Error: "+res.status);document.getElementById("ragSendBtn").disabled=false;return}const bubble=addRagMsg("assistant","");const reader=res.body.getReader();const dec=new TextDecoder();let full="";while(true){const{done,value}=await reader.read();if(done)break;const chunk=dec.decode(value,{stream:true});for(const line of chunk.split("\\n")){if(line.startsWith("data: ")){const d=line.slice(6);if(d==="[DONE]")continue;try{const p=JSON.parse(d);const t=p.textDelta||p.choices?.[0]?.delta?.content||p.content||p.text||"";full+=t;bubble.textContent=full;ragEl.scrollTop=ragEl.scrollHeight}catch{}}}};}catch(err){addRagMsg("assistant","Error: "+err.message)}document.getElementById("ragSendBtn").disabled=false;document.getElementById("ragInput").focus()});
|
|
591
|
+
document.getElementById("ragInput").focus();
|
|
592
|
+
</script>`;
|
|
593
|
+
}
|
|
594
|
+
function agentAppBody() {
|
|
595
|
+
return ` <div class="h-full flex flex-col">
|
|
596
|
+
<div id="agentMessages" class="flex-1 overflow-y-auto px-4 py-6 space-y-4">
|
|
597
|
+
<div class="text-center py-12">
|
|
598
|
+
<div class="w-16 h-16 mx-auto mb-4 rounded-2xl bg-gradient-to-br from-purple-500/20 to-orange-500/20 border border-purple-500/20 flex items-center justify-center"><svg class="w-8 h-8 text-purple-400" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5" d="M9.75 17L9 20l-1 1h8l-1-1-.75-3M3 13h18M5 17h14a2 2 0 002-2V5a2 2 0 00-2-2H5a2 2 0 00-2 2v10a2 2 0 002 2z"/></svg></div>
|
|
599
|
+
<h2 class="text-xl font-semibold text-white mb-2">AI Agent</h2>
|
|
600
|
+
<p class="text-gray-500 text-sm">Your agent can use tools to answer questions accurately.</p>
|
|
601
|
+
</div>
|
|
602
|
+
</div>
|
|
603
|
+
<div class="flex-shrink-0 border-t border-gray-800 px-4 py-4">
|
|
604
|
+
<form id="agentForm" class="flex gap-3">
|
|
605
|
+
<input id="agentInput" type="text" placeholder="Ask the agent anything..." autocomplete="off" class="flex-1 bg-gray-900 border border-gray-700 rounded-xl px-4 py-3 text-sm text-white placeholder-gray-500 focus:outline-none focus:border-purple-500 focus:ring-1 focus:ring-purple-500 transition-colors" />
|
|
606
|
+
<button type="submit" id="agentSendBtn" class="px-5 py-3 bg-purple-600 hover:bg-purple-500 disabled:bg-gray-700 disabled:text-gray-500 text-white text-sm font-medium rounded-xl transition-colors">Run</button>
|
|
607
|
+
</form>
|
|
608
|
+
</div>
|
|
609
|
+
</div>
|
|
610
|
+
<script>
|
|
611
|
+
const agentEl=document.getElementById("agentMessages");
|
|
612
|
+
function addAgentMsg(role,c,isStep){const d=document.createElement("div");d.className="msg-enter flex "+(role==="user"?"justify-end":"justify-start");const b=document.createElement("div");if(isStep){b.className="max-w-[85%] px-3 py-2 rounded-lg bg-gray-900 border border-gray-700 text-xs text-gray-400 font-mono"}else{b.className=role==="user"?"max-w-[75%] px-4 py-2.5 rounded-2xl rounded-br-md bg-purple-600 text-white text-sm leading-relaxed":"max-w-[75%] px-4 py-2.5 rounded-2xl rounded-bl-md bg-gray-800 text-gray-200 text-sm leading-relaxed whitespace-pre-wrap"}b.textContent=c;d.appendChild(b);const w=agentEl.querySelector(".text-center.py-12");if(w)w.remove();agentEl.appendChild(d);agentEl.scrollTop=agentEl.scrollHeight;return b}
|
|
613
|
+
function addThinking(){const d=document.createElement("div");d.id="thinking";d.className="msg-enter flex justify-start";d.innerHTML='<div class="px-4 py-2.5 rounded-2xl rounded-bl-md bg-gray-800 flex items-center gap-2 text-sm text-gray-400"><svg class="w-4 h-4 animate-spin" fill="none" viewBox="0 0 24 24"><circle class="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" stroke-width="4"></circle><path class="opacity-75" fill="currentColor" d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4z"></path></svg>Agent is thinking...</div>';agentEl.appendChild(d);agentEl.scrollTop=agentEl.scrollHeight}
|
|
614
|
+
function removeThinking(){const t=document.getElementById("thinking");if(t)t.remove()}
|
|
615
|
+
document.getElementById("agentForm").addEventListener("submit",async e=>{e.preventDefault();const input=document.getElementById("agentInput"),text=input.value.trim();if(!text)return;addAgentMsg("user",text);input.value="";document.getElementById("agentSendBtn").disabled=true;addThinking();try{const res=await fetch("/api/agent",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({input:text})});removeThinking();if(!res.ok){const err=await res.json().catch(()=>({}));addAgentMsg("assistant","Error: "+(err.error||res.statusText));document.getElementById("agentSendBtn").disabled=false;return}const data=await res.json();if(data.steps&&data.steps.length>0){for(const s of data.steps){const name=s.tool||s.name||"tool";const inp=typeof s.input==="string"?s.input:JSON.stringify(s.input||{});const out=typeof s.output==="string"?s.output:JSON.stringify(s.output||{});addAgentMsg("assistant","\u{1F527} "+name+"("+inp+")\\n\u2192 "+out.slice(0,300),true)}}addAgentMsg("assistant",data.content||"No response.")}catch(err){removeThinking();addAgentMsg("assistant","Error: "+err.message)}document.getElementById("agentSendBtn").disabled=false;input.focus()});
|
|
616
|
+
document.getElementById("agentInput").focus();
|
|
617
|
+
</script>`;
|
|
618
|
+
}
|
|
619
|
+
if (typeof require !== "undefined" && require.main === module && process.argv[1]?.includes("create")) {
|
|
528
620
|
const projectName = process.argv[2];
|
|
529
621
|
if (!projectName) {
|
|
530
622
|
console.log("Usage: create-voltx-app <project-name> [--template chatbot] [--auth jwt]");
|
|
@@ -934,7 +1026,7 @@ import { createAgent } from "@voltx/agents";
|
|
|
934
1026
|
|
|
935
1027
|
export const ${toCamelCase(name)} = createAgent({
|
|
936
1028
|
name: "${name}",
|
|
937
|
-
model: "cerebras:
|
|
1029
|
+
model: "cerebras:llama3.1-8b",
|
|
938
1030
|
instructions: "You are a helpful AI assistant named ${name}.",
|
|
939
1031
|
tools: [
|
|
940
1032
|
// Add tools here:
|
|
@@ -1017,7 +1109,7 @@ function toCamelCase(str) {
|
|
|
1017
1109
|
}
|
|
1018
1110
|
|
|
1019
1111
|
// src/index.ts
|
|
1020
|
-
var CLI_VERSION = "0.3.
|
|
1112
|
+
var CLI_VERSION = "0.3.5";
|
|
1021
1113
|
// Annotate the CommonJS export names for ESM import in node:
|
|
1022
1114
|
0 && (module.exports = {
|
|
1023
1115
|
CLI_VERSION,
|
package/dist/index.mjs
CHANGED
|
@@ -3,13 +3,13 @@ import {
|
|
|
3
3
|
} from "./chunk-ZB2F3WTS.mjs";
|
|
4
4
|
import {
|
|
5
5
|
createProject
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-P5FSO2UH.mjs";
|
|
7
7
|
import {
|
|
8
8
|
runDev
|
|
9
9
|
} from "./chunk-QND74HUW.mjs";
|
|
10
10
|
import {
|
|
11
11
|
runGenerate
|
|
12
|
-
} from "./chunk-
|
|
12
|
+
} from "./chunk-HAFJKS2O.mjs";
|
|
13
13
|
import {
|
|
14
14
|
runStart
|
|
15
15
|
} from "./chunk-BXHQORLN.mjs";
|
|
@@ -17,7 +17,7 @@ import "./chunk-IV352HZA.mjs";
|
|
|
17
17
|
import "./chunk-Y6FXYEAI.mjs";
|
|
18
18
|
|
|
19
19
|
// src/index.ts
|
|
20
|
-
var CLI_VERSION = "0.3.
|
|
20
|
+
var CLI_VERSION = "0.3.5";
|
|
21
21
|
export {
|
|
22
22
|
CLI_VERSION,
|
|
23
23
|
createProject,
|