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.
@@ -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
- Project Context:
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
- Special Commands (user may use these):
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
- currentModel = args[0];
344
- this.logger.success(`Model switched to: ${currentModel}`);
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
- this.logger.error('Failed to get response:', (error as Error).message);
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('Available Models');
880
- models.forEach(m => {
881
- console.log(chalk.cyan(m.id.padEnd(20)) + chalk.gray(m.description));
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.4.5'}`,
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.4.5'}`,
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 - Supports multiple inference strategies
234
+ * Chat API - SIMPLIFIED Architecture (NO Ollama!)
235
235
  *
236
- * For authenticated users: Uses Vigthoria Cloud API
237
- * For local users: Uses local Ollama or Model Router
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
- // If authenticated and not forcing local, use Vigthoria Cloud API
243
- if (!useLocal && this.config.isAuthenticated()) {
245
+ // STRATEGY 1: Vigthoria Cloud API (authenticated users)
246
+ if (this.config.isAuthenticated()) {
244
247
  try {
245
- this.logger.debug(`Attempting Vigthoria Cloud API call to /api/ai/chat with model: ${resolvedModel}`);
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: ${JSON.stringify(response.data)}`);
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
- const status = error.response?.status || 'no status';
265
- this.logger.debug(`Vigthoria Cloud API failed (${status}): ${errMsg}`);
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
- // Strategy 1: Try Vigthoria Inference Server directly (NATIVE models on port 8010)
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: 120000 });
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-native-${Date.now()}`,
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 Server (8010) failed, trying Model Router...');
292
+ this.logger.debug('Vigthoria Inference Service (8010) unavailable');
291
293
  }
292
294
 
293
- // Strategy 2: Try local Model Router's Vigthoria chat endpoint
295
+ // STRATEGY 3: Model Router (port 4009) - Routes to OpenRouter (Kimi/DeepSeek)
294
296
  try {
295
- const response = await axios.post('http://localhost:4009/api/vigthoria/chat', {
296
- messages,
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
- maxTokens: this.config.get('preferences').maxTokens,
300
+ messages,
301
+ max_tokens: this.config.get('preferences').maxTokens,
299
302
  temperature: 0.7,
300
303
  stream: false,
301
- }, { timeout: 120000 });
304
+ }, { timeout: 180000 });
302
305
 
303
- if (response.data.success !== false) {
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.response || response.data.message || response.data.content,
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) failed, trying Ollama directly...');
315
+ this.logger.debug('Model Router (4009) unavailable');
313
316
  }
314
317
 
315
- // Strategy 3: Try Ollama directly (for local development/testing)
316
- try {
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 short names to actual Vigthoria model IDs
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
- // Vigthoria Native Models - Core Suite
498
+ // VIGTHORIA LOCAL - Self-hosted models
551
499
  // ═══════════════════════════════════════════════════════════════
552
500
  'fast': 'vigthoria-fast-1.7b',
553
- 'mini': 'vigthoria-mini-0.6b',
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
- // Aliases
576
- 'pro': 'vigthoria-balanced-4b',
577
- 'ultra': 'vigthoria-creative-9b-v4',
578
-
579
- // Legacy Vigthoria models
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
- // External Models (via Ollama fallback)
512
+ // VIGTHORIA CLOUD - Premium cloud models (internal routing)
586
513
  // ═══════════════════════════════════════════════════════════════
587
- 'qwen-coder': 'qwen2.5-coder:7b',
588
- 'qwen-coder-7b': 'qwen2.5-coder:7b',
589
- 'qwen-coder-32b': 'qwen2.5-coder:32b',
590
- 'deepseek': 'deepseek-coder-v2:latest',
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 (contains 'vigthoria' or known prefix), return as-is
598
- if (shortName.includes('vigthoria') || shortName.includes(':') || 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] || shortName;
528
+ return modelMap[shortName] || 'qwen3-coder:latest'; // Default to 30B
608
529
  }
609
530
 
610
- // Health check with short timeout and multiple fallbacks
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
- // Try the main API health endpoint first with shorter timeout
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 (error) {
621
- // Fallback 1: try root health endpoint with axios
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
  }