@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/cli.js
CHANGED
|
@@ -153,62 +153,26 @@ async function createProject(options) {
|
|
|
153
153
|
process.exit(1);
|
|
154
154
|
}
|
|
155
155
|
fs.mkdirSync(targetDir, { recursive: true });
|
|
156
|
-
const
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
"@voltx/core": "^0.3.0",
|
|
169
|
-
"@voltx/ai": "^0.3.0",
|
|
170
|
-
"@voltx/server": "^0.3.0",
|
|
171
|
-
"@voltx/rag": "^0.3.0",
|
|
172
|
-
"@voltx/db": "^0.3.0"
|
|
173
|
-
},
|
|
174
|
-
"agent-app": {
|
|
175
|
-
"@voltx/core": "^0.3.0",
|
|
176
|
-
"@voltx/ai": "^0.3.0",
|
|
177
|
-
"@voltx/server": "^0.3.0",
|
|
178
|
-
"@voltx/agents": "^0.3.0",
|
|
179
|
-
"@voltx/memory": "^0.3.0"
|
|
180
|
-
}
|
|
181
|
-
};
|
|
182
|
-
const packageJson = {
|
|
156
|
+
const provider = template === "rag-app" ? "openai" : "cerebras";
|
|
157
|
+
const model = template === "rag-app" ? "gpt-4o" : "llama3.1-8b";
|
|
158
|
+
const hasDb = template === "rag-app" || template === "agent-app" || auth === "better-auth";
|
|
159
|
+
const deps = { ...TEMPLATE_DEPS[template] ?? TEMPLATE_DEPS["blank"], "@voltx/cli": V };
|
|
160
|
+
if (auth === "better-auth") {
|
|
161
|
+
deps["@voltx/auth"] = V;
|
|
162
|
+
deps["better-auth"] = "^1.5.0";
|
|
163
|
+
} else if (auth === "jwt") {
|
|
164
|
+
deps["@voltx/auth"] = V;
|
|
165
|
+
deps["jose"] = "^6.0.0";
|
|
166
|
+
}
|
|
167
|
+
fs.writeFileSync(path.join(targetDir, "package.json"), JSON.stringify({
|
|
183
168
|
name,
|
|
184
169
|
version: "0.1.0",
|
|
185
170
|
private: true,
|
|
186
|
-
scripts: {
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
dependencies: {
|
|
192
|
-
...templateDeps[template] ?? templateDeps["blank"],
|
|
193
|
-
"@voltx/cli": "^0.3.0",
|
|
194
|
-
...auth === "better-auth" ? { "@voltx/auth": "^0.3.0", "better-auth": "^1.5.0" } : {},
|
|
195
|
-
...auth === "jwt" ? { "@voltx/auth": "^0.3.0", "jose": "^6.0.0" } : {}
|
|
196
|
-
},
|
|
197
|
-
devDependencies: {
|
|
198
|
-
typescript: "^5.7.0",
|
|
199
|
-
tsx: "^4.21.0",
|
|
200
|
-
tsup: "^8.0.0",
|
|
201
|
-
"@types/node": "^22.0.0"
|
|
202
|
-
}
|
|
203
|
-
};
|
|
204
|
-
fs.writeFileSync(
|
|
205
|
-
path.join(targetDir, "package.json"),
|
|
206
|
-
JSON.stringify(packageJson, null, 2)
|
|
207
|
-
);
|
|
208
|
-
const hasDb = template === "rag-app" || template === "agent-app" || auth === "better-auth";
|
|
209
|
-
const provider = template === "rag-app" ? "openai" : "cerebras";
|
|
210
|
-
const model = template === "rag-app" ? "gpt-4o" : "llama-4-scout-17b-16e";
|
|
211
|
-
let configContent = `import { defineConfig } from "@voltx/core";
|
|
171
|
+
scripts: { dev: "voltx dev", build: "voltx build", start: "voltx start" },
|
|
172
|
+
dependencies: deps,
|
|
173
|
+
devDependencies: { typescript: "^5.7.0", tsx: "^4.21.0", tsup: "^8.0.0", "@types/node": "^22.0.0" }
|
|
174
|
+
}, null, 2));
|
|
175
|
+
let config = `import { defineConfig } from "@voltx/core";
|
|
212
176
|
|
|
213
177
|
export default defineConfig({
|
|
214
178
|
name: "${name}",
|
|
@@ -217,19 +181,15 @@ export default defineConfig({
|
|
|
217
181
|
provider: "${provider}",
|
|
218
182
|
model: "${model}",
|
|
219
183
|
},`;
|
|
220
|
-
if (hasDb)
|
|
221
|
-
configContent += `
|
|
184
|
+
if (hasDb) config += `
|
|
222
185
|
db: {
|
|
223
186
|
url: process.env.DATABASE_URL,
|
|
224
187
|
},`;
|
|
225
|
-
|
|
226
|
-
if (auth !== "none") {
|
|
227
|
-
configContent += `
|
|
188
|
+
if (auth !== "none") config += `
|
|
228
189
|
auth: {
|
|
229
190
|
provider: "${auth}",
|
|
230
191
|
},`;
|
|
231
|
-
|
|
232
|
-
configContent += `
|
|
192
|
+
config += `
|
|
233
193
|
server: {
|
|
234
194
|
routesDir: "src/routes",
|
|
235
195
|
staticDir: "public",
|
|
@@ -237,9 +197,13 @@ export default defineConfig({
|
|
|
237
197
|
},
|
|
238
198
|
});
|
|
239
199
|
`;
|
|
240
|
-
fs.writeFileSync(path.join(targetDir, "voltx.config.ts"),
|
|
200
|
+
fs.writeFileSync(path.join(targetDir, "voltx.config.ts"), config);
|
|
241
201
|
fs.mkdirSync(path.join(targetDir, "src", "routes", "api"), { recursive: true });
|
|
242
202
|
fs.mkdirSync(path.join(targetDir, "public"), { recursive: true });
|
|
203
|
+
fs.writeFileSync(path.join(targetDir, "tsconfig.json"), JSON.stringify({
|
|
204
|
+
compilerOptions: { target: "ES2022", module: "ESNext", moduleResolution: "bundler", strict: true, esModuleInterop: true, skipLibCheck: true, outDir: "dist" },
|
|
205
|
+
include: ["src", "voltx.config.ts"]
|
|
206
|
+
}, null, 2));
|
|
243
207
|
fs.writeFileSync(
|
|
244
208
|
path.join(targetDir, "src", "index.ts"),
|
|
245
209
|
`import { createApp } from "@voltx/core";
|
|
@@ -267,19 +231,16 @@ import type { Context } from "@voltx/server";
|
|
|
267
231
|
import { streamText } from "@voltx/ai";
|
|
268
232
|
import { createMemory } from "@voltx/memory";
|
|
269
233
|
|
|
270
|
-
// In-memory for dev; swap to createMemory("postgres", { url }) for production
|
|
271
234
|
const memory = createMemory({ maxMessages: 50 });
|
|
272
235
|
|
|
273
236
|
export async function POST(c: Context) {
|
|
274
237
|
const { messages, conversationId = "default" } = await c.req.json();
|
|
275
238
|
|
|
276
|
-
// Store the latest user message
|
|
277
239
|
const lastMessage = messages[messages.length - 1];
|
|
278
240
|
if (lastMessage?.role === "user") {
|
|
279
241
|
await memory.add(conversationId, { role: "user", content: lastMessage.content });
|
|
280
242
|
}
|
|
281
243
|
|
|
282
|
-
// Get conversation history from memory
|
|
283
244
|
const history = await memory.get(conversationId);
|
|
284
245
|
|
|
285
246
|
const result = await streamText({
|
|
@@ -288,7 +249,6 @@ export async function POST(c: Context) {
|
|
|
288
249
|
messages: history.map((m) => ({ role: m.role, content: m.content })),
|
|
289
250
|
});
|
|
290
251
|
|
|
291
|
-
// Store assistant response after stream completes
|
|
292
252
|
result.text.then(async (text) => {
|
|
293
253
|
await memory.add(conversationId, { role: "assistant", content: text });
|
|
294
254
|
});
|
|
@@ -301,41 +261,69 @@ export async function POST(c: Context) {
|
|
|
301
261
|
if (template === "agent-app") {
|
|
302
262
|
fs.mkdirSync(path.join(targetDir, "src", "agents"), { recursive: true });
|
|
303
263
|
fs.mkdirSync(path.join(targetDir, "src", "tools"), { recursive: true });
|
|
304
|
-
fs.writeFileSync(
|
|
305
|
-
|
|
306
|
-
`import { createAgent } from "@voltx/agents";
|
|
307
|
-
import { searchTool } from "../tools/search";
|
|
264
|
+
fs.writeFileSync(path.join(targetDir, "src", "tools", "calculator.ts"), `// Calculator tool \u2014 evaluates math expressions (no API key needed)
|
|
265
|
+
import type { Tool } from "@voltx/agents";
|
|
308
266
|
|
|
309
|
-
export const
|
|
310
|
-
name: "
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
267
|
+
export const calculatorTool: Tool = {
|
|
268
|
+
name: "calculator",
|
|
269
|
+
description: "Evaluate a math expression. Supports +, -, *, /, %, parentheses, and Math functions.",
|
|
270
|
+
parameters: {
|
|
271
|
+
type: "object",
|
|
272
|
+
properties: { expression: { type: "string", description: "The math expression to evaluate" } },
|
|
273
|
+
required: ["expression"],
|
|
274
|
+
},
|
|
275
|
+
async execute(args: { expression: string }) {
|
|
276
|
+
try {
|
|
277
|
+
const safe = args.expression.replace(/[^0-9+\\-*/.()%\\s,]|(?<!Math)\\.[a-z]/gi, (match) => {
|
|
278
|
+
if (args.expression.includes("Math.")) return match;
|
|
279
|
+
throw new Error("Invalid character: " + match);
|
|
280
|
+
});
|
|
281
|
+
const result = new Function("return " + safe)();
|
|
282
|
+
return \`\${args.expression} = \${result}\`;
|
|
283
|
+
} catch (err) {
|
|
284
|
+
return \`Error: \${err instanceof Error ? err.message : String(err)}\`;
|
|
285
|
+
}
|
|
286
|
+
},
|
|
287
|
+
};
|
|
288
|
+
`);
|
|
289
|
+
fs.writeFileSync(path.join(targetDir, "src", "tools", "datetime.ts"), `// Date & time tool \u2014 returns current date, time, timezone (no API key needed)
|
|
290
|
+
import type { Tool } from "@voltx/agents";
|
|
321
291
|
|
|
322
|
-
export const
|
|
323
|
-
name: "
|
|
324
|
-
description: "
|
|
292
|
+
export const datetimeTool: Tool = {
|
|
293
|
+
name: "datetime",
|
|
294
|
+
description: "Get the current date, time, day of week, and timezone.",
|
|
325
295
|
parameters: {
|
|
326
296
|
type: "object",
|
|
327
|
-
properties: {
|
|
328
|
-
required: ["query"],
|
|
297
|
+
properties: { timezone: { type: "string", description: "Optional IANA timezone. Defaults to server timezone." } },
|
|
329
298
|
},
|
|
330
|
-
async execute(args: {
|
|
331
|
-
|
|
299
|
+
async execute(args: { timezone?: string }) {
|
|
300
|
+
const now = new Date();
|
|
301
|
+
const tz = args.timezone || Intl.DateTimeFormat().resolvedOptions().timeZone;
|
|
302
|
+
const formatted = now.toLocaleString("en-US", {
|
|
303
|
+
timeZone: tz, weekday: "long", year: "numeric", month: "long", day: "numeric",
|
|
304
|
+
hour: "2-digit", minute: "2-digit", second: "2-digit", hour12: true,
|
|
305
|
+
});
|
|
306
|
+
return \`Current date/time (\${tz}): \${formatted}\`;
|
|
332
307
|
},
|
|
333
308
|
};
|
|
334
|
-
`
|
|
335
|
-
)
|
|
309
|
+
`);
|
|
310
|
+
fs.writeFileSync(path.join(targetDir, "src", "agents", "assistant.ts"), `// AI Agent \u2014 autonomous assistant with tools
|
|
311
|
+
import { createAgent } from "@voltx/agents";
|
|
312
|
+
import { calculatorTool } from "../tools/calculator";
|
|
313
|
+
import { datetimeTool } from "../tools/datetime";
|
|
314
|
+
|
|
315
|
+
export const assistant = createAgent({
|
|
316
|
+
name: "assistant",
|
|
317
|
+
model: "${provider}:${model}",
|
|
318
|
+
instructions: "You are a helpful AI assistant with access to tools: Calculator, Date & Time. Use them when needed to answer questions accurately.",
|
|
319
|
+
tools: [calculatorTool, datetimeTool],
|
|
320
|
+
maxIterations: 5,
|
|
321
|
+
});
|
|
322
|
+
`);
|
|
336
323
|
fs.writeFileSync(
|
|
337
324
|
path.join(targetDir, "src", "routes", "api", "agent.ts"),
|
|
338
|
-
|
|
325
|
+
`// POST /api/agent \u2014 Run the AI agent
|
|
326
|
+
import type { Context } from "@voltx/server";
|
|
339
327
|
import { assistant } from "../../agents/assistant";
|
|
340
328
|
|
|
341
329
|
export async function POST(c: Context) {
|
|
@@ -358,21 +346,18 @@ import { streamText } from "@voltx/ai";
|
|
|
358
346
|
import { createRAGPipeline, createEmbedder } from "@voltx/rag";
|
|
359
347
|
import { createVectorStore } from "@voltx/db";
|
|
360
348
|
|
|
361
|
-
const vectorStore = createVectorStore();
|
|
349
|
+
const vectorStore = createVectorStore();
|
|
362
350
|
const embedder = createEmbedder({ model: "${embedModel}" });
|
|
363
351
|
const rag = createRAGPipeline({ embedder, vectorStore });
|
|
364
352
|
|
|
365
353
|
export async function POST(c: Context) {
|
|
366
354
|
const { question } = await c.req.json();
|
|
367
|
-
|
|
368
355
|
const context = await rag.getContext(question, { topK: 5 });
|
|
369
|
-
|
|
370
356
|
const result = await streamText({
|
|
371
357
|
model: "${provider}:${model}",
|
|
372
|
-
system: \`Answer
|
|
358
|
+
system: \`Answer based on context. If not relevant, say so.\\n\\nContext:\\n\${context}\`,
|
|
373
359
|
messages: [{ role: "user", content: question }],
|
|
374
360
|
});
|
|
375
|
-
|
|
376
361
|
return result.toSSEResponse();
|
|
377
362
|
}
|
|
378
363
|
`
|
|
@@ -390,11 +375,7 @@ const rag = createRAGPipeline({ embedder, vectorStore });
|
|
|
390
375
|
|
|
391
376
|
export async function POST(c: Context) {
|
|
392
377
|
const { text, idPrefix } = await c.req.json();
|
|
393
|
-
|
|
394
|
-
if (!text || typeof text !== "string") {
|
|
395
|
-
return c.json({ error: "Missing 'text' field" }, 400);
|
|
396
|
-
}
|
|
397
|
-
|
|
378
|
+
if (!text || typeof text !== "string") return c.json({ error: "Missing 'text' field" }, 400);
|
|
398
379
|
const result = await rag.ingest(text, idPrefix ?? "doc");
|
|
399
380
|
return c.json({ status: "ok", chunks: result.chunks, ids: result.ids });
|
|
400
381
|
}
|
|
@@ -419,8 +400,7 @@ export const POST = (c: Context) => handler(c);
|
|
|
419
400
|
fs.mkdirSync(path.join(targetDir, "src", "lib"), { recursive: true });
|
|
420
401
|
fs.writeFileSync(
|
|
421
402
|
path.join(targetDir, "src", "lib", "auth.ts"),
|
|
422
|
-
|
|
423
|
-
import { createAuth, createAuthMiddleware } from "@voltx/auth";
|
|
403
|
+
`import { createAuth, createAuthMiddleware } from "@voltx/auth";
|
|
424
404
|
|
|
425
405
|
export const auth = createAuth("better-auth", {
|
|
426
406
|
database: process.env.DATABASE_URL!,
|
|
@@ -437,8 +417,7 @@ export const authMiddleware = createAuthMiddleware({
|
|
|
437
417
|
fs.mkdirSync(path.join(targetDir, "src", "lib"), { recursive: true });
|
|
438
418
|
fs.writeFileSync(
|
|
439
419
|
path.join(targetDir, "src", "lib", "auth.ts"),
|
|
440
|
-
|
|
441
|
-
import { createAuth, createAuthMiddleware } from "@voltx/auth";
|
|
420
|
+
`import { createAuth, createAuthMiddleware } from "@voltx/auth";
|
|
442
421
|
|
|
443
422
|
export const jwt = createAuth("jwt", {
|
|
444
423
|
secret: process.env.JWT_SECRET!,
|
|
@@ -453,17 +432,12 @@ export const authMiddleware = createAuthMiddleware({
|
|
|
453
432
|
);
|
|
454
433
|
fs.writeFileSync(
|
|
455
434
|
path.join(targetDir, "src", "routes", "api", "auth.ts"),
|
|
456
|
-
|
|
457
|
-
import type { Context } from "@voltx/server";
|
|
435
|
+
`import type { Context } from "@voltx/server";
|
|
458
436
|
import { jwt } from "../../lib/auth";
|
|
459
437
|
|
|
460
438
|
export async function POST(c: Context) {
|
|
461
439
|
const { email, password } = await c.req.json();
|
|
462
|
-
|
|
463
|
-
if (!email || !password) {
|
|
464
|
-
return c.json({ error: "Email and password are required" }, 400);
|
|
465
|
-
}
|
|
466
|
-
|
|
440
|
+
if (!email || !password) return c.json({ error: "Email and password are required" }, 400);
|
|
467
441
|
const token = await jwt.sign({ sub: email, email });
|
|
468
442
|
return c.json({ token });
|
|
469
443
|
}
|
|
@@ -473,62 +447,180 @@ export async function POST(c: Context) {
|
|
|
473
447
|
let envContent = "";
|
|
474
448
|
if (template === "rag-app") {
|
|
475
449
|
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";
|
|
476
|
-
envContent += "# \u2500\u2500\u2500 Database
|
|
477
|
-
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";
|
|
450
|
+
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";
|
|
478
451
|
} else if (template === "chatbot" || template === "agent-app") {
|
|
479
452
|
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";
|
|
480
453
|
if (template === "agent-app") {
|
|
481
|
-
envContent += "# \u2500\u2500\u2500 Database (
|
|
454
|
+
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";
|
|
455
|
+
envContent += "# \u2500\u2500\u2500 Tool API Keys (add keys for tools you use) \u2500\u2500\n";
|
|
456
|
+
envContent += "# TAVILY_API_KEY=tvly-... (Web Search \u2014 https://tavily.com)\n";
|
|
457
|
+
envContent += "# SERPER_API_KEY= (Google Search \u2014 https://serper.dev)\n";
|
|
458
|
+
envContent += "# OPENWEATHER_API_KEY= (Weather \u2014 https://openweathermap.org/api)\n";
|
|
459
|
+
envContent += "# NEWS_API_KEY= (News \u2014 https://newsapi.org)\n\n";
|
|
482
460
|
}
|
|
483
461
|
} else {
|
|
484
|
-
envContent += "# \u2500\u2500\u2500 LLM Provider
|
|
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\n# OPENAI_API_KEY=sk-...\n# CEREBRAS_API_KEY=csk-...\n\n";
|
|
485
463
|
}
|
|
486
464
|
if (auth === "better-auth") {
|
|
487
|
-
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";
|
|
488
|
-
if (template !== "rag-app" && template !== "agent-app") {
|
|
489
|
-
envContent += "DATABASE_URL=postgresql://user:pass@ep-xxx.us-east-2.aws.neon.tech/dbname?sslmode=require\n";
|
|
490
|
-
}
|
|
491
|
-
envContent += "# GITHUB_CLIENT_ID=\n# GITHUB_CLIENT_SECRET=\n\n";
|
|
465
|
+
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";
|
|
492
466
|
} else if (auth === "jwt") {
|
|
493
467
|
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";
|
|
494
468
|
}
|
|
495
469
|
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";
|
|
496
470
|
fs.writeFileSync(path.join(targetDir, ".env.example"), envContent);
|
|
497
|
-
|
|
498
|
-
path.join(targetDir, ".
|
|
499
|
-
|
|
500
|
-
);
|
|
501
|
-
fs.writeFileSync(
|
|
502
|
-
path.join(targetDir, "tsconfig.json"),
|
|
503
|
-
JSON.stringify(
|
|
504
|
-
{
|
|
505
|
-
compilerOptions: {
|
|
506
|
-
target: "ES2022",
|
|
507
|
-
module: "ESNext",
|
|
508
|
-
moduleResolution: "bundler",
|
|
509
|
-
strict: true,
|
|
510
|
-
esModuleInterop: true,
|
|
511
|
-
skipLibCheck: true,
|
|
512
|
-
outDir: "dist",
|
|
513
|
-
rootDir: "src"
|
|
514
|
-
},
|
|
515
|
-
include: ["src"]
|
|
516
|
-
},
|
|
517
|
-
null,
|
|
518
|
-
2
|
|
519
|
-
)
|
|
520
|
-
);
|
|
471
|
+
if (template !== "blank") {
|
|
472
|
+
fs.writeFileSync(path.join(targetDir, "public", "index.html"), generateFrontendHTML(name, template));
|
|
473
|
+
}
|
|
474
|
+
fs.writeFileSync(path.join(targetDir, ".gitignore"), "node_modules\ndist\n.env\n");
|
|
521
475
|
printWelcomeBanner(name);
|
|
522
476
|
}
|
|
523
|
-
|
|
477
|
+
function generateFrontendHTML(projectName, template) {
|
|
478
|
+
const badge = template === "chatbot" ? "Chatbot" : template === "rag-app" ? "RAG App" : "Agent App";
|
|
479
|
+
const accentClass = template === "rag-app" ? "emerald" : template === "agent-app" ? "purple" : "blue";
|
|
480
|
+
const shell = (body) => `<!DOCTYPE html>
|
|
481
|
+
<html lang="en" class="h-full">
|
|
482
|
+
<head>
|
|
483
|
+
<meta charset="UTF-8" />
|
|
484
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
485
|
+
<title>${projectName}</title>
|
|
486
|
+
<script src="https://cdn.tailwindcss.com/3.4.17"></script>
|
|
487
|
+
<style>
|
|
488
|
+
@import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap');
|
|
489
|
+
body { font-family: 'Inter', system-ui, sans-serif; }
|
|
490
|
+
.msg-enter { animation: msgIn 0.25s ease-out; }
|
|
491
|
+
@keyframes msgIn { from { opacity: 0; transform: translateY(8px); } to { opacity: 1; transform: translateY(0); } }
|
|
492
|
+
.typing-dot { animation: blink 1.4s infinite both; }
|
|
493
|
+
.typing-dot:nth-child(2) { animation-delay: 0.2s; }
|
|
494
|
+
.typing-dot:nth-child(3) { animation-delay: 0.4s; }
|
|
495
|
+
@keyframes blink { 0%, 80%, 100% { opacity: 0.2; } 40% { opacity: 1; } }
|
|
496
|
+
::-webkit-scrollbar { width: 6px; }
|
|
497
|
+
::-webkit-scrollbar-track { background: transparent; }
|
|
498
|
+
::-webkit-scrollbar-thumb { background: #334155; border-radius: 3px; }
|
|
499
|
+
</style>
|
|
500
|
+
</head>
|
|
501
|
+
<body class="h-full bg-gray-950 text-gray-100">
|
|
502
|
+
<div id="app" class="h-full flex flex-col">
|
|
503
|
+
<header class="flex-shrink-0 border-b border-gray-800 bg-gray-950/80 backdrop-blur-sm px-4 py-3">
|
|
504
|
+
<div class="max-w-4xl mx-auto flex items-center justify-between">
|
|
505
|
+
<div class="flex items-center gap-3">
|
|
506
|
+
<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>
|
|
507
|
+
<h1 class="text-lg font-semibold text-white">${projectName}</h1>
|
|
508
|
+
<span class="text-xs px-2 py-0.5 rounded-full bg-gray-800 text-gray-400">${badge}</span>
|
|
509
|
+
</div>
|
|
510
|
+
<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>
|
|
511
|
+
</div>
|
|
512
|
+
</header>
|
|
513
|
+
<main class="flex-1 overflow-hidden"><div class="h-full max-w-4xl mx-auto">
|
|
514
|
+
${body}
|
|
515
|
+
</div></main>
|
|
516
|
+
</div>
|
|
517
|
+
</body>
|
|
518
|
+
</html>`;
|
|
519
|
+
if (template === "chatbot") return shell(chatbotBody());
|
|
520
|
+
if (template === "rag-app") return shell(ragAppBody());
|
|
521
|
+
if (template === "agent-app") return shell(agentAppBody());
|
|
522
|
+
return "";
|
|
523
|
+
}
|
|
524
|
+
function chatbotBody() {
|
|
525
|
+
return ` <div class="h-full flex flex-col">
|
|
526
|
+
<div id="messages" class="flex-1 overflow-y-auto px-4 py-6 space-y-4">
|
|
527
|
+
<div class="text-center py-12">
|
|
528
|
+
<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">
|
|
529
|
+
<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>
|
|
530
|
+
</div>
|
|
531
|
+
<h2 class="text-xl font-semibold text-white mb-2">Start a conversation</h2>
|
|
532
|
+
<p class="text-gray-500 text-sm">Type a message below to chat with your AI assistant.</p>
|
|
533
|
+
</div>
|
|
534
|
+
</div>
|
|
535
|
+
<div class="flex-shrink-0 border-t border-gray-800 px-4 py-4">
|
|
536
|
+
<form id="chatForm" class="flex gap-3">
|
|
537
|
+
<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" />
|
|
538
|
+
<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>
|
|
539
|
+
</form>
|
|
540
|
+
</div>
|
|
541
|
+
</div>
|
|
542
|
+
<script>
|
|
543
|
+
const messages=[], messagesEl=document.getElementById("messages"), form=document.getElementById("chatForm"), input=document.getElementById("chatInput"), sendBtn=document.getElementById("sendBtn");
|
|
544
|
+
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}
|
|
545
|
+
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()});
|
|
546
|
+
input.focus();
|
|
547
|
+
</script>`;
|
|
548
|
+
}
|
|
549
|
+
function ragAppBody() {
|
|
550
|
+
return ` <div class="h-full flex flex-col md:flex-row">
|
|
551
|
+
<div class="md:w-80 flex-shrink-0 border-b md:border-b-0 md:border-r border-gray-800 flex flex-col">
|
|
552
|
+
<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>
|
|
553
|
+
<div class="flex-1 p-4 flex flex-col gap-3">
|
|
554
|
+
<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>
|
|
555
|
+
<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>
|
|
556
|
+
<div id="ingestStatus" class="text-xs text-gray-500 hidden"></div>
|
|
557
|
+
<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>
|
|
558
|
+
</div>
|
|
559
|
+
</div>
|
|
560
|
+
<div class="flex-1 flex flex-col min-w-0">
|
|
561
|
+
<div id="ragMessages" class="flex-1 overflow-y-auto px-4 py-6 space-y-4">
|
|
562
|
+
<div class="text-center py-12">
|
|
563
|
+
<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>
|
|
564
|
+
<h2 class="text-xl font-semibold text-white mb-2">Ask your documents</h2>
|
|
565
|
+
<p class="text-gray-500 text-sm">Ingest documents on the left, then ask questions here.</p>
|
|
566
|
+
</div>
|
|
567
|
+
</div>
|
|
568
|
+
<div class="flex-shrink-0 border-t border-gray-800 px-4 py-4">
|
|
569
|
+
<form id="ragForm" class="flex gap-3">
|
|
570
|
+
<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" />
|
|
571
|
+
<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>
|
|
572
|
+
</form>
|
|
573
|
+
</div>
|
|
574
|
+
</div>
|
|
575
|
+
</div>
|
|
576
|
+
<script>
|
|
577
|
+
const ragEl=document.getElementById("ragMessages");
|
|
578
|
+
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}
|
|
579
|
+
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"}
|
|
580
|
+
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()});
|
|
581
|
+
document.getElementById("ragInput").focus();
|
|
582
|
+
</script>`;
|
|
583
|
+
}
|
|
584
|
+
function agentAppBody() {
|
|
585
|
+
return ` <div class="h-full flex flex-col">
|
|
586
|
+
<div id="agentMessages" class="flex-1 overflow-y-auto px-4 py-6 space-y-4">
|
|
587
|
+
<div class="text-center py-12">
|
|
588
|
+
<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>
|
|
589
|
+
<h2 class="text-xl font-semibold text-white mb-2">AI Agent</h2>
|
|
590
|
+
<p class="text-gray-500 text-sm">Your agent can use tools to answer questions accurately.</p>
|
|
591
|
+
</div>
|
|
592
|
+
</div>
|
|
593
|
+
<div class="flex-shrink-0 border-t border-gray-800 px-4 py-4">
|
|
594
|
+
<form id="agentForm" class="flex gap-3">
|
|
595
|
+
<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" />
|
|
596
|
+
<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>
|
|
597
|
+
</form>
|
|
598
|
+
</div>
|
|
599
|
+
</div>
|
|
600
|
+
<script>
|
|
601
|
+
const agentEl=document.getElementById("agentMessages");
|
|
602
|
+
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}
|
|
603
|
+
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}
|
|
604
|
+
function removeThinking(){const t=document.getElementById("thinking");if(t)t.remove()}
|
|
605
|
+
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()});
|
|
606
|
+
document.getElementById("agentInput").focus();
|
|
607
|
+
</script>`;
|
|
608
|
+
}
|
|
609
|
+
var fs, path, V, TEMPLATE_DEPS;
|
|
524
610
|
var init_create = __esm({
|
|
525
611
|
"src/create.ts"() {
|
|
526
612
|
"use strict";
|
|
527
613
|
fs = __toESM(require("fs"));
|
|
528
614
|
path = __toESM(require("path"));
|
|
529
615
|
init_welcome();
|
|
530
|
-
|
|
531
|
-
|
|
616
|
+
V = "^0.3.0";
|
|
617
|
+
TEMPLATE_DEPS = {
|
|
618
|
+
blank: { "@voltx/core": V, "@voltx/server": V },
|
|
619
|
+
chatbot: { "@voltx/core": V, "@voltx/ai": V, "@voltx/server": V, "@voltx/memory": V },
|
|
620
|
+
"rag-app": { "@voltx/core": V, "@voltx/ai": V, "@voltx/server": V, "@voltx/rag": V, "@voltx/db": V },
|
|
621
|
+
"agent-app": { "@voltx/core": V, "@voltx/ai": V, "@voltx/server": V, "@voltx/agents": V, "@voltx/memory": V }
|
|
622
|
+
};
|
|
623
|
+
if (typeof require !== "undefined" && require.main === module && process.argv[1]?.includes("create")) {
|
|
532
624
|
const projectName = process.argv[2];
|
|
533
625
|
if (!projectName) {
|
|
534
626
|
console.log("Usage: create-voltx-app <project-name> [--template chatbot] [--auth jwt]");
|
|
@@ -972,7 +1064,7 @@ import { createAgent } from "@voltx/agents";
|
|
|
972
1064
|
|
|
973
1065
|
export const ${toCamelCase(name)} = createAgent({
|
|
974
1066
|
name: "${name}",
|
|
975
|
-
model: "cerebras:
|
|
1067
|
+
model: "cerebras:llama3.1-8b",
|
|
976
1068
|
instructions: "You are a helpful AI assistant named ${name}.",
|
|
977
1069
|
tools: [
|
|
978
1070
|
// Add tools here:
|
|
@@ -1081,7 +1173,7 @@ var init_index = __esm({
|
|
|
1081
1173
|
init_build();
|
|
1082
1174
|
init_start();
|
|
1083
1175
|
init_generate();
|
|
1084
|
-
CLI_VERSION = "0.3.
|
|
1176
|
+
CLI_VERSION = "0.3.5";
|
|
1085
1177
|
}
|
|
1086
1178
|
});
|
|
1087
1179
|
|