vantuz 3.0.0 → 3.0.2

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.
Files changed (3) hide show
  1. package/cli.js +44 -28
  2. package/core/ai-provider.js +205 -0
  3. package/package.json +1 -1
package/cli.js CHANGED
@@ -11,12 +11,19 @@
11
11
 
12
12
  import fs from 'fs';
13
13
  import path from 'path';
14
- import { fileURLToPath } from 'url';
14
+ import os from 'os';
15
15
  import readline from 'readline';
16
+ import { chat as aiChat, log, getLogs, clearLogs } from './core/ai-provider.js';
16
17
 
17
- const __dirname = path.dirname(fileURLToPath(import.meta.url));
18
- const CONFIG_PATH = path.join(__dirname, '.env');
19
- const CONFIG_JSON = path.join(__dirname, 'vantuz.config.json');
18
+ // Config dosyaları kullanıcının home dizininde saklanır
19
+ const VANTUZ_HOME = path.join(os.homedir(), '.vantuz');
20
+ const CONFIG_PATH = path.join(VANTUZ_HOME, '.env');
21
+ const CONFIG_JSON = path.join(VANTUZ_HOME, 'config.json');
22
+
23
+ // Dizin yoksa oluştur
24
+ if (!fs.existsSync(VANTUZ_HOME)) {
25
+ fs.mkdirSync(VANTUZ_HOME, { recursive: true });
26
+ }
20
27
 
21
28
  // ═══════════════════════════════════════════════════════════════════════════
22
29
  // RENK KODLARI
@@ -89,6 +96,11 @@ function saveEnv(env) {
89
96
  fs.writeFileSync(CONFIG_PATH, lines.join('\n'));
90
97
  }
91
98
 
99
+ function hasAnyAIKey(env) {
100
+ return env.OPENAI_API_KEY || env.ANTHROPIC_API_KEY ||
101
+ env.DEEPSEEK_API_KEY || env.GROQ_API_KEY || env.GEMINI_API_KEY;
102
+ }
103
+
92
104
  // ═══════════════════════════════════════════════════════════════════════════
93
105
  // READLINE HELPER
94
106
  // ═══════════════════════════════════════════════════════════════════════════
@@ -219,7 +231,7 @@ async function runTUI() {
219
231
  console.log(c('dim', ' Komutlar: /help, /stok, /fiyat, /rapor, /cikis\n'));
220
232
 
221
233
  // Check AI config
222
- const hasAI = env.OPENAI_API_KEY || env.ANTHROPIC_API_KEY || env.DEEPSEEK_API_KEY;
234
+ const hasAI = hasAnyAIKey(env);
223
235
  if (!hasAI) {
224
236
  console.log(c('yellow', ' ⚠️ AI sağlayıcı yapılandırılmamış.'));
225
237
  console.log(c('dim', ' → vantuz config komutunu çalıştırın\n'));
@@ -263,6 +275,8 @@ async function handleCommand(input, config, env) {
263
275
  /fiyat <ürün> <tl> → Fiyat güncelle
264
276
  /rapor [dönem] → Satış raporu
265
277
  /platformlar → Bağlı platformlar
278
+ /logs [n] → Son n log satırı
279
+ /logs clear → Logları temizle
266
280
  /config → Ayarları aç
267
281
  /cikis → Çıkış
268
282
  `);
@@ -307,6 +321,18 @@ async function handleCommand(input, config, env) {
307
321
  console.log(c('cyan', '\n 👋 Görüşmek üzere!\n'));
308
322
  process.exit(0);
309
323
 
324
+ case 'logs':
325
+ case 'log':
326
+ if (args[0] === 'clear') {
327
+ clearLogs();
328
+ console.log(c('green', '\n ✓ Loglar temizlendi'));
329
+ } else {
330
+ const lineCount = parseInt(args[0]) || 30;
331
+ console.log(c('cyan', `\n 📝 Son ${lineCount} log:`));
332
+ console.log(c('dim', getLogs(lineCount)));
333
+ }
334
+ break;
335
+
310
336
  default:
311
337
  console.log(c('red', ` ❌ Bilinmeyen komut: /${cmd}`));
312
338
  console.log(c('dim', ' /help yazarak komutları görebilirsiniz'));
@@ -314,31 +340,20 @@ async function handleCommand(input, config, env) {
314
340
  }
315
341
 
316
342
  async function processChat(input, config, env) {
317
- // Simple NL parsing
318
- const lower = input.toLowerCase();
319
-
320
- if (lower.includes('stok') && (lower.includes('düşük') || lower.includes('az'))) {
321
- return 'Düşük stoklu ürünleri kontrol ediyorum... (API bağlantısı gerekli)';
322
- }
323
-
324
- if (lower.includes('fiyat') && lower.includes('güncelle')) {
325
- return 'Fiyat güncellemesi için /fiyat <ürün> <tl> komutunu kullanın.';
326
- }
327
-
328
- if (lower.includes('sipariş') || lower.includes('order')) {
329
- return 'Siparişleri kontrol ediyorum... (API bağlantısı gerekli)';
330
- }
331
-
332
- if (lower.includes('rapor')) {
333
- return 'Rapor için /rapor 7d yazabilirsiniz.';
334
- }
335
-
336
- // Default response
337
- if (!env.OPENAI_API_KEY && !env.ANTHROPIC_API_KEY) {
343
+ // AI API anahtarı kontrolü
344
+ if (!hasAnyAIKey(env)) {
338
345
  return 'AI yanıtı için API anahtarı gerekli. "vantuz config" ile ayarlayın.';
339
346
  }
340
347
 
341
- return 'Anladım! Bu işlem için pazaryeri API bağlantısı gerekiyor.';
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
+ }
342
357
  }
343
358
 
344
359
  // ═══════════════════════════════════════════════════════════════════════════
@@ -355,7 +370,7 @@ async function runStatus() {
355
370
 
356
371
  // AI
357
372
  const aiProvider = config.aiProvider || 'Ayarlanmamış';
358
- const hasAIKey = env.OPENAI_API_KEY || env.ANTHROPIC_API_KEY;
373
+ const hasAIKey = hasAnyAIKey(env);
359
374
  console.log(` AI Sağlayıcı: ${aiProvider} ${hasAIKey ? c('green', '✓') : c('red', '✗')}`);
360
375
 
361
376
  // Platforms
@@ -378,6 +393,7 @@ async function runStatus() {
378
393
  }
379
394
 
380
395
  console.log(`\n Toplam: ${connected}/${platforms.length} platform bağlı`);
396
+ console.log(c('dim', `\n Config: ${CONFIG_PATH}`));
381
397
  console.log();
382
398
  }
383
399
 
@@ -0,0 +1,205 @@
1
+ /**
2
+ * 🤖 AI Provider Integration
3
+ * Gerçek AI API çağrıları
4
+ */
5
+
6
+ import axios from 'axios';
7
+ import fs from 'fs';
8
+ import path from 'path';
9
+ import os from 'os';
10
+
11
+ const LOG_FILE = path.join(os.homedir(), '.vantuz', 'vantuz.log');
12
+
13
+ // Log fonksiyonu
14
+ export function log(level, message, data = null) {
15
+ const timestamp = new Date().toISOString();
16
+ const logLine = `[${timestamp}] [${level}] ${message}${data ? ' | ' + JSON.stringify(data) : ''}\n`;
17
+
18
+ try {
19
+ fs.appendFileSync(LOG_FILE, logLine);
20
+ } catch (e) { }
21
+
22
+ if (level === 'ERROR') {
23
+ console.error(`❌ ${message}`);
24
+ }
25
+ }
26
+
27
+ export function getLogs(lines = 50) {
28
+ try {
29
+ if (!fs.existsSync(LOG_FILE)) {
30
+ return 'Log dosyası bulunamadı.';
31
+ }
32
+ const content = fs.readFileSync(LOG_FILE, 'utf-8');
33
+ const allLines = content.split('\n').filter(l => l.trim());
34
+ return allLines.slice(-lines).join('\n');
35
+ } catch (e) {
36
+ return `Log okuma hatası: ${e.message}`;
37
+ }
38
+ }
39
+
40
+ export function clearLogs() {
41
+ try {
42
+ fs.writeFileSync(LOG_FILE, '');
43
+ return true;
44
+ } catch (e) {
45
+ return false;
46
+ }
47
+ }
48
+
49
+ // AI Chat fonksiyonu
50
+ export async function chat(message, config, env) {
51
+ const provider = config.aiProvider || 'gemini';
52
+
53
+ log('INFO', `AI isteği: ${provider}`, { message: message.slice(0, 100) });
54
+
55
+ try {
56
+ switch (provider) {
57
+ case 'gemini':
58
+ return await chatGemini(message, env.GEMINI_API_KEY);
59
+ case 'groq':
60
+ return await chatGroq(message, env.GROQ_API_KEY);
61
+ case 'openai':
62
+ return await chatOpenAI(message, env.OPENAI_API_KEY);
63
+ case 'anthropic':
64
+ return await chatAnthropic(message, env.ANTHROPIC_API_KEY);
65
+ case 'deepseek':
66
+ return await chatDeepSeek(message, env.DEEPSEEK_API_KEY);
67
+ default:
68
+ return 'Desteklenmeyen AI sağlayıcı: ' + provider;
69
+ }
70
+ } catch (error) {
71
+ log('ERROR', `AI hatası: ${error.message}`, { provider });
72
+ return `AI hatası: ${error.message}. /logs komutu ile detay görün.`;
73
+ }
74
+ }
75
+
76
+ // Gemini API
77
+ async function chatGemini(message, apiKey) {
78
+ if (!apiKey) throw new Error('GEMINI_API_KEY ayarlanmamış');
79
+
80
+ const url = `https://generativelanguage.googleapis.com/v1beta/models/gemini-1.5-flash:generateContent?key=${apiKey}`;
81
+
82
+ const response = await axios.post(url, {
83
+ contents: [{
84
+ parts: [{
85
+ text: `Sen Vantuz AI, bir e-ticaret asistanısın. Türkiye pazaryerleri (Trendyol, Hepsiburada, N11, Amazon, Çiçeksepeti, PTTavm, Pazarama) konusunda uzmansın. Kısa ve öz yanıt ver.\n\nKullanıcı: ${message}`
86
+ }]
87
+ }]
88
+ }, {
89
+ headers: { 'Content-Type': 'application/json' },
90
+ timeout: 30000
91
+ });
92
+
93
+ const text = response.data?.candidates?.[0]?.content?.parts?.[0]?.text;
94
+ if (!text) throw new Error('Gemini yanıt vermedi');
95
+
96
+ log('INFO', 'Gemini yanıtı alındı', { chars: text.length });
97
+ return text;
98
+ }
99
+
100
+ // Groq API
101
+ async function chatGroq(message, apiKey) {
102
+ if (!apiKey) throw new Error('GROQ_API_KEY ayarlanmamış');
103
+
104
+ const response = await axios.post('https://api.groq.com/openai/v1/chat/completions', {
105
+ model: 'llama-3.3-70b-versatile',
106
+ messages: [
107
+ { role: 'system', content: 'Sen Vantuz AI, bir e-ticaret asistanısın. Türkiye pazaryerleri konusunda uzmansın. Kısa ve öz yanıt ver.' },
108
+ { role: 'user', content: message }
109
+ ],
110
+ max_tokens: 1000
111
+ }, {
112
+ headers: {
113
+ 'Authorization': `Bearer ${apiKey}`,
114
+ 'Content-Type': 'application/json'
115
+ },
116
+ timeout: 30000
117
+ });
118
+
119
+ const text = response.data?.choices?.[0]?.message?.content;
120
+ if (!text) throw new Error('Groq yanıt vermedi');
121
+
122
+ log('INFO', 'Groq yanıtı alındı', { chars: text.length });
123
+ return text;
124
+ }
125
+
126
+ // OpenAI API
127
+ async function chatOpenAI(message, apiKey) {
128
+ if (!apiKey) throw new Error('OPENAI_API_KEY ayarlanmamış');
129
+
130
+ const response = await axios.post('https://api.openai.com/v1/chat/completions', {
131
+ model: 'gpt-4o-mini',
132
+ messages: [
133
+ { role: 'system', content: 'Sen Vantuz AI, bir e-ticaret asistanısın. Türkiye pazaryerleri konusunda uzmansın. Kısa ve öz yanıt ver.' },
134
+ { role: 'user', content: message }
135
+ ],
136
+ max_tokens: 1000
137
+ }, {
138
+ headers: {
139
+ 'Authorization': `Bearer ${apiKey}`,
140
+ 'Content-Type': 'application/json'
141
+ },
142
+ timeout: 30000
143
+ });
144
+
145
+ const text = response.data?.choices?.[0]?.message?.content;
146
+ if (!text) throw new Error('OpenAI yanıt vermedi');
147
+
148
+ log('INFO', 'OpenAI yanıtı alındı', { chars: text.length });
149
+ return text;
150
+ }
151
+
152
+ // Anthropic API
153
+ async function chatAnthropic(message, apiKey) {
154
+ if (!apiKey) throw new Error('ANTHROPIC_API_KEY ayarlanmamış');
155
+
156
+ const response = await axios.post('https://api.anthropic.com/v1/messages', {
157
+ model: 'claude-3-haiku-20240307',
158
+ max_tokens: 1000,
159
+ messages: [
160
+ { role: 'user', content: message }
161
+ ],
162
+ system: 'Sen Vantuz AI, bir e-ticaret asistanısın. Türkiye pazaryerleri konusunda uzmansın. Kısa ve öz yanıt ver.'
163
+ }, {
164
+ headers: {
165
+ 'x-api-key': apiKey,
166
+ 'anthropic-version': '2023-06-01',
167
+ 'Content-Type': 'application/json'
168
+ },
169
+ timeout: 30000
170
+ });
171
+
172
+ const text = response.data?.content?.[0]?.text;
173
+ if (!text) throw new Error('Anthropic yanıt vermedi');
174
+
175
+ log('INFO', 'Anthropic yanıtı alındı', { chars: text.length });
176
+ return text;
177
+ }
178
+
179
+ // DeepSeek API
180
+ async function chatDeepSeek(message, apiKey) {
181
+ if (!apiKey) throw new Error('DEEPSEEK_API_KEY ayarlanmamış');
182
+
183
+ const response = await axios.post('https://api.deepseek.com/v1/chat/completions', {
184
+ model: 'deepseek-chat',
185
+ messages: [
186
+ { role: 'system', content: 'Sen Vantuz AI, bir e-ticaret asistanısın. Türkiye pazaryerleri konusunda uzmansın. Kısa ve öz yanıt ver.' },
187
+ { role: 'user', content: message }
188
+ ],
189
+ max_tokens: 1000
190
+ }, {
191
+ headers: {
192
+ 'Authorization': `Bearer ${apiKey}`,
193
+ 'Content-Type': 'application/json'
194
+ },
195
+ timeout: 30000
196
+ });
197
+
198
+ const text = response.data?.choices?.[0]?.message?.content;
199
+ if (!text) throw new Error('DeepSeek yanıt vermedi');
200
+
201
+ log('INFO', 'DeepSeek yanıtı alındı', { chars: text.length });
202
+ return text;
203
+ }
204
+
205
+ export default { chat, log, getLogs, clearLogs };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vantuz",
3
- "version": "3.0.0",
3
+ "version": "3.0.2",
4
4
  "description": "Yapay Zeka Destekli E-Ticaret Yönetim Platformu - 7 Pazaryeri Entegrasyonu",
5
5
  "type": "module",
6
6
  "main": "cli.js",