vantuz 3.3.1 → 3.3.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.
- package/cli.js +185 -70
- package/core/agent.js +82 -0
- package/core/ai-provider.js +26 -6
- package/core/automation.js +504 -0
- package/core/channels.js +2 -2
- package/core/engine.js +319 -90
- package/core/gateway.js +68 -16
- package/core/migrations/001-initial-schema.sql +20 -0
- package/core/openclaw-bridge.js +191 -0
- package/package.json +83 -89
- package/platforms/amazon.js +5 -3
- package/platforms/ciceksepeti.js +4 -2
- package/platforms/hepsiburada.js +6 -4
- package/platforms/n11.js +5 -3
- package/platforms/pazarama.js +4 -2
- package/platforms/trendyol.js +3 -3
- package/plugins/vantuz/package.json +2 -2
- package/plugins/vantuz/platforms/index.js +34 -7
- package/plugins/vantuz/platforms/n11.js +75 -26
- package/server/app.js +29 -12
- package/server/public/index.html +2 -2
- package/.openclaw/completions/openclaw.bash +0 -227
- package/.openclaw/completions/openclaw.fish +0 -1552
- package/.openclaw/completions/openclaw.ps1 +0 -1966
- package/.openclaw/completions/openclaw.zsh +0 -3571
- package/.openclaw/gateway.cmd +0 -10
- package/.openclaw/identity/device.json +0 -7
- package/.openclaw/openclaw.json +0 -32
- package/DOCS_TR.md +0 -298
- package/onboard.js +0 -322
package/cli.js
CHANGED
|
@@ -12,6 +12,7 @@ import readline from 'readline';
|
|
|
12
12
|
import { log, getLogs, clearLogs } from './core/ai-provider.js';
|
|
13
13
|
import { getEngine } from './core/engine.js';
|
|
14
14
|
import { getGateway } from './core/gateway.js';
|
|
15
|
+
import { Configurator } from './config.js'; // Import the new Configurator
|
|
15
16
|
|
|
16
17
|
// ═══════════════════════════════════════════════════════════════════════════
|
|
17
18
|
// CONFIG
|
|
@@ -71,10 +72,44 @@ function saveConfigJson(config) {
|
|
|
71
72
|
}
|
|
72
73
|
}
|
|
73
74
|
|
|
74
|
-
function clearScreen() {
|
|
75
|
-
process.stdout.write('\x1Bc');
|
|
76
|
-
}
|
|
77
|
-
|
|
75
|
+
function clearScreen() {
|
|
76
|
+
process.stdout.write('\x1Bc');
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
async function promptInput(question) {
|
|
80
|
+
const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
|
|
81
|
+
const answer = await new Promise(resolve => rl.question(question, resolve));
|
|
82
|
+
rl.close();
|
|
83
|
+
return answer.trim();
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
function normalizePhone(input) {
|
|
87
|
+
if (!input) return '';
|
|
88
|
+
const cleaned = input.replace(/[\s-]/g, '');
|
|
89
|
+
return cleaned.startsWith('+') ? cleaned : `+${cleaned}`;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
function loadOpenclawConfig(configPath) {
|
|
93
|
+
try {
|
|
94
|
+
if (fs.existsSync(configPath)) {
|
|
95
|
+
return JSON.parse(fs.readFileSync(configPath, 'utf-8'));
|
|
96
|
+
}
|
|
97
|
+
} catch (e) {
|
|
98
|
+
console.log(c('red', `Gateway config okunamadı: ${e.message}`));
|
|
99
|
+
}
|
|
100
|
+
return {};
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
function saveOpenclawConfig(configPath, config) {
|
|
104
|
+
try {
|
|
105
|
+
fs.writeFileSync(configPath, JSON.stringify(config, null, 2));
|
|
106
|
+
return true;
|
|
107
|
+
} catch (e) {
|
|
108
|
+
console.log(c('red', `Gateway config yazılamadı: ${e.message}`));
|
|
109
|
+
return false;
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
|
|
78
113
|
function printHeader() {
|
|
79
114
|
const version = JSON.parse(fs.readFileSync(new URL('./package.json', import.meta.url))).version;
|
|
80
115
|
console.log(c('cyan', `
|
|
@@ -86,7 +121,7 @@ function printHeader() {
|
|
|
86
121
|
╚═══╝ ╚═╝ ╚═╝╚═╝ ╚═══╝ ╚═╝ ╚═════╝ ╚══════╝
|
|
87
122
|
`));
|
|
88
123
|
console.log(c('magenta', ` Enterprise E-Commerce Management System v${version}`));
|
|
89
|
-
console.log(c('dim', ' Powered by Vantuz
|
|
124
|
+
console.log(c('dim', ' Powered by Vantuz Gateway'));
|
|
90
125
|
console.log(c('dim', ' ----------------------------------------------------------\n'));
|
|
91
126
|
}
|
|
92
127
|
|
|
@@ -106,7 +141,7 @@ async function showSpinner(text, duration = 1000) {
|
|
|
106
141
|
// COMMANDS
|
|
107
142
|
// ═══════════════════════════════════════════════════════════════════════════
|
|
108
143
|
|
|
109
|
-
async function runTUI() {
|
|
144
|
+
async function runTUI() {
|
|
110
145
|
clearScreen();
|
|
111
146
|
printHeader();
|
|
112
147
|
|
|
@@ -126,7 +161,7 @@ async function runTUI() {
|
|
|
126
161
|
|
|
127
162
|
console.log(`${c('green', '●')} Sistem Aktif ${c('dim', `(${status.connectedCount}/${status.totalPlatforms} Platform Bağlı)`)}`);
|
|
128
163
|
console.log(`${c('blue', 'ℹ')} AI Sağlayıcı: ${c('bold', status.aiProvider || 'Gemini')}`);
|
|
129
|
-
console.log(`${c('yellow', '⚡')} Komutlar: ${c('cyan', '/stok, /siparis, /rapor, /analiz, /durum, /temizle, /exit')}\n`);
|
|
164
|
+
console.log(`${c('yellow', '⚡')} Komutlar: ${c('cyan', '/stok, /siparis, /rapor, /analiz, /durum, /temizle, /exit')}\n`);
|
|
130
165
|
|
|
131
166
|
const rl = readline.createInterface({
|
|
132
167
|
input: process.stdin,
|
|
@@ -159,25 +194,42 @@ async function runTUI() {
|
|
|
159
194
|
console.log(` ${c('cyan', '/temizle')} - Ekranı temizler`);
|
|
160
195
|
console.log(` ${c('cyan', '/exit')} - Çıkış\n`);
|
|
161
196
|
break;
|
|
162
|
-
case '/stok':
|
|
163
|
-
console.log(c('dim', 'Stok verileri çekiliyor...'));
|
|
164
|
-
const stocks = await engine.getStock();
|
|
165
|
-
if (stocks.length === 0) console.log(c('yellow', 'Bağlı platform bulunamadı.'));
|
|
166
|
-
stocks.forEach(s => {
|
|
167
|
-
console.log(`\n${s.icon} ${c('bold', s.platform.toUpperCase())}`);
|
|
168
|
-
s.products.slice(0, 5).forEach(p => {
|
|
169
|
-
console.log(` - ${p.title}: ${c('green', p.stock)} Adet | ${c('yellow', p.price)} TL`);
|
|
170
|
-
});
|
|
171
|
-
});
|
|
172
|
-
break;
|
|
173
|
-
case '/
|
|
174
|
-
|
|
175
|
-
const
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
197
|
+
case '/stok':
|
|
198
|
+
console.log(c('dim', 'Stok verileri çekiliyor...'));
|
|
199
|
+
const stocks = await engine.getStock();
|
|
200
|
+
if (stocks.length === 0) console.log(c('yellow', 'Bağlı platform bulunamadı.'));
|
|
201
|
+
stocks.forEach(s => {
|
|
202
|
+
console.log(`\n${s.icon} ${c('bold', s.platform.toUpperCase())}`);
|
|
203
|
+
s.products.slice(0, 5).forEach(p => {
|
|
204
|
+
console.log(` - ${p.title}: ${c('green', p.stock)} Adet | ${c('yellow', p.price)} TL`);
|
|
205
|
+
});
|
|
206
|
+
});
|
|
207
|
+
break;
|
|
208
|
+
case '/analiz':
|
|
209
|
+
process.stdout.write(c('dim', 'Analiz hazırlanıyor... '));
|
|
210
|
+
const analysis = await engine.chat('satış ve stok analiz raporu hazırla');
|
|
211
|
+
process.stdout.write('\r' + ' '.repeat(30) + '\r');
|
|
212
|
+
console.log(`\n${analysis}\n`);
|
|
213
|
+
break;
|
|
214
|
+
case '/siparis':
|
|
215
|
+
console.log(c('dim', 'Siparişler çekiliyor...'));
|
|
216
|
+
const orders = await engine.getOrders({ size: 50, allStatuses: true });
|
|
217
|
+
const activeOrders = Array.isArray(orders)
|
|
218
|
+
? orders.filter(o => ['Created', 'Picking', 'UnPacked'].includes(String(o.status || o.shipmentPackageStatus || o.orderStatus)))
|
|
219
|
+
: [];
|
|
220
|
+
const visible = activeOrders.slice(0, 5);
|
|
221
|
+
if (!Array.isArray(orders) || visible.length === 0) {
|
|
222
|
+
console.log(c('yellow', 'Son sipariş bulunamadı.'));
|
|
223
|
+
break;
|
|
224
|
+
}
|
|
225
|
+
visible.forEach(o => {
|
|
226
|
+
const names = Array.isArray(o.lines)
|
|
227
|
+
? o.lines.map(l => l?.productName || l?.name).filter(Boolean)
|
|
228
|
+
: [];
|
|
229
|
+
const namePart = names.length > 0 ? ` | ${names.join(', ')}` : '';
|
|
230
|
+
console.log(`${o._icon} [#${o.orderNumber || o.id}] ${c('bold', o.customerName || 'Müşteri')}: ${c('green', o.totalPrice ?? o.totalAmount ?? o.total ?? '—')} TL (${o._platform})${namePart}`);
|
|
231
|
+
});
|
|
232
|
+
break;
|
|
181
233
|
case '/durum':
|
|
182
234
|
const s = engine.getStatus();
|
|
183
235
|
console.log(c('yellow', '\n── Sistem Durumu ──'));
|
|
@@ -190,12 +242,12 @@ async function runTUI() {
|
|
|
190
242
|
default:
|
|
191
243
|
console.log(c('red', `[HATA] Bilinmeyen komut: ${cmd}. /help yazın.`));
|
|
192
244
|
}
|
|
193
|
-
} else {
|
|
194
|
-
process.stdout.write(c('dim', 'Düşünüyor... '));
|
|
195
|
-
const response = await engine.
|
|
196
|
-
process.stdout.write('\r' + ' '.repeat(20) + '\r');
|
|
197
|
-
console.log(`\n${c('cyan', '🐙 Vantuz:')}\n${response}\n`);
|
|
198
|
-
}
|
|
245
|
+
} else {
|
|
246
|
+
process.stdout.write(c('dim', 'Düşünüyor... '));
|
|
247
|
+
const response = await engine.handleMessage(input, { channel: 'local', from: 'local' });
|
|
248
|
+
process.stdout.write('\r' + ' '.repeat(20) + '\r');
|
|
249
|
+
console.log(`\n${c('cyan', '🐙 Vantuz:')}\n${response}\n`);
|
|
250
|
+
}
|
|
199
251
|
} catch (e) {
|
|
200
252
|
console.log(c('red', `\n[HATA] ${e.message}`));
|
|
201
253
|
}
|
|
@@ -206,11 +258,23 @@ async function runTUI() {
|
|
|
206
258
|
|
|
207
259
|
async function runConfig(args) {
|
|
208
260
|
const sub = args[1]?.toLowerCase();
|
|
209
|
-
const config = loadConfigJson();
|
|
261
|
+
const config = loadConfigJson(); // config.json operations
|
|
262
|
+
|
|
263
|
+
if (sub === 'init') {
|
|
264
|
+
const configurator = new Configurator();
|
|
265
|
+
await configurator.run();
|
|
266
|
+
return;
|
|
267
|
+
}
|
|
210
268
|
|
|
211
|
-
if (
|
|
269
|
+
if (sub === 'init' || !sub) { // If sub is 'init' OR no sub-command is provided
|
|
270
|
+
const configurator = new Configurator();
|
|
271
|
+
await configurator.run();
|
|
272
|
+
return; // IMPORTANT: Return after running the configurator
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
if (sub === 'get') { // Handle 'get' sub-command
|
|
212
276
|
printHeader();
|
|
213
|
-
if (
|
|
277
|
+
if (args[2]) {
|
|
214
278
|
const key = args[2];
|
|
215
279
|
const value = config?.[key];
|
|
216
280
|
console.log(value === undefined ? '' : String(value));
|
|
@@ -238,7 +302,7 @@ async function runConfig(args) {
|
|
|
238
302
|
return;
|
|
239
303
|
}
|
|
240
304
|
|
|
241
|
-
console.log(c('red', 'Geçersiz config komutu. Kullanım: vantuz config [get [key] | set <key> <value>]'));
|
|
305
|
+
console.log(c('red', 'Geçersiz config komutu. Kullanım: vantuz config [init | get [key] | set <key> <value>]'));
|
|
242
306
|
process.exitCode = 2;
|
|
243
307
|
}
|
|
244
308
|
|
|
@@ -260,7 +324,7 @@ async function runLogs(args) {
|
|
|
260
324
|
console.log(getLogs(n));
|
|
261
325
|
}
|
|
262
326
|
|
|
263
|
-
async function runGateway(args) {
|
|
327
|
+
async function runGateway(args) {
|
|
264
328
|
const sub = args[1]?.toLowerCase();
|
|
265
329
|
const gw = await getGateway();
|
|
266
330
|
const info = gw.getInfo();
|
|
@@ -276,8 +340,8 @@ async function runGateway(args) {
|
|
|
276
340
|
console.log('');
|
|
277
341
|
|
|
278
342
|
if (!info.connected) {
|
|
279
|
-
console.log(c('dim', ' Gateway başlatmak için: vantuz gateway run'));
|
|
280
|
-
console.log(c('dim', ' Veya: start.bat\n'));
|
|
343
|
+
console.log(c('dim', ' Gateway başlatmak için: vantuz gateway run'));
|
|
344
|
+
console.log(c('dim', ' Veya: start.bat\n'));
|
|
281
345
|
}
|
|
282
346
|
return;
|
|
283
347
|
}
|
|
@@ -311,31 +375,18 @@ async function runGateway(args) {
|
|
|
311
375
|
return;
|
|
312
376
|
}
|
|
313
377
|
|
|
314
|
-
if (sub === 'run' || sub === 'start') {
|
|
315
|
-
console.log(c('cyan', 'Gateway başlatılıyor...'));
|
|
316
|
-
const
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
child.unref(); // Parent process'ten ayır
|
|
327
|
-
|
|
328
|
-
console.log(c('green', '✔ Gateway arka planda başlatıldı.'));
|
|
329
|
-
console.log(c('dim', 'Birkaç saniye içinde hazır olacak.'));
|
|
330
|
-
console.log(c('dim', 'Kontrol için: vantuz gateway status'));
|
|
331
|
-
} catch (e) {
|
|
332
|
-
console.log(c('red', `Başlatma hatası: ${e.message}`));
|
|
333
|
-
}
|
|
334
|
-
} else {
|
|
335
|
-
console.log(c('red', 'Gateway başlatma dosyası bulunamadı: .openclaw/gateway.cmd'));
|
|
336
|
-
}
|
|
337
|
-
return;
|
|
338
|
-
}
|
|
378
|
+
if (sub === 'run' || sub === 'start') {
|
|
379
|
+
console.log(c('cyan', 'Gateway başlatılıyor...'));
|
|
380
|
+
const result = await gw.start();
|
|
381
|
+
if (result.success) {
|
|
382
|
+
console.log(c('green', '✔ Gateway arka planda başlatıldı.'));
|
|
383
|
+
console.log(c('dim', 'Birkaç saniye içinde hazır olacak.'));
|
|
384
|
+
console.log(c('dim', 'Kontrol için: vantuz gateway status'));
|
|
385
|
+
} else {
|
|
386
|
+
console.log(c('red', result.error || 'Gateway başlatılamadı'));
|
|
387
|
+
}
|
|
388
|
+
return;
|
|
389
|
+
}
|
|
339
390
|
|
|
340
391
|
console.log(c('red', 'Kullanım: vantuz gateway [status|health|models|run]'));
|
|
341
392
|
}
|
|
@@ -385,9 +436,72 @@ async function runDoctor() {
|
|
|
385
436
|
console.log('');
|
|
386
437
|
}
|
|
387
438
|
|
|
388
|
-
async function runChannels(args) {
|
|
389
|
-
|
|
390
|
-
|
|
439
|
+
async function runChannels(args) {
|
|
440
|
+
const sub = args[1]?.toLowerCase();
|
|
441
|
+
if (sub === 'login') {
|
|
442
|
+
printHeader();
|
|
443
|
+
console.log(c('yellow', '── WhatsApp Login ──\n'));
|
|
444
|
+
|
|
445
|
+
const openclawDir = path.join(os.homedir(), '.openclaw');
|
|
446
|
+
const configPath = path.join(openclawDir, 'openclaw.json');
|
|
447
|
+
|
|
448
|
+
if (!fs.existsSync(openclawDir)) {
|
|
449
|
+
fs.mkdirSync(openclawDir, { recursive: true });
|
|
450
|
+
}
|
|
451
|
+
|
|
452
|
+
const rawPhone = await promptInput('WhatsApp numaranız (E.164, örn: +905551112233): ');
|
|
453
|
+
const phone = normalizePhone(rawPhone);
|
|
454
|
+
if (!phone || phone === '+') {
|
|
455
|
+
console.log(c('red', 'Geçerli bir numara girilmedi.'));
|
|
456
|
+
process.exitCode = 2;
|
|
457
|
+
return;
|
|
458
|
+
}
|
|
459
|
+
|
|
460
|
+
const config = loadOpenclawConfig(configPath);
|
|
461
|
+
if (!config.channels) config.channels = {};
|
|
462
|
+
if (!config.channels.whatsapp) config.channels.whatsapp = {};
|
|
463
|
+
|
|
464
|
+
if (!config.channels.whatsapp.dmPolicy) {
|
|
465
|
+
config.channels.whatsapp.dmPolicy = 'allowlist';
|
|
466
|
+
}
|
|
467
|
+
|
|
468
|
+
const allowFrom = Array.isArray(config.channels.whatsapp.allowFrom)
|
|
469
|
+
? config.channels.whatsapp.allowFrom
|
|
470
|
+
: [];
|
|
471
|
+
if (!allowFrom.includes(phone)) {
|
|
472
|
+
allowFrom.push(phone);
|
|
473
|
+
}
|
|
474
|
+
config.channels.whatsapp.allowFrom = allowFrom;
|
|
475
|
+
|
|
476
|
+
const saved = saveOpenclawConfig(configPath, config);
|
|
477
|
+
if (!saved) {
|
|
478
|
+
process.exitCode = 1;
|
|
479
|
+
return;
|
|
480
|
+
}
|
|
481
|
+
|
|
482
|
+
console.log(c('green', '✔ Gateway config güncellendi.'));
|
|
483
|
+
console.log(c('dim', 'Şimdi QR için login başlatılıyor...\n'));
|
|
484
|
+
|
|
485
|
+
try {
|
|
486
|
+
const { spawn } = await import('child_process');
|
|
487
|
+
const child = spawn('openclaw', ['channels', 'login'], {
|
|
488
|
+
stdio: 'inherit',
|
|
489
|
+
shell: true
|
|
490
|
+
});
|
|
491
|
+
await new Promise((resolve, reject) => {
|
|
492
|
+
child.on('exit', code => (code === 0 ? resolve() : reject(new Error(`gateway exit ${code}`))));
|
|
493
|
+
child.on('error', reject);
|
|
494
|
+
});
|
|
495
|
+
console.log(c('green', '\n✔ QR eşleştirme tamamlandı.'));
|
|
496
|
+
console.log(c('dim', 'Gateway başlatmak için: vantuz gateway run'));
|
|
497
|
+
} catch (e) {
|
|
498
|
+
console.log(c('red', `Login çalıştırılamadı: ${e.message}`));
|
|
499
|
+
}
|
|
500
|
+
return;
|
|
501
|
+
}
|
|
502
|
+
|
|
503
|
+
printHeader();
|
|
504
|
+
console.log(c('yellow', '── İletişim Kanalları ──\n'));
|
|
391
505
|
|
|
392
506
|
const engine = await getEngine();
|
|
393
507
|
const status = engine.getStatus();
|
|
@@ -459,10 +573,11 @@ async function main() {
|
|
|
459
573
|
console.log(` ${c('cyan', 'vantuz status')} - Durum kontrolü`);
|
|
460
574
|
console.log(` ${c('cyan', 'vantuz gateway')} - Gateway yönetimi`);
|
|
461
575
|
console.log(` ${c('cyan', 'vantuz doctor')} - Sistem sağlık kontrolü`);
|
|
462
|
-
console.log(` ${c('cyan', 'vantuz channels')} - İletişim kanalları`);
|
|
463
|
-
console.log(` ${c('cyan', 'vantuz
|
|
576
|
+
console.log(` ${c('cyan', 'vantuz channels')} - İletişim kanalları`);
|
|
577
|
+
console.log(` ${c('cyan', 'vantuz channels login')} - WhatsApp QR login`);
|
|
578
|
+
console.log(` ${c('cyan', 'vantuz config')} - Ayarları göster/güncelle`);
|
|
464
579
|
console.log(` ${c('cyan', 'vantuz logs')} - Logları göster`);
|
|
465
|
-
console.log(`\nKurulum için: ${c('cyan', 'vantuz
|
|
580
|
+
console.log(`\nKurulum ve başlangıç ayarları için: ${c('cyan', 'vantuz config init')}`);
|
|
466
581
|
process.exitCode = command ? 2 : 0;
|
|
467
582
|
}
|
|
468
583
|
}
|
package/core/agent.js
ADDED
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import fs from 'fs';
|
|
2
|
+
import path from 'path';
|
|
3
|
+
import { exec } from 'child_process';
|
|
4
|
+
import https from 'https';
|
|
5
|
+
import http from 'http';
|
|
6
|
+
|
|
7
|
+
const DEFAULT_ALLOW_CMDS = [
|
|
8
|
+
'dir', 'ls', 'rg', 'cat', 'type', 'node', 'npm', 'git', 'curl'
|
|
9
|
+
];
|
|
10
|
+
|
|
11
|
+
function isAllowedCommand(command, allowList = []) {
|
|
12
|
+
const trimmed = String(command || '').trim();
|
|
13
|
+
if (!trimmed) return false;
|
|
14
|
+
const cmd = trimmed.split(/\s+/)[0].toLowerCase();
|
|
15
|
+
const allowed = allowList.length > 0 ? allowList : DEFAULT_ALLOW_CMDS;
|
|
16
|
+
return allowed.includes(cmd);
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
function runCommand(command, timeoutMs = 15000) {
|
|
20
|
+
return new Promise((resolve) => {
|
|
21
|
+
exec(command, { timeout: timeoutMs, windowsHide: true }, (err, stdout, stderr) => {
|
|
22
|
+
if (err) {
|
|
23
|
+
resolve({ success: false, output: stderr || err.message });
|
|
24
|
+
return;
|
|
25
|
+
}
|
|
26
|
+
resolve({ success: true, output: stdout || stderr || '' });
|
|
27
|
+
});
|
|
28
|
+
});
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
function readFileSafe(filePath, maxBytes = 200000) {
|
|
32
|
+
const resolved = path.resolve(filePath);
|
|
33
|
+
if (!fs.existsSync(resolved)) return { success: false, output: 'Dosya bulunamadı.' };
|
|
34
|
+
const stat = fs.statSync(resolved);
|
|
35
|
+
if (stat.size > maxBytes) return { success: false, output: 'Dosya çok büyük.' };
|
|
36
|
+
return { success: true, output: fs.readFileSync(resolved, 'utf-8') };
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
function listDirSafe(dirPath = '.') {
|
|
40
|
+
const resolved = path.resolve(dirPath);
|
|
41
|
+
if (!fs.existsSync(resolved)) return { success: false, output: 'Klasör bulunamadı.' };
|
|
42
|
+
const entries = fs.readdirSync(resolved, { withFileTypes: true })
|
|
43
|
+
.map(d => (d.isDirectory() ? `[D] ${d.name}` : `[F] ${d.name}`));
|
|
44
|
+
return { success: true, output: entries.join('\n') };
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
function httpGet(url, timeoutMs = 15000) {
|
|
48
|
+
return new Promise((resolve) => {
|
|
49
|
+
const lib = url.startsWith('https') ? https : http;
|
|
50
|
+
const req = lib.get(url, { timeout: timeoutMs }, (res) => {
|
|
51
|
+
let data = '';
|
|
52
|
+
res.on('data', chunk => data += chunk);
|
|
53
|
+
res.on('end', () => resolve({ success: true, output: data.slice(0, 200000) }));
|
|
54
|
+
});
|
|
55
|
+
req.on('error', (e) => resolve({ success: false, output: e.message }));
|
|
56
|
+
req.on('timeout', () => {
|
|
57
|
+
req.destroy();
|
|
58
|
+
resolve({ success: false, output: 'Timeout' });
|
|
59
|
+
});
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
export async function executeTool(tool, args = {}, config = {}) {
|
|
64
|
+
switch (tool) {
|
|
65
|
+
case 'exec': {
|
|
66
|
+
const command = args.command || '';
|
|
67
|
+
const allowList = config.agentAllowCommands || [];
|
|
68
|
+
if (!isAllowedCommand(command, allowList)) {
|
|
69
|
+
return { success: false, output: 'Komut izinli değil.' };
|
|
70
|
+
}
|
|
71
|
+
return await runCommand(command, config.agentCommandTimeoutMs || 15000);
|
|
72
|
+
}
|
|
73
|
+
case 'readFile':
|
|
74
|
+
return readFileSafe(args.path);
|
|
75
|
+
case 'listDir':
|
|
76
|
+
return listDirSafe(args.path);
|
|
77
|
+
case 'httpGet':
|
|
78
|
+
return await httpGet(args.url || '');
|
|
79
|
+
default:
|
|
80
|
+
return { success: false, output: 'Bilinmeyen araç.' };
|
|
81
|
+
}
|
|
82
|
+
}
|
package/core/ai-provider.js
CHANGED
|
@@ -10,7 +10,7 @@ import os from 'os';
|
|
|
10
10
|
|
|
11
11
|
const LOG_FILE = path.join(os.homedir(), '.vantuz', 'vantuz.log');
|
|
12
12
|
|
|
13
|
-
const PROVIDER_CONFIG = {
|
|
13
|
+
export const PROVIDER_CONFIG = {
|
|
14
14
|
gemini: {
|
|
15
15
|
url: (apiKey) => `https://generativelanguage.googleapis.com/v1beta/models/gemini-1.5-flash:generateContent?key=${apiKey}`,
|
|
16
16
|
body: (systemPrompt, message) => ({
|
|
@@ -18,7 +18,11 @@ const PROVIDER_CONFIG = {
|
|
|
18
18
|
}),
|
|
19
19
|
headers: { 'Content-Type': 'application/json' },
|
|
20
20
|
parseResponse: (data) => data?.candidates?.[0]?.content?.parts?.[0]?.text,
|
|
21
|
-
errorMsg: 'Gemini yanıt vermedi'
|
|
21
|
+
errorMsg: 'Gemini yanıt vermedi',
|
|
22
|
+
config_label: 'Google Gemini',
|
|
23
|
+
config_description: 'Önerilen/Ücretsiz',
|
|
24
|
+
config_icon: '🔷',
|
|
25
|
+
envKey: 'GEMINI_API_KEY'
|
|
22
26
|
},
|
|
23
27
|
groq: {
|
|
24
28
|
url: 'https://api.groq.com/openai/v1/chat/completions',
|
|
@@ -33,7 +37,11 @@ const PROVIDER_CONFIG = {
|
|
|
33
37
|
}),
|
|
34
38
|
headers: (apiKey) => ({ 'Authorization': `Bearer ${apiKey}`, 'Content-Type': 'application/json' }),
|
|
35
39
|
parseResponse: (data) => data?.choices?.[0]?.message?.content,
|
|
36
|
-
errorMsg: 'Groq yanıt vermedi'
|
|
40
|
+
errorMsg: 'Groq yanıt vermedi',
|
|
41
|
+
config_label: 'Groq',
|
|
42
|
+
config_description: 'Hızlı/Ücretsiz',
|
|
43
|
+
config_icon: '⚡',
|
|
44
|
+
envKey: 'GROQ_API_KEY'
|
|
37
45
|
},
|
|
38
46
|
openai: {
|
|
39
47
|
url: 'https://api.openai.com/v1/chat/completions',
|
|
@@ -47,7 +55,11 @@ const PROVIDER_CONFIG = {
|
|
|
47
55
|
}),
|
|
48
56
|
headers: (apiKey) => ({ 'Authorization': `Bearer ${apiKey}`, 'Content-Type': 'application/json' }),
|
|
49
57
|
parseResponse: (data) => data?.choices?.[0]?.message?.content,
|
|
50
|
-
errorMsg: 'OpenAI yanıt vermedi'
|
|
58
|
+
errorMsg: 'OpenAI yanıt vermedi',
|
|
59
|
+
config_label: 'OpenAI GPT-4o',
|
|
60
|
+
config_description: 'Premium',
|
|
61
|
+
config_icon: '🟢',
|
|
62
|
+
envKey: 'OPENAI_API_KEY'
|
|
51
63
|
},
|
|
52
64
|
anthropic: {
|
|
53
65
|
url: 'https://api.anthropic.com/v1/messages',
|
|
@@ -61,7 +73,11 @@ const PROVIDER_CONFIG = {
|
|
|
61
73
|
}),
|
|
62
74
|
headers: (apiKey) => ({ 'x-api-key': apiKey, 'anthropic-version': '2023-06-01', 'Content-Type': 'application/json' }),
|
|
63
75
|
parseResponse: (data) => data?.content?.[0]?.text,
|
|
64
|
-
errorMsg: 'Anthropic yanıt vermedi'
|
|
76
|
+
errorMsg: 'Anthropic yanıt vermedi',
|
|
77
|
+
config_label: 'Anthropic Claude 3.5',
|
|
78
|
+
config_description: 'Advanced',
|
|
79
|
+
config_icon: '🟣',
|
|
80
|
+
envKey: 'ANTHROPIC_API_KEY'
|
|
65
81
|
},
|
|
66
82
|
deepseek: {
|
|
67
83
|
url: 'https://api.deepseek.com/v1/chat/completions',
|
|
@@ -75,7 +91,11 @@ const PROVIDER_CONFIG = {
|
|
|
75
91
|
}),
|
|
76
92
|
headers: (apiKey) => ({ 'Authorization': `Bearer ${apiKey}`, 'Content-Type': 'application/json' }),
|
|
77
93
|
parseResponse: (data) => data?.choices?.[0]?.message?.content,
|
|
78
|
-
errorMsg: 'DeepSeek yanıt vermedi'
|
|
94
|
+
errorMsg: 'DeepSeek yanıt vermedi',
|
|
95
|
+
config_label: 'DeepSeek V3',
|
|
96
|
+
config_description: 'Fast',
|
|
97
|
+
config_icon: '🔵',
|
|
98
|
+
envKey: 'DEEPSEEK_API_KEY'
|
|
79
99
|
}
|
|
80
100
|
};
|
|
81
101
|
|