@elizaos/cli 1.2.3 → 1.2.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/bun-exec-4BOHUSSZ.js +21 -0
- package/dist/chunk-6ZB77OJK.js +154 -0
- package/dist/chunk-AQ6OMR2A.js +14 -0
- package/dist/{chunk-JZG5QBNT.js → chunk-ECH6TQ7M.js} +2 -2
- package/dist/chunk-EVE5GO74.js +183 -0
- package/dist/{chunk-2XI6N7KN.js → chunk-JR4V32X7.js} +348 -67
- package/dist/{chunk-PSSTO76B.js → chunk-X5K7QYAH.js} +79 -97
- package/dist/commands/agent/actions/index.js +4 -3
- package/dist/commands/agent/index.js +4 -3
- package/dist/commands/create/actions/index.d.ts +5 -1
- package/dist/commands/create/actions/index.js +8 -7
- package/dist/commands/create/index.js +6 -6
- package/dist/commands/shared/index.js +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +17 -27
- package/dist/{plugin-creator-5CER524N.js → plugin-creator-UBYADX3B.js} +16 -15
- package/dist/{registry-SN5V2VXR.js → registry-U2ZGKGSS.js} +4 -3
- package/dist/templates/plugin-starter/dist/assets/index-CgkejLs_.css +1 -0
- package/dist/templates/plugin-starter/dist/assets/index-DUtsQhKX.js +49 -0
- package/dist/templates/plugin-starter/dist/index.html +14 -0
- package/dist/templates/plugin-starter/package.json +1 -1
- package/dist/templates/plugin-starter/src/__tests__/build-order.test.ts +51 -0
- package/dist/templates/plugin-starter/src/__tests__/vite-config-utils.ts +33 -0
- package/dist/templates/plugin-starter/tsup.config.ts +1 -1
- package/dist/templates/plugin-starter/vite.config.ts +1 -1
- package/dist/templates/project-starter/package.json +4 -4
- package/dist/templates/project-starter/src/__tests__/build-order.test.ts +59 -0
- package/dist/templates/project-starter/src/__tests__/character-plugin-ordering.test.ts +11 -110
- package/dist/templates/project-starter/src/__tests__/vite-config-utils.ts +33 -0
- package/dist/templates/project-starter/src/character.ts +14 -17
- package/dist/templates/project-starter/tsup.config.ts +1 -1
- package/dist/templates/project-tee-starter/package.json +3 -3
- package/dist/templates/project-tee-starter/src/character.ts +3 -0
- package/dist/{utils-DTW3XU6O.js → utils-7XPDALF7.js} +4 -3
- package/package.json +6 -6
- package/templates/plugin-starter/dist/.vite/manifest.json +2 -2
- package/templates/plugin-starter/dist/assets/index-CgkejLs_.css +1 -0
- package/templates/plugin-starter/dist/assets/index-DUtsQhKX.js +49 -0
- package/templates/plugin-starter/dist/index.html +14 -0
- package/templates/plugin-starter/package.json +1 -1
- package/templates/plugin-starter/src/__tests__/build-order.test.ts +51 -0
- package/templates/plugin-starter/src/__tests__/vite-config-utils.ts +33 -0
- package/templates/plugin-starter/tsup.config.ts +1 -1
- package/templates/plugin-starter/vite.config.ts +1 -1
- package/templates/project-starter/package.json +4 -4
- package/templates/project-starter/src/__tests__/build-order.test.ts +59 -0
- package/templates/project-starter/src/__tests__/character-plugin-ordering.test.ts +11 -110
- package/templates/project-starter/src/__tests__/vite-config-utils.ts +33 -0
- package/templates/project-starter/src/character.ts +14 -17
- package/templates/project-starter/tsup.config.ts +1 -1
- package/templates/project-tee-starter/package.json +3 -3
- package/templates/project-tee-starter/src/character.ts +3 -0
- package/dist/chunk-5DYKNYEY.js +0 -2262
- package/dist/chunk-XB5JBFO6.js +0 -41
- package/dist/chunk-ZWDXDKSA.js +0 -281
- package/dist/setup-UQOWDHFN.js +0 -20
|
@@ -2,17 +2,24 @@
|
|
|
2
2
|
import { createRequire } from 'module';
|
|
3
3
|
const require = createRequire(import.meta.url);
|
|
4
4
|
|
|
5
|
-
import {
|
|
6
|
-
setupProjectEnvironment
|
|
7
|
-
} from "./chunk-ZWDXDKSA.js";
|
|
8
5
|
import {
|
|
9
6
|
buildProjectWithSpinner,
|
|
10
7
|
copyTemplate,
|
|
11
8
|
createTask,
|
|
9
|
+
ensureElizaDir,
|
|
12
10
|
getDisplayDirectory,
|
|
13
11
|
installDependenciesWithSpinner,
|
|
14
|
-
|
|
15
|
-
|
|
12
|
+
installPluginWithSpinner,
|
|
13
|
+
promptAndStoreAnthropicKey,
|
|
14
|
+
promptAndStoreGoogleKey,
|
|
15
|
+
promptAndStoreOllamaConfig,
|
|
16
|
+
promptAndStoreOllamaEmbeddingConfig,
|
|
17
|
+
promptAndStoreOpenAIKey,
|
|
18
|
+
promptAndStoreOpenRouterKey,
|
|
19
|
+
promptAndStorePostgresUrl,
|
|
20
|
+
runTasks,
|
|
21
|
+
setupPgLite
|
|
22
|
+
} from "./chunk-X5K7QYAH.js";
|
|
16
23
|
|
|
17
24
|
// src/characters/eliza.ts
|
|
18
25
|
var baseCharacter = {
|
|
@@ -199,19 +206,19 @@ function getElizaCharacter() {
|
|
|
199
206
|
// Core plugins first
|
|
200
207
|
"@elizaos/plugin-sql",
|
|
201
208
|
// Text-only plugins (no embedding support)
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
// Embedding-capable plugins
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
...!!process.env.GOOGLE_GENERATIVE_AI_API_KEY ? ["@elizaos/plugin-google-genai"] : [],
|
|
208
|
-
...!process.env.GOOGLE_GENERATIVE_AI_API_KEY && !process.env.OLLAMA_API_ENDPOINT && !process.env.OPENAI_API_KEY ? ["@elizaos/plugin-local-ai"] : [],
|
|
209
|
+
...process.env.ANTHROPIC_API_KEY?.trim() ? ["@elizaos/plugin-anthropic"] : [],
|
|
210
|
+
...process.env.OPENROUTER_API_KEY?.trim() ? ["@elizaos/plugin-openrouter"] : [],
|
|
211
|
+
// Embedding-capable plugins (before platform plugins per documented order)
|
|
212
|
+
...process.env.OPENAI_API_KEY?.trim() ? ["@elizaos/plugin-openai"] : [],
|
|
213
|
+
...process.env.GOOGLE_GENERATIVE_AI_API_KEY?.trim() ? ["@elizaos/plugin-google-genai"] : [],
|
|
209
214
|
// Platform plugins
|
|
210
|
-
...process.env.DISCORD_API_TOKEN ? ["@elizaos/plugin-discord"] : [],
|
|
211
|
-
...process.env.TWITTER_API_KEY && process.env.TWITTER_API_SECRET_KEY && process.env.TWITTER_ACCESS_TOKEN && process.env.TWITTER_ACCESS_TOKEN_SECRET ? ["@elizaos/plugin-twitter"] : [],
|
|
212
|
-
...process.env.TELEGRAM_BOT_TOKEN ? ["@elizaos/plugin-telegram"] : [],
|
|
215
|
+
...process.env.DISCORD_API_TOKEN?.trim() ? ["@elizaos/plugin-discord"] : [],
|
|
216
|
+
...process.env.TWITTER_API_KEY?.trim() && process.env.TWITTER_API_SECRET_KEY?.trim() && process.env.TWITTER_ACCESS_TOKEN?.trim() && process.env.TWITTER_ACCESS_TOKEN_SECRET?.trim() ? ["@elizaos/plugin-twitter"] : [],
|
|
217
|
+
...process.env.TELEGRAM_BOT_TOKEN?.trim() ? ["@elizaos/plugin-telegram"] : [],
|
|
213
218
|
// Bootstrap plugin
|
|
214
|
-
...!process.env.IGNORE_BOOTSTRAP ? ["@elizaos/plugin-bootstrap"] : []
|
|
219
|
+
...!process.env.IGNORE_BOOTSTRAP ? ["@elizaos/plugin-bootstrap"] : [],
|
|
220
|
+
// Always include Ollama as ultimate fallback for local AI
|
|
221
|
+
"@elizaos/plugin-ollama"
|
|
215
222
|
];
|
|
216
223
|
return {
|
|
217
224
|
...baseCharacter,
|
|
@@ -221,7 +228,7 @@ function getElizaCharacter() {
|
|
|
221
228
|
|
|
222
229
|
// src/commands/create/actions/creators.ts
|
|
223
230
|
import { join } from "path";
|
|
224
|
-
import
|
|
231
|
+
import fs3 from "fs/promises";
|
|
225
232
|
import * as clack2 from "@clack/prompts";
|
|
226
233
|
import colors from "yoctocolors";
|
|
227
234
|
|
|
@@ -331,9 +338,9 @@ import * as clack from "@clack/prompts";
|
|
|
331
338
|
function getAvailableAIModels() {
|
|
332
339
|
return [
|
|
333
340
|
{
|
|
334
|
-
title: "Local AI",
|
|
341
|
+
title: "Local AI (Ollama)",
|
|
335
342
|
value: "local",
|
|
336
|
-
description: "Local models, no API required"
|
|
343
|
+
description: "Local models via Ollama, no API required"
|
|
337
344
|
},
|
|
338
345
|
{
|
|
339
346
|
title: "OpenAI",
|
|
@@ -350,11 +357,6 @@ function getAvailableAIModels() {
|
|
|
350
357
|
value: "openrouter",
|
|
351
358
|
description: "Access multiple AI models"
|
|
352
359
|
},
|
|
353
|
-
{
|
|
354
|
-
title: "Ollama",
|
|
355
|
-
value: "ollama",
|
|
356
|
-
description: "Self-hosted models"
|
|
357
|
-
},
|
|
358
360
|
{
|
|
359
361
|
title: "Google Generative AI",
|
|
360
362
|
value: "google",
|
|
@@ -413,20 +415,15 @@ async function selectAIModel() {
|
|
|
413
415
|
function getAvailableEmbeddingModels() {
|
|
414
416
|
return [
|
|
415
417
|
{
|
|
416
|
-
title: "Local AI",
|
|
418
|
+
title: "Local AI (Ollama)",
|
|
417
419
|
value: "local",
|
|
418
|
-
description: "Local embeddings, no API required"
|
|
420
|
+
description: "Local embeddings via Ollama, no API required"
|
|
419
421
|
},
|
|
420
422
|
{
|
|
421
423
|
title: "OpenAI",
|
|
422
424
|
value: "openai",
|
|
423
425
|
description: "OpenAI text-embedding-ada-002"
|
|
424
426
|
},
|
|
425
|
-
{
|
|
426
|
-
title: "Ollama",
|
|
427
|
-
value: "ollama",
|
|
428
|
-
description: "Self-hosted embedding models"
|
|
429
|
-
},
|
|
430
427
|
{
|
|
431
428
|
title: "Google Generative AI",
|
|
432
429
|
value: "google",
|
|
@@ -452,12 +449,317 @@ async function selectEmbeddingModel() {
|
|
|
452
449
|
return embeddingModel;
|
|
453
450
|
}
|
|
454
451
|
|
|
452
|
+
// src/commands/create/actions/setup.ts
|
|
453
|
+
import { existsSync as existsSync2 } from "fs";
|
|
454
|
+
import fs2 from "fs/promises";
|
|
455
|
+
async function createProjectDirectories(targetDir) {
|
|
456
|
+
await ensureElizaDir(targetDir);
|
|
457
|
+
}
|
|
458
|
+
async function setupAIModelConfig(aiModel, envFilePath, isNonInteractive = false) {
|
|
459
|
+
try {
|
|
460
|
+
switch (aiModel) {
|
|
461
|
+
case "local": {
|
|
462
|
+
if (isNonInteractive) {
|
|
463
|
+
let content = "";
|
|
464
|
+
if (existsSync2(envFilePath)) {
|
|
465
|
+
content = await fs2.readFile(envFilePath, "utf8");
|
|
466
|
+
}
|
|
467
|
+
if (content && !content.endsWith("\n")) {
|
|
468
|
+
content += "\n";
|
|
469
|
+
}
|
|
470
|
+
content += "\n# Local AI Configuration (using Ollama)\n";
|
|
471
|
+
content += "OLLAMA_API_ENDPOINT=http://localhost:11434\n";
|
|
472
|
+
content += "OLLAMA_MODEL=gemma3\n";
|
|
473
|
+
content += "OLLAMA_EMBEDDING_MODEL=nomic-embed-text\n";
|
|
474
|
+
content += "USE_OLLAMA_TEXT_MODELS=true\n";
|
|
475
|
+
content += "# Make sure Ollama is installed and running: https://ollama.ai/\n";
|
|
476
|
+
content += "# Pull models with: ollama pull gemma3 && ollama pull nomic-embed-text\n";
|
|
477
|
+
await fs2.writeFile(envFilePath, content, "utf8");
|
|
478
|
+
} else {
|
|
479
|
+
await promptAndStoreOllamaConfig(envFilePath);
|
|
480
|
+
await promptAndStoreOllamaEmbeddingConfig(envFilePath);
|
|
481
|
+
}
|
|
482
|
+
break;
|
|
483
|
+
}
|
|
484
|
+
case "openai": {
|
|
485
|
+
if (isNonInteractive) {
|
|
486
|
+
let content = "";
|
|
487
|
+
if (existsSync2(envFilePath)) {
|
|
488
|
+
content = await fs2.readFile(envFilePath, "utf8");
|
|
489
|
+
}
|
|
490
|
+
if (content && !content.endsWith("\n")) {
|
|
491
|
+
content += "\n";
|
|
492
|
+
}
|
|
493
|
+
content += "\n# AI Model Configuration\n";
|
|
494
|
+
content += "# OpenAI Configuration\n";
|
|
495
|
+
content += "OPENAI_API_KEY=your_openai_api_key_here\n";
|
|
496
|
+
content += "# Get your API key from: https://platform.openai.com/api-keys\n";
|
|
497
|
+
await fs2.writeFile(envFilePath, content, "utf8");
|
|
498
|
+
} else {
|
|
499
|
+
await promptAndStoreOpenAIKey(envFilePath);
|
|
500
|
+
}
|
|
501
|
+
break;
|
|
502
|
+
}
|
|
503
|
+
case "claude": {
|
|
504
|
+
if (isNonInteractive) {
|
|
505
|
+
let content = "";
|
|
506
|
+
if (existsSync2(envFilePath)) {
|
|
507
|
+
content = await fs2.readFile(envFilePath, "utf8");
|
|
508
|
+
}
|
|
509
|
+
if (content && !content.endsWith("\n")) {
|
|
510
|
+
content += "\n";
|
|
511
|
+
}
|
|
512
|
+
content += "\n# AI Model Configuration\n";
|
|
513
|
+
content += "# Anthropic API Configuration\n";
|
|
514
|
+
content += "ANTHROPIC_API_KEY=your_anthropic_api_key_here\n";
|
|
515
|
+
content += "# Get your API key from: https://console.anthropic.com/\n";
|
|
516
|
+
await fs2.writeFile(envFilePath, content, "utf8");
|
|
517
|
+
} else {
|
|
518
|
+
await promptAndStoreAnthropicKey(envFilePath);
|
|
519
|
+
}
|
|
520
|
+
break;
|
|
521
|
+
}
|
|
522
|
+
case "openrouter": {
|
|
523
|
+
if (isNonInteractive) {
|
|
524
|
+
let content = "";
|
|
525
|
+
if (existsSync2(envFilePath)) {
|
|
526
|
+
content = await fs2.readFile(envFilePath, "utf8");
|
|
527
|
+
}
|
|
528
|
+
if (content && !content.endsWith("\n")) {
|
|
529
|
+
content += "\n";
|
|
530
|
+
}
|
|
531
|
+
content += "\n# AI Model Configuration\n";
|
|
532
|
+
content += "# OpenRouter Configuration\n";
|
|
533
|
+
content += "OPENROUTER_API_KEY=your_openrouter_api_key_here\n";
|
|
534
|
+
content += "# Get your API key from: https://openrouter.ai/keys\n";
|
|
535
|
+
await fs2.writeFile(envFilePath, content, "utf8");
|
|
536
|
+
} else {
|
|
537
|
+
await promptAndStoreOpenRouterKey(envFilePath);
|
|
538
|
+
}
|
|
539
|
+
break;
|
|
540
|
+
}
|
|
541
|
+
case "ollama": {
|
|
542
|
+
if (isNonInteractive) {
|
|
543
|
+
let content = "";
|
|
544
|
+
if (existsSync2(envFilePath)) {
|
|
545
|
+
content = await fs2.readFile(envFilePath, "utf8");
|
|
546
|
+
}
|
|
547
|
+
if (content && !content.endsWith("\n")) {
|
|
548
|
+
content += "\n";
|
|
549
|
+
}
|
|
550
|
+
content += "\n# AI Model Configuration\n";
|
|
551
|
+
content += "# Ollama Configuration\n";
|
|
552
|
+
content += "OLLAMA_API_ENDPOINT=http://localhost:11434\n";
|
|
553
|
+
content += "OLLAMA_MODEL=gemma3\n";
|
|
554
|
+
content += "USE_OLLAMA_TEXT_MODELS=true\n";
|
|
555
|
+
content += "# Make sure Ollama is installed and running: https://ollama.ai/\n";
|
|
556
|
+
await fs2.writeFile(envFilePath, content, "utf8");
|
|
557
|
+
} else {
|
|
558
|
+
await promptAndStoreOllamaConfig(envFilePath);
|
|
559
|
+
}
|
|
560
|
+
break;
|
|
561
|
+
}
|
|
562
|
+
case "google": {
|
|
563
|
+
if (isNonInteractive) {
|
|
564
|
+
let content = "";
|
|
565
|
+
if (existsSync2(envFilePath)) {
|
|
566
|
+
content = await fs2.readFile(envFilePath, "utf8");
|
|
567
|
+
}
|
|
568
|
+
if (content && !content.endsWith("\n")) {
|
|
569
|
+
content += "\n";
|
|
570
|
+
}
|
|
571
|
+
content += "\n# AI Model Configuration\n";
|
|
572
|
+
content += "# Google Generative AI Configuration\n";
|
|
573
|
+
content += "GOOGLE_GENERATIVE_AI_API_KEY=your_google_api_key_here\n";
|
|
574
|
+
content += "# Get your API key from: https://aistudio.google.com/apikey\n";
|
|
575
|
+
await fs2.writeFile(envFilePath, content, "utf8");
|
|
576
|
+
} else {
|
|
577
|
+
await promptAndStoreGoogleKey(envFilePath);
|
|
578
|
+
}
|
|
579
|
+
break;
|
|
580
|
+
}
|
|
581
|
+
default:
|
|
582
|
+
console.warn(`Unknown AI model: ${aiModel}, skipping configuration`);
|
|
583
|
+
return;
|
|
584
|
+
}
|
|
585
|
+
} catch (error) {
|
|
586
|
+
const errorMessage = error instanceof Error ? error.message : "Unknown error";
|
|
587
|
+
console.error(`Failed to set up AI model configuration: ${errorMessage}`);
|
|
588
|
+
}
|
|
589
|
+
}
|
|
590
|
+
function hasValidApiKey(content, keyName) {
|
|
591
|
+
const regex = new RegExp(`^${keyName}=(.+)$`, "m");
|
|
592
|
+
const match = content.match(regex);
|
|
593
|
+
if (!match) return false;
|
|
594
|
+
const value = match[1].trim();
|
|
595
|
+
return value !== "" && !value.includes("your_") && !value.includes("_here") && !value.includes("PLACEHOLDER") && !value.includes("placeholder");
|
|
596
|
+
}
|
|
597
|
+
async function setupEmbeddingModelConfig(embeddingModel, envFilePath, isNonInteractive = false) {
|
|
598
|
+
try {
|
|
599
|
+
let content = "";
|
|
600
|
+
if (existsSync2(envFilePath)) {
|
|
601
|
+
content = await fs2.readFile(envFilePath, "utf8");
|
|
602
|
+
}
|
|
603
|
+
if (content && !content.endsWith("\n")) {
|
|
604
|
+
content += "\n";
|
|
605
|
+
}
|
|
606
|
+
switch (embeddingModel) {
|
|
607
|
+
case "local": {
|
|
608
|
+
content += "\n# Embedding Model Configuration (Fallback)\n";
|
|
609
|
+
content += "# Using local embeddings - no additional configuration needed\n";
|
|
610
|
+
await fs2.writeFile(envFilePath, content, "utf8");
|
|
611
|
+
break;
|
|
612
|
+
}
|
|
613
|
+
case "openai": {
|
|
614
|
+
if (!hasValidApiKey(content, "OPENAI_API_KEY")) {
|
|
615
|
+
if (isNonInteractive) {
|
|
616
|
+
if (!content.includes("OPENAI_API_KEY=")) {
|
|
617
|
+
content += "\n# Embedding Model Configuration (Fallback)\n";
|
|
618
|
+
content += "# OpenAI Embeddings Configuration\n";
|
|
619
|
+
content += "OPENAI_API_KEY=your_openai_api_key_here\n";
|
|
620
|
+
content += "# Get your API key from: https://platform.openai.com/api-keys\n";
|
|
621
|
+
}
|
|
622
|
+
await fs2.writeFile(envFilePath, content, "utf8");
|
|
623
|
+
} else {
|
|
624
|
+
await promptAndStoreOpenAIKey(envFilePath);
|
|
625
|
+
}
|
|
626
|
+
}
|
|
627
|
+
break;
|
|
628
|
+
}
|
|
629
|
+
case "ollama": {
|
|
630
|
+
if (!hasValidApiKey(content, "OLLAMA_API_ENDPOINT")) {
|
|
631
|
+
if (isNonInteractive) {
|
|
632
|
+
if (!content.includes("OLLAMA_API_ENDPOINT=")) {
|
|
633
|
+
content += "\n# Embedding Model Configuration (Fallback)\n";
|
|
634
|
+
content += "# Ollama Embeddings Configuration\n";
|
|
635
|
+
content += "OLLAMA_API_ENDPOINT=http://localhost:11434\n";
|
|
636
|
+
content += "OLLAMA_EMBEDDING_MODEL=nomic-embed-text\n";
|
|
637
|
+
content += "USE_OLLAMA_EMBEDDINGS=true\n";
|
|
638
|
+
content += "# Make sure Ollama is installed and running: https://ollama.ai/\n";
|
|
639
|
+
}
|
|
640
|
+
await fs2.writeFile(envFilePath, content, "utf8");
|
|
641
|
+
} else {
|
|
642
|
+
await promptAndStoreOllamaEmbeddingConfig(envFilePath);
|
|
643
|
+
}
|
|
644
|
+
} else {
|
|
645
|
+
if (isNonInteractive) {
|
|
646
|
+
if (!content.includes("OLLAMA_EMBEDDING_MODEL")) {
|
|
647
|
+
content += "OLLAMA_EMBEDDING_MODEL=nomic-embed-text\n";
|
|
648
|
+
}
|
|
649
|
+
if (!content.includes("USE_OLLAMA_EMBEDDINGS")) {
|
|
650
|
+
content += "USE_OLLAMA_EMBEDDINGS=true\n";
|
|
651
|
+
}
|
|
652
|
+
await fs2.writeFile(envFilePath, content, "utf8");
|
|
653
|
+
} else {
|
|
654
|
+
await promptAndStoreOllamaEmbeddingConfig(envFilePath);
|
|
655
|
+
}
|
|
656
|
+
}
|
|
657
|
+
break;
|
|
658
|
+
}
|
|
659
|
+
case "google": {
|
|
660
|
+
if (!hasValidApiKey(content, "GOOGLE_GENERATIVE_AI_API_KEY")) {
|
|
661
|
+
if (isNonInteractive) {
|
|
662
|
+
if (!content.includes("GOOGLE_GENERATIVE_AI_API_KEY=")) {
|
|
663
|
+
content += "\n# Embedding Model Configuration (Fallback)\n";
|
|
664
|
+
content += "# Google Generative AI Embeddings Configuration\n";
|
|
665
|
+
content += "GOOGLE_GENERATIVE_AI_API_KEY=your_google_api_key_here\n";
|
|
666
|
+
content += "# Get your API key from: https://aistudio.google.com/apikey\n";
|
|
667
|
+
}
|
|
668
|
+
await fs2.writeFile(envFilePath, content, "utf8");
|
|
669
|
+
} else {
|
|
670
|
+
await promptAndStoreGoogleKey(envFilePath);
|
|
671
|
+
}
|
|
672
|
+
}
|
|
673
|
+
break;
|
|
674
|
+
}
|
|
675
|
+
default:
|
|
676
|
+
console.warn(`Unknown embedding model: ${embeddingModel}, skipping configuration`);
|
|
677
|
+
return;
|
|
678
|
+
}
|
|
679
|
+
} catch (error) {
|
|
680
|
+
const errorMessage = error instanceof Error ? error.message : "Unknown error";
|
|
681
|
+
console.error(`Failed to set up embedding model configuration: ${errorMessage}`);
|
|
682
|
+
}
|
|
683
|
+
}
|
|
684
|
+
function resolveModelToPlugin(modelName) {
|
|
685
|
+
const modelToPlugin = {
|
|
686
|
+
openai: "openai",
|
|
687
|
+
claude: "anthropic",
|
|
688
|
+
anthropic: "anthropic",
|
|
689
|
+
openrouter: "openrouter",
|
|
690
|
+
ollama: "ollama",
|
|
691
|
+
google: "google-genai"
|
|
692
|
+
};
|
|
693
|
+
return modelToPlugin[modelName] || null;
|
|
694
|
+
}
|
|
695
|
+
async function installModelPlugin(modelName, targetDir, purpose = "") {
|
|
696
|
+
const pluginName = resolveModelToPlugin(modelName);
|
|
697
|
+
if (!pluginName) {
|
|
698
|
+
return;
|
|
699
|
+
}
|
|
700
|
+
await installPluginWithSpinner(pluginName, targetDir, purpose);
|
|
701
|
+
}
|
|
702
|
+
async function setupProjectEnvironment(targetDir, database, aiModel, embeddingModel, isNonInteractive = false) {
|
|
703
|
+
await createProjectDirectories(targetDir);
|
|
704
|
+
const envFilePath = `${targetDir}/.env`;
|
|
705
|
+
if (database === "postgres") {
|
|
706
|
+
if (!isNonInteractive) {
|
|
707
|
+
await promptAndStorePostgresUrl(envFilePath);
|
|
708
|
+
}
|
|
709
|
+
} else if (database === "pglite") {
|
|
710
|
+
await setupPgLite(void 0, `${targetDir}/.env`, targetDir);
|
|
711
|
+
}
|
|
712
|
+
if (!isNonInteractive) {
|
|
713
|
+
await setupAIModelConfig(aiModel, envFilePath, isNonInteractive);
|
|
714
|
+
if (embeddingModel) {
|
|
715
|
+
await setupEmbeddingModelConfig(embeddingModel, envFilePath, isNonInteractive);
|
|
716
|
+
}
|
|
717
|
+
}
|
|
718
|
+
const envContent = existsSync2(envFilePath) ? await fs2.readFile(envFilePath, "utf8") : "";
|
|
719
|
+
if (!hasValidApiKey(envContent, "OLLAMA_API_ENDPOINT")) {
|
|
720
|
+
await setupEmbeddingModelConfig("ollama", envFilePath, true);
|
|
721
|
+
}
|
|
722
|
+
if (aiModel === "local") {
|
|
723
|
+
await installModelPlugin("ollama", targetDir, "for local AI");
|
|
724
|
+
} else {
|
|
725
|
+
await installModelPlugin(aiModel, targetDir);
|
|
726
|
+
if (aiModel !== "ollama") {
|
|
727
|
+
await installModelPlugin("ollama", targetDir, "as fallback");
|
|
728
|
+
}
|
|
729
|
+
}
|
|
730
|
+
if (embeddingModel && embeddingModel !== "local") {
|
|
731
|
+
const aiPluginName = resolveModelToPlugin(aiModel);
|
|
732
|
+
const embeddingPluginName = resolveModelToPlugin(embeddingModel);
|
|
733
|
+
if (embeddingPluginName && embeddingPluginName !== aiPluginName) {
|
|
734
|
+
await installModelPlugin(embeddingModel, targetDir, "for embeddings");
|
|
735
|
+
}
|
|
736
|
+
}
|
|
737
|
+
}
|
|
738
|
+
|
|
455
739
|
// src/commands/create/actions/creators.ts
|
|
456
|
-
import { existsSync as
|
|
740
|
+
import { existsSync as existsSync3, rmSync } from "fs";
|
|
741
|
+
async function handleInteractiveConfiguration(targetDir, database, aiModel, embeddingModel) {
|
|
742
|
+
const envFilePath = `${targetDir}/.env`;
|
|
743
|
+
if (database === "postgres") {
|
|
744
|
+
await promptAndStorePostgresUrl(envFilePath);
|
|
745
|
+
}
|
|
746
|
+
if (aiModel !== "local" || embeddingModel) {
|
|
747
|
+
if (aiModel !== "local") {
|
|
748
|
+
await setupAIModelConfig(aiModel, envFilePath, false);
|
|
749
|
+
}
|
|
750
|
+
if (embeddingModel) {
|
|
751
|
+
await setupEmbeddingModelConfig(embeddingModel, envFilePath, false);
|
|
752
|
+
}
|
|
753
|
+
}
|
|
754
|
+
const envContent = existsSync3(envFilePath) ? await fs3.readFile(envFilePath, "utf8") : "";
|
|
755
|
+
if (!hasValidApiKey(envContent, "OLLAMA_API_ENDPOINT")) {
|
|
756
|
+
await setupEmbeddingModelConfig("ollama", envFilePath, false);
|
|
757
|
+
}
|
|
758
|
+
}
|
|
457
759
|
async function withCleanupOnInterrupt(targetDir, displayName, fn) {
|
|
458
|
-
const directoryExistedBefore =
|
|
760
|
+
const directoryExistedBefore = existsSync3(targetDir);
|
|
459
761
|
const cleanup = () => {
|
|
460
|
-
if (!directoryExistedBefore &&
|
|
762
|
+
if (!directoryExistedBefore && existsSync3(targetDir)) {
|
|
461
763
|
console.info(colors.red(`
|
|
462
764
|
|
|
463
765
|
Interrupted! Cleaning up ${displayName}...`));
|
|
@@ -488,7 +790,7 @@ Interrupted! Cleaning up ${displayName}...`));
|
|
|
488
790
|
process.removeListener("exit", cleanup);
|
|
489
791
|
process.removeListener("SIGINT", sigintHandler);
|
|
490
792
|
process.removeListener("SIGTERM", sigtermHandler);
|
|
491
|
-
if (!directoryExistedBefore &&
|
|
793
|
+
if (!directoryExistedBefore && existsSync3(targetDir)) {
|
|
492
794
|
try {
|
|
493
795
|
console.info(colors.red(`
|
|
494
796
|
Cleaning up due to error...`));
|
|
@@ -549,7 +851,7 @@ Next steps:`);
|
|
|
549
851
|
async function createAgent(agentName, targetDir, isNonInteractive = false) {
|
|
550
852
|
const agentFilePath = join(targetDir, `${agentName}.json`);
|
|
551
853
|
try {
|
|
552
|
-
await
|
|
854
|
+
await fs3.access(agentFilePath);
|
|
553
855
|
throw new Error(`Agent file ${agentFilePath} already exists`);
|
|
554
856
|
} catch (error) {
|
|
555
857
|
if (error.code !== "ENOENT") {
|
|
@@ -574,7 +876,7 @@ async function createAgent(agentName, targetDir, isNonInteractive = false) {
|
|
|
574
876
|
`${agentName} is knowledgeable, creative, and always eager to help users with their questions and tasks.`
|
|
575
877
|
]
|
|
576
878
|
};
|
|
577
|
-
await
|
|
879
|
+
await fs3.writeFile(agentFilePath, JSON.stringify(agentCharacter, null, 2));
|
|
578
880
|
console.info(`
|
|
579
881
|
${colors.green("\u2713")} Agent "${agentName}" created successfully!`);
|
|
580
882
|
console.info(`Agent character created successfully at: ${agentFilePath}`);
|
|
@@ -603,22 +905,9 @@ async function createTEEProject(projectName, targetDir, database, aiModel, embed
|
|
|
603
905
|
}
|
|
604
906
|
}
|
|
605
907
|
await withCleanupOnInterrupt(teeTargetDir, projectName, async () => {
|
|
606
|
-
await
|
|
908
|
+
await fs3.mkdir(teeTargetDir, { recursive: true });
|
|
607
909
|
if (!isNonInteractive) {
|
|
608
|
-
|
|
609
|
-
const { promptAndStorePostgresUrl } = await import("./utils-DTW3XU6O.js");
|
|
610
|
-
const envFilePath = `${teeTargetDir}/.env`;
|
|
611
|
-
if (database === "postgres") {
|
|
612
|
-
await promptAndStorePostgresUrl(envFilePath);
|
|
613
|
-
}
|
|
614
|
-
if (aiModel !== "local" || embeddingModel) {
|
|
615
|
-
if (aiModel !== "local") {
|
|
616
|
-
await setupAIModelConfig(aiModel, envFilePath, false);
|
|
617
|
-
}
|
|
618
|
-
if (embeddingModel) {
|
|
619
|
-
await setupEmbeddingModelConfig(embeddingModel, envFilePath, false);
|
|
620
|
-
}
|
|
621
|
-
}
|
|
910
|
+
await handleInteractiveConfiguration(teeTargetDir, database, aiModel, embeddingModel);
|
|
622
911
|
}
|
|
623
912
|
await runTasks([
|
|
624
913
|
createTask(
|
|
@@ -663,23 +952,10 @@ async function createProject(projectName, targetDir, database, aiModel, embeddin
|
|
|
663
952
|
}
|
|
664
953
|
const createFn = async () => {
|
|
665
954
|
if (projectName !== ".") {
|
|
666
|
-
await
|
|
955
|
+
await fs3.mkdir(projectTargetDir, { recursive: true });
|
|
667
956
|
}
|
|
668
957
|
if (!isNonInteractive) {
|
|
669
|
-
|
|
670
|
-
const { promptAndStorePostgresUrl } = await import("./utils-DTW3XU6O.js");
|
|
671
|
-
const envFilePath = `${projectTargetDir}/.env`;
|
|
672
|
-
if (database === "postgres") {
|
|
673
|
-
await promptAndStorePostgresUrl(envFilePath);
|
|
674
|
-
}
|
|
675
|
-
if (aiModel !== "local" || embeddingModel) {
|
|
676
|
-
if (aiModel !== "local") {
|
|
677
|
-
await setupAIModelConfig(aiModel, envFilePath, false);
|
|
678
|
-
}
|
|
679
|
-
if (embeddingModel) {
|
|
680
|
-
await setupEmbeddingModelConfig(embeddingModel, envFilePath, false);
|
|
681
|
-
}
|
|
682
|
-
}
|
|
958
|
+
await handleInteractiveConfiguration(projectTargetDir, database, aiModel, embeddingModel);
|
|
683
959
|
}
|
|
684
960
|
await runTasks([
|
|
685
961
|
createTask(
|
|
@@ -721,6 +997,11 @@ export {
|
|
|
721
997
|
selectAIModel,
|
|
722
998
|
selectEmbeddingModel,
|
|
723
999
|
getElizaCharacter,
|
|
1000
|
+
createProjectDirectories,
|
|
1001
|
+
setupAIModelConfig,
|
|
1002
|
+
hasValidApiKey,
|
|
1003
|
+
setupEmbeddingModelConfig,
|
|
1004
|
+
setupProjectEnvironment,
|
|
724
1005
|
createPlugin,
|
|
725
1006
|
createAgent,
|
|
726
1007
|
createTEEProject,
|