vigthoria-cli 1.6.1 → 1.6.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 +52 -1
- package/dist/commands/chat.d.ts +31 -45
- package/dist/commands/chat.d.ts.map +1 -1
- package/dist/commands/chat.js +374 -855
- package/dist/commands/chat.js.map +1 -1
- package/dist/commands/repo.d.ts +10 -0
- package/dist/commands/repo.d.ts.map +1 -1
- package/dist/commands/repo.js +215 -97
- package/dist/commands/repo.js.map +1 -1
- package/dist/index.js +32 -4
- package/dist/index.js.map +1 -1
- package/dist/utils/api.d.ts +8 -0
- package/dist/utils/api.d.ts.map +1 -1
- package/dist/utils/api.js +183 -42
- package/dist/utils/api.js.map +1 -1
- package/dist/utils/config.d.ts.map +1 -1
- package/dist/utils/config.js +2 -1
- package/dist/utils/config.js.map +1 -1
- package/dist/utils/tools.d.ts +3 -0
- package/dist/utils/tools.d.ts.map +1 -1
- package/dist/utils/tools.js +252 -14
- package/dist/utils/tools.js.map +1 -1
- package/package.json +13 -2
- package/install.ps1 +0 -290
- package/install.sh +0 -307
- package/src/commands/auth.ts +0 -226
- package/src/commands/chat.ts +0 -1101
- package/src/commands/config.ts +0 -306
- package/src/commands/deploy.ts +0 -609
- package/src/commands/edit.ts +0 -310
- package/src/commands/explain.ts +0 -115
- package/src/commands/generate.ts +0 -222
- package/src/commands/hub.ts +0 -382
- package/src/commands/repo.ts +0 -742
- package/src/commands/review.ts +0 -186
- package/src/index.ts +0 -601
- package/src/types/marked-terminal.d.ts +0 -31
- package/src/utils/api.ts +0 -526
- package/src/utils/config.ts +0 -241
- package/src/utils/files.ts +0 -273
- package/src/utils/logger.ts +0 -130
- package/src/utils/session.ts +0 -179
- package/src/utils/tools.ts +0 -1964
- package/test-parse.js +0 -105
- package/test-parse2.js +0 -35
- package/tsconfig.json +0 -20
package/src/utils/api.ts
DELETED
|
@@ -1,526 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* API Client for Vigthoria Backend
|
|
3
|
-
* Connects to coder.vigthoria.io API endpoints
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
import axios, { AxiosInstance, AxiosError } from 'axios';
|
|
7
|
-
import https from 'https';
|
|
8
|
-
import WebSocket from 'ws';
|
|
9
|
-
import { Config } from './config.js';
|
|
10
|
-
import { Logger } from './logger.js';
|
|
11
|
-
|
|
12
|
-
export interface ChatMessage {
|
|
13
|
-
role: 'user' | 'assistant' | 'system';
|
|
14
|
-
content: string;
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
export interface ChatResponse {
|
|
18
|
-
id: string;
|
|
19
|
-
message: string;
|
|
20
|
-
model: string;
|
|
21
|
-
usage?: {
|
|
22
|
-
prompt_tokens: number;
|
|
23
|
-
completion_tokens: number;
|
|
24
|
-
total_tokens: number;
|
|
25
|
-
};
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
export interface StreamChunk {
|
|
29
|
-
type: 'content' | 'done' | 'error';
|
|
30
|
-
content?: string;
|
|
31
|
-
error?: string;
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
export interface VigthoriUser {
|
|
35
|
-
id: string;
|
|
36
|
-
username: string;
|
|
37
|
-
email: string;
|
|
38
|
-
isAdmin: boolean;
|
|
39
|
-
subscription: {
|
|
40
|
-
plan: string;
|
|
41
|
-
projectLimit: number;
|
|
42
|
-
storageLimit: number;
|
|
43
|
-
viagen6Access: boolean;
|
|
44
|
-
aiModelsLimit: number;
|
|
45
|
-
prioritySupport: boolean;
|
|
46
|
-
teamCollaboration: boolean;
|
|
47
|
-
adminAccess: boolean;
|
|
48
|
-
};
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
export class APIClient {
|
|
52
|
-
private client: AxiosInstance;
|
|
53
|
-
private modelRouterClient: AxiosInstance;
|
|
54
|
-
private config: Config;
|
|
55
|
-
private logger: Logger;
|
|
56
|
-
private ws: WebSocket | null = null;
|
|
57
|
-
|
|
58
|
-
constructor(config: Config, logger: Logger) {
|
|
59
|
-
this.config = config;
|
|
60
|
-
this.logger = logger;
|
|
61
|
-
|
|
62
|
-
// Create HTTPS agent with proper settings for cross-platform compatibility
|
|
63
|
-
const httpsAgent = new https.Agent({
|
|
64
|
-
rejectUnauthorized: true, // Enforce SSL verification
|
|
65
|
-
keepAlive: true,
|
|
66
|
-
timeout: 30000,
|
|
67
|
-
});
|
|
68
|
-
|
|
69
|
-
// Main Vigthoria Coder API (coder.vigthoria.io)
|
|
70
|
-
this.client = axios.create({
|
|
71
|
-
baseURL: config.get('apiUrl'),
|
|
72
|
-
timeout: 120000,
|
|
73
|
-
httpsAgent,
|
|
74
|
-
headers: {
|
|
75
|
-
'Content-Type': 'application/json',
|
|
76
|
-
'User-Agent': `Vigthoria-CLI/${process.env.npm_package_version || '1.5.7'}`,
|
|
77
|
-
},
|
|
78
|
-
});
|
|
79
|
-
|
|
80
|
-
// Direct AI Models API - bypasses Coder for direct model access
|
|
81
|
-
// This is the centralized Vigthoria API that routes to Model Router
|
|
82
|
-
this.modelRouterClient = axios.create({
|
|
83
|
-
baseURL: config.get('modelsApiUrl') || 'https://api.vigthoria.io',
|
|
84
|
-
timeout: 180000, // 3 minutes for model inference
|
|
85
|
-
httpsAgent,
|
|
86
|
-
headers: {
|
|
87
|
-
'Content-Type': 'application/json',
|
|
88
|
-
'User-Agent': `Vigthoria-CLI/${process.env.npm_package_version || '1.5.9'}`,
|
|
89
|
-
},
|
|
90
|
-
});
|
|
91
|
-
|
|
92
|
-
// Add auth interceptor
|
|
93
|
-
this.client.interceptors.request.use((req) => {
|
|
94
|
-
const token = this.config.get('authToken');
|
|
95
|
-
if (token) {
|
|
96
|
-
req.headers.Authorization = `Bearer ${token}`;
|
|
97
|
-
req.headers.Cookie = `vigthoria-auth-token=${token}`;
|
|
98
|
-
}
|
|
99
|
-
return req;
|
|
100
|
-
});
|
|
101
|
-
|
|
102
|
-
this.modelRouterClient.interceptors.request.use((req) => {
|
|
103
|
-
const token = this.config.get('authToken');
|
|
104
|
-
if (token) {
|
|
105
|
-
req.headers.Authorization = `Bearer ${token}`;
|
|
106
|
-
req.headers.Cookie = `vigthoria-auth-token=${token}`;
|
|
107
|
-
}
|
|
108
|
-
return req;
|
|
109
|
-
});
|
|
110
|
-
|
|
111
|
-
// Add response interceptor for token refresh
|
|
112
|
-
this.client.interceptors.response.use(
|
|
113
|
-
(res) => res,
|
|
114
|
-
async (error: AxiosError) => {
|
|
115
|
-
if (error.response?.status === 401) {
|
|
116
|
-
const refreshed = await this.refreshToken();
|
|
117
|
-
if (refreshed && error.config) {
|
|
118
|
-
return this.client.request(error.config);
|
|
119
|
-
}
|
|
120
|
-
}
|
|
121
|
-
throw error;
|
|
122
|
-
}
|
|
123
|
-
);
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
// Authentication - Uses Vigthoria Coder /api/login endpoint
|
|
127
|
-
async login(email: string, password: string): Promise<boolean> {
|
|
128
|
-
try {
|
|
129
|
-
const response = await this.client.post('/api/login', { email, password });
|
|
130
|
-
|
|
131
|
-
if (!response.data.success) {
|
|
132
|
-
throw new Error(response.data.error || 'Login failed');
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
const { token, user } = response.data as { token: string; user: VigthoriUser };
|
|
136
|
-
|
|
137
|
-
this.config.setAuth({
|
|
138
|
-
token,
|
|
139
|
-
userId: user.id,
|
|
140
|
-
email: user.email,
|
|
141
|
-
});
|
|
142
|
-
|
|
143
|
-
// Set subscription from user data
|
|
144
|
-
this.config.setSubscription({
|
|
145
|
-
plan: user.subscription?.plan || 'developer',
|
|
146
|
-
status: 'active',
|
|
147
|
-
expiresAt: undefined,
|
|
148
|
-
});
|
|
149
|
-
|
|
150
|
-
return true;
|
|
151
|
-
} catch (error) {
|
|
152
|
-
const axiosError = error as AxiosError;
|
|
153
|
-
const message = (axiosError.response?.data as { error?: string })?.error || (error as Error).message;
|
|
154
|
-
this.logger.error('Login failed:', message);
|
|
155
|
-
return false;
|
|
156
|
-
}
|
|
157
|
-
}
|
|
158
|
-
|
|
159
|
-
async loginWithToken(token: string): Promise<boolean> {
|
|
160
|
-
try {
|
|
161
|
-
// Validate token by making a request to user info endpoint
|
|
162
|
-
this.config.set('authToken', token);
|
|
163
|
-
|
|
164
|
-
const response = await this.client.get('/api/user/profile', {
|
|
165
|
-
headers: {
|
|
166
|
-
Authorization: `Bearer ${token}`,
|
|
167
|
-
Cookie: `vigthoria-auth-token=${token}`,
|
|
168
|
-
},
|
|
169
|
-
});
|
|
170
|
-
|
|
171
|
-
if (response.data && response.data.user) {
|
|
172
|
-
const user = response.data.user;
|
|
173
|
-
|
|
174
|
-
this.config.setAuth({
|
|
175
|
-
token,
|
|
176
|
-
userId: user.id,
|
|
177
|
-
email: user.email,
|
|
178
|
-
});
|
|
179
|
-
|
|
180
|
-
this.config.setSubscription({
|
|
181
|
-
plan: user.subscription?.plan || user.subscription_plan || 'developer',
|
|
182
|
-
status: 'active',
|
|
183
|
-
expiresAt: undefined,
|
|
184
|
-
});
|
|
185
|
-
|
|
186
|
-
return true;
|
|
187
|
-
}
|
|
188
|
-
|
|
189
|
-
return false;
|
|
190
|
-
} catch (error) {
|
|
191
|
-
this.config.clearAuth();
|
|
192
|
-
this.logger.error('Token validation failed:', (error as Error).message);
|
|
193
|
-
return false;
|
|
194
|
-
}
|
|
195
|
-
}
|
|
196
|
-
|
|
197
|
-
private async refreshToken(): Promise<boolean> {
|
|
198
|
-
const refreshToken = this.config.get('refreshToken');
|
|
199
|
-
if (!refreshToken) return false;
|
|
200
|
-
|
|
201
|
-
try {
|
|
202
|
-
const response = await this.client.post('/api/token/refresh', {
|
|
203
|
-
refresh_token: refreshToken
|
|
204
|
-
});
|
|
205
|
-
const { token, access_token, refresh_token } = response.data;
|
|
206
|
-
|
|
207
|
-
this.config.set('authToken', token || access_token);
|
|
208
|
-
if (refresh_token) {
|
|
209
|
-
this.config.set('refreshToken', refresh_token);
|
|
210
|
-
}
|
|
211
|
-
|
|
212
|
-
return true;
|
|
213
|
-
} catch {
|
|
214
|
-
this.config.clearAuth();
|
|
215
|
-
return false;
|
|
216
|
-
}
|
|
217
|
-
}
|
|
218
|
-
|
|
219
|
-
async getSubscriptionStatus(): Promise<void> {
|
|
220
|
-
try {
|
|
221
|
-
const response = await this.client.get('/api/user/subscription');
|
|
222
|
-
const data = response.data;
|
|
223
|
-
|
|
224
|
-
this.config.setSubscription({
|
|
225
|
-
plan: data.plan || data.subscription_plan || 'developer',
|
|
226
|
-
status: data.status || 'active',
|
|
227
|
-
expiresAt: data.expiresAt || data.expires_at
|
|
228
|
-
});
|
|
229
|
-
} catch (error) {
|
|
230
|
-
this.logger.debug('Failed to get subscription status:', (error as Error).message);
|
|
231
|
-
}
|
|
232
|
-
}
|
|
233
|
-
|
|
234
|
-
/**
|
|
235
|
-
* Chat API - Direct Vigthoria Models API Architecture
|
|
236
|
-
*
|
|
237
|
-
* PRIMARY: api.vigthoria.io - Direct access to Vigthoria Model Router
|
|
238
|
-
* This is the centralized public API for all AI operations.
|
|
239
|
-
* Works for both authenticated and unauthenticated users.
|
|
240
|
-
*
|
|
241
|
-
* FALLBACK: Coder Cloud API - For authenticated users only
|
|
242
|
-
*
|
|
243
|
-
* NO localhost fallbacks - CLI is for external users, not server-side!
|
|
244
|
-
*/
|
|
245
|
-
async chat(messages: ChatMessage[], model: string, useLocal: boolean = false): Promise<ChatResponse> {
|
|
246
|
-
const resolvedModel = this.resolveModelId(model);
|
|
247
|
-
|
|
248
|
-
// STRATEGY 1: Direct Vigthoria Models API (api.vigthoria.io)
|
|
249
|
-
// This is the preferred method - direct access to Model Router
|
|
250
|
-
try {
|
|
251
|
-
this.logger.debug(`Direct Vigthoria Models API: ${resolvedModel}`);
|
|
252
|
-
const token = this.config.get('authToken');
|
|
253
|
-
const response = await this.modelRouterClient.post('/v1/chat/completions', {
|
|
254
|
-
model: resolvedModel,
|
|
255
|
-
messages,
|
|
256
|
-
max_tokens: this.config.get('preferences').maxTokens,
|
|
257
|
-
temperature: 0.7,
|
|
258
|
-
stream: false,
|
|
259
|
-
}, {
|
|
260
|
-
headers: token ? { Authorization: `Bearer ${token}` } : {},
|
|
261
|
-
});
|
|
262
|
-
|
|
263
|
-
if (response.data.choices && response.data.choices.length > 0) {
|
|
264
|
-
return {
|
|
265
|
-
id: response.data.id || `vigthoria-${Date.now()}`,
|
|
266
|
-
message: response.data.choices[0].message?.content || response.data.choices[0].text,
|
|
267
|
-
model: response.data.model || model,
|
|
268
|
-
usage: response.data.usage,
|
|
269
|
-
};
|
|
270
|
-
}
|
|
271
|
-
this.logger.debug('Direct API returned no choices');
|
|
272
|
-
} catch (error: any) {
|
|
273
|
-
const errMsg = error.response?.data?.error || error.message || 'Unknown error';
|
|
274
|
-
this.logger.debug(`Direct Vigthoria Models API failed: ${errMsg}`);
|
|
275
|
-
// Continue to fallback
|
|
276
|
-
}
|
|
277
|
-
|
|
278
|
-
// STRATEGY 2: Vigthoria Cloud API via Coder (authenticated users only)
|
|
279
|
-
if (this.config.isAuthenticated()) {
|
|
280
|
-
try {
|
|
281
|
-
this.logger.debug(`Vigthoria Cloud API fallback: ${resolvedModel}`);
|
|
282
|
-
const response = await this.client.post('/api/ai/chat', {
|
|
283
|
-
messages,
|
|
284
|
-
model: resolvedModel,
|
|
285
|
-
maxTokens: this.config.get('preferences').maxTokens,
|
|
286
|
-
temperature: 0.7,
|
|
287
|
-
});
|
|
288
|
-
|
|
289
|
-
if (response.data.success !== false) {
|
|
290
|
-
return {
|
|
291
|
-
id: response.data.id || `vigthoria-coder-${Date.now()}`,
|
|
292
|
-
message: response.data.response || response.data.message || response.data.content,
|
|
293
|
-
model: response.data.model || model,
|
|
294
|
-
usage: response.data.usage,
|
|
295
|
-
};
|
|
296
|
-
}
|
|
297
|
-
this.logger.debug(`Cloud API returned success=false`);
|
|
298
|
-
} catch (error: any) {
|
|
299
|
-
const errMsg = error.response?.data?.error || error.message || 'Unknown error';
|
|
300
|
-
this.logger.debug(`Vigthoria Cloud API failed: ${errMsg}`);
|
|
301
|
-
}
|
|
302
|
-
}
|
|
303
|
-
|
|
304
|
-
// No more localhost fallbacks - CLI is for external users!
|
|
305
|
-
throw new Error('AI service unavailable. Please check your internet connection or try again later.');
|
|
306
|
-
}
|
|
307
|
-
|
|
308
|
-
// Streaming chat
|
|
309
|
-
async *chatStream(
|
|
310
|
-
messages: ChatMessage[],
|
|
311
|
-
model: string
|
|
312
|
-
): AsyncGenerator<StreamChunk> {
|
|
313
|
-
const wsUrl = this.config.get('wsUrl');
|
|
314
|
-
const token = this.config.get('authToken');
|
|
315
|
-
|
|
316
|
-
return new Promise((resolve, reject) => {
|
|
317
|
-
const ws = new WebSocket(`${wsUrl}/chat`, {
|
|
318
|
-
headers: { Authorization: `Bearer ${token}` },
|
|
319
|
-
});
|
|
320
|
-
|
|
321
|
-
ws.on('open', () => {
|
|
322
|
-
ws.send(JSON.stringify({
|
|
323
|
-
type: 'chat',
|
|
324
|
-
messages,
|
|
325
|
-
model: this.resolveModelId(model),
|
|
326
|
-
stream: true,
|
|
327
|
-
}));
|
|
328
|
-
});
|
|
329
|
-
|
|
330
|
-
ws.on('message', (data) => {
|
|
331
|
-
const chunk = JSON.parse(data.toString());
|
|
332
|
-
// Yield chunk - but this pattern won't work directly
|
|
333
|
-
// Need to use event emitter pattern instead
|
|
334
|
-
});
|
|
335
|
-
|
|
336
|
-
ws.on('error', (error) => {
|
|
337
|
-
reject(error);
|
|
338
|
-
});
|
|
339
|
-
|
|
340
|
-
ws.on('close', () => {
|
|
341
|
-
resolve(undefined);
|
|
342
|
-
});
|
|
343
|
-
});
|
|
344
|
-
}
|
|
345
|
-
|
|
346
|
-
// Non-streaming alternative with callback
|
|
347
|
-
async chatWithCallback(
|
|
348
|
-
messages: ChatMessage[],
|
|
349
|
-
model: string,
|
|
350
|
-
onChunk: (chunk: string) => void,
|
|
351
|
-
onDone: () => void,
|
|
352
|
-
onError: (error: Error) => void
|
|
353
|
-
): Promise<void> {
|
|
354
|
-
const wsUrl = this.config.get('wsUrl');
|
|
355
|
-
const token = this.config.get('authToken');
|
|
356
|
-
|
|
357
|
-
return new Promise((resolve, reject) => {
|
|
358
|
-
const ws = new WebSocket(`${wsUrl}/chat`, {
|
|
359
|
-
headers: { Authorization: `Bearer ${token}` },
|
|
360
|
-
});
|
|
361
|
-
|
|
362
|
-
ws.on('open', () => {
|
|
363
|
-
ws.send(JSON.stringify({
|
|
364
|
-
type: 'chat',
|
|
365
|
-
messages,
|
|
366
|
-
model: this.resolveModelId(model),
|
|
367
|
-
stream: true,
|
|
368
|
-
}));
|
|
369
|
-
});
|
|
370
|
-
|
|
371
|
-
ws.on('message', (data) => {
|
|
372
|
-
try {
|
|
373
|
-
const chunk = JSON.parse(data.toString());
|
|
374
|
-
if (chunk.type === 'content') {
|
|
375
|
-
onChunk(chunk.content);
|
|
376
|
-
} else if (chunk.type === 'done') {
|
|
377
|
-
onDone();
|
|
378
|
-
ws.close();
|
|
379
|
-
resolve();
|
|
380
|
-
} else if (chunk.type === 'error') {
|
|
381
|
-
onError(new Error(chunk.error));
|
|
382
|
-
ws.close();
|
|
383
|
-
reject(new Error(chunk.error));
|
|
384
|
-
}
|
|
385
|
-
} catch (e) {
|
|
386
|
-
// Raw text chunk
|
|
387
|
-
onChunk(data.toString());
|
|
388
|
-
}
|
|
389
|
-
});
|
|
390
|
-
|
|
391
|
-
ws.on('error', (error) => {
|
|
392
|
-
onError(error as Error);
|
|
393
|
-
reject(error);
|
|
394
|
-
});
|
|
395
|
-
|
|
396
|
-
ws.on('close', () => {
|
|
397
|
-
resolve();
|
|
398
|
-
});
|
|
399
|
-
});
|
|
400
|
-
}
|
|
401
|
-
|
|
402
|
-
// Code operations - Using Vigthoria Centralized API
|
|
403
|
-
async generateCode(prompt: string, language: string, model: string): Promise<string> {
|
|
404
|
-
const response = await this.client.post('/api/ai/generate', {
|
|
405
|
-
prompt,
|
|
406
|
-
language,
|
|
407
|
-
model: this.resolveModelId(model),
|
|
408
|
-
});
|
|
409
|
-
|
|
410
|
-
return response.data.code;
|
|
411
|
-
}
|
|
412
|
-
|
|
413
|
-
// Senior Developer Mode - Planning + Generation + Quality Check
|
|
414
|
-
async generateProject(prompt: string, projectType: string, model: string): Promise<{
|
|
415
|
-
code: string;
|
|
416
|
-
plan?: any;
|
|
417
|
-
quality?: {
|
|
418
|
-
lineCount: number;
|
|
419
|
-
score: number;
|
|
420
|
-
checks: {
|
|
421
|
-
hasAnimations: boolean;
|
|
422
|
-
hasNeonEffects: boolean;
|
|
423
|
-
hasResponsive: boolean;
|
|
424
|
-
hasFontAwesome: boolean;
|
|
425
|
-
hasGoogleFonts: boolean;
|
|
426
|
-
};
|
|
427
|
-
};
|
|
428
|
-
}> {
|
|
429
|
-
const response = await this.client.post('/api/ai/generate-project', {
|
|
430
|
-
prompt,
|
|
431
|
-
projectType,
|
|
432
|
-
model: this.resolveModelId(model),
|
|
433
|
-
}, {
|
|
434
|
-
timeout: 300000, // 5 minutes for complex generation
|
|
435
|
-
});
|
|
436
|
-
|
|
437
|
-
return {
|
|
438
|
-
code: response.data.code,
|
|
439
|
-
plan: response.data.plan,
|
|
440
|
-
quality: response.data.quality,
|
|
441
|
-
};
|
|
442
|
-
}
|
|
443
|
-
|
|
444
|
-
async explainCode(code: string, language: string): Promise<string> {
|
|
445
|
-
const response = await this.client.post('/api/ai/explain', {
|
|
446
|
-
code,
|
|
447
|
-
language,
|
|
448
|
-
});
|
|
449
|
-
|
|
450
|
-
return response.data.explanation;
|
|
451
|
-
}
|
|
452
|
-
|
|
453
|
-
async reviewCode(code: string, language: string): Promise<{
|
|
454
|
-
score: number;
|
|
455
|
-
issues: { type: string; line: number; message: string; severity: string }[];
|
|
456
|
-
suggestions: string[];
|
|
457
|
-
}> {
|
|
458
|
-
const response = await this.client.post('/api/ai/review', {
|
|
459
|
-
code,
|
|
460
|
-
language,
|
|
461
|
-
});
|
|
462
|
-
|
|
463
|
-
return response.data;
|
|
464
|
-
}
|
|
465
|
-
|
|
466
|
-
async fixCode(code: string, language: string, fixType: string): Promise<{
|
|
467
|
-
fixed: string;
|
|
468
|
-
changes: { line: number; before: string; after: string; reason: string }[];
|
|
469
|
-
}> {
|
|
470
|
-
const response = await this.client.post('/api/ai/fix', {
|
|
471
|
-
code,
|
|
472
|
-
language,
|
|
473
|
-
fixType,
|
|
474
|
-
});
|
|
475
|
-
|
|
476
|
-
return response.data;
|
|
477
|
-
}
|
|
478
|
-
|
|
479
|
-
// Model resolution - maps Vigthoria model names to internal IDs
|
|
480
|
-
// INTERNAL USE ONLY - users see only Vigthoria branding
|
|
481
|
-
private resolveModelId(shortName: string): string {
|
|
482
|
-
const modelMap: Record<string, string> = {
|
|
483
|
-
// ═══════════════════════════════════════════════════════════════
|
|
484
|
-
// VIGTHORIA LOCAL - Self-hosted models
|
|
485
|
-
// ═══════════════════════════════════════════════════════════════
|
|
486
|
-
'fast': 'vigthoria-fast-1.7b',
|
|
487
|
-
'mini': 'vigthoria-fast-1.7b',
|
|
488
|
-
'balanced': 'vigthoria-balanced-4b',
|
|
489
|
-
'creative': 'vigthoria-creative-9b-v4',
|
|
490
|
-
|
|
491
|
-
// Code Models - 30B is the default powerhouse
|
|
492
|
-
'code': 'qwen3-coder:latest', // Internal: qwen3-coder 30B
|
|
493
|
-
'code-30b': 'qwen3-coder:latest',
|
|
494
|
-
'code-8b': 'vigthoria-v2-code-8b',
|
|
495
|
-
'pro': 'qwen3-coder:latest',
|
|
496
|
-
|
|
497
|
-
// ═══════════════════════════════════════════════════════════════
|
|
498
|
-
// VIGTHORIA CLOUD - Premium cloud models (internal routing)
|
|
499
|
-
// ═══════════════════════════════════════════════════════════════
|
|
500
|
-
'cloud': 'deepseek-v3.1:671b-cloud',
|
|
501
|
-
'cloud-reason': 'moonshotai/kimi-k2.5',
|
|
502
|
-
'agent': 'deepseek-v3.1:671b-cloud',
|
|
503
|
-
'ultra': 'deepseek-v3.1:671b-cloud',
|
|
504
|
-
};
|
|
505
|
-
|
|
506
|
-
// If already a full model ID, return as-is
|
|
507
|
-
if (shortName.includes('vigthoria') || shortName.includes('/') || shortName.includes(':')) {
|
|
508
|
-
if (modelMap[shortName]) {
|
|
509
|
-
return modelMap[shortName];
|
|
510
|
-
}
|
|
511
|
-
return shortName;
|
|
512
|
-
}
|
|
513
|
-
|
|
514
|
-
return modelMap[shortName] || 'qwen3-coder:latest'; // Default to 30B
|
|
515
|
-
}
|
|
516
|
-
|
|
517
|
-
// Health check
|
|
518
|
-
async healthCheck(): Promise<boolean> {
|
|
519
|
-
try {
|
|
520
|
-
const response = await this.client.get('/api/health', { timeout: 10000 });
|
|
521
|
-
return response.data?.status === 'ok' || response.data?.healthy === true;
|
|
522
|
-
} catch {
|
|
523
|
-
return false;
|
|
524
|
-
}
|
|
525
|
-
}
|
|
526
|
-
}
|