vantuz 3.3.0 → 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/eia-monitor.js +14 -6
- 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/core/scrapers/TrendyolScraper.js +74 -19
- package/package.json +85 -91
- 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/_request.js +34 -0
- package/plugins/vantuz/platforms/amazon.js +59 -35
- package/plugins/vantuz/platforms/ciceksepeti.js +14 -9
- package/plugins/vantuz/platforms/hepsiburada.js +14 -9
- package/plugins/vantuz/platforms/index.js +101 -54
- package/plugins/vantuz/platforms/n11.js +91 -34
- package/plugins/vantuz/platforms/pazarama.js +30 -17
- package/plugins/vantuz/platforms/pttavm.js +14 -9
- package/plugins/vantuz/platforms/trendyol.js +16 -11
- 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/core/engine.js
CHANGED
|
@@ -16,8 +16,11 @@ import platformHub from '../plugins/vantuz/platforms/index.js';
|
|
|
16
16
|
// AI Provider & Gateway
|
|
17
17
|
import { getChannelManager } from './channels.js';
|
|
18
18
|
import { chat as aiChat, log } from './ai-provider.js';
|
|
19
|
-
import { getGateway } from './gateway.js';
|
|
20
|
-
import { getEIAMonitor } from './eia-monitor.js'; // New import
|
|
19
|
+
import { getGateway } from './gateway.js';
|
|
20
|
+
import { getEIAMonitor } from './eia-monitor.js'; // New import
|
|
21
|
+
import AutomationManager from './automation.js';
|
|
22
|
+
import OpenClawBridge from './openclaw-bridge.js';
|
|
23
|
+
import { executeTool } from './agent.js';
|
|
21
24
|
|
|
22
25
|
// Tools
|
|
23
26
|
import { repricerTool } from '../plugins/vantuz/tools/repricer.js';
|
|
@@ -37,10 +40,10 @@ const PLATFORM_CONFIG_MAP = {
|
|
|
37
40
|
envPrefix: 'HEPSIBURADA',
|
|
38
41
|
keys: ['merchantId', 'username', 'password']
|
|
39
42
|
},
|
|
40
|
-
n11: {
|
|
41
|
-
envPrefix: 'N11',
|
|
42
|
-
keys: ['apiKey', 'apiSecret']
|
|
43
|
-
},
|
|
43
|
+
n11: {
|
|
44
|
+
envPrefix: 'N11',
|
|
45
|
+
keys: ['apiKey', 'apiSecret']
|
|
46
|
+
},
|
|
44
47
|
amazon: {
|
|
45
48
|
envPrefix: 'AMAZON',
|
|
46
49
|
nested: {
|
|
@@ -79,7 +82,7 @@ const CONFIG_JSON = path.join(VANTUZ_HOME, 'config.json');
|
|
|
79
82
|
// ═══════════════════════════════════════════════════════════════════════════
|
|
80
83
|
|
|
81
84
|
export class VantuzEngine {
|
|
82
|
-
constructor() {
|
|
85
|
+
constructor() {
|
|
83
86
|
this.initialized = false;
|
|
84
87
|
this.config = {};
|
|
85
88
|
this.env = {};
|
|
@@ -90,7 +93,9 @@ export class VantuzEngine {
|
|
|
90
93
|
products: [],
|
|
91
94
|
connectedPlatforms: []
|
|
92
95
|
};
|
|
93
|
-
this.eiaMonitor = null; // New property
|
|
96
|
+
this.eiaMonitor = null; // New property
|
|
97
|
+
this.automation = null;
|
|
98
|
+
this.bridge = null;
|
|
94
99
|
|
|
95
100
|
// Tool Registry
|
|
96
101
|
this.tools = {
|
|
@@ -107,22 +112,29 @@ export class VantuzEngine {
|
|
|
107
112
|
/**
|
|
108
113
|
* Engine'i başlat
|
|
109
114
|
*/
|
|
110
|
-
async initialize() {
|
|
111
|
-
log('INFO', 'Vantuz Engine v3.2 başlatılıyor...');
|
|
112
|
-
|
|
113
|
-
// Config ve env yükle
|
|
114
|
-
this._loadConfig();
|
|
115
|
-
this._loadEnv();
|
|
116
|
-
|
|
117
|
-
// Vantuz Gateway bağlantısı
|
|
118
|
-
try {
|
|
119
|
-
this.gateway = await getGateway();
|
|
120
|
-
if (this.gateway.isConnected()) {
|
|
121
|
-
log('INFO', 'Vantuz Gateway bağlı', this.gateway.getInfo());
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
115
|
+
async initialize() {
|
|
116
|
+
log('INFO', 'Vantuz Engine v3.2 başlatılıyor...');
|
|
117
|
+
|
|
118
|
+
// Config ve env yükle
|
|
119
|
+
this._loadConfig();
|
|
120
|
+
this._loadEnv();
|
|
121
|
+
|
|
122
|
+
// Vantuz Gateway bağlantısı
|
|
123
|
+
try {
|
|
124
|
+
this.gateway = await getGateway();
|
|
125
|
+
if (this.gateway.isConnected()) {
|
|
126
|
+
log('INFO', 'Vantuz Gateway bağlı', this.gateway.getInfo());
|
|
127
|
+
} else if (this._shouldAutoStartGateway()) {
|
|
128
|
+
const started = await this.gateway.ensureRunning();
|
|
129
|
+
if (started.success) {
|
|
130
|
+
log('INFO', 'Vantuz Gateway otomatik başlatıldı', this.gateway.getInfo());
|
|
131
|
+
} else {
|
|
132
|
+
log('WARN', 'Gateway otomatik başlatılamadı', { error: started.error });
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
} catch (e) {
|
|
136
|
+
log('WARN', 'Gateway bağlantısı başarısız, direkt mod', { error: e.message });
|
|
137
|
+
}
|
|
126
138
|
|
|
127
139
|
// Channel Manager'ı başlat
|
|
128
140
|
this.channels = await getChannelManager();
|
|
@@ -134,17 +146,70 @@ export class VantuzEngine {
|
|
|
134
146
|
await this._buildContext();
|
|
135
147
|
|
|
136
148
|
// Initialize and start EIA Monitor
|
|
137
|
-
this.eiaMonitor = getEIAMonitor(this.config, this.env);
|
|
138
|
-
await this.eiaMonitor.initMonitoringTasks(); // New line
|
|
139
|
-
|
|
140
|
-
|
|
149
|
+
this.eiaMonitor = getEIAMonitor(this.config, this.env);
|
|
150
|
+
await this.eiaMonitor.initMonitoringTasks(); // New line
|
|
151
|
+
|
|
152
|
+
// Automation manager
|
|
153
|
+
this.automation = new AutomationManager(this);
|
|
154
|
+
this.automation.init();
|
|
155
|
+
|
|
156
|
+
// Gateway WS bridge (inbound)
|
|
157
|
+
if (this._shouldStartBridge()) {
|
|
158
|
+
try {
|
|
159
|
+
this.bridge = new OpenClawBridge(this, this.gateway);
|
|
160
|
+
this.bridge.start();
|
|
161
|
+
} catch (e) {
|
|
162
|
+
log('WARN', 'Gateway bridge başlatılamadı', { error: e.message });
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
this.initialized = true;
|
|
141
167
|
log('INFO', 'Vantuz Engine hazır', {
|
|
142
168
|
platforms: this.context.connectedPlatforms.length,
|
|
143
169
|
gateway: this.gateway?.isConnected() || false
|
|
144
170
|
});
|
|
145
171
|
|
|
146
|
-
return this;
|
|
147
|
-
}
|
|
172
|
+
return this;
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
/**
|
|
176
|
+
* Gelişmiş mesaj işleme (otomasyon + onay)
|
|
177
|
+
*/
|
|
178
|
+
async handleMessage(message, meta = { channel: 'local', from: 'local' }) {
|
|
179
|
+
if (!this.initialized) await this.initialize();
|
|
180
|
+
if (this.automation) {
|
|
181
|
+
const result = await this.automation.handleMessage(message, meta);
|
|
182
|
+
if (result?.handled) {
|
|
183
|
+
return result.response;
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
return await this.chat(message);
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
/**
|
|
190
|
+
* Gateway otomatik başlatılsın mı?
|
|
191
|
+
*/
|
|
192
|
+
_shouldAutoStartGateway() {
|
|
193
|
+
const envValue = this.env.VANTUZ_GATEWAY_AUTOSTART;
|
|
194
|
+
if (envValue !== undefined) {
|
|
195
|
+
return !['0', 'false', 'no'].includes(String(envValue).toLowerCase());
|
|
196
|
+
}
|
|
197
|
+
if (this.config && this.config.gatewayAutoStart !== undefined) {
|
|
198
|
+
return this.config.gatewayAutoStart !== false;
|
|
199
|
+
}
|
|
200
|
+
return true;
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
_shouldStartBridge() {
|
|
204
|
+
const envValue = this.env.VANTUZ_OPENCLAW_BRIDGE;
|
|
205
|
+
if (envValue !== undefined) {
|
|
206
|
+
return !['0', 'false', 'no'].includes(String(envValue).toLowerCase());
|
|
207
|
+
}
|
|
208
|
+
if (this.config && this.config.openclawBridge !== undefined) {
|
|
209
|
+
return this.config.openclawBridge !== false;
|
|
210
|
+
}
|
|
211
|
+
return true;
|
|
212
|
+
}
|
|
148
213
|
|
|
149
214
|
/**
|
|
150
215
|
* Config dosyasını yükle
|
|
@@ -186,36 +251,61 @@ export class VantuzEngine {
|
|
|
186
251
|
|
|
187
252
|
for (const platformName in PLATFORM_CONFIG_MAP) {
|
|
188
253
|
const platformMap = PLATFORM_CONFIG_MAP[platformName];
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
if (this.env[envKey]) {
|
|
195
|
-
config[key] = this.env[envKey];
|
|
196
|
-
hasRequiredEnv = true;
|
|
197
|
-
}
|
|
198
|
-
}
|
|
199
|
-
if (hasRequiredEnv) {
|
|
200
|
-
platformConfig[platformName] = config;
|
|
201
|
-
}
|
|
202
|
-
} else if (platformName === 'amazon' && this.env.AMAZON_SELLER_ID) { // Specific handling for Amazon's nested structure
|
|
203
|
-
platformConfig.amazon = {};
|
|
254
|
+
|
|
255
|
+
if (platformName === 'amazon') { // Handle Amazon's specific nested structure first
|
|
256
|
+
const amazonConfig = {};
|
|
257
|
+
let hasAmazonEnv = false;
|
|
258
|
+
|
|
204
259
|
// Handle EU configuration
|
|
205
260
|
const euConfig = {};
|
|
206
261
|
let hasEuEnv = false;
|
|
207
262
|
for (const key of PLATFORM_CONFIG_MAP.amazon.nested.eu.keys) {
|
|
208
|
-
const envKey = `
|
|
263
|
+
const envKey = `AMAZON_EU_${key.toUpperCase()}`; // Assuming EU specific env keys
|
|
209
264
|
if (this.env[envKey]) {
|
|
210
265
|
euConfig[key] = this.env[envKey];
|
|
211
266
|
hasEuEnv = true;
|
|
212
267
|
}
|
|
213
268
|
}
|
|
214
269
|
if (hasEuEnv) {
|
|
215
|
-
|
|
270
|
+
amazonConfig.eu = euConfig;
|
|
271
|
+
hasAmazonEnv = true;
|
|
216
272
|
}
|
|
217
273
|
|
|
218
|
-
// Handle US configuration
|
|
274
|
+
// Handle US configuration (add similar logic here if needed)
|
|
275
|
+
const usConfig = {};
|
|
276
|
+
let hasUsEnv = false;
|
|
277
|
+
for (const key of PLATFORM_CONFIG_MAP.amazon.nested.us.keys) {
|
|
278
|
+
const envKey = `AMAZON_US_${key.toUpperCase()}`; // Assuming US specific env keys
|
|
279
|
+
if (this.env[envKey]) {
|
|
280
|
+
usConfig[key] = this.env[envKey];
|
|
281
|
+
hasUsEnv = true;
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
if (hasUsEnv) {
|
|
285
|
+
amazonConfig.us = usConfig;
|
|
286
|
+
hasAmazonEnv = true;
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
if (hasAmazonEnv) {
|
|
290
|
+
platformConfig[platformName] = amazonConfig;
|
|
291
|
+
}
|
|
292
|
+
} else if (platformMap.envPrefix && platformMap.keys) { // Handle other platforms with direct keys
|
|
293
|
+
const config = {};
|
|
294
|
+
let hasRequiredEnv = false;
|
|
295
|
+
for (const key of platformMap.keys) {
|
|
296
|
+
const upper = key.toUpperCase();
|
|
297
|
+
const snake = key.replace(/([a-z0-9])([A-Z])/g, '$1_$2').toUpperCase();
|
|
298
|
+
const envKey = `${platformMap.envPrefix}_${upper}`;
|
|
299
|
+
const altEnvKey = `${platformMap.envPrefix}_${snake}`;
|
|
300
|
+
const value = this.env[envKey] || this.env[altEnvKey];
|
|
301
|
+
if (value) {
|
|
302
|
+
config[key] = value;
|
|
303
|
+
hasRequiredEnv = true;
|
|
304
|
+
}
|
|
305
|
+
}
|
|
306
|
+
if (hasRequiredEnv) {
|
|
307
|
+
platformConfig[platformName] = config;
|
|
308
|
+
}
|
|
219
309
|
}
|
|
220
310
|
}
|
|
221
311
|
|
|
@@ -234,40 +324,50 @@ export class VantuzEngine {
|
|
|
234
324
|
async _buildContext() {
|
|
235
325
|
this.context.connectedPlatforms = platformHub.getConnected();
|
|
236
326
|
|
|
237
|
-
for (const platform of this.context.connectedPlatforms) {
|
|
238
|
-
try {
|
|
239
|
-
const api = platformHub.resolve(platform);
|
|
240
|
-
if (api && typeof api.getProducts === 'function') {
|
|
241
|
-
const result = await api.getProducts({ page: 0, size: 10 });
|
|
242
|
-
if (result?.success) {
|
|
243
|
-
const
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
327
|
+
for (const platform of this.context.connectedPlatforms) {
|
|
328
|
+
try {
|
|
329
|
+
const api = platformHub.resolve(platform);
|
|
330
|
+
if (api && typeof api.getProducts === 'function') {
|
|
331
|
+
const result = await api.getProducts({ page: 0, size: 10 });
|
|
332
|
+
if (result?.success) {
|
|
333
|
+
const data = result.data;
|
|
334
|
+
let products = [];
|
|
335
|
+
if (Array.isArray(data?.content)) products = data.content;
|
|
336
|
+
else if (Array.isArray(data)) products = data;
|
|
337
|
+
else if (Array.isArray(data?.productList?.product)) products = data.productList.product;
|
|
338
|
+
if (products.length > 0) {
|
|
339
|
+
this.context.products.push(...products.map(p => ({
|
|
340
|
+
...p,
|
|
341
|
+
_platform: platform
|
|
342
|
+
})));
|
|
343
|
+
}
|
|
344
|
+
}
|
|
345
|
+
}
|
|
346
|
+
} catch (e) {
|
|
347
|
+
log('ERROR', `${platform} veri çekme hatası`, { error: e.message });
|
|
348
|
+
}
|
|
349
|
+
}
|
|
254
350
|
}
|
|
255
351
|
|
|
256
352
|
/**
|
|
257
353
|
* AI ile sohbet - Tool destekli
|
|
258
354
|
*/
|
|
259
|
-
async chat(message) {
|
|
260
|
-
if (!this.initialized) await this.initialize();
|
|
261
|
-
|
|
262
|
-
// 1. Basit komut kontrolü (Tool çağırma)
|
|
263
|
-
const toolResult = await this._tryExecuteToolFromMessage(message);
|
|
264
|
-
if (toolResult) return toolResult;
|
|
265
|
-
|
|
266
|
-
//
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
355
|
+
async chat(message) {
|
|
356
|
+
if (!this.initialized) await this.initialize();
|
|
357
|
+
|
|
358
|
+
// 1. Basit komut kontrolü (Tool çağırma)
|
|
359
|
+
const toolResult = await this._tryExecuteToolFromMessage(message);
|
|
360
|
+
if (toolResult) return toolResult;
|
|
361
|
+
|
|
362
|
+
// 1.5 Gelişmiş ajan (araç çağrıları)
|
|
363
|
+
const agentResult = await this._tryAgent(message);
|
|
364
|
+
if (agentResult) return agentResult;
|
|
365
|
+
|
|
366
|
+
// 2. Gateway üzerinden AI (Eğer varsa)
|
|
367
|
+
if (this.gateway?.isConnected()) {
|
|
368
|
+
try {
|
|
369
|
+
const gatewayResult = await this.gateway.chat(message, {
|
|
370
|
+
systemPrompt: this._buildContextInfo()
|
|
271
371
|
});
|
|
272
372
|
if (gatewayResult.success) return gatewayResult.response;
|
|
273
373
|
} catch (e) { }
|
|
@@ -279,17 +379,95 @@ export class VantuzEngine {
|
|
|
279
379
|
systemContext: this._buildContextInfo()
|
|
280
380
|
};
|
|
281
381
|
|
|
282
|
-
return await aiChat(message, enrichedConfig, this.env);
|
|
283
|
-
}
|
|
382
|
+
return await aiChat(message, enrichedConfig, this.env);
|
|
383
|
+
}
|
|
384
|
+
|
|
385
|
+
async _tryAgent(message) {
|
|
386
|
+
const mode = this.config?.agentMode || this.env.VANTUZ_AGENT_MODE;
|
|
387
|
+
if (!mode || mode === 'off') return null;
|
|
388
|
+
|
|
389
|
+
const systemPrompt = [
|
|
390
|
+
'Sen Vantuz gelişmiş ajanısın.',
|
|
391
|
+
'Gerekirse aşağıdaki araçlardan birini çağır:',
|
|
392
|
+
'exec, readFile, listDir, httpGet, apiQuery',
|
|
393
|
+
'Sadece JSON döndür.',
|
|
394
|
+
'Şema: { "tool": "exec|readFile|listDir|httpGet|apiQuery", "args": { ... } }',
|
|
395
|
+
'apiQuery args: { "platform": "n11|trendyol|hepsiburada|amazon|ciceksepeti|pazarama|pttavm", "action": "orders|products|stock|categories", "params": { ... } }',
|
|
396
|
+
'Eğer araç gerekmezse: { "final": "cevap" }',
|
|
397
|
+
'Dosya yollarını ve komutları kısa tut.'
|
|
398
|
+
].join('\n');
|
|
399
|
+
|
|
400
|
+
const plan = await aiChat(message, {
|
|
401
|
+
aiProvider: this.config.aiProvider || 'gemini',
|
|
402
|
+
systemContext: systemPrompt
|
|
403
|
+
}, this.env);
|
|
404
|
+
|
|
405
|
+
const jsonMatch = plan.match(/\{[\s\S]*\}/);
|
|
406
|
+
if (!jsonMatch) return null;
|
|
407
|
+
let obj;
|
|
408
|
+
try { obj = JSON.parse(jsonMatch[0]); } catch { return null; }
|
|
409
|
+
if (obj.final) return obj.final;
|
|
410
|
+
if (!obj.tool) return null;
|
|
411
|
+
|
|
412
|
+
let toolResult;
|
|
413
|
+
if (obj.tool === 'apiQuery') {
|
|
414
|
+
toolResult = await this._runApiQuery(obj.args || {});
|
|
415
|
+
} else {
|
|
416
|
+
toolResult = await executeTool(obj.tool, obj.args || {}, this.config);
|
|
417
|
+
}
|
|
418
|
+
const followup = await aiChat(
|
|
419
|
+
`Kullanıcı mesajı: ${message}\nAraç çıktısı:\n${toolResult.output}\nCevap ver.`,
|
|
420
|
+
{ aiProvider: this.config.aiProvider || 'gemini' },
|
|
421
|
+
this.env
|
|
422
|
+
);
|
|
423
|
+
return followup;
|
|
424
|
+
}
|
|
425
|
+
|
|
426
|
+
async _runApiQuery(args = {}) {
|
|
427
|
+
const platform = (args.platform || '').toLowerCase();
|
|
428
|
+
const action = (args.action || '').toLowerCase();
|
|
429
|
+
const params = args.params || {};
|
|
430
|
+
const api = platformHub.resolve(platform);
|
|
431
|
+
if (!api) return { success: false, output: 'Platform bulunamadı.' };
|
|
432
|
+
|
|
433
|
+
try {
|
|
434
|
+
if (action === 'orders' && api.getOrders) {
|
|
435
|
+
const result = await api.getOrders(params);
|
|
436
|
+
return { success: true, output: JSON.stringify(result?.data || result || {}, null, 2) };
|
|
437
|
+
}
|
|
438
|
+
if (action === 'products' && api.getProducts) {
|
|
439
|
+
const result = await api.getProducts(params);
|
|
440
|
+
return { success: true, output: JSON.stringify(result?.data || result || {}, null, 2) };
|
|
441
|
+
}
|
|
442
|
+
if (action === 'stock' && api.getProducts) {
|
|
443
|
+
const result = await api.getProducts(params);
|
|
444
|
+
return { success: true, output: JSON.stringify(result?.data || result || {}, null, 2) };
|
|
445
|
+
}
|
|
446
|
+
if (action === 'categories' && api.getTopCategories) {
|
|
447
|
+
const result = await api.getTopCategories(params);
|
|
448
|
+
return { success: true, output: JSON.stringify(result?.data || result || {}, null, 2) };
|
|
449
|
+
}
|
|
450
|
+
return { success: false, output: 'Bu platform için istenen action desteklenmiyor.' };
|
|
451
|
+
} catch (e) {
|
|
452
|
+
return { success: false, output: e.message };
|
|
453
|
+
}
|
|
454
|
+
}
|
|
284
455
|
|
|
285
456
|
/**
|
|
286
457
|
* Mesajdan Tool tespiti (Basit NLP)
|
|
287
458
|
*/
|
|
288
|
-
async _tryExecuteToolFromMessage(message) {
|
|
289
|
-
const lower = message.toLowerCase().trim();
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
459
|
+
async _tryExecuteToolFromMessage(message) {
|
|
460
|
+
const lower = message.toLowerCase().trim();
|
|
461
|
+
const normalized = lower
|
|
462
|
+
.replace(/[çÇ]/g, 'c')
|
|
463
|
+
.replace(/[ğĞ]/g, 'g')
|
|
464
|
+
.replace(/[ıİ]/g, 'i')
|
|
465
|
+
.replace(/[öÖ]/g, 'o')
|
|
466
|
+
.replace(/[şŞ]/g, 's')
|
|
467
|
+
.replace(/[üÜ]/g, 'u');
|
|
468
|
+
|
|
469
|
+
// Check for explicit commands
|
|
470
|
+
if (lower.startsWith('/')) {
|
|
293
471
|
const parts = lower.substring(1).split(' ');
|
|
294
472
|
const command = parts[0];
|
|
295
473
|
const args = parts.slice(1);
|
|
@@ -307,12 +485,63 @@ export class VantuzEngine {
|
|
|
307
485
|
case 'help':
|
|
308
486
|
return "Kullanabileceğin komutlar: /rakip, /stok-durumu";
|
|
309
487
|
default:
|
|
310
|
-
return `Bilinmeyen komut: /${command}. Yardım için /help yazabilirsin.`;
|
|
311
|
-
}
|
|
312
|
-
}
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
488
|
+
return `Bilinmeyen komut: /${command}. Yardım için /help yazabilirsin.`;
|
|
489
|
+
}
|
|
490
|
+
}
|
|
491
|
+
|
|
492
|
+
// Natural language shortcuts (no hallucination)
|
|
493
|
+
if (
|
|
494
|
+
lower.includes('hangi pazaryerleri bağlı') ||
|
|
495
|
+
lower.includes('hangi pazaryeri bağlı') ||
|
|
496
|
+
lower.includes('hangi platformlar bağlı') ||
|
|
497
|
+
normalized.includes('hangi pazaryerleri bagli') ||
|
|
498
|
+
normalized.includes('hangi platformlar bagli')
|
|
499
|
+
) {
|
|
500
|
+
const connected = this.context.connectedPlatforms;
|
|
501
|
+
if (connected.length === 0) return 'Şu an bağlı pazaryeri yok.';
|
|
502
|
+
return `Bağlı pazaryerleri: ${connected.map(p => p.toUpperCase()).join(', ')}`;
|
|
503
|
+
}
|
|
504
|
+
|
|
505
|
+
const orderKeywords = [
|
|
506
|
+
'sipariş',
|
|
507
|
+
'siparis'
|
|
508
|
+
];
|
|
509
|
+
const hasOrderKeyword = orderKeywords.some(k => lower.includes(k) || normalized.includes(k));
|
|
510
|
+
|
|
511
|
+
if (hasOrderKeyword) {
|
|
512
|
+
const orders = await this.getOrders({ size: 50, allStatuses: true });
|
|
513
|
+
if (!orders || orders.length === 0) {
|
|
514
|
+
return 'Sipariş verisine ulaşılamadı. Lütfen platform API bağlantılarını kontrol edin.';
|
|
515
|
+
}
|
|
516
|
+
const summary = this._summarizeOrdersByStatus(orders);
|
|
517
|
+
return `Şu an bağlı platformlardan gelen toplam ${orders.length} sipariş var.${summary ? ` Durum kırılımı: ${summary}` : ''}`;
|
|
518
|
+
}
|
|
519
|
+
|
|
520
|
+
if (lower.includes('onaylanan')) {
|
|
521
|
+
const orders = await this.getOrders({ size: 100, status: 'Picking' });
|
|
522
|
+
return `Şu an onaylanan (Picking) ${orders.length} sipariş var.`;
|
|
523
|
+
}
|
|
524
|
+
|
|
525
|
+
if (lower.includes('kargoya verilmemiş') || lower.includes('henüz kargoya') || lower.includes('kargoya verilmedi') || normalized.includes('kargoya verilmemis')) {
|
|
526
|
+
const orders = await this.getOrders({ size: 100, status: 'Created' });
|
|
527
|
+
return `Şu an kargoya verilmemiş (Created) ${orders.length} sipariş var.`;
|
|
528
|
+
}
|
|
529
|
+
|
|
530
|
+
return null;
|
|
531
|
+
}
|
|
532
|
+
|
|
533
|
+
_summarizeOrdersByStatus(orders = []) {
|
|
534
|
+
if (!Array.isArray(orders) || orders.length === 0) return '';
|
|
535
|
+
const counts = {};
|
|
536
|
+
orders.forEach(o => {
|
|
537
|
+
const s = (o.status || o.shipmentPackageStatus || o.orderStatus || 'UNKNOWN').toString();
|
|
538
|
+
counts[s] = (counts[s] || 0) + 1;
|
|
539
|
+
});
|
|
540
|
+
const entries = Object.entries(counts)
|
|
541
|
+
.sort((a, b) => b[1] - a[1])
|
|
542
|
+
.map(([s, n]) => `${s}:${n}`);
|
|
543
|
+
return entries.join(', ');
|
|
544
|
+
}
|
|
316
545
|
|
|
317
546
|
/**
|
|
318
547
|
* Context bilgisi oluştur (AI system prompt için)
|
package/core/gateway.js
CHANGED
|
@@ -9,11 +9,11 @@
|
|
|
9
9
|
* - Sistem durumu sorgulama
|
|
10
10
|
*/
|
|
11
11
|
|
|
12
|
-
import axios from 'axios';
|
|
13
|
-
import fs from 'fs';
|
|
14
|
-
import path from 'path';
|
|
15
|
-
import os from 'os';
|
|
16
|
-
import { log } from './ai-provider.js';
|
|
12
|
+
import axios from 'axios';
|
|
13
|
+
import fs from 'fs';
|
|
14
|
+
import path from 'path';
|
|
15
|
+
import os from 'os';
|
|
16
|
+
import { log } from './ai-provider.js';
|
|
17
17
|
|
|
18
18
|
// ═══════════════════════════════════════════════════════════════════════════
|
|
19
19
|
// CONFIG - Gateway ayarları
|
|
@@ -42,15 +42,15 @@ function getGatewayToken(config) {
|
|
|
42
42
|
// GATEWAY CLIENT
|
|
43
43
|
// ═══════════════════════════════════════════════════════════════════════════
|
|
44
44
|
|
|
45
|
-
export class VantuzGateway {
|
|
45
|
+
export class VantuzGateway {
|
|
46
46
|
constructor() {
|
|
47
47
|
this.config = loadGatewayConfig();
|
|
48
48
|
const port = this.config?.gateway?.port || 18789;
|
|
49
49
|
this.baseUrl = `http://localhost:${port}`;
|
|
50
50
|
this.token = getGatewayToken(this.config);
|
|
51
51
|
this.connected = false;
|
|
52
|
-
this.version = null;
|
|
53
|
-
}
|
|
52
|
+
this.version = null;
|
|
53
|
+
}
|
|
54
54
|
|
|
55
55
|
/**
|
|
56
56
|
* HTTP Headers (token auth)
|
|
@@ -101,14 +101,66 @@ export class VantuzGateway {
|
|
|
101
101
|
/**
|
|
102
102
|
* Gateway sağlık kontrolü
|
|
103
103
|
*/
|
|
104
|
-
async health() {
|
|
105
|
-
const result = await this._request('GET', '/health');
|
|
106
|
-
this.connected = result.success;
|
|
107
|
-
if (result.success) {
|
|
108
|
-
this.version = result.data?.version || 'unknown';
|
|
109
|
-
}
|
|
110
|
-
return result;
|
|
111
|
-
}
|
|
104
|
+
async health() {
|
|
105
|
+
const result = await this._request('GET', '/health');
|
|
106
|
+
this.connected = result.success;
|
|
107
|
+
if (result.success) {
|
|
108
|
+
this.version = result.data?.version || 'unknown';
|
|
109
|
+
}
|
|
110
|
+
return result;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
/**
|
|
114
|
+
* Gateway sürecini başlat (lokal gateway.cmd)
|
|
115
|
+
*/
|
|
116
|
+
async start() {
|
|
117
|
+
const gatewayCmd = path.join(process.cwd(), '.openclaw', 'gateway.cmd');
|
|
118
|
+
if (!fs.existsSync(gatewayCmd)) {
|
|
119
|
+
return { success: false, error: 'Gateway başlatma dosyası bulunamadı: gateway.cmd' };
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
try {
|
|
123
|
+
const { spawn } = await import('child_process');
|
|
124
|
+
const child = spawn(gatewayCmd, [], {
|
|
125
|
+
detached: true,
|
|
126
|
+
stdio: 'ignore',
|
|
127
|
+
shell: true
|
|
128
|
+
});
|
|
129
|
+
child.unref();
|
|
130
|
+
return { success: true };
|
|
131
|
+
} catch (e) {
|
|
132
|
+
return { success: false, error: e.message };
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
/**
|
|
137
|
+
* Gateway çalışmıyorsa başlat ve sağlık kontrolü yap
|
|
138
|
+
*/
|
|
139
|
+
async ensureRunning(options = {}) {
|
|
140
|
+
const {
|
|
141
|
+
retries = 5,
|
|
142
|
+
intervalMs = 1000
|
|
143
|
+
} = options;
|
|
144
|
+
|
|
145
|
+
if (this.isConnected()) {
|
|
146
|
+
return { success: true, already: true };
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
const started = await this.start();
|
|
150
|
+
if (!started.success) {
|
|
151
|
+
return started;
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
for (let i = 0; i < retries; i++) {
|
|
155
|
+
await new Promise(r => setTimeout(r, intervalMs));
|
|
156
|
+
const health = await this.health();
|
|
157
|
+
if (health.success) {
|
|
158
|
+
return { success: true, started: true };
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
return { success: false, error: 'Gateway başlatıldı ancak sağlık kontrolü geçmedi' };
|
|
163
|
+
}
|
|
112
164
|
|
|
113
165
|
/**
|
|
114
166
|
* Detaylı sistem durumu
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
CREATE TABLE products (
|
|
2
|
+
id TEXT PRIMARY KEY,
|
|
3
|
+
name TEXT NOT NULL,
|
|
4
|
+
price REAL,
|
|
5
|
+
cost REAL,
|
|
6
|
+
platform TEXT NOT NULL,
|
|
7
|
+
lastUpdated TEXT
|
|
8
|
+
);
|
|
9
|
+
|
|
10
|
+
CREATE TABLE historical_prices (
|
|
11
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
12
|
+
productId TEXT NOT NULL,
|
|
13
|
+
price REAL NOT NULL,
|
|
14
|
+
timestamp TEXT NOT NULL,
|
|
15
|
+
FOREIGN KEY (productId) REFERENCES products(id) ON DELETE CASCADE
|
|
16
|
+
);
|
|
17
|
+
|
|
18
|
+
-- down
|
|
19
|
+
DROP TABLE IF EXISTS historical_prices;
|
|
20
|
+
DROP TABLE IF EXISTS products;
|