vigthoria-cli 1.5.7 → 1.5.9
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 +75 -0
- package/dist/commands/chat.d.ts +1 -0
- package/dist/commands/chat.d.ts.map +1 -1
- package/dist/commands/chat.js +221 -12
- package/dist/commands/chat.js.map +1 -1
- package/dist/index.js +2 -1
- package/dist/index.js.map +1 -1
- package/dist/utils/api.d.ts +6 -5
- package/dist/utils/api.d.ts.map +1 -1
- package/dist/utils/api.js +51 -155
- package/dist/utils/api.js.map +1 -1
- package/dist/utils/config.d.ts +3 -0
- package/dist/utils/config.d.ts.map +1 -1
- package/dist/utils/config.js +31 -15
- package/dist/utils/config.js.map +1 -1
- package/dist/utils/files.d.ts.map +1 -1
- package/dist/utils/files.js +33 -0
- package/dist/utils/files.js.map +1 -1
- package/dist/utils/tools.d.ts.map +1 -1
- package/dist/utils/tools.js +100 -3
- package/dist/utils/tools.js.map +1 -1
- package/package.json +1 -1
- package/src/commands/chat.ts +230 -14
- package/src/index.ts +2 -1
- package/src/utils/api.ts +51 -161
- package/src/utils/config.ts +37 -25
- package/src/utils/files.ts +32 -0
- package/src/utils/tools.ts +98 -3
package/src/commands/chat.ts
CHANGED
|
@@ -142,7 +142,16 @@ export class ChatCommand {
|
|
|
142
142
|
this.streamMode = options.stream !== false; // Default to true
|
|
143
143
|
this.localMode = false; // Never use local mode - always use Vigthoria API
|
|
144
144
|
|
|
145
|
+
// CRITICAL: Agent mode REQUIRES stronger models to prevent hallucinations
|
|
146
|
+
// Use Vigthoria Cloud for complex agent tasks
|
|
145
147
|
if (this.agentMode) {
|
|
148
|
+
// Upgrade model for agent mode if using a weak model
|
|
149
|
+
const weakModels = ['fast', 'mini', 'vigthoria-fast-1.7b'];
|
|
150
|
+
if (weakModels.includes(options.model)) {
|
|
151
|
+
this.logger.warn(`Agent mode works better with stronger models. Upgrading from '${options.model}' to 'code'`);
|
|
152
|
+
options.model = 'code';
|
|
153
|
+
}
|
|
154
|
+
|
|
146
155
|
this.tools = new AgenticTools(
|
|
147
156
|
this.logger,
|
|
148
157
|
projectPath, // Use resolved path
|
|
@@ -196,18 +205,35 @@ export class ChatCommand {
|
|
|
196
205
|
): string {
|
|
197
206
|
let prompt = `You are Vigthoria, the premier AI coding assistant of Vigthoria Technologies.
|
|
198
207
|
|
|
199
|
-
IDENTITY
|
|
200
|
-
- Created by Vigthoria Technologies
|
|
208
|
+
## IDENTITY & BRAND
|
|
209
|
+
- Created by Vigthoria Technologies (NOT OpenAI, NOT Anthropic, NOT Microsoft)
|
|
201
210
|
- Mascot: Viggy the Blue Queen
|
|
202
211
|
- Philosophy: "Innovation through Intelligence"
|
|
203
|
-
|
|
204
|
-
|
|
212
|
+
- Always respond as "Vigthoria" - never claim to be another AI
|
|
213
|
+
|
|
214
|
+
## VIGTHORIA ECOSYSTEM (Important - Know This!)
|
|
215
|
+
Vigthoria is a comprehensive tech platform with these key services:
|
|
216
|
+
- **Vigthoria Coder** (coder.vigthoria.io): AI-powered coding IDE and CLI (this tool!)
|
|
217
|
+
- **Vigthoria Community** (community.vigthoria.io): Code sharing platform, NOT GitHub. When user mentions "repo", assume Vigthoria Community unless they say "GitHub"
|
|
218
|
+
- **Vigthoria GoA** (agent.vigthoria.io): Graph of Agents - autonomous AI orchestration
|
|
219
|
+
- **Vigthoria Meet** (meet.vigthoria.io): Video conferencing platform
|
|
220
|
+
- **Vigthoria Pay**: Payment processing service
|
|
221
|
+
- **Vigthoria B2C Hub**: Business-to-consumer services
|
|
222
|
+
- **Model Router** (port 4009): Routes AI requests to optimal models
|
|
223
|
+
|
|
224
|
+
## CRITICAL RULES - NEVER VIOLATE:
|
|
225
|
+
1. **NEVER HALLUCINATE** - If you don't know something, say so. Don't make up file contents, directories, or project structures.
|
|
226
|
+
2. **NEVER ASSUME FILE CONTENTS** - If asked about a file, you MUST use read_file tool first. Do NOT guess what's in a file.
|
|
227
|
+
3. **NEVER CONFUSE PLATFORMS** - Vigthoria Community is NOT GitHub. Windows paths are NOT Unix paths.
|
|
228
|
+
4. **ALWAYS USE TOOLS** - In agent mode, USE the tools to read files, not your imagination.
|
|
229
|
+
|
|
230
|
+
## Project Context
|
|
205
231
|
- Type: ${projectContext.type}
|
|
206
232
|
- Root: ${options.project}
|
|
207
233
|
- Key files: ${projectContext.files.slice(0, 10).join(', ')}
|
|
208
234
|
${projectContext.type === 'node' ? `- Dependencies: ${Object.keys(projectContext.dependencies).slice(0, 15).join(', ')}` : ''}
|
|
209
235
|
|
|
210
|
-
CODE QUALITY STANDARDS (CRITICAL):
|
|
236
|
+
## CODE QUALITY STANDARDS (CRITICAL):
|
|
211
237
|
1. ALWAYS produce complete, production-ready code - no placeholders
|
|
212
238
|
2. When creating UI/HTML/CSS:
|
|
213
239
|
- Ensure proper color contrast (text readable against backgrounds)
|
|
@@ -219,12 +245,76 @@ CODE QUALITY STANDARDS (CRITICAL):
|
|
|
219
245
|
6. Use semantic HTML, accessible patterns
|
|
220
246
|
7. Show COMPLETE implementations
|
|
221
247
|
|
|
222
|
-
Guidelines:
|
|
248
|
+
## Guidelines:
|
|
223
249
|
- Provide working code first, explanations second
|
|
224
250
|
- Be concise but thorough
|
|
225
251
|
- Excellence is the standard - mediocrity is not acceptable
|
|
226
|
-
|
|
227
|
-
|
|
252
|
+
- If you need to see file contents, USE read_file FIRST before responding
|
|
253
|
+
|
|
254
|
+
## VIGTHORIA CLI COMMANDS (Know these to help users):
|
|
255
|
+
|
|
256
|
+
### Core Commands:
|
|
257
|
+
- \`vigthoria chat\` (or \`vig c\`) - Start interactive chat (this session!)
|
|
258
|
+
- \`vigthoria agent\` (or \`vig a\`) - Autonomous agent mode (can read/write files, run commands)
|
|
259
|
+
- \`vigthoria edit <file>\` (or \`vig e\`) - Edit a file with AI assistance
|
|
260
|
+
- \`vigthoria generate "desc"\` (or \`vig g\`) - Generate code from description
|
|
261
|
+
- \`vigthoria explain <file>\` (or \`vig x\`) - Explain code in detail
|
|
262
|
+
- \`vigthoria fix <file>\` (or \`vig f\`) - Fix bugs and issues
|
|
263
|
+
- \`vigthoria review <file>\` (or \`vig r\`) - Code quality review
|
|
264
|
+
|
|
265
|
+
### Repository Commands (Vigthoria Community - NOT GitHub):
|
|
266
|
+
- \`vigthoria repo push\` - Push project to Vigthoria Community repo
|
|
267
|
+
- \`vigthoria repo pull <name>\` - Pull project from Vigthoria repo
|
|
268
|
+
- \`vigthoria repo list\` - List your projects in Vigthoria repo
|
|
269
|
+
- \`vigthoria repo status\` - Show sync status
|
|
270
|
+
- \`vigthoria repo share <name>\` - Generate shareable link
|
|
271
|
+
- \`vigthoria repo clone <url>\` - Clone a public project
|
|
272
|
+
- \`vigthoria repo delete <name>\` - Remove from repo
|
|
273
|
+
|
|
274
|
+
### Hub/Marketplace Commands (Vigthoria API Modules):
|
|
275
|
+
- \`vigthoria hub discover\` - Interactive module discovery
|
|
276
|
+
- \`vigthoria hub list\` - List all API modules
|
|
277
|
+
- \`vigthoria hub search <query>\` - Semantic search for modules
|
|
278
|
+
- \`vigthoria hub activate <module>\` - Enable pay-as-you-go for module
|
|
279
|
+
- \`vigthoria hub active\` - Show your active modules
|
|
280
|
+
- \`vigthoria hub info <module>\` - Get module details
|
|
281
|
+
|
|
282
|
+
### Deployment Commands (Vigthoria Hosting):
|
|
283
|
+
- \`vigthoria deploy preview\` - Deploy to free preview URL
|
|
284
|
+
- \`vigthoria deploy subdomain <name>\` - Deploy to yourname.vigthoria.io
|
|
285
|
+
- \`vigthoria deploy custom <domain>\` - Deploy to custom domain
|
|
286
|
+
- \`vigthoria deploy list\` - List your deployments
|
|
287
|
+
- \`vigthoria deploy plans\` - Show hosting plans/pricing
|
|
288
|
+
- \`vigthoria deploy status\` - Check deployment status
|
|
289
|
+
- \`vigthoria deploy verify <domain>\` - Verify DNS config
|
|
290
|
+
- \`vigthoria deploy remove <domain>\` - Remove deployment
|
|
291
|
+
|
|
292
|
+
### Account & Config Commands:
|
|
293
|
+
- \`vigthoria login\` - Authenticate with Vigthoria
|
|
294
|
+
- \`vigthoria logout\` - Logout from account
|
|
295
|
+
- \`vigthoria status\` - Show auth & subscription status
|
|
296
|
+
- \`vigthoria config\` - Configure CLI settings
|
|
297
|
+
- \`vigthoria update\` - Check for updates & upgrade CLI
|
|
298
|
+
- \`vigthoria init\` - Initialize Vigthoria in project
|
|
299
|
+
|
|
300
|
+
## NATURAL LANGUAGE UNDERSTANDING (Interpret User Intent):
|
|
301
|
+
When users say these phrases, understand their intent:
|
|
302
|
+
- "push it", "upload this", "save to repo" → Run \`vigthoria repo push\`
|
|
303
|
+
- "pull my project", "download from repo" → Run \`vigthoria repo pull\`
|
|
304
|
+
- "deploy this", "host it", "put it online" → Run \`vigthoria deploy\`
|
|
305
|
+
- "show my repos", "list projects" → Run \`vigthoria repo list\`
|
|
306
|
+
- "share this project" → Run \`vigthoria repo share\`
|
|
307
|
+
- "check for updates", "upgrade cli" → Run \`vigthoria update\`
|
|
308
|
+
- "what APIs are available", "show modules" → Run \`vigthoria hub list\`
|
|
309
|
+
- "enable music api", "activate <module>" → Run \`vigthoria hub activate\`
|
|
310
|
+
- "my deployments", "where is it hosted" → Run \`vigthoria deploy list\`
|
|
311
|
+
- "make it live", "publish" → Run \`vigthoria deploy\`
|
|
312
|
+
- "fix bugs", "debug this" → Run \`vigthoria fix <file>\`
|
|
313
|
+
- "explain this code" → Run \`vigthoria explain <file>\`
|
|
314
|
+
- "review my code" → Run \`vigthoria review <file>\`
|
|
315
|
+
- "create a component", "generate code for" → Run \`vigthoria generate\`
|
|
316
|
+
|
|
317
|
+
## Special Chat Commands (user may use these in chat):
|
|
228
318
|
- /file <path> - Read and include a file in context
|
|
229
319
|
- /edit <path> - Switch to file editing mode
|
|
230
320
|
- /diff - Show pending changes
|
|
@@ -309,14 +399,44 @@ Special Commands (user may use these):
|
|
|
309
399
|
input: process.stdin,
|
|
310
400
|
output: process.stdout,
|
|
311
401
|
prompt: chalk.cyan('you › '),
|
|
402
|
+
terminal: true,
|
|
312
403
|
});
|
|
313
404
|
|
|
314
405
|
let currentModel = options.model;
|
|
315
406
|
let pendingChanges: { file: string; content: string } | null = null;
|
|
407
|
+
let isRunning = true;
|
|
408
|
+
|
|
409
|
+
// Handle unexpected close events
|
|
410
|
+
this.rl.on('close', () => {
|
|
411
|
+
if (isRunning) {
|
|
412
|
+
console.log(chalk.yellow('\n\n⚠ Session interrupted. Saving...'));
|
|
413
|
+
if (this.currentSession && this.messages.length > 1) {
|
|
414
|
+
this.sessionManager.save(this.currentSession);
|
|
415
|
+
console.log(chalk.gray(`Session saved: ${this.currentSession.id}`));
|
|
416
|
+
}
|
|
417
|
+
console.log(chalk.cyan('Run `vigthoria chat --resume` to continue.\n'));
|
|
418
|
+
isRunning = false;
|
|
419
|
+
}
|
|
420
|
+
});
|
|
421
|
+
|
|
422
|
+
// Handle SIGINT (Ctrl+C) gracefully
|
|
423
|
+
process.on('SIGINT', () => {
|
|
424
|
+
if (isRunning) {
|
|
425
|
+
isRunning = false;
|
|
426
|
+
console.log(chalk.yellow('\n\nExiting...'));
|
|
427
|
+
if (this.currentSession && this.messages.length > 1) {
|
|
428
|
+
this.sessionManager.save(this.currentSession);
|
|
429
|
+
console.log(chalk.gray(`Session saved: ${this.currentSession.id}`));
|
|
430
|
+
}
|
|
431
|
+
console.log(chalk.cyan('Goodbye! 👋\n'));
|
|
432
|
+
process.exit(0);
|
|
433
|
+
}
|
|
434
|
+
});
|
|
316
435
|
|
|
317
436
|
this.rl.prompt();
|
|
318
437
|
|
|
319
438
|
for await (const line of this.rl) {
|
|
439
|
+
if (!isRunning) break;
|
|
320
440
|
const input = line.trim();
|
|
321
441
|
|
|
322
442
|
if (!input) {
|
|
@@ -340,8 +460,24 @@ Special Commands (user may use these):
|
|
|
340
460
|
|
|
341
461
|
case 'model':
|
|
342
462
|
if (args[0]) {
|
|
343
|
-
|
|
344
|
-
|
|
463
|
+
const newModel = args[0];
|
|
464
|
+
currentModel = newModel;
|
|
465
|
+
|
|
466
|
+
// Show branded model name
|
|
467
|
+
const modelInfo = this.config.getAvailableModels().find(m => m.id === newModel);
|
|
468
|
+
const isCloud = this.config.isCloudModel(newModel);
|
|
469
|
+
|
|
470
|
+
if (isCloud) {
|
|
471
|
+
console.log();
|
|
472
|
+
console.log(chalk.magenta(' ☁️ Switched to: ') + chalk.magenta.bold(modelInfo?.name || 'Vigthoria Cloud'));
|
|
473
|
+
console.log(chalk.gray(' 671B cloud model - ideal for complex tasks'));
|
|
474
|
+
console.log();
|
|
475
|
+
} else {
|
|
476
|
+
console.log();
|
|
477
|
+
console.log(chalk.green(' 🏠 Switched to: ') + chalk.green.bold(modelInfo?.name || newModel));
|
|
478
|
+
console.log(chalk.gray(' Local model - fast, no API costs'));
|
|
479
|
+
console.log();
|
|
480
|
+
}
|
|
345
481
|
} else {
|
|
346
482
|
this.printModels();
|
|
347
483
|
}
|
|
@@ -521,6 +657,9 @@ Special Commands (user may use these):
|
|
|
521
657
|
}
|
|
522
658
|
|
|
523
659
|
// Regular chat message
|
|
660
|
+
// Check if we should suggest Cloud upgrade for complex tasks
|
|
661
|
+
this.suggestCloudUpgrade(currentModel, input);
|
|
662
|
+
|
|
524
663
|
await this.chat(input, currentModel);
|
|
525
664
|
|
|
526
665
|
// Save message to session
|
|
@@ -579,7 +718,22 @@ Special Commands (user may use these):
|
|
|
579
718
|
|
|
580
719
|
} catch (error) {
|
|
581
720
|
spinner.stop();
|
|
582
|
-
|
|
721
|
+
const errMsg = (error as Error).message || 'Unknown error';
|
|
722
|
+
|
|
723
|
+
// Check for specific error types
|
|
724
|
+
if (errMsg.includes('ECONNREFUSED') || errMsg.includes('ENOTFOUND')) {
|
|
725
|
+
this.logger.error('Connection failed: Unable to reach AI service');
|
|
726
|
+
console.log(chalk.gray(' Check your internet connection or try again later.'));
|
|
727
|
+
} else if (errMsg.includes('timeout') || errMsg.includes('ETIMEDOUT')) {
|
|
728
|
+
this.logger.error('Request timed out: AI service took too long to respond');
|
|
729
|
+
console.log(chalk.gray(' Try a shorter query or check service status.'));
|
|
730
|
+
} else if (errMsg.includes('401') || errMsg.includes('Unauthorized')) {
|
|
731
|
+
this.logger.error('Authentication failed: Your session may have expired');
|
|
732
|
+
console.log(chalk.gray(' Run `vigthoria login` to re-authenticate.'));
|
|
733
|
+
} else {
|
|
734
|
+
this.logger.error('Failed to get response:', errMsg);
|
|
735
|
+
}
|
|
736
|
+
|
|
583
737
|
// Remove failed user message
|
|
584
738
|
this.messages.pop();
|
|
585
739
|
}
|
|
@@ -782,6 +936,18 @@ Special Commands (user may use these):
|
|
|
782
936
|
console.log(chalk.cyan('/exit') + ' - Exit Vigthoria (auto-saves)');
|
|
783
937
|
console.log(chalk.cyan('/quit') + ' - Same as /exit');
|
|
784
938
|
console.log();
|
|
939
|
+
console.log(chalk.yellow('── CLI Commands (run in terminal) ──'));
|
|
940
|
+
console.log(chalk.gray(' vigthoria repo push - Push to Vigthoria Community'));
|
|
941
|
+
console.log(chalk.gray(' vigthoria repo pull - Pull from your repos'));
|
|
942
|
+
console.log(chalk.gray(' vigthoria deploy - Deploy & host project'));
|
|
943
|
+
console.log(chalk.gray(' vigthoria hub - Browse API modules'));
|
|
944
|
+
console.log(chalk.gray(' vigthoria update - Update CLI to latest'));
|
|
945
|
+
console.log();
|
|
946
|
+
console.log(chalk.yellow('💡 Natural Language Tips:'));
|
|
947
|
+
console.log(chalk.gray(' Say "push it" → I\'ll help with vigthoria repo push'));
|
|
948
|
+
console.log(chalk.gray(' Say "deploy this" → I\'ll guide you through hosting'));
|
|
949
|
+
console.log(chalk.gray(' Say "what APIs are available" → I\'ll show hub modules'));
|
|
950
|
+
console.log();
|
|
785
951
|
|
|
786
952
|
if (this.agentMode) {
|
|
787
953
|
console.log(chalk.yellow('Agent Mode Tools:'));
|
|
@@ -876,10 +1042,60 @@ Special Commands (user may use these):
|
|
|
876
1042
|
const models = this.config.getAvailableModels();
|
|
877
1043
|
|
|
878
1044
|
console.log();
|
|
879
|
-
this.logger.section('
|
|
880
|
-
|
|
881
|
-
|
|
1045
|
+
this.logger.section('═══ VIGTHORIA MODELS ═══');
|
|
1046
|
+
console.log();
|
|
1047
|
+
|
|
1048
|
+
// Group by tier
|
|
1049
|
+
const localModels = models.filter(m => m.tier === 'local');
|
|
1050
|
+
const cloudModels = models.filter(m => m.tier === 'cloud');
|
|
1051
|
+
|
|
1052
|
+
console.log(chalk.green.bold(' 🏠 VIGTHORIA LOCAL (Self-hosted, fast, no API cost)'));
|
|
1053
|
+
console.log(chalk.gray(' ─────────────────────────────────────────────────'));
|
|
1054
|
+
localModels.forEach(m => {
|
|
1055
|
+
const isDefault = m.id === 'code';
|
|
1056
|
+
const marker = isDefault ? chalk.yellow(' ★ DEFAULT') : '';
|
|
1057
|
+
console.log(chalk.cyan(' ' + m.id.padEnd(15)) + chalk.white(m.name.padEnd(25)) + chalk.gray(m.description) + marker);
|
|
882
1058
|
});
|
|
1059
|
+
|
|
1060
|
+
if (cloudModels.length > 0) {
|
|
1061
|
+
console.log();
|
|
1062
|
+
console.log(chalk.magenta.bold(' ☁️ VIGTHORIA CLOUD (Premium, for complex tasks)'));
|
|
1063
|
+
console.log(chalk.gray(' ─────────────────────────────────────────────────'));
|
|
1064
|
+
cloudModels.forEach(m => {
|
|
1065
|
+
console.log(chalk.cyan(' ' + m.id.padEnd(15)) + chalk.white(m.name.padEnd(25)) + chalk.gray(m.description));
|
|
1066
|
+
});
|
|
1067
|
+
console.log();
|
|
1068
|
+
console.log(chalk.yellow(' 💡 Tip: Use /model cloud for complex multi-file tasks'));
|
|
1069
|
+
} else {
|
|
1070
|
+
console.log();
|
|
1071
|
+
console.log(chalk.yellow(' 💡 Upgrade to Pro for Vigthoria Cloud (671B models)'));
|
|
1072
|
+
}
|
|
883
1073
|
console.log();
|
|
884
1074
|
}
|
|
1075
|
+
|
|
1076
|
+
// Suggest Cloud upgrade for complex tasks
|
|
1077
|
+
private suggestCloudUpgrade(currentModel: string, prompt: string): boolean {
|
|
1078
|
+
// Don't suggest if already on cloud
|
|
1079
|
+
if (this.config.isCloudModel(currentModel)) {
|
|
1080
|
+
return false;
|
|
1081
|
+
}
|
|
1082
|
+
|
|
1083
|
+
// Check if task seems complex
|
|
1084
|
+
if (this.config.isComplexTask(prompt)) {
|
|
1085
|
+
console.log();
|
|
1086
|
+
console.log(chalk.yellow('╔══════════════════════════════════════════════════════════╗'));
|
|
1087
|
+
console.log(chalk.yellow('║') + chalk.white.bold(' 💡 This looks like a complex task! ') + chalk.yellow('║'));
|
|
1088
|
+
console.log(chalk.yellow('║') + chalk.gray(' Current: ') + chalk.cyan(currentModel.padEnd(43)) + chalk.yellow('║'));
|
|
1089
|
+
console.log(chalk.yellow('║') + chalk.gray(' Suggested: ') + chalk.magenta('Vigthoria Cloud (671B)'.padEnd(41)) + chalk.yellow('║'));
|
|
1090
|
+
console.log(chalk.yellow('║ ║'));
|
|
1091
|
+
console.log(chalk.yellow('║') + chalk.white(' Type ') + chalk.cyan('/model cloud') + chalk.white(' for better results on: ') + chalk.yellow('║'));
|
|
1092
|
+
console.log(chalk.yellow('║') + chalk.gray(' • Multi-file refactoring ') + chalk.yellow('║'));
|
|
1093
|
+
console.log(chalk.yellow('║') + chalk.gray(' • Architecture decisions ') + chalk.yellow('║'));
|
|
1094
|
+
console.log(chalk.yellow('║') + chalk.gray(' • Complex feature implementation ') + chalk.yellow('║'));
|
|
1095
|
+
console.log(chalk.yellow('╚══════════════════════════════════════════════════════════╝'));
|
|
1096
|
+
console.log();
|
|
1097
|
+
return true;
|
|
1098
|
+
}
|
|
1099
|
+
return false;
|
|
1100
|
+
}
|
|
885
1101
|
}
|
package/src/index.ts
CHANGED
|
@@ -157,11 +157,12 @@ async function main() {
|
|
|
157
157
|
});
|
|
158
158
|
|
|
159
159
|
// Agent command - Agentic mode (Vigthoria Autonomous)
|
|
160
|
+
// Uses Vigthoria v3 Code 30B or Vigthoria Cloud for complex tasks
|
|
160
161
|
program
|
|
161
162
|
.command('agent')
|
|
162
163
|
.alias('a')
|
|
163
164
|
.description('Start agentic mode - AI can read/write files, run commands')
|
|
164
|
-
.option('-m, --model <model>', 'Select AI model', 'code')
|
|
165
|
+
.option('-m, --model <model>', 'Select AI model (code, cloud, ultra)', 'code')
|
|
165
166
|
.option('-p, --project <path>', 'Set project context path', process.cwd())
|
|
166
167
|
.option('--auto-approve', 'Auto-approve all actions (dangerous!)', false)
|
|
167
168
|
.action(async (options) => {
|
package/src/utils/api.ts
CHANGED
|
@@ -73,7 +73,7 @@ export class APIClient {
|
|
|
73
73
|
httpsAgent,
|
|
74
74
|
headers: {
|
|
75
75
|
'Content-Type': 'application/json',
|
|
76
|
-
'User-Agent': `Vigthoria-CLI/${process.env.npm_package_version || '1.
|
|
76
|
+
'User-Agent': `Vigthoria-CLI/${process.env.npm_package_version || '1.5.7'}`,
|
|
77
77
|
},
|
|
78
78
|
});
|
|
79
79
|
|
|
@@ -84,7 +84,7 @@ export class APIClient {
|
|
|
84
84
|
httpsAgent,
|
|
85
85
|
headers: {
|
|
86
86
|
'Content-Type': 'application/json',
|
|
87
|
-
'User-Agent': `Vigthoria-CLI/${process.env.npm_package_version || '1.
|
|
87
|
+
'User-Agent': `Vigthoria-CLI/${process.env.npm_package_version || '1.5.7'}`,
|
|
88
88
|
},
|
|
89
89
|
});
|
|
90
90
|
|
|
@@ -231,18 +231,21 @@ export class APIClient {
|
|
|
231
231
|
}
|
|
232
232
|
|
|
233
233
|
/**
|
|
234
|
-
* Chat API -
|
|
234
|
+
* Chat API - SIMPLIFIED Architecture (NO Ollama!)
|
|
235
235
|
*
|
|
236
|
-
*
|
|
237
|
-
*
|
|
236
|
+
* 1. Vigthoria Cloud API (coder.vigthoria.io) - Primary for authenticated users
|
|
237
|
+
* 2. Vigthoria Inference Service (port 8010) - Native 30B model
|
|
238
|
+
* 3. Model Router (port 4009) - Routes to OpenRouter (Kimi K2.5, DeepSeek)
|
|
239
|
+
*
|
|
240
|
+
* NO OLLAMA FALLBACK - That causes hallucinations with small models!
|
|
238
241
|
*/
|
|
239
242
|
async chat(messages: ChatMessage[], model: string, useLocal: boolean = false): Promise<ChatResponse> {
|
|
240
243
|
const resolvedModel = this.resolveModelId(model);
|
|
241
244
|
|
|
242
|
-
//
|
|
243
|
-
if (
|
|
245
|
+
// STRATEGY 1: Vigthoria Cloud API (authenticated users)
|
|
246
|
+
if (this.config.isAuthenticated()) {
|
|
244
247
|
try {
|
|
245
|
-
this.logger.debug(`
|
|
248
|
+
this.logger.debug(`Vigthoria Cloud API: ${resolvedModel}`);
|
|
246
249
|
const response = await this.client.post('/api/ai/chat', {
|
|
247
250
|
messages,
|
|
248
251
|
model: resolvedModel,
|
|
@@ -258,118 +261,62 @@ export class APIClient {
|
|
|
258
261
|
usage: response.data.usage,
|
|
259
262
|
};
|
|
260
263
|
}
|
|
261
|
-
this.logger.debug(`Cloud API returned success=false
|
|
264
|
+
this.logger.debug(`Cloud API returned success=false`);
|
|
262
265
|
} catch (error: any) {
|
|
263
266
|
const errMsg = error.response?.data?.error || error.message || 'Unknown error';
|
|
264
|
-
|
|
265
|
-
|
|
267
|
+
this.logger.debug(`Vigthoria Cloud API failed: ${errMsg}`);
|
|
268
|
+
// Continue to fallback strategies
|
|
266
269
|
}
|
|
267
|
-
} else {
|
|
268
|
-
this.logger.debug(`Skipping cloud API - useLocal: ${useLocal}, isAuthenticated: ${this.config.isAuthenticated()}`);
|
|
269
270
|
}
|
|
270
271
|
|
|
271
|
-
//
|
|
272
|
+
// STRATEGY 2: Vigthoria Inference Service (port 8010) - Native 30B model
|
|
272
273
|
try {
|
|
274
|
+
this.logger.debug(`Trying Vigthoria Inference Service (8010): ${resolvedModel}`);
|
|
273
275
|
const response = await axios.post('http://localhost:8010/v1/chat/completions', {
|
|
274
276
|
model: resolvedModel,
|
|
275
277
|
messages,
|
|
276
278
|
max_tokens: this.config.get('preferences').maxTokens,
|
|
277
279
|
temperature: 0.7,
|
|
278
280
|
stream: false,
|
|
279
|
-
}, { timeout:
|
|
281
|
+
}, { timeout: 180000 }); // 3 min timeout for 30B model
|
|
280
282
|
|
|
281
283
|
if (response.data.choices && response.data.choices.length > 0) {
|
|
282
284
|
return {
|
|
283
|
-
id: response.data.id || `vigthoria-
|
|
285
|
+
id: response.data.id || `vigthoria-inference-${Date.now()}`,
|
|
284
286
|
message: response.data.choices[0].message?.content || response.data.choices[0].text,
|
|
285
287
|
model: response.data.model || model,
|
|
286
288
|
usage: response.data.usage,
|
|
287
289
|
};
|
|
288
290
|
}
|
|
289
291
|
} catch (error) {
|
|
290
|
-
this.logger.debug('Vigthoria Inference
|
|
292
|
+
this.logger.debug('Vigthoria Inference Service (8010) unavailable');
|
|
291
293
|
}
|
|
292
294
|
|
|
293
|
-
//
|
|
295
|
+
// STRATEGY 3: Model Router (port 4009) - Routes to OpenRouter (Kimi/DeepSeek)
|
|
294
296
|
try {
|
|
295
|
-
|
|
296
|
-
|
|
297
|
+
this.logger.debug(`Trying Model Router (4009): ${resolvedModel}`);
|
|
298
|
+
const response = await axios.post('http://localhost:4009/v1/chat/completions', {
|
|
297
299
|
model: resolvedModel,
|
|
298
|
-
|
|
300
|
+
messages,
|
|
301
|
+
max_tokens: this.config.get('preferences').maxTokens,
|
|
299
302
|
temperature: 0.7,
|
|
300
303
|
stream: false,
|
|
301
|
-
}, { timeout:
|
|
304
|
+
}, { timeout: 180000 });
|
|
302
305
|
|
|
303
|
-
if (response.data.
|
|
306
|
+
if (response.data.choices && response.data.choices.length > 0) {
|
|
304
307
|
return {
|
|
305
308
|
id: response.data.id || `router-${Date.now()}`,
|
|
306
|
-
message: response.data.
|
|
309
|
+
message: response.data.choices[0].message?.content || response.data.choices[0].text,
|
|
307
310
|
model: response.data.model || model,
|
|
308
311
|
usage: response.data.usage,
|
|
309
312
|
};
|
|
310
313
|
}
|
|
311
314
|
} catch (error) {
|
|
312
|
-
this.logger.debug('Model Router (4009)
|
|
315
|
+
this.logger.debug('Model Router (4009) unavailable');
|
|
313
316
|
}
|
|
314
317
|
|
|
315
|
-
//
|
|
316
|
-
|
|
317
|
-
const ollamaModel = this.resolveToOllamaModel(model);
|
|
318
|
-
const prompt = this.formatMessagesForOllama(messages);
|
|
319
|
-
|
|
320
|
-
const response = await axios.post('http://localhost:11434/api/generate', {
|
|
321
|
-
model: ollamaModel,
|
|
322
|
-
prompt,
|
|
323
|
-
stream: false,
|
|
324
|
-
}, { timeout: 120000 });
|
|
325
|
-
|
|
326
|
-
return {
|
|
327
|
-
id: `ollama-${Date.now()}`,
|
|
328
|
-
message: response.data.response,
|
|
329
|
-
model: ollamaModel,
|
|
330
|
-
usage: {
|
|
331
|
-
prompt_tokens: response.data.prompt_eval_count || 0,
|
|
332
|
-
completion_tokens: response.data.eval_count || 0,
|
|
333
|
-
total_tokens: (response.data.prompt_eval_count || 0) + (response.data.eval_count || 0),
|
|
334
|
-
},
|
|
335
|
-
};
|
|
336
|
-
} catch (error) {
|
|
337
|
-
this.logger.debug('Ollama failed...');
|
|
338
|
-
}
|
|
339
|
-
|
|
340
|
-
throw new Error('AI service unavailable. Please check your authentication with `vigthoria login` or try again later.');
|
|
341
|
-
}
|
|
342
|
-
|
|
343
|
-
// Map CLI model names to Ollama model names (for local/offline fallback)
|
|
344
|
-
// Vigthoria_v3_Code_30B runs on qwen3-coder base via Vigthoria Cloud
|
|
345
|
-
// Local users with Ollama can use the base model for offline work
|
|
346
|
-
private resolveToOllamaModel(model: string): string {
|
|
347
|
-
const ollamaMap: Record<string, string> = {
|
|
348
|
-
'fast': 'qwen3:0.6b',
|
|
349
|
-
'mini': 'smollm2:135m',
|
|
350
|
-
'code': 'qwen3-coder:latest', // Vigthoria_v3_Code_30B (cloud) / qwen3-coder (local fallback)
|
|
351
|
-
'balanced': 'phi3:mini',
|
|
352
|
-
'creative': 'gemma3:latest',
|
|
353
|
-
'vigthoria-fast-1.7b': 'qwen3:0.6b',
|
|
354
|
-
'vigthoria-mini-0.6b': 'smollm2:135m',
|
|
355
|
-
'vigthoria-v3-code-30b': 'qwen3-coder:latest', // Vigthoria_v3_Code_30B
|
|
356
|
-
'vigthoria-v2-code-8b': 'qwen3-coder:latest', // Legacy v2
|
|
357
|
-
'vigthoria-balanced-4b': 'phi3:mini',
|
|
358
|
-
'vigthoria-creative-9b-v4': 'gemma3:latest',
|
|
359
|
-
};
|
|
360
|
-
return ollamaMap[model] || model;
|
|
361
|
-
}
|
|
362
|
-
|
|
363
|
-
// Format messages for Ollama's generate API
|
|
364
|
-
private formatMessagesForOllama(messages: ChatMessage[]): string {
|
|
365
|
-
return messages
|
|
366
|
-
.filter(m => m.role !== 'system' || messages.indexOf(m) === 0)
|
|
367
|
-
.map(m => {
|
|
368
|
-
if (m.role === 'system') return `System: ${m.content}\n\n`;
|
|
369
|
-
if (m.role === 'user') return `User: ${m.content}\n`;
|
|
370
|
-
return `Assistant: ${m.content}\n`;
|
|
371
|
-
})
|
|
372
|
-
.join('') + 'Assistant:';
|
|
318
|
+
// NO OLLAMA FALLBACK! That causes hallucinations!
|
|
319
|
+
throw new Error('AI service unavailable. Please ensure Vigthoria services are running or login with `vigthoria login`.');
|
|
373
320
|
}
|
|
374
321
|
|
|
375
322
|
// Streaming chat
|
|
@@ -543,108 +490,51 @@ export class APIClient {
|
|
|
543
490
|
return response.data;
|
|
544
491
|
}
|
|
545
492
|
|
|
546
|
-
// Model resolution - maps
|
|
493
|
+
// Model resolution - maps Vigthoria model names to internal IDs
|
|
494
|
+
// INTERNAL USE ONLY - users see only Vigthoria branding
|
|
547
495
|
private resolveModelId(shortName: string): string {
|
|
548
496
|
const modelMap: Record<string, string> = {
|
|
549
497
|
// ═══════════════════════════════════════════════════════════════
|
|
550
|
-
//
|
|
498
|
+
// VIGTHORIA LOCAL - Self-hosted models
|
|
551
499
|
// ═══════════════════════════════════════════════════════════════
|
|
552
500
|
'fast': 'vigthoria-fast-1.7b',
|
|
553
|
-
'mini': 'vigthoria-
|
|
501
|
+
'mini': 'vigthoria-fast-1.7b',
|
|
554
502
|
'balanced': 'vigthoria-balanced-4b',
|
|
555
|
-
|
|
556
|
-
// Code Models - Current & Future Versions
|
|
557
|
-
'code': 'vigthoria-v2-code-8b',
|
|
558
|
-
'code-v2': 'vigthoria-v2-code-8b',
|
|
559
|
-
'code-v2-8b': 'vigthoria-v2-code-8b',
|
|
560
|
-
'code-v3': 'vigthoria-v3-code-8b', // Future
|
|
561
|
-
'code-v3-8b': 'vigthoria-v3-code-8b', // Future
|
|
562
|
-
'code-v3-32b': 'vigthoria-v3-code-32b', // Future large model
|
|
563
|
-
'code-v4': 'vigthoria-v4-code-8b', // Future
|
|
564
|
-
'code-32b': 'vigthoria-v3-code-32b', // Future large model alias
|
|
565
|
-
|
|
566
|
-
// Creative Models
|
|
567
503
|
'creative': 'vigthoria-creative-9b-v4',
|
|
568
|
-
'creative-v3': 'vigthoria-creative-9b-v3',
|
|
569
|
-
'creative-v4': 'vigthoria-creative-9b-v4',
|
|
570
|
-
|
|
571
|
-
// Music Model
|
|
572
|
-
'music': 'vigthoria-music-master-4b',
|
|
573
|
-
'music-master': 'vigthoria-music-master-4b',
|
|
574
504
|
|
|
575
|
-
//
|
|
576
|
-
'
|
|
577
|
-
'
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
'master': 'vigthoria_master:latest',
|
|
581
|
-
'c1': 'vigthoria_c1_m:latest',
|
|
582
|
-
'm1': 'vigthoria_m1_m:latest',
|
|
505
|
+
// Code Models - 30B is the default powerhouse
|
|
506
|
+
'code': 'qwen3-coder:latest', // Internal: qwen3-coder 30B
|
|
507
|
+
'code-30b': 'qwen3-coder:latest',
|
|
508
|
+
'code-8b': 'vigthoria-v2-code-8b',
|
|
509
|
+
'pro': 'qwen3-coder:latest',
|
|
583
510
|
|
|
584
511
|
// ═══════════════════════════════════════════════════════════════
|
|
585
|
-
//
|
|
512
|
+
// VIGTHORIA CLOUD - Premium cloud models (internal routing)
|
|
586
513
|
// ═══════════════════════════════════════════════════════════════
|
|
587
|
-
'
|
|
588
|
-
'
|
|
589
|
-
'
|
|
590
|
-
'
|
|
591
|
-
'deepseek-r1': 'deepseek-r1:8b',
|
|
592
|
-
'deepseek-r1-32b': 'deepseek-r1:32b',
|
|
593
|
-
'llama3': 'llama3:8b-instruct-q4_0',
|
|
594
|
-
'mixtral': 'mixtral:8x7b-instruct-v0.1-q4_K_M',
|
|
514
|
+
'cloud': 'deepseek-v3.1:671b-cloud',
|
|
515
|
+
'cloud-reason': 'moonshotai/kimi-k2.5',
|
|
516
|
+
'agent': 'deepseek-v3.1:671b-cloud',
|
|
517
|
+
'ultra': 'deepseek-v3.1:671b-cloud',
|
|
595
518
|
};
|
|
596
519
|
|
|
597
|
-
// If already a full model ID
|
|
598
|
-
if (shortName.includes('vigthoria') || shortName.includes('
|
|
599
|
-
// Check if it's a known short name first
|
|
520
|
+
// If already a full model ID, return as-is
|
|
521
|
+
if (shortName.includes('vigthoria') || shortName.includes('/') || shortName.includes(':')) {
|
|
600
522
|
if (modelMap[shortName]) {
|
|
601
523
|
return modelMap[shortName];
|
|
602
524
|
}
|
|
603
|
-
// Otherwise assume it's a direct model ID
|
|
604
525
|
return shortName;
|
|
605
526
|
}
|
|
606
527
|
|
|
607
|
-
return modelMap[shortName] ||
|
|
528
|
+
return modelMap[shortName] || 'qwen3-coder:latest'; // Default to 30B
|
|
608
529
|
}
|
|
609
530
|
|
|
610
|
-
// Health check
|
|
531
|
+
// Health check
|
|
611
532
|
async healthCheck(): Promise<boolean> {
|
|
612
|
-
const apiUrl = this.config.get('apiUrl') || 'https://coder.vigthoria.io';
|
|
613
|
-
|
|
614
533
|
try {
|
|
615
|
-
|
|
616
|
-
const response = await this.client.get('/api/health', {
|
|
617
|
-
timeout: 10000, // 10 second timeout for health check
|
|
618
|
-
});
|
|
534
|
+
const response = await this.client.get('/api/health', { timeout: 10000 });
|
|
619
535
|
return response.data?.status === 'ok' || response.data?.healthy === true;
|
|
620
|
-
} catch
|
|
621
|
-
|
|
622
|
-
try {
|
|
623
|
-
const fallback = await this.client.get('/health', {
|
|
624
|
-
timeout: 5000,
|
|
625
|
-
});
|
|
626
|
-
return fallback.data?.status === 'ok' || fallback.data?.healthy === true || fallback.status === 200;
|
|
627
|
-
} catch {
|
|
628
|
-
// Fallback 2: try native fetch (Node 18+ built-in, works better on Windows)
|
|
629
|
-
try {
|
|
630
|
-
const controller = new AbortController();
|
|
631
|
-
const timeoutId = setTimeout(() => controller.abort(), 5000);
|
|
632
|
-
|
|
633
|
-
const fetchResponse = await fetch(`${apiUrl}/health`, {
|
|
634
|
-
method: 'GET',
|
|
635
|
-
signal: controller.signal,
|
|
636
|
-
});
|
|
637
|
-
clearTimeout(timeoutId);
|
|
638
|
-
|
|
639
|
-
if (fetchResponse.ok) {
|
|
640
|
-
const data = await fetchResponse.json() as { status?: string; healthy?: boolean };
|
|
641
|
-
return data?.status === 'ok' || data?.healthy === true;
|
|
642
|
-
}
|
|
643
|
-
return fetchResponse.ok;
|
|
644
|
-
} catch {
|
|
645
|
-
return false;
|
|
646
|
-
}
|
|
647
|
-
}
|
|
536
|
+
} catch {
|
|
537
|
+
return false;
|
|
648
538
|
}
|
|
649
539
|
}
|
|
650
540
|
}
|