vantuz 3.0.2 → 3.1.0
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/cli.js +192 -108
- package/core/ai-provider.js +76 -29
- package/core/channels.js +334 -0
- package/core/engine.js +373 -0
- package/package.json +6 -3
package/cli.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
/**
|
|
3
|
-
* 🐙 VANTUZ CLI
|
|
4
|
-
*
|
|
3
|
+
* 🐙 VANTUZ CLI v3.1
|
|
4
|
+
* Enterprise e-ticaret yönetimi
|
|
5
5
|
*
|
|
6
6
|
* Kullanım:
|
|
7
7
|
* vantuz tui → Sohbet modu
|
|
@@ -13,20 +13,23 @@ import fs from 'fs';
|
|
|
13
13
|
import path from 'path';
|
|
14
14
|
import os from 'os';
|
|
15
15
|
import readline from 'readline';
|
|
16
|
-
import {
|
|
16
|
+
import { getEngine } from './core/engine.js';
|
|
17
|
+
import { log, getLogs, clearLogs } from './core/ai-provider.js';
|
|
18
|
+
|
|
19
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
20
|
+
// CONFIG
|
|
21
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
17
22
|
|
|
18
|
-
// Config dosyaları kullanıcının home dizininde saklanır
|
|
19
23
|
const VANTUZ_HOME = path.join(os.homedir(), '.vantuz');
|
|
20
24
|
const CONFIG_PATH = path.join(VANTUZ_HOME, '.env');
|
|
21
25
|
const CONFIG_JSON = path.join(VANTUZ_HOME, 'config.json');
|
|
22
26
|
|
|
23
|
-
// Dizin yoksa oluştur
|
|
24
27
|
if (!fs.existsSync(VANTUZ_HOME)) {
|
|
25
28
|
fs.mkdirSync(VANTUZ_HOME, { recursive: true });
|
|
26
29
|
}
|
|
27
30
|
|
|
28
31
|
// ═══════════════════════════════════════════════════════════════════════════
|
|
29
|
-
//
|
|
32
|
+
// COLORS
|
|
30
33
|
// ═══════════════════════════════════════════════════════════════════════════
|
|
31
34
|
|
|
32
35
|
const colors = {
|
|
@@ -39,25 +42,21 @@ const colors = {
|
|
|
39
42
|
blue: '\x1b[34m',
|
|
40
43
|
magenta: '\x1b[35m',
|
|
41
44
|
cyan: '\x1b[36m',
|
|
42
|
-
white: '\x1b[37m'
|
|
43
|
-
bgBlue: '\x1b[44m',
|
|
44
|
-
bgMagenta: '\x1b[45m'
|
|
45
|
+
white: '\x1b[37m'
|
|
45
46
|
};
|
|
46
47
|
|
|
47
48
|
const c = (color, text) => `${colors[color]}${text}${colors.reset}`;
|
|
48
49
|
|
|
49
50
|
// ═══════════════════════════════════════════════════════════════════════════
|
|
50
|
-
//
|
|
51
|
+
// HELPERS
|
|
51
52
|
// ═══════════════════════════════════════════════════════════════════════════
|
|
52
53
|
|
|
53
|
-
function clearScreen() {
|
|
54
|
-
console.clear();
|
|
55
|
-
}
|
|
54
|
+
function clearScreen() { console.clear(); }
|
|
56
55
|
|
|
57
56
|
function printHeader() {
|
|
58
57
|
console.log(c('cyan', `
|
|
59
58
|
╔═══════════════════════════════════════════════════════════╗
|
|
60
|
-
║ 🐙 ${c('bold', 'VANTUZ AI')} - E-
|
|
59
|
+
║ 🐙 ${c('bold', 'VANTUZ AI v3.1')} - Enterprise E-Ticaret ║
|
|
61
60
|
╚═══════════════════════════════════════════════════════════╝
|
|
62
61
|
`));
|
|
63
62
|
}
|
|
@@ -101,10 +100,6 @@ function hasAnyAIKey(env) {
|
|
|
101
100
|
env.DEEPSEEK_API_KEY || env.GROQ_API_KEY || env.GEMINI_API_KEY;
|
|
102
101
|
}
|
|
103
102
|
|
|
104
|
-
// ═══════════════════════════════════════════════════════════════════════════
|
|
105
|
-
// READLINE HELPER
|
|
106
|
-
// ═══════════════════════════════════════════════════════════════════════════
|
|
107
|
-
|
|
108
103
|
function createRL() {
|
|
109
104
|
return readline.createInterface({
|
|
110
105
|
input: process.stdin,
|
|
@@ -131,7 +126,7 @@ async function askYesNo(rl, question, defaultYes = true) {
|
|
|
131
126
|
}
|
|
132
127
|
|
|
133
128
|
// ═══════════════════════════════════════════════════════════════════════════
|
|
134
|
-
// CONFIG
|
|
129
|
+
// CONFIG COMMAND
|
|
135
130
|
// ═══════════════════════════════════════════════════════════════════════════
|
|
136
131
|
|
|
137
132
|
async function runConfig() {
|
|
@@ -154,10 +149,10 @@ async function runConfig() {
|
|
|
154
149
|
console.log(' 5) Gemini');
|
|
155
150
|
console.log(' 6) Atla (skip)');
|
|
156
151
|
|
|
157
|
-
const aiChoice = await ask(rl, '\n Seçim', '
|
|
152
|
+
const aiChoice = await ask(rl, '\n Seçim', '5');
|
|
158
153
|
if (aiChoice !== '6' && aiChoice.toLowerCase() !== 'skip') {
|
|
159
154
|
const providers = ['openai', 'anthropic', 'deepseek', 'groq', 'gemini'];
|
|
160
|
-
config.aiProvider = providers[parseInt(aiChoice) - 1] || '
|
|
155
|
+
config.aiProvider = providers[parseInt(aiChoice) - 1] || 'gemini';
|
|
161
156
|
|
|
162
157
|
const keyMap = {
|
|
163
158
|
openai: 'OPENAI_API_KEY',
|
|
@@ -216,7 +211,7 @@ async function runConfig() {
|
|
|
216
211
|
}
|
|
217
212
|
|
|
218
213
|
// ═══════════════════════════════════════════════════════════════════════════
|
|
219
|
-
// TUI (
|
|
214
|
+
// TUI (CHAT MODE)
|
|
220
215
|
// ═══════════════════════════════════════════════════════════════════════════
|
|
221
216
|
|
|
222
217
|
async function runTUI() {
|
|
@@ -224,15 +219,30 @@ async function runTUI() {
|
|
|
224
219
|
printHeader();
|
|
225
220
|
|
|
226
221
|
const rl = createRL();
|
|
227
|
-
const config = loadConfig();
|
|
228
222
|
const env = loadEnv();
|
|
229
223
|
|
|
230
|
-
console.log(c('
|
|
231
|
-
|
|
224
|
+
console.log(c('yellow', ' 🔄 Engine başlatılıyor...'));
|
|
225
|
+
|
|
226
|
+
let engine;
|
|
227
|
+
try {
|
|
228
|
+
engine = await getEngine();
|
|
229
|
+
const status = engine.getStatus();
|
|
230
|
+
console.log(c('green', ` ✓ Engine hazır - ${status.connectedCount} platform bağlı`));
|
|
231
|
+
|
|
232
|
+
if (status.productCount > 0) {
|
|
233
|
+
console.log(c('dim', ` 📦 ${status.productCount} ürün yüklendi`));
|
|
234
|
+
}
|
|
235
|
+
} catch (e) {
|
|
236
|
+
console.log(c('red', ` ❌ Engine hatası: ${e.message}`));
|
|
237
|
+
console.log(c('dim', ' Temel modda devam ediliyor...\n'));
|
|
238
|
+
engine = null;
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
console.log(c('green', '\n 💬 Sohbet Modu'));
|
|
242
|
+
console.log(c('dim', ' Komutlar: /help, /stok, /siparis, /fiyat, /test, /logs, /cikis\n'));
|
|
232
243
|
|
|
233
244
|
// Check AI config
|
|
234
|
-
|
|
235
|
-
if (!hasAI) {
|
|
245
|
+
if (!hasAnyAIKey(env)) {
|
|
236
246
|
console.log(c('yellow', ' ⚠️ AI sağlayıcı yapılandırılmamış.'));
|
|
237
247
|
console.log(c('dim', ' → vantuz config komutunu çalıştırın\n'));
|
|
238
248
|
}
|
|
@@ -249,13 +259,28 @@ async function runTUI() {
|
|
|
249
259
|
|
|
250
260
|
// Commands
|
|
251
261
|
if (input.startsWith('/')) {
|
|
252
|
-
await handleCommand(input,
|
|
262
|
+
await handleCommand(input, engine, env);
|
|
253
263
|
prompt();
|
|
254
264
|
return;
|
|
255
265
|
}
|
|
256
266
|
|
|
257
|
-
// AI Chat
|
|
258
|
-
|
|
267
|
+
// AI Chat via Engine
|
|
268
|
+
try {
|
|
269
|
+
console.log(c('dim', '\n 🧠 Düşünüyorum...'));
|
|
270
|
+
|
|
271
|
+
let response;
|
|
272
|
+
if (engine) {
|
|
273
|
+
response = await engine.chat(input);
|
|
274
|
+
} else {
|
|
275
|
+
const { chat } = await import('./core/ai-provider.js');
|
|
276
|
+
response = await chat(input, loadConfig(), env);
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
console.log(c('magenta', '\n Vantuz: ') + response);
|
|
280
|
+
} catch (e) {
|
|
281
|
+
console.log(c('red', `\n ❌ Hata: ${e.message}`));
|
|
282
|
+
}
|
|
283
|
+
|
|
259
284
|
prompt();
|
|
260
285
|
});
|
|
261
286
|
};
|
|
@@ -263,7 +288,7 @@ async function runTUI() {
|
|
|
263
288
|
prompt();
|
|
264
289
|
}
|
|
265
290
|
|
|
266
|
-
async function handleCommand(input,
|
|
291
|
+
async function handleCommand(input, engine, env) {
|
|
267
292
|
const [cmd, ...args] = input.slice(1).split(' ');
|
|
268
293
|
|
|
269
294
|
switch (cmd.toLowerCase()) {
|
|
@@ -271,55 +296,115 @@ async function handleCommand(input, config, env) {
|
|
|
271
296
|
case 'yardim':
|
|
272
297
|
console.log(`
|
|
273
298
|
${c('cyan', 'Komutlar:')}
|
|
274
|
-
/stok [platform] → Stok durumu
|
|
275
|
-
/
|
|
276
|
-
/
|
|
277
|
-
/
|
|
299
|
+
/stok [platform] → Stok durumu (gerçek veri)
|
|
300
|
+
/siparis [n] → Son n sipariş
|
|
301
|
+
/fiyat <bkod> <tl> → Fiyat güncelle
|
|
302
|
+
/test → Platform bağlantı testi
|
|
278
303
|
/logs [n] → Son n log satırı
|
|
279
304
|
/logs clear → Logları temizle
|
|
280
|
-
/
|
|
305
|
+
/platformlar → Bağlı platformlar
|
|
281
306
|
/cikis → Çıkış
|
|
282
307
|
`);
|
|
283
308
|
break;
|
|
284
309
|
|
|
285
310
|
case 'stok':
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
311
|
+
if (!engine) {
|
|
312
|
+
console.log(c('red', '\n ❌ Engine yüklenmedi'));
|
|
313
|
+
return;
|
|
314
|
+
}
|
|
315
|
+
console.log(c('yellow', '\n 📦 Stok çekiliyor...'));
|
|
316
|
+
try {
|
|
317
|
+
const platform = args[0] || 'all';
|
|
318
|
+
const results = await engine.getStock(platform);
|
|
319
|
+
|
|
320
|
+
if (results.length === 0) {
|
|
321
|
+
console.log(c('dim', ' Bağlı platform yok veya stok bulunamadı.'));
|
|
322
|
+
return;
|
|
323
|
+
}
|
|
289
324
|
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
325
|
+
for (const r of results) {
|
|
326
|
+
console.log(c('cyan', `\n ${r.icon} ${r.platform.toUpperCase()}`));
|
|
327
|
+
if (r.products.length === 0) {
|
|
328
|
+
console.log(c('dim', ' Ürün bulunamadı'));
|
|
329
|
+
} else {
|
|
330
|
+
r.products.slice(0, 10).forEach(p => {
|
|
331
|
+
const stockColor = p.stock > 10 ? 'green' : p.stock > 0 ? 'yellow' : 'red';
|
|
332
|
+
console.log(` ${p.barcode}: ${c(stockColor, `${p.stock} adet`)} - ${p.price} TL`);
|
|
333
|
+
});
|
|
334
|
+
if (r.products.length > 10) {
|
|
335
|
+
console.log(c('dim', ` ... ve ${r.products.length - 10} ürün daha`));
|
|
336
|
+
}
|
|
337
|
+
}
|
|
338
|
+
}
|
|
339
|
+
} catch (e) {
|
|
340
|
+
console.log(c('red', ` ❌ Hata: ${e.message}`));
|
|
341
|
+
log('ERROR', 'Stok çekme hatası', { error: e.message });
|
|
342
|
+
}
|
|
293
343
|
break;
|
|
294
344
|
|
|
295
|
-
case '
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
345
|
+
case 'siparis':
|
|
346
|
+
case 'siparisler':
|
|
347
|
+
if (!engine) {
|
|
348
|
+
console.log(c('red', '\n ❌ Engine yüklenmedi'));
|
|
349
|
+
return;
|
|
350
|
+
}
|
|
351
|
+
console.log(c('yellow', '\n 📋 Siparişler çekiliyor...'));
|
|
352
|
+
try {
|
|
353
|
+
const orders = await engine.getOrders();
|
|
354
|
+
const limit = parseInt(args[0]) || 10;
|
|
355
|
+
|
|
356
|
+
if (orders.length === 0) {
|
|
357
|
+
console.log(c('dim', ' Sipariş bulunamadı.'));
|
|
358
|
+
return;
|
|
359
|
+
}
|
|
300
360
|
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
${
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
🌸 Çiçeksepeti: ${env.CICEKSEPETI_API_KEY ? c('green', '✓ Bağlı') : c('dim', '○ Ayarlanmamış')}
|
|
309
|
-
📮 PTTavm: ${env.PTTAVM_API_KEY ? c('green', '✓ Bağlı') : c('dim', '○ Ayarlanmamış')}
|
|
310
|
-
🛒 Pazarama: ${env.PAZARAMA_CLIENT_ID ? c('green', '✓ Bağlı') : c('dim', '○ Ayarlanmamış')}
|
|
311
|
-
`);
|
|
361
|
+
console.log(c('cyan', `\n Son ${Math.min(limit, orders.length)} sipariş:`));
|
|
362
|
+
orders.slice(0, limit).forEach((o, i) => {
|
|
363
|
+
console.log(` ${i + 1}. ${o._icon} #${o.orderNumber || o.id} - ${o.totalPrice || 'N/A'} TL`);
|
|
364
|
+
});
|
|
365
|
+
} catch (e) {
|
|
366
|
+
console.log(c('red', ` ❌ Hata: ${e.message}`));
|
|
367
|
+
}
|
|
312
368
|
break;
|
|
313
369
|
|
|
314
|
-
case '
|
|
315
|
-
|
|
370
|
+
case 'fiyat':
|
|
371
|
+
if (!engine) {
|
|
372
|
+
console.log(c('red', '\n ❌ Engine yüklenmedi'));
|
|
373
|
+
return;
|
|
374
|
+
}
|
|
375
|
+
const [barcode, priceStr] = args;
|
|
376
|
+
if (!barcode || !priceStr) {
|
|
377
|
+
console.log(c('yellow', ' Kullanım: /fiyat <barkod> <fiyat>'));
|
|
378
|
+
return;
|
|
379
|
+
}
|
|
380
|
+
console.log(c('yellow', `\n 💰 Fiyat güncelleniyor: ${barcode} → ${priceStr} TL`));
|
|
381
|
+
try {
|
|
382
|
+
const results = await engine.updatePrice(barcode, parseFloat(priceStr));
|
|
383
|
+
for (const [platform, result] of Object.entries(results)) {
|
|
384
|
+
const status = result?.success ? c('green', '✓') : c('red', '✗');
|
|
385
|
+
console.log(` ${status} ${platform}`);
|
|
386
|
+
}
|
|
387
|
+
} catch (e) {
|
|
388
|
+
console.log(c('red', ` ❌ Hata: ${e.message}`));
|
|
389
|
+
}
|
|
316
390
|
break;
|
|
317
391
|
|
|
318
|
-
case '
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
392
|
+
case 'test':
|
|
393
|
+
if (!engine) {
|
|
394
|
+
console.log(c('red', '\n ❌ Engine yüklenmedi'));
|
|
395
|
+
return;
|
|
396
|
+
}
|
|
397
|
+
console.log(c('yellow', '\n 🔌 Bağlantılar test ediliyor...'));
|
|
398
|
+
try {
|
|
399
|
+
const results = await engine.testConnections();
|
|
400
|
+
for (const [platform, connected] of Object.entries(results)) {
|
|
401
|
+
const status = connected ? c('green', '✓ Bağlı') : c('red', '✗ Bağlanamadı');
|
|
402
|
+
console.log(` ${platform}: ${status}`);
|
|
403
|
+
}
|
|
404
|
+
} catch (e) {
|
|
405
|
+
console.log(c('red', ` ❌ Hata: ${e.message}`));
|
|
406
|
+
}
|
|
407
|
+
break;
|
|
323
408
|
|
|
324
409
|
case 'logs':
|
|
325
410
|
case 'log':
|
|
@@ -333,67 +418,66 @@ async function handleCommand(input, config, env) {
|
|
|
333
418
|
}
|
|
334
419
|
break;
|
|
335
420
|
|
|
421
|
+
case 'platformlar':
|
|
422
|
+
if (engine) {
|
|
423
|
+
const status = engine.getStatus();
|
|
424
|
+
console.log(c('cyan', '\n Platform Durumu:'));
|
|
425
|
+
for (const [name, info] of Object.entries(status.platforms)) {
|
|
426
|
+
const connStatus = info.connected ? c('green', '✓ Bağlı') : c('dim', '○');
|
|
427
|
+
console.log(` ${info.icon} ${name}: ${connStatus}`);
|
|
428
|
+
}
|
|
429
|
+
console.log(c('dim', `\n Toplam: ${status.connectedCount}/${status.totalPlatforms} bağlı`));
|
|
430
|
+
} else {
|
|
431
|
+
console.log(c('dim', ' Engine yüklenmedi.'));
|
|
432
|
+
}
|
|
433
|
+
break;
|
|
434
|
+
|
|
435
|
+
case 'cikis':
|
|
436
|
+
case 'exit':
|
|
437
|
+
case 'quit':
|
|
438
|
+
console.log(c('cyan', '\n 👋 Görüşmek üzere!\n'));
|
|
439
|
+
process.exit(0);
|
|
440
|
+
|
|
336
441
|
default:
|
|
337
442
|
console.log(c('red', ` ❌ Bilinmeyen komut: /${cmd}`));
|
|
338
443
|
console.log(c('dim', ' /help yazarak komutları görebilirsiniz'));
|
|
339
444
|
}
|
|
340
445
|
}
|
|
341
446
|
|
|
342
|
-
async function processChat(input, config, env) {
|
|
343
|
-
// AI API anahtarı kontrolü
|
|
344
|
-
if (!hasAnyAIKey(env)) {
|
|
345
|
-
return 'AI yanıtı için API anahtarı gerekli. "vantuz config" ile ayarlayın.';
|
|
346
|
-
}
|
|
347
|
-
|
|
348
|
-
try {
|
|
349
|
-
// Gerçek AI çağrısı
|
|
350
|
-
console.log(c('dim', '\n 🧠 Düşünüyorum...'));
|
|
351
|
-
const response = await aiChat(input, config, env);
|
|
352
|
-
return response;
|
|
353
|
-
} catch (error) {
|
|
354
|
-
log('ERROR', `Chat hatası: ${error.message}`);
|
|
355
|
-
return `Hata: ${error.message}. /logs komutu ile detay görün.`;
|
|
356
|
-
}
|
|
357
|
-
}
|
|
358
|
-
|
|
359
447
|
// ═══════════════════════════════════════════════════════════════════════════
|
|
360
|
-
// STATUS
|
|
448
|
+
// STATUS COMMAND
|
|
361
449
|
// ═══════════════════════════════════════════════════════════════════════════
|
|
362
450
|
|
|
363
451
|
async function runStatus() {
|
|
364
452
|
printHeader();
|
|
365
453
|
|
|
366
|
-
|
|
367
|
-
|
|
454
|
+
console.log(c('yellow', ' 🔄 Engine başlatılıyor...\n'));
|
|
455
|
+
|
|
456
|
+
try {
|
|
457
|
+
const engine = await getEngine();
|
|
458
|
+
const status = engine.getStatus();
|
|
368
459
|
|
|
369
|
-
|
|
460
|
+
console.log(c('cyan', ' 📊 Sistem Durumu\n'));
|
|
370
461
|
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
462
|
+
// AI
|
|
463
|
+
console.log(` AI Sağlayıcı: ${status.aiProvider || 'Ayarlanmamış'} ${hasAnyAIKey(loadEnv()) ? c('green', '✓') : c('red', '✗')}`);
|
|
464
|
+
console.log(` Engine: ${status.engine === 'active' ? c('green', '✓ Aktif') : c('red', '✗ Pasif')}`);
|
|
465
|
+
console.log(` Ürün Sayısı: ${status.productCount}`);
|
|
375
466
|
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
['Amazon', 'AMAZON_SELLER_ID'],
|
|
383
|
-
['Çiçeksepeti', 'CICEKSEPETI_API_KEY'],
|
|
384
|
-
['PTTavm', 'PTTAVM_API_KEY'],
|
|
385
|
-
['Pazarama', 'PAZARAMA_CLIENT_ID']
|
|
386
|
-
];
|
|
467
|
+
// Platforms
|
|
468
|
+
console.log('\n Platformlar:');
|
|
469
|
+
for (const [name, info] of Object.entries(status.platforms)) {
|
|
470
|
+
const connStatus = info.connected ? c('green', '✓ Bağlı') : c('dim', '○');
|
|
471
|
+
console.log(` ${info.icon} ${name}: ${connStatus}`);
|
|
472
|
+
}
|
|
387
473
|
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
console.log(
|
|
474
|
+
console.log(`\n Toplam: ${status.connectedCount}/${status.totalPlatforms} platform bağlı`);
|
|
475
|
+
console.log(c('dim', `\n Config: ${CONFIG_PATH}`));
|
|
476
|
+
} catch (e) {
|
|
477
|
+
console.log(c('red', ` ❌ Engine hatası: ${e.message}`));
|
|
478
|
+
console.log(c('dim', ' /logs komutu ile detay görün'));
|
|
393
479
|
}
|
|
394
480
|
|
|
395
|
-
console.log(`\n Toplam: ${connected}/${platforms.length} platform bağlı`);
|
|
396
|
-
console.log(c('dim', `\n Config: ${CONFIG_PATH}`));
|
|
397
481
|
console.log();
|
|
398
482
|
}
|
|
399
483
|
|
package/core/ai-provider.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* 🤖 AI Provider Integration
|
|
3
|
-
* Gerçek AI API çağrıları
|
|
2
|
+
* 🤖 AI Provider Integration v3.1
|
|
3
|
+
* Gerçek AI API çağrıları + Context desteği
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
6
|
import axios from 'axios';
|
|
@@ -10,7 +10,10 @@ import os from 'os';
|
|
|
10
10
|
|
|
11
11
|
const LOG_FILE = path.join(os.homedir(), '.vantuz', 'vantuz.log');
|
|
12
12
|
|
|
13
|
-
//
|
|
13
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
14
|
+
// LOGGING
|
|
15
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
16
|
+
|
|
14
17
|
export function log(level, message, data = null) {
|
|
15
18
|
const timestamp = new Date().toISOString();
|
|
16
19
|
const logLine = `[${timestamp}] [${level}] ${message}${data ? ' | ' + JSON.stringify(data) : ''}\n`;
|
|
@@ -18,10 +21,6 @@ export function log(level, message, data = null) {
|
|
|
18
21
|
try {
|
|
19
22
|
fs.appendFileSync(LOG_FILE, logLine);
|
|
20
23
|
} catch (e) { }
|
|
21
|
-
|
|
22
|
-
if (level === 'ERROR') {
|
|
23
|
-
console.error(`❌ ${message}`);
|
|
24
|
-
}
|
|
25
24
|
}
|
|
26
25
|
|
|
27
26
|
export function getLogs(lines = 50) {
|
|
@@ -46,24 +45,72 @@ export function clearLogs() {
|
|
|
46
45
|
}
|
|
47
46
|
}
|
|
48
47
|
|
|
49
|
-
//
|
|
48
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
49
|
+
// SYSTEM PROMPT
|
|
50
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
51
|
+
|
|
52
|
+
const VANTUZ_SYSTEM_PROMPT = `Sen Vantuz AI, e-ticaret operasyonlarını yöneten yapay zeka asistanısın.
|
|
53
|
+
|
|
54
|
+
## Kimliğin
|
|
55
|
+
- İsim: Vantuz AI
|
|
56
|
+
- Uzmanlık: E-ticaret yönetimi, pazaryeri entegrasyonları, fiyatlandırma stratejileri
|
|
57
|
+
- Dil: Türkçe
|
|
58
|
+
- Kişilik: Profesyonel, çözüm odaklı, verimli
|
|
59
|
+
|
|
60
|
+
## Desteklenen Pazaryerleri
|
|
61
|
+
1. 🟠 Trendyol - Tam entegrasyon
|
|
62
|
+
2. 🟣 Hepsiburada - Tam entegrasyon
|
|
63
|
+
3. 🔵 N11 - Tam entegrasyon
|
|
64
|
+
4. 🟡 Amazon - FBA destekli
|
|
65
|
+
5. 🌸 Çiçeksepeti - Entegre
|
|
66
|
+
6. 📮 PTTavm - Entegre
|
|
67
|
+
7. 🛒 Pazarama - Entegre
|
|
68
|
+
|
|
69
|
+
## Yeteneklerin
|
|
70
|
+
- Stok kontrolü ve güncelleme
|
|
71
|
+
- Fiyat analizi ve güncelleme
|
|
72
|
+
- Sipariş yönetimi
|
|
73
|
+
- Rakip analizi
|
|
74
|
+
- Satış raporları
|
|
75
|
+
|
|
76
|
+
## Önemli Kurallar
|
|
77
|
+
1. Kar marjının altına fiyat düşürme önerme
|
|
78
|
+
2. Stokta olmayan ürünü satışa açma
|
|
79
|
+
3. Kritik işlemlerden önce onay iste
|
|
80
|
+
4. Kısa ve öz yanıt ver
|
|
81
|
+
5. Sayısal verileri düzgün formatla
|
|
82
|
+
|
|
83
|
+
## Yanıt Formatı
|
|
84
|
+
- Kısa ve öz ol
|
|
85
|
+
- Emoji kullan ama abartma
|
|
86
|
+
- Sayısal verileri tablo formatında göster
|
|
87
|
+
- Hata durumunda çözüm öner`;
|
|
88
|
+
|
|
89
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
90
|
+
// AI CHAT
|
|
91
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
92
|
+
|
|
50
93
|
export async function chat(message, config, env) {
|
|
51
94
|
const provider = config.aiProvider || 'gemini';
|
|
52
95
|
|
|
96
|
+
// Context bilgisi ekle
|
|
97
|
+
const contextInfo = config.systemContext || '';
|
|
98
|
+
const fullSystemPrompt = VANTUZ_SYSTEM_PROMPT + contextInfo;
|
|
99
|
+
|
|
53
100
|
log('INFO', `AI isteği: ${provider}`, { message: message.slice(0, 100) });
|
|
54
101
|
|
|
55
102
|
try {
|
|
56
103
|
switch (provider) {
|
|
57
104
|
case 'gemini':
|
|
58
|
-
return await chatGemini(message, env.GEMINI_API_KEY);
|
|
105
|
+
return await chatGemini(message, env.GEMINI_API_KEY, fullSystemPrompt);
|
|
59
106
|
case 'groq':
|
|
60
|
-
return await chatGroq(message, env.GROQ_API_KEY);
|
|
107
|
+
return await chatGroq(message, env.GROQ_API_KEY, fullSystemPrompt);
|
|
61
108
|
case 'openai':
|
|
62
|
-
return await chatOpenAI(message, env.OPENAI_API_KEY);
|
|
109
|
+
return await chatOpenAI(message, env.OPENAI_API_KEY, fullSystemPrompt);
|
|
63
110
|
case 'anthropic':
|
|
64
|
-
return await chatAnthropic(message, env.ANTHROPIC_API_KEY);
|
|
111
|
+
return await chatAnthropic(message, env.ANTHROPIC_API_KEY, fullSystemPrompt);
|
|
65
112
|
case 'deepseek':
|
|
66
|
-
return await chatDeepSeek(message, env.DEEPSEEK_API_KEY);
|
|
113
|
+
return await chatDeepSeek(message, env.DEEPSEEK_API_KEY, fullSystemPrompt);
|
|
67
114
|
default:
|
|
68
115
|
return 'Desteklenmeyen AI sağlayıcı: ' + provider;
|
|
69
116
|
}
|
|
@@ -73,8 +120,11 @@ export async function chat(message, config, env) {
|
|
|
73
120
|
}
|
|
74
121
|
}
|
|
75
122
|
|
|
76
|
-
//
|
|
77
|
-
|
|
123
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
124
|
+
// PROVIDER IMPLEMENTATIONS
|
|
125
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
126
|
+
|
|
127
|
+
async function chatGemini(message, apiKey, systemPrompt) {
|
|
78
128
|
if (!apiKey) throw new Error('GEMINI_API_KEY ayarlanmamış');
|
|
79
129
|
|
|
80
130
|
const url = `https://generativelanguage.googleapis.com/v1beta/models/gemini-1.5-flash:generateContent?key=${apiKey}`;
|
|
@@ -82,7 +132,7 @@ async function chatGemini(message, apiKey) {
|
|
|
82
132
|
const response = await axios.post(url, {
|
|
83
133
|
contents: [{
|
|
84
134
|
parts: [{
|
|
85
|
-
text:
|
|
135
|
+
text: `${systemPrompt}\n\nKullanıcı: ${message}`
|
|
86
136
|
}]
|
|
87
137
|
}]
|
|
88
138
|
}, {
|
|
@@ -97,17 +147,17 @@ async function chatGemini(message, apiKey) {
|
|
|
97
147
|
return text;
|
|
98
148
|
}
|
|
99
149
|
|
|
100
|
-
|
|
101
|
-
async function chatGroq(message, apiKey) {
|
|
150
|
+
async function chatGroq(message, apiKey, systemPrompt) {
|
|
102
151
|
if (!apiKey) throw new Error('GROQ_API_KEY ayarlanmamış');
|
|
103
152
|
|
|
104
153
|
const response = await axios.post('https://api.groq.com/openai/v1/chat/completions', {
|
|
105
154
|
model: 'llama-3.3-70b-versatile',
|
|
106
155
|
messages: [
|
|
107
|
-
{ role: 'system', content:
|
|
156
|
+
{ role: 'system', content: systemPrompt },
|
|
108
157
|
{ role: 'user', content: message }
|
|
109
158
|
],
|
|
110
|
-
max_tokens: 1000
|
|
159
|
+
max_tokens: 1000,
|
|
160
|
+
temperature: 0.7
|
|
111
161
|
}, {
|
|
112
162
|
headers: {
|
|
113
163
|
'Authorization': `Bearer ${apiKey}`,
|
|
@@ -123,14 +173,13 @@ async function chatGroq(message, apiKey) {
|
|
|
123
173
|
return text;
|
|
124
174
|
}
|
|
125
175
|
|
|
126
|
-
|
|
127
|
-
async function chatOpenAI(message, apiKey) {
|
|
176
|
+
async function chatOpenAI(message, apiKey, systemPrompt) {
|
|
128
177
|
if (!apiKey) throw new Error('OPENAI_API_KEY ayarlanmamış');
|
|
129
178
|
|
|
130
179
|
const response = await axios.post('https://api.openai.com/v1/chat/completions', {
|
|
131
180
|
model: 'gpt-4o-mini',
|
|
132
181
|
messages: [
|
|
133
|
-
{ role: 'system', content:
|
|
182
|
+
{ role: 'system', content: systemPrompt },
|
|
134
183
|
{ role: 'user', content: message }
|
|
135
184
|
],
|
|
136
185
|
max_tokens: 1000
|
|
@@ -149,8 +198,7 @@ async function chatOpenAI(message, apiKey) {
|
|
|
149
198
|
return text;
|
|
150
199
|
}
|
|
151
200
|
|
|
152
|
-
|
|
153
|
-
async function chatAnthropic(message, apiKey) {
|
|
201
|
+
async function chatAnthropic(message, apiKey, systemPrompt) {
|
|
154
202
|
if (!apiKey) throw new Error('ANTHROPIC_API_KEY ayarlanmamış');
|
|
155
203
|
|
|
156
204
|
const response = await axios.post('https://api.anthropic.com/v1/messages', {
|
|
@@ -159,7 +207,7 @@ async function chatAnthropic(message, apiKey) {
|
|
|
159
207
|
messages: [
|
|
160
208
|
{ role: 'user', content: message }
|
|
161
209
|
],
|
|
162
|
-
system:
|
|
210
|
+
system: systemPrompt
|
|
163
211
|
}, {
|
|
164
212
|
headers: {
|
|
165
213
|
'x-api-key': apiKey,
|
|
@@ -176,14 +224,13 @@ async function chatAnthropic(message, apiKey) {
|
|
|
176
224
|
return text;
|
|
177
225
|
}
|
|
178
226
|
|
|
179
|
-
|
|
180
|
-
async function chatDeepSeek(message, apiKey) {
|
|
227
|
+
async function chatDeepSeek(message, apiKey, systemPrompt) {
|
|
181
228
|
if (!apiKey) throw new Error('DEEPSEEK_API_KEY ayarlanmamış');
|
|
182
229
|
|
|
183
230
|
const response = await axios.post('https://api.deepseek.com/v1/chat/completions', {
|
|
184
231
|
model: 'deepseek-chat',
|
|
185
232
|
messages: [
|
|
186
|
-
{ role: 'system', content:
|
|
233
|
+
{ role: 'system', content: systemPrompt },
|
|
187
234
|
{ role: 'user', content: message }
|
|
188
235
|
],
|
|
189
236
|
max_tokens: 1000
|