vantuz 3.4.1 β 3.5.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/LICENSE +45 -45
- package/admin-keygen.js +51 -0
- package/cli.js +685 -585
- package/config.js +733 -733
- package/core/agent-loop.js +190 -190
- package/core/ai-provider.js +298 -261
- package/core/automation.js +523 -523
- package/core/brand-analyst.js +101 -0
- package/core/channels.js +167 -167
- package/core/dashboard.js +230 -230
- package/core/database.js +135 -36
- package/core/eia-monitor.js +3 -1
- package/core/engine.js +648 -636
- package/core/gateway.js +447 -447
- package/core/learning.js +214 -214
- package/core/license.js +113 -0
- package/core/marketplace-adapter.js +168 -168
- package/core/memory.js +190 -190
- package/core/migrations/001-initial-schema.sql +1 -1
- package/core/queue.js +120 -120
- package/core/self-healer.js +314 -314
- package/core/unified-product.js +214 -214
- package/core/vision-service.js +113 -113
- package/index.js +217 -174
- package/modules/crm/sentiment-crm.js +231 -231
- package/modules/healer/listing-healer.js +201 -201
- package/modules/oracle/predictor.js +214 -214
- package/modules/researcher/agent.js +169 -169
- package/modules/team/agents/base.js +92 -92
- package/modules/team/agents/dev.js +33 -33
- package/modules/team/agents/josh.js +40 -40
- package/modules/team/agents/marketing.js +33 -33
- package/modules/team/agents/milo.js +36 -36
- package/modules/team/index.js +78 -78
- package/modules/team/shared-memory.js +87 -87
- package/modules/war-room/competitor-tracker.js +250 -250
- package/modules/war-room/pricing-engine.js +308 -308
- package/nodes/warehouse.js +238 -238
- package/onboard.js +1 -1
- package/package.json +7 -6
- package/platforms/pttavm.js +14 -14
- package/plugins/vantuz/index.js +528 -528
- package/plugins/vantuz/memory/hippocampus.js +465 -464
- package/plugins/vantuz/package.json +20 -20
- package/plugins/vantuz/platforms/_template.js +118 -118
- package/plugins/vantuz/platforms/amazon.js +236 -236
- package/plugins/vantuz/platforms/ciceksepeti.js +166 -166
- package/plugins/vantuz/platforms/hepsiburada.js +180 -180
- package/plugins/vantuz/platforms/index.js +165 -165
- package/plugins/vantuz/platforms/n11.js +229 -229
- package/plugins/vantuz/platforms/pazarama.js +154 -154
- package/plugins/vantuz/platforms/pttavm.js +127 -127
- package/plugins/vantuz/platforms/trendyol.js +326 -326
- package/plugins/vantuz/services/alerts.js +253 -253
- package/plugins/vantuz/services/license.js +34 -34
- package/plugins/vantuz/services/scheduler.js +232 -232
- package/plugins/vantuz/tools/analytics.js +152 -152
- package/plugins/vantuz/tools/crossborder.js +187 -187
- package/plugins/vantuz/tools/nl-parser.js +211 -211
- package/plugins/vantuz/tools/product.js +110 -110
- package/plugins/vantuz/tools/quick-report.js +175 -175
- package/plugins/vantuz/tools/repricer.js +314 -314
- package/plugins/vantuz/tools/sentiment.js +115 -115
- package/plugins/vantuz/tools/vision.js +257 -257
- package/private.pem +28 -0
- package/public.pem +9 -0
- package/server/app.js +260 -260
- package/server/public/index.html +514 -514
- package/start.bat +33 -33
- package/vantuz.sqlite +0 -0
package/core/gateway.js
CHANGED
|
@@ -1,447 +1,447 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* π VANTUZ GATEWAY BRIDGE v1.0
|
|
3
|
-
* Vantuz β Vantuz Gateway iletiΕim katmanΔ±
|
|
4
|
-
*
|
|
5
|
-
* Gateway ΓΌzerinden:
|
|
6
|
-
* - AI model yΓΆnlendirmesi
|
|
7
|
-
* - Kanal yΓΆnetimi (WhatsApp, Telegram)
|
|
8
|
-
* - Plugin RPC Γ§aΔrΔ±larΔ±
|
|
9
|
-
* - Sistem durumu sorgulama
|
|
10
|
-
*/
|
|
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';
|
|
17
|
-
|
|
18
|
-
// βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
|
19
|
-
// CONFIG - Gateway ayarlarΔ±
|
|
20
|
-
// βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
|
21
|
-
|
|
22
|
-
const OPENCLAW_HOME = path.join(process.cwd(), '.openclaw');
|
|
23
|
-
const OPENCLAW_CONFIG = path.join(OPENCLAW_HOME, 'openclaw.json');
|
|
24
|
-
const VANTUZ_HOME = path.join(os.homedir(), '.vantuz');
|
|
25
|
-
|
|
26
|
-
function loadGatewayConfig() {
|
|
27
|
-
try {
|
|
28
|
-
if (fs.existsSync(OPENCLAW_CONFIG)) {
|
|
29
|
-
return JSON.parse(fs.readFileSync(OPENCLAW_CONFIG, 'utf-8'));
|
|
30
|
-
}
|
|
31
|
-
} catch (e) {
|
|
32
|
-
log('WARN', 'Gateway config okunamadΔ±', { error: e.message });
|
|
33
|
-
}
|
|
34
|
-
return null;
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
function getGatewayToken(config) {
|
|
38
|
-
return config?.gateway?.auth?.token || null;
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
// βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
|
42
|
-
// GATEWAY CLIENT
|
|
43
|
-
// βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
|
44
|
-
|
|
45
|
-
export class VantuzGateway {
|
|
46
|
-
constructor() {
|
|
47
|
-
this.config = loadGatewayConfig();
|
|
48
|
-
const port = this.config?.gateway?.port || 18789;
|
|
49
|
-
this.baseUrl = `http://localhost:${port}`;
|
|
50
|
-
this.token = getGatewayToken(this.config);
|
|
51
|
-
this.connected = false;
|
|
52
|
-
this.version = null;
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
/**
|
|
56
|
-
* HTTP Headers (token auth)
|
|
57
|
-
*/
|
|
58
|
-
_headers() {
|
|
59
|
-
const headers = { 'Content-Type': 'application/json' };
|
|
60
|
-
if (this.token) {
|
|
61
|
-
headers['Authorization'] = `Bearer ${this.token}`;
|
|
62
|
-
}
|
|
63
|
-
return headers;
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
/**
|
|
67
|
-
* Gateway'e HTTP isteΔi gΓΆnder
|
|
68
|
-
*/
|
|
69
|
-
async _request(method, endpoint, data = null, timeout = 10000) {
|
|
70
|
-
try {
|
|
71
|
-
const config = {
|
|
72
|
-
method,
|
|
73
|
-
url: `${this.baseUrl}${endpoint}`,
|
|
74
|
-
headers: this._headers(),
|
|
75
|
-
timeout
|
|
76
|
-
};
|
|
77
|
-
|
|
78
|
-
if (data) config.data = data;
|
|
79
|
-
|
|
80
|
-
const response = await axios(config);
|
|
81
|
-
return { success: true, data: response.data };
|
|
82
|
-
} catch (error) {
|
|
83
|
-
if (error.code === 'ECONNREFUSED') {
|
|
84
|
-
return { success: false, error: 'Gateway Γ§alΔ±ΕmΔ±yor', code: 'NOT_RUNNING' };
|
|
85
|
-
}
|
|
86
|
-
if (error.response?.status === 401) {
|
|
87
|
-
return { success: false, error: 'Token geΓ§ersiz', code: 'AUTH_FAILED' };
|
|
88
|
-
}
|
|
89
|
-
return {
|
|
90
|
-
success: false,
|
|
91
|
-
error: error.message,
|
|
92
|
-
code: error.code || 'UNKNOWN'
|
|
93
|
-
};
|
|
94
|
-
}
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
// βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
|
98
|
-
// SAΔLIK & DURUM
|
|
99
|
-
// βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
|
100
|
-
|
|
101
|
-
/**
|
|
102
|
-
* Gateway saΔlΔ±k kontrolΓΌ
|
|
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
|
-
}
|
|
112
|
-
|
|
113
|
-
/**
|
|
114
|
-
* Gateway sΓΌrecini baΕlat
|
|
115
|
-
*/
|
|
116
|
-
async start() {
|
|
117
|
-
const cwd = process.cwd();
|
|
118
|
-
const gatewayCmd = path.join(cwd, '.openclaw', 'gateway.cmd');
|
|
119
|
-
const isWin = process.platform === 'win32';
|
|
120
|
-
|
|
121
|
-
try {
|
|
122
|
-
const { spawn } = await import('child_process');
|
|
123
|
-
let child;
|
|
124
|
-
|
|
125
|
-
if (isWin && fs.existsSync(gatewayCmd)) {
|
|
126
|
-
// Windows: Use generated CMD (has config env vars)
|
|
127
|
-
child = spawn(gatewayCmd, [], {
|
|
128
|
-
detached: true,
|
|
129
|
-
stdio: 'ignore', // Keep it in background
|
|
130
|
-
shell: true,
|
|
131
|
-
cwd // Ensure CWD is correct for finding node_modules
|
|
132
|
-
});
|
|
133
|
-
} else {
|
|
134
|
-
// Linux/Mac or missing CMD: Use npx directly
|
|
135
|
-
// We try to load token from config if possible to pass as ENV
|
|
136
|
-
const env = { ...process.env };
|
|
137
|
-
if (this.config?.gateway?.auth?.token) {
|
|
138
|
-
env.OPENCLAW_GATEWAY_TOKEN = this.config.gateway.auth.token;
|
|
139
|
-
}
|
|
140
|
-
|
|
141
|
-
child = spawn('npx', ['openclaw', 'gateway', '--port', '18789', '--allow-unconfigured'], {
|
|
142
|
-
detached: true,
|
|
143
|
-
stdio: 'ignore',
|
|
144
|
-
shell: true,
|
|
145
|
-
cwd,
|
|
146
|
-
env
|
|
147
|
-
});
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
if (child) {
|
|
151
|
-
child.unref(); // Detach process so it outlives parent
|
|
152
|
-
return { success: true };
|
|
153
|
-
}
|
|
154
|
-
return { success: false, error: 'Child process could not be spawned' };
|
|
155
|
-
|
|
156
|
-
} catch (e) {
|
|
157
|
-
return { success: false, error: e.message };
|
|
158
|
-
}
|
|
159
|
-
}
|
|
160
|
-
|
|
161
|
-
/**
|
|
162
|
-
* Vantuz API Server (server/app.js) baΕlat
|
|
163
|
-
*/
|
|
164
|
-
async startServer() {
|
|
165
|
-
const serverPath = path.join(process.cwd(), 'server', 'app.js');
|
|
166
|
-
if (!fs.existsSync(serverPath)) {
|
|
167
|
-
return { success: false, error: 'Server dosyasΔ± bulunamadΔ±: server/app.js' };
|
|
168
|
-
}
|
|
169
|
-
|
|
170
|
-
try {
|
|
171
|
-
const { spawn } = await import('child_process');
|
|
172
|
-
const child = spawn('node', [serverPath], {
|
|
173
|
-
detached: true,
|
|
174
|
-
stdio: 'ignore',
|
|
175
|
-
shell: true,
|
|
176
|
-
cwd: process.cwd(),
|
|
177
|
-
env: { ...process.env, PORT: '3001' } // Ensure default port
|
|
178
|
-
});
|
|
179
|
-
|
|
180
|
-
child.unref();
|
|
181
|
-
return { success: true };
|
|
182
|
-
} catch (e) {
|
|
183
|
-
return { success: false, error: e.message };
|
|
184
|
-
}
|
|
185
|
-
}
|
|
186
|
-
|
|
187
|
-
/**
|
|
188
|
-
* TΓΌm sistemi baΕlat (Gateway + Server)
|
|
189
|
-
*/
|
|
190
|
-
async startFullStack() {
|
|
191
|
-
// 1. Start Gateway
|
|
192
|
-
const gwResult = await this.start();
|
|
193
|
-
|
|
194
|
-
// 2. Wait for Gateway to initialize (approx 3s)
|
|
195
|
-
await new Promise(resolve => setTimeout(resolve, 3000));
|
|
196
|
-
|
|
197
|
-
// 3. Start Server
|
|
198
|
-
const serverResult = await this.startServer();
|
|
199
|
-
|
|
200
|
-
return {
|
|
201
|
-
success: gwResult.success && serverResult.success,
|
|
202
|
-
gateway: gwResult,
|
|
203
|
-
server: serverResult
|
|
204
|
-
};
|
|
205
|
-
}
|
|
206
|
-
|
|
207
|
-
/**
|
|
208
|
-
* Gateway Γ§alΔ±ΕmΔ±yorsa baΕlat ve saΔlΔ±k kontrolΓΌ yap
|
|
209
|
-
*/
|
|
210
|
-
async ensureRunning(options = {}) {
|
|
211
|
-
const {
|
|
212
|
-
retries = 5,
|
|
213
|
-
intervalMs = 1000
|
|
214
|
-
} = options;
|
|
215
|
-
|
|
216
|
-
if (this.isConnected()) {
|
|
217
|
-
return { success: true, already: true };
|
|
218
|
-
}
|
|
219
|
-
|
|
220
|
-
const started = await this.start();
|
|
221
|
-
if (!started.success) {
|
|
222
|
-
return started;
|
|
223
|
-
}
|
|
224
|
-
|
|
225
|
-
for (let i = 0; i < retries; i++) {
|
|
226
|
-
await new Promise(r => setTimeout(r, intervalMs));
|
|
227
|
-
const health = await this.health();
|
|
228
|
-
if (health.success) {
|
|
229
|
-
return { success: true, started: true };
|
|
230
|
-
}
|
|
231
|
-
}
|
|
232
|
-
|
|
233
|
-
return { success: false, error: 'Gateway baΕlatΔ±ldΔ± ancak saΔlΔ±k kontrolΓΌ geΓ§medi' };
|
|
234
|
-
}
|
|
235
|
-
|
|
236
|
-
/**
|
|
237
|
-
* DetaylΔ± sistem durumu
|
|
238
|
-
*/
|
|
239
|
-
async status() {
|
|
240
|
-
const result = await this._request('GET', '/status');
|
|
241
|
-
if (result.success) {
|
|
242
|
-
this.connected = true;
|
|
243
|
-
}
|
|
244
|
-
return result;
|
|
245
|
-
}
|
|
246
|
-
|
|
247
|
-
/**
|
|
248
|
-
* Gateway baΔlΔ± mΔ±?
|
|
249
|
-
*/
|
|
250
|
-
isConnected() {
|
|
251
|
-
return this.connected;
|
|
252
|
-
}
|
|
253
|
-
|
|
254
|
-
/**
|
|
255
|
-
* Gateway bilgileri
|
|
256
|
-
*/
|
|
257
|
-
getInfo() {
|
|
258
|
-
return {
|
|
259
|
-
url: this.baseUrl,
|
|
260
|
-
connected: this.connected,
|
|
261
|
-
version: this.version,
|
|
262
|
-
hasToken: !!this.token,
|
|
263
|
-
configFound: !!this.config
|
|
264
|
-
};
|
|
265
|
-
}
|
|
266
|
-
|
|
267
|
-
// βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
|
268
|
-
// AI MODEL YΓNLENDΔ°RME
|
|
269
|
-
// βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
|
270
|
-
|
|
271
|
-
/**
|
|
272
|
-
* Gateway ΓΌzerinden AI chat
|
|
273
|
-
* Gateway AI model routing saΔlΔ±yorsa kullan
|
|
274
|
-
*/
|
|
275
|
-
async chat(message, options = {}) {
|
|
276
|
-
const result = await this._request('POST', '/v1/chat/completions', {
|
|
277
|
-
messages: [
|
|
278
|
-
...(options.systemPrompt ? [{ role: 'system', content: options.systemPrompt }] : []),
|
|
279
|
-
{ role: 'user', content: message }
|
|
280
|
-
],
|
|
281
|
-
model: options.model || 'default',
|
|
282
|
-
max_tokens: options.maxTokens || 1000,
|
|
283
|
-
temperature: options.temperature || 0.7
|
|
284
|
-
}, 30000);
|
|
285
|
-
|
|
286
|
-
if (result.success) {
|
|
287
|
-
const text = result.data?.choices?.[0]?.message?.content;
|
|
288
|
-
return { success: true, response: text };
|
|
289
|
-
}
|
|
290
|
-
|
|
291
|
-
return { success: false, error: result.error };
|
|
292
|
-
}
|
|
293
|
-
|
|
294
|
-
/**
|
|
295
|
-
* KullanΔ±labilir AI modelleri
|
|
296
|
-
*/
|
|
297
|
-
async getModels() {
|
|
298
|
-
return await this._request('GET', '/v1/models');
|
|
299
|
-
}
|
|
300
|
-
|
|
301
|
-
// βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
|
302
|
-
// KANAL YΓNETΔ°MΔ°
|
|
303
|
-
// βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
|
304
|
-
|
|
305
|
-
/**
|
|
306
|
-
* Kanal listesi ve durumlarΔ±
|
|
307
|
-
*/
|
|
308
|
-
async getChannels() {
|
|
309
|
-
return await this._request('GET', '/channels');
|
|
310
|
-
}
|
|
311
|
-
|
|
312
|
-
/**
|
|
313
|
-
* Kanal baΔlantΔ± durumu
|
|
314
|
-
*/
|
|
315
|
-
async getChannelStatus(channelName) {
|
|
316
|
-
return await this._request('GET', `/channels/${channelName}/status`);
|
|
317
|
-
}
|
|
318
|
-
|
|
319
|
-
/**
|
|
320
|
-
* Kanal ΓΌzerinden mesaj gΓΆnder
|
|
321
|
-
*/
|
|
322
|
-
async sendMessage(channel, to, message) {
|
|
323
|
-
return await this._request('POST', `/channels/${channel}/send`, {
|
|
324
|
-
to,
|
|
325
|
-
message,
|
|
326
|
-
type: 'text'
|
|
327
|
-
});
|
|
328
|
-
}
|
|
329
|
-
|
|
330
|
-
// βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
|
331
|
-
// RPC - Plugin Gateway MethodlarΔ±
|
|
332
|
-
// βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
|
333
|
-
|
|
334
|
-
/**
|
|
335
|
-
* Gateway RPC Γ§aΔrΔ±sΔ±
|
|
336
|
-
*/
|
|
337
|
-
async call(method, params = {}) {
|
|
338
|
-
return await this._request('POST', '/rpc', {
|
|
339
|
-
method,
|
|
340
|
-
params
|
|
341
|
-
});
|
|
342
|
-
}
|
|
343
|
-
|
|
344
|
-
/**
|
|
345
|
-
* Vantuz plugin durumu
|
|
346
|
-
*/
|
|
347
|
-
async getPluginStatus() {
|
|
348
|
-
return await this.call('vantuz.status');
|
|
349
|
-
}
|
|
350
|
-
|
|
351
|
-
/**
|
|
352
|
-
* Vantuz plugin config
|
|
353
|
-
*/
|
|
354
|
-
async getPluginConfig() {
|
|
355
|
-
return await this.call('vantuz.config', { action: 'get' });
|
|
356
|
-
}
|
|
357
|
-
|
|
358
|
-
// βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
|
359
|
-
// CRON & ZAMANLAMA
|
|
360
|
-
// βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
|
361
|
-
|
|
362
|
-
/**
|
|
363
|
-
* ZamanlanmΔ±Ε gΓΆrev listesi
|
|
364
|
-
*/
|
|
365
|
-
async getCronJobs() {
|
|
366
|
-
return await this._request('GET', '/cron');
|
|
367
|
-
}
|
|
368
|
-
|
|
369
|
-
/**
|
|
370
|
-
* ZamanlanmΔ±Ε gΓΆrev ekle
|
|
371
|
-
*/
|
|
372
|
-
async addCronJob(schedule, command, description) {
|
|
373
|
-
return await this._request('POST', '/cron', {
|
|
374
|
-
schedule,
|
|
375
|
-
command,
|
|
376
|
-
description
|
|
377
|
-
});
|
|
378
|
-
}
|
|
379
|
-
|
|
380
|
-
// βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
|
381
|
-
// HAFIZA (Memory)
|
|
382
|
-
// βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
|
383
|
-
|
|
384
|
-
/**
|
|
385
|
-
* Gateway hafΔ±za durumu
|
|
386
|
-
*/
|
|
387
|
-
async getMemoryStatus() {
|
|
388
|
-
return await this._request('GET', '/memory/status');
|
|
389
|
-
}
|
|
390
|
-
|
|
391
|
-
/**
|
|
392
|
-
* HafΔ±za aramasΔ±
|
|
393
|
-
*/
|
|
394
|
-
async searchMemory(query) {
|
|
395
|
-
return await this._request('POST', '/memory/search', { query });
|
|
396
|
-
}
|
|
397
|
-
|
|
398
|
-
// βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
|
399
|
-
// LOGLAR
|
|
400
|
-
// βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
|
401
|
-
|
|
402
|
-
/**
|
|
403
|
-
* Gateway loglarΔ±
|
|
404
|
-
*/
|
|
405
|
-
async getLogs(limit = 50) {
|
|
406
|
-
return await this._request('GET', `/logs?limit=${limit}`);
|
|
407
|
-
}
|
|
408
|
-
}
|
|
409
|
-
|
|
410
|
-
// βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
|
411
|
-
// SINGLETON & FACTORY
|
|
412
|
-
// βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
|
413
|
-
|
|
414
|
-
let gatewayInstance = null;
|
|
415
|
-
|
|
416
|
-
/**
|
|
417
|
-
* Vantuz Gateway singleton instance
|
|
418
|
-
* Otomatik baΔlantΔ± kontrolΓΌ yapar
|
|
419
|
-
*/
|
|
420
|
-
export async function getGateway() {
|
|
421
|
-
if (!gatewayInstance) {
|
|
422
|
-
gatewayInstance = new VantuzGateway();
|
|
423
|
-
|
|
424
|
-
// Δ°lk baΔlantΔ± denemesi
|
|
425
|
-
const health = await gatewayInstance.health();
|
|
426
|
-
if (health.success) {
|
|
427
|
-
log('INFO', 'Vantuz Gateway baΔlantΔ±sΔ± baΕarΔ±lΔ±', {
|
|
428
|
-
url: gatewayInstance.baseUrl,
|
|
429
|
-
version: gatewayInstance.version
|
|
430
|
-
});
|
|
431
|
-
} else {
|
|
432
|
-
log('WARN', 'Vantuz Gateway eriΕilemez, direkt mod kullanΔ±lacak', {
|
|
433
|
-
error: health.error
|
|
434
|
-
});
|
|
435
|
-
}
|
|
436
|
-
}
|
|
437
|
-
return gatewayInstance;
|
|
438
|
-
}
|
|
439
|
-
|
|
440
|
-
/**
|
|
441
|
-
* Gateway durumunu sΔ±fΔ±rla (reconnect iΓ§in)
|
|
442
|
-
*/
|
|
443
|
-
export function resetGateway() {
|
|
444
|
-
gatewayInstance = null;
|
|
445
|
-
}
|
|
446
|
-
|
|
447
|
-
export default VantuzGateway;
|
|
1
|
+
/**
|
|
2
|
+
* π VANTUZ GATEWAY BRIDGE v1.0
|
|
3
|
+
* Vantuz β Vantuz Gateway iletiΕim katmanΔ±
|
|
4
|
+
*
|
|
5
|
+
* Gateway ΓΌzerinden:
|
|
6
|
+
* - AI model yΓΆnlendirmesi
|
|
7
|
+
* - Kanal yΓΆnetimi (WhatsApp, Telegram)
|
|
8
|
+
* - Plugin RPC Γ§aΔrΔ±larΔ±
|
|
9
|
+
* - Sistem durumu sorgulama
|
|
10
|
+
*/
|
|
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';
|
|
17
|
+
|
|
18
|
+
// βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
|
19
|
+
// CONFIG - Gateway ayarlarΔ±
|
|
20
|
+
// βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
|
21
|
+
|
|
22
|
+
const OPENCLAW_HOME = path.join(process.cwd(), '.openclaw');
|
|
23
|
+
const OPENCLAW_CONFIG = path.join(OPENCLAW_HOME, 'openclaw.json');
|
|
24
|
+
const VANTUZ_HOME = path.join(os.homedir(), '.vantuz');
|
|
25
|
+
|
|
26
|
+
function loadGatewayConfig() {
|
|
27
|
+
try {
|
|
28
|
+
if (fs.existsSync(OPENCLAW_CONFIG)) {
|
|
29
|
+
return JSON.parse(fs.readFileSync(OPENCLAW_CONFIG, 'utf-8'));
|
|
30
|
+
}
|
|
31
|
+
} catch (e) {
|
|
32
|
+
log('WARN', 'Gateway config okunamadΔ±', { error: e.message });
|
|
33
|
+
}
|
|
34
|
+
return null;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
function getGatewayToken(config) {
|
|
38
|
+
return config?.gateway?.auth?.token || null;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
// βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
|
42
|
+
// GATEWAY CLIENT
|
|
43
|
+
// βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
|
44
|
+
|
|
45
|
+
export class VantuzGateway {
|
|
46
|
+
constructor() {
|
|
47
|
+
this.config = loadGatewayConfig();
|
|
48
|
+
const port = this.config?.gateway?.port || 18789;
|
|
49
|
+
this.baseUrl = `http://localhost:${port}`;
|
|
50
|
+
this.token = getGatewayToken(this.config);
|
|
51
|
+
this.connected = false;
|
|
52
|
+
this.version = null;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* HTTP Headers (token auth)
|
|
57
|
+
*/
|
|
58
|
+
_headers() {
|
|
59
|
+
const headers = { 'Content-Type': 'application/json' };
|
|
60
|
+
if (this.token) {
|
|
61
|
+
headers['Authorization'] = `Bearer ${this.token}`;
|
|
62
|
+
}
|
|
63
|
+
return headers;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* Gateway'e HTTP isteΔi gΓΆnder
|
|
68
|
+
*/
|
|
69
|
+
async _request(method, endpoint, data = null, timeout = 10000) {
|
|
70
|
+
try {
|
|
71
|
+
const config = {
|
|
72
|
+
method,
|
|
73
|
+
url: `${this.baseUrl}${endpoint}`,
|
|
74
|
+
headers: this._headers(),
|
|
75
|
+
timeout
|
|
76
|
+
};
|
|
77
|
+
|
|
78
|
+
if (data) config.data = data;
|
|
79
|
+
|
|
80
|
+
const response = await axios(config);
|
|
81
|
+
return { success: true, data: response.data };
|
|
82
|
+
} catch (error) {
|
|
83
|
+
if (error.code === 'ECONNREFUSED') {
|
|
84
|
+
return { success: false, error: 'Gateway Γ§alΔ±ΕmΔ±yor', code: 'NOT_RUNNING' };
|
|
85
|
+
}
|
|
86
|
+
if (error.response?.status === 401) {
|
|
87
|
+
return { success: false, error: 'Token geΓ§ersiz', code: 'AUTH_FAILED' };
|
|
88
|
+
}
|
|
89
|
+
return {
|
|
90
|
+
success: false,
|
|
91
|
+
error: error.message,
|
|
92
|
+
code: error.code || 'UNKNOWN'
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
// βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
|
98
|
+
// SAΔLIK & DURUM
|
|
99
|
+
// βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
|
100
|
+
|
|
101
|
+
/**
|
|
102
|
+
* Gateway saΔlΔ±k kontrolΓΌ
|
|
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
|
+
}
|
|
112
|
+
|
|
113
|
+
/**
|
|
114
|
+
* Gateway sΓΌrecini baΕlat
|
|
115
|
+
*/
|
|
116
|
+
async start() {
|
|
117
|
+
const cwd = process.cwd();
|
|
118
|
+
const gatewayCmd = path.join(cwd, '.openclaw', 'gateway.cmd');
|
|
119
|
+
const isWin = process.platform === 'win32';
|
|
120
|
+
|
|
121
|
+
try {
|
|
122
|
+
const { spawn } = await import('child_process');
|
|
123
|
+
let child;
|
|
124
|
+
|
|
125
|
+
if (isWin && fs.existsSync(gatewayCmd)) {
|
|
126
|
+
// Windows: Use generated CMD (has config env vars)
|
|
127
|
+
child = spawn(gatewayCmd, [], {
|
|
128
|
+
detached: true,
|
|
129
|
+
stdio: 'ignore', // Keep it in background
|
|
130
|
+
shell: true,
|
|
131
|
+
cwd // Ensure CWD is correct for finding node_modules
|
|
132
|
+
});
|
|
133
|
+
} else {
|
|
134
|
+
// Linux/Mac or missing CMD: Use npx directly
|
|
135
|
+
// We try to load token from config if possible to pass as ENV
|
|
136
|
+
const env = { ...process.env };
|
|
137
|
+
if (this.config?.gateway?.auth?.token) {
|
|
138
|
+
env.OPENCLAW_GATEWAY_TOKEN = this.config.gateway.auth.token;
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
child = spawn('npx', ['openclaw', 'gateway', '--port', '18789', '--allow-unconfigured'], {
|
|
142
|
+
detached: true,
|
|
143
|
+
stdio: 'ignore',
|
|
144
|
+
shell: true,
|
|
145
|
+
cwd,
|
|
146
|
+
env
|
|
147
|
+
});
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
if (child) {
|
|
151
|
+
child.unref(); // Detach process so it outlives parent
|
|
152
|
+
return { success: true };
|
|
153
|
+
}
|
|
154
|
+
return { success: false, error: 'Child process could not be spawned' };
|
|
155
|
+
|
|
156
|
+
} catch (e) {
|
|
157
|
+
return { success: false, error: e.message };
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
/**
|
|
162
|
+
* Vantuz API Server (server/app.js) baΕlat
|
|
163
|
+
*/
|
|
164
|
+
async startServer() {
|
|
165
|
+
const serverPath = path.join(process.cwd(), 'server', 'app.js');
|
|
166
|
+
if (!fs.existsSync(serverPath)) {
|
|
167
|
+
return { success: false, error: 'Server dosyasΔ± bulunamadΔ±: server/app.js' };
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
try {
|
|
171
|
+
const { spawn } = await import('child_process');
|
|
172
|
+
const child = spawn('node', [serverPath], {
|
|
173
|
+
detached: true,
|
|
174
|
+
stdio: 'ignore',
|
|
175
|
+
shell: true,
|
|
176
|
+
cwd: process.cwd(),
|
|
177
|
+
env: { ...process.env, PORT: '3001' } // Ensure default port
|
|
178
|
+
});
|
|
179
|
+
|
|
180
|
+
child.unref();
|
|
181
|
+
return { success: true };
|
|
182
|
+
} catch (e) {
|
|
183
|
+
return { success: false, error: e.message };
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
/**
|
|
188
|
+
* TΓΌm sistemi baΕlat (Gateway + Server)
|
|
189
|
+
*/
|
|
190
|
+
async startFullStack() {
|
|
191
|
+
// 1. Start Gateway
|
|
192
|
+
const gwResult = await this.start();
|
|
193
|
+
|
|
194
|
+
// 2. Wait for Gateway to initialize (approx 3s)
|
|
195
|
+
await new Promise(resolve => setTimeout(resolve, 3000));
|
|
196
|
+
|
|
197
|
+
// 3. Start Server
|
|
198
|
+
const serverResult = await this.startServer();
|
|
199
|
+
|
|
200
|
+
return {
|
|
201
|
+
success: gwResult.success && serverResult.success,
|
|
202
|
+
gateway: gwResult,
|
|
203
|
+
server: serverResult
|
|
204
|
+
};
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
/**
|
|
208
|
+
* Gateway Γ§alΔ±ΕmΔ±yorsa baΕlat ve saΔlΔ±k kontrolΓΌ yap
|
|
209
|
+
*/
|
|
210
|
+
async ensureRunning(options = {}) {
|
|
211
|
+
const {
|
|
212
|
+
retries = 5,
|
|
213
|
+
intervalMs = 1000
|
|
214
|
+
} = options;
|
|
215
|
+
|
|
216
|
+
if (this.isConnected()) {
|
|
217
|
+
return { success: true, already: true };
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
const started = await this.start();
|
|
221
|
+
if (!started.success) {
|
|
222
|
+
return started;
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
for (let i = 0; i < retries; i++) {
|
|
226
|
+
await new Promise(r => setTimeout(r, intervalMs));
|
|
227
|
+
const health = await this.health();
|
|
228
|
+
if (health.success) {
|
|
229
|
+
return { success: true, started: true };
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
return { success: false, error: 'Gateway baΕlatΔ±ldΔ± ancak saΔlΔ±k kontrolΓΌ geΓ§medi' };
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
/**
|
|
237
|
+
* DetaylΔ± sistem durumu
|
|
238
|
+
*/
|
|
239
|
+
async status() {
|
|
240
|
+
const result = await this._request('GET', '/status');
|
|
241
|
+
if (result.success) {
|
|
242
|
+
this.connected = true;
|
|
243
|
+
}
|
|
244
|
+
return result;
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
/**
|
|
248
|
+
* Gateway baΔlΔ± mΔ±?
|
|
249
|
+
*/
|
|
250
|
+
isConnected() {
|
|
251
|
+
return this.connected;
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
/**
|
|
255
|
+
* Gateway bilgileri
|
|
256
|
+
*/
|
|
257
|
+
getInfo() {
|
|
258
|
+
return {
|
|
259
|
+
url: this.baseUrl,
|
|
260
|
+
connected: this.connected,
|
|
261
|
+
version: this.version,
|
|
262
|
+
hasToken: !!this.token,
|
|
263
|
+
configFound: !!this.config
|
|
264
|
+
};
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
// βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
|
268
|
+
// AI MODEL YΓNLENDΔ°RME
|
|
269
|
+
// βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
|
270
|
+
|
|
271
|
+
/**
|
|
272
|
+
* Gateway ΓΌzerinden AI chat
|
|
273
|
+
* Gateway AI model routing saΔlΔ±yorsa kullan
|
|
274
|
+
*/
|
|
275
|
+
async chat(message, options = {}) {
|
|
276
|
+
const result = await this._request('POST', '/v1/chat/completions', {
|
|
277
|
+
messages: [
|
|
278
|
+
...(options.systemPrompt ? [{ role: 'system', content: options.systemPrompt }] : []),
|
|
279
|
+
{ role: 'user', content: message }
|
|
280
|
+
],
|
|
281
|
+
model: options.model || 'default',
|
|
282
|
+
max_tokens: options.maxTokens || 1000,
|
|
283
|
+
temperature: options.temperature || 0.7
|
|
284
|
+
}, 30000);
|
|
285
|
+
|
|
286
|
+
if (result.success) {
|
|
287
|
+
const text = result.data?.choices?.[0]?.message?.content;
|
|
288
|
+
return { success: true, response: text };
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
return { success: false, error: result.error };
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
/**
|
|
295
|
+
* KullanΔ±labilir AI modelleri
|
|
296
|
+
*/
|
|
297
|
+
async getModels() {
|
|
298
|
+
return await this._request('GET', '/v1/models');
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
// βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
|
302
|
+
// KANAL YΓNETΔ°MΔ°
|
|
303
|
+
// βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
|
304
|
+
|
|
305
|
+
/**
|
|
306
|
+
* Kanal listesi ve durumlarΔ±
|
|
307
|
+
*/
|
|
308
|
+
async getChannels() {
|
|
309
|
+
return await this._request('GET', '/channels');
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
/**
|
|
313
|
+
* Kanal baΔlantΔ± durumu
|
|
314
|
+
*/
|
|
315
|
+
async getChannelStatus(channelName) {
|
|
316
|
+
return await this._request('GET', `/channels/${channelName}/status`);
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
/**
|
|
320
|
+
* Kanal ΓΌzerinden mesaj gΓΆnder
|
|
321
|
+
*/
|
|
322
|
+
async sendMessage(channel, to, message) {
|
|
323
|
+
return await this._request('POST', `/channels/${channel}/send`, {
|
|
324
|
+
to,
|
|
325
|
+
message,
|
|
326
|
+
type: 'text'
|
|
327
|
+
});
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
// βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
|
331
|
+
// RPC - Plugin Gateway MethodlarΔ±
|
|
332
|
+
// βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
|
333
|
+
|
|
334
|
+
/**
|
|
335
|
+
* Gateway RPC Γ§aΔrΔ±sΔ±
|
|
336
|
+
*/
|
|
337
|
+
async call(method, params = {}) {
|
|
338
|
+
return await this._request('POST', '/rpc', {
|
|
339
|
+
method,
|
|
340
|
+
params
|
|
341
|
+
});
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
/**
|
|
345
|
+
* Vantuz plugin durumu
|
|
346
|
+
*/
|
|
347
|
+
async getPluginStatus() {
|
|
348
|
+
return await this.call('vantuz.status');
|
|
349
|
+
}
|
|
350
|
+
|
|
351
|
+
/**
|
|
352
|
+
* Vantuz plugin config
|
|
353
|
+
*/
|
|
354
|
+
async getPluginConfig() {
|
|
355
|
+
return await this.call('vantuz.config', { action: 'get' });
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
// βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
|
359
|
+
// CRON & ZAMANLAMA
|
|
360
|
+
// βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
|
361
|
+
|
|
362
|
+
/**
|
|
363
|
+
* ZamanlanmΔ±Ε gΓΆrev listesi
|
|
364
|
+
*/
|
|
365
|
+
async getCronJobs() {
|
|
366
|
+
return await this._request('GET', '/cron');
|
|
367
|
+
}
|
|
368
|
+
|
|
369
|
+
/**
|
|
370
|
+
* ZamanlanmΔ±Ε gΓΆrev ekle
|
|
371
|
+
*/
|
|
372
|
+
async addCronJob(schedule, command, description) {
|
|
373
|
+
return await this._request('POST', '/cron', {
|
|
374
|
+
schedule,
|
|
375
|
+
command,
|
|
376
|
+
description
|
|
377
|
+
});
|
|
378
|
+
}
|
|
379
|
+
|
|
380
|
+
// βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
|
381
|
+
// HAFIZA (Memory)
|
|
382
|
+
// βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
|
383
|
+
|
|
384
|
+
/**
|
|
385
|
+
* Gateway hafΔ±za durumu
|
|
386
|
+
*/
|
|
387
|
+
async getMemoryStatus() {
|
|
388
|
+
return await this._request('GET', '/memory/status');
|
|
389
|
+
}
|
|
390
|
+
|
|
391
|
+
/**
|
|
392
|
+
* HafΔ±za aramasΔ±
|
|
393
|
+
*/
|
|
394
|
+
async searchMemory(query) {
|
|
395
|
+
return await this._request('POST', '/memory/search', { query });
|
|
396
|
+
}
|
|
397
|
+
|
|
398
|
+
// βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
|
399
|
+
// LOGLAR
|
|
400
|
+
// βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
|
401
|
+
|
|
402
|
+
/**
|
|
403
|
+
* Gateway loglarΔ±
|
|
404
|
+
*/
|
|
405
|
+
async getLogs(limit = 50) {
|
|
406
|
+
return await this._request('GET', `/logs?limit=${limit}`);
|
|
407
|
+
}
|
|
408
|
+
}
|
|
409
|
+
|
|
410
|
+
// βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
|
411
|
+
// SINGLETON & FACTORY
|
|
412
|
+
// βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
|
413
|
+
|
|
414
|
+
let gatewayInstance = null;
|
|
415
|
+
|
|
416
|
+
/**
|
|
417
|
+
* Vantuz Gateway singleton instance
|
|
418
|
+
* Otomatik baΔlantΔ± kontrolΓΌ yapar
|
|
419
|
+
*/
|
|
420
|
+
export async function getGateway() {
|
|
421
|
+
if (!gatewayInstance) {
|
|
422
|
+
gatewayInstance = new VantuzGateway();
|
|
423
|
+
|
|
424
|
+
// Δ°lk baΔlantΔ± denemesi
|
|
425
|
+
const health = await gatewayInstance.health();
|
|
426
|
+
if (health.success) {
|
|
427
|
+
log('INFO', 'Vantuz Gateway baΔlantΔ±sΔ± baΕarΔ±lΔ±', {
|
|
428
|
+
url: gatewayInstance.baseUrl,
|
|
429
|
+
version: gatewayInstance.version
|
|
430
|
+
});
|
|
431
|
+
} else {
|
|
432
|
+
log('WARN', 'Vantuz Gateway eriΕilemez, direkt mod kullanΔ±lacak', {
|
|
433
|
+
error: health.error
|
|
434
|
+
});
|
|
435
|
+
}
|
|
436
|
+
}
|
|
437
|
+
return gatewayInstance;
|
|
438
|
+
}
|
|
439
|
+
|
|
440
|
+
/**
|
|
441
|
+
* Gateway durumunu sΔ±fΔ±rla (reconnect iΓ§in)
|
|
442
|
+
*/
|
|
443
|
+
export function resetGateway() {
|
|
444
|
+
gatewayInstance = null;
|
|
445
|
+
}
|
|
446
|
+
|
|
447
|
+
export default VantuzGateway;
|