vantuz 3.4.2 → 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.
Files changed (70) hide show
  1. package/LICENSE +45 -45
  2. package/admin-keygen.js +51 -0
  3. package/cli.js +685 -585
  4. package/config.js +733 -733
  5. package/core/agent-loop.js +190 -190
  6. package/core/ai-provider.js +298 -261
  7. package/core/automation.js +523 -523
  8. package/core/brand-analyst.js +101 -0
  9. package/core/channels.js +167 -167
  10. package/core/dashboard.js +230 -230
  11. package/core/database.js +135 -37
  12. package/core/eia-monitor.js +3 -1
  13. package/core/engine.js +648 -636
  14. package/core/gateway.js +447 -447
  15. package/core/learning.js +214 -214
  16. package/core/license.js +113 -0
  17. package/core/marketplace-adapter.js +168 -168
  18. package/core/memory.js +190 -190
  19. package/core/migrations/001-initial-schema.sql +1 -1
  20. package/core/queue.js +120 -120
  21. package/core/self-healer.js +314 -314
  22. package/core/unified-product.js +214 -214
  23. package/core/vision-service.js +113 -113
  24. package/index.js +217 -174
  25. package/modules/crm/sentiment-crm.js +231 -231
  26. package/modules/healer/listing-healer.js +201 -201
  27. package/modules/oracle/predictor.js +214 -214
  28. package/modules/researcher/agent.js +169 -169
  29. package/modules/team/agents/base.js +92 -92
  30. package/modules/team/agents/dev.js +33 -33
  31. package/modules/team/agents/josh.js +40 -40
  32. package/modules/team/agents/marketing.js +33 -33
  33. package/modules/team/agents/milo.js +36 -36
  34. package/modules/team/index.js +78 -78
  35. package/modules/team/shared-memory.js +87 -87
  36. package/modules/war-room/competitor-tracker.js +250 -250
  37. package/modules/war-room/pricing-engine.js +308 -308
  38. package/nodes/warehouse.js +238 -238
  39. package/onboard.js +1 -1
  40. package/package.json +7 -5
  41. package/platforms/pttavm.js +14 -14
  42. package/plugins/vantuz/index.js +528 -528
  43. package/plugins/vantuz/memory/hippocampus.js +465 -465
  44. package/plugins/vantuz/package.json +20 -20
  45. package/plugins/vantuz/platforms/_template.js +118 -118
  46. package/plugins/vantuz/platforms/amazon.js +236 -236
  47. package/plugins/vantuz/platforms/ciceksepeti.js +166 -166
  48. package/plugins/vantuz/platforms/hepsiburada.js +180 -180
  49. package/plugins/vantuz/platforms/index.js +165 -165
  50. package/plugins/vantuz/platforms/n11.js +229 -229
  51. package/plugins/vantuz/platforms/pazarama.js +154 -154
  52. package/plugins/vantuz/platforms/pttavm.js +127 -127
  53. package/plugins/vantuz/platforms/trendyol.js +326 -326
  54. package/plugins/vantuz/services/alerts.js +253 -253
  55. package/plugins/vantuz/services/license.js +34 -34
  56. package/plugins/vantuz/services/scheduler.js +232 -232
  57. package/plugins/vantuz/tools/analytics.js +152 -152
  58. package/plugins/vantuz/tools/crossborder.js +187 -187
  59. package/plugins/vantuz/tools/nl-parser.js +211 -211
  60. package/plugins/vantuz/tools/product.js +110 -110
  61. package/plugins/vantuz/tools/quick-report.js +175 -175
  62. package/plugins/vantuz/tools/repricer.js +314 -314
  63. package/plugins/vantuz/tools/sentiment.js +115 -115
  64. package/plugins/vantuz/tools/vision.js +257 -257
  65. package/private.pem +28 -0
  66. package/public.pem +9 -0
  67. package/server/app.js +260 -260
  68. package/server/public/index.html +514 -514
  69. package/start.bat +33 -33
  70. package/vantuz.sqlite +0 -0
package/core/learning.js CHANGED
@@ -1,214 +1,214 @@
1
- // core/learning.js
2
- // Reinforcement Learning Module for Vantuz OS V2
3
- // Weighted scoring system — tracks AI decisions and adjusts behavior.
4
-
5
- import fs from 'fs';
6
- import path from 'path';
7
- import os from 'os';
8
- import { log } from './ai-provider.js';
9
-
10
- const LEARNING_FILE = path.join(os.homedir(), '.vantuz', 'memory', 'learning.json');
11
-
12
- // ═══════════════════════════════════════════════════════════════════════════
13
- // WEIGHTED SCORE DEFINITIONS
14
- // ═══════════════════════════════════════════════════════════════════════════
15
-
16
- const SCORE_WEIGHTS = {
17
- // Positive Outcomes (Ödül)
18
- 'successful_price_update': +1,
19
- 'successful_stock_update': +1,
20
- 'good_prediction': +2,
21
- 'user_approval': +3,
22
- 'successful_auto_reply': +1,
23
- 'sale_after_optimization': +2,
24
-
25
- // Negative Outcomes (Ceza)
26
- 'price_increase_rejected': -2,
27
- 'stock_error': -5, // Stok hataları kritik
28
- 'user_rejection': -3,
29
- 'wrong_prediction': -1,
30
- 'listing_error': -2,
31
- 'kill_switch_triggered': -4,
32
- 'escalated_customer': -2,
33
-
34
- // Custom (Kullanıcı tanımlı)
35
- 'custom_positive': +1,
36
- 'custom_negative': -1
37
- };
38
-
39
- // ═══════════════════════════════════════════════════════════════════════════
40
- // AUTONOMOUS MODE CONTROL
41
- // ═══════════════════════════════════════════════════════════════════════════
42
-
43
- const AUTONOMY_THRESHOLD = -10; // Below this → manual mode
44
-
45
- // ═══════════════════════════════════════════════════════════════════════════
46
- // LEARNING MODULE
47
- // ═══════════════════════════════════════════════════════════════════════════
48
-
49
- class LearningModule {
50
- constructor() {
51
- this.data = this._load();
52
- log('INFO', 'LearningModule initialized', {
53
- netScore: this.data.netScore,
54
- totalEvents: this.data.events.length,
55
- autonomousMode: this.isAutonomous()
56
- });
57
- }
58
-
59
- _load() {
60
- try {
61
- if (fs.existsSync(LEARNING_FILE)) {
62
- return JSON.parse(fs.readFileSync(LEARNING_FILE, 'utf-8'));
63
- }
64
- } catch (e) { /* ignore */ }
65
- return {
66
- netScore: 0,
67
- events: [],
68
- autonomousModeOverride: null, // null = auto, true/false = manual override
69
- categoryScores: {} // per-category running totals
70
- };
71
- }
72
-
73
- _save() {
74
- const dir = path.dirname(LEARNING_FILE);
75
- if (!fs.existsSync(dir)) fs.mkdirSync(dir, { recursive: true });
76
- const tmp = LEARNING_FILE + '.tmp';
77
- fs.writeFileSync(tmp, JSON.stringify(this.data, null, 2), 'utf-8');
78
- fs.renameSync(tmp, LEARNING_FILE);
79
- }
80
-
81
- /**
82
- * Record a learning event.
83
- * @param {string} eventType - Event type (must be in SCORE_WEIGHTS or 'custom_*').
84
- * @param {string} context - Human-readable context.
85
- * @param {string} category - Category for grouping (e.g., 'pricing', 'stock').
86
- */
87
- record(eventType, context = '', category = 'general') {
88
- const weight = SCORE_WEIGHTS[eventType];
89
- if (weight === undefined) {
90
- log('WARN', `Unknown learning event type: ${eventType}`);
91
- return;
92
- }
93
-
94
- const event = {
95
- type: eventType,
96
- weight,
97
- context,
98
- category,
99
- timestamp: new Date().toISOString()
100
- };
101
-
102
- this.data.events.push(event);
103
- this.data.netScore += weight;
104
-
105
- // Category scoring
106
- if (!this.data.categoryScores[category]) {
107
- this.data.categoryScores[category] = 0;
108
- }
109
- this.data.categoryScores[category] += weight;
110
-
111
- // Trim old events (keep last 500)
112
- if (this.data.events.length > 500) {
113
- this.data.events = this.data.events.slice(-500);
114
- }
115
-
116
- this._save();
117
-
118
- // Check autonomy
119
- if (!this.isAutonomous()) {
120
- log('WARN', `⚠️ OTONOM MOD KAPANDI! Net skor: ${this.data.netScore} (eşik: ${AUTONOMY_THRESHOLD}). Manuel onay gerekiyor.`);
121
- }
122
-
123
- log('INFO', `Learning: ${eventType} (${weight > 0 ? '+' : ''}${weight})`, {
124
- context, netScore: this.data.netScore
125
- });
126
-
127
- return event;
128
- }
129
-
130
- /**
131
- * Is the system in autonomous mode?
132
- */
133
- isAutonomous() {
134
- // Manual override takes precedence
135
- if (this.data.autonomousModeOverride !== null) {
136
- return this.data.autonomousModeOverride;
137
- }
138
- return this.data.netScore >= AUTONOMY_THRESHOLD;
139
- }
140
-
141
- /**
142
- * Force autonomous mode on/off (manual override).
143
- */
144
- setAutonomousMode(enabled) {
145
- this.data.autonomousModeOverride = enabled;
146
- this._save();
147
- log('INFO', `Autonomous mode manually set to: ${enabled}`);
148
- }
149
-
150
- /**
151
- * Clear the manual override (revert to score-based control).
152
- */
153
- clearOverride() {
154
- this.data.autonomousModeOverride = null;
155
- this._save();
156
- log('INFO', 'Autonomous mode override cleared — score-based control active');
157
- }
158
-
159
- /**
160
- * Get net score.
161
- */
162
- getNetScore() {
163
- return this.data.netScore;
164
- }
165
-
166
- /**
167
- * Get per-category breakdown.
168
- */
169
- getCategoryScores() {
170
- return { ...this.data.categoryScores };
171
- }
172
-
173
- /**
174
- * Get recent events.
175
- */
176
- getRecentEvents(limit = 20) {
177
- return this.data.events.slice(-limit);
178
- }
179
-
180
- /**
181
- * Reset score (nuclear option).
182
- */
183
- reset() {
184
- this.data.netScore = 0;
185
- this.data.events = [];
186
- this.data.categoryScores = {};
187
- this.data.autonomousModeOverride = null;
188
- this._save();
189
- log('INFO', 'Learning module reset');
190
- }
191
-
192
- getStatus() {
193
- return {
194
- netScore: this.data.netScore,
195
- autonomous: this.isAutonomous(),
196
- threshold: AUTONOMY_THRESHOLD,
197
- override: this.data.autonomousModeOverride,
198
- totalEvents: this.data.events.length,
199
- categoryScores: this.data.categoryScores
200
- };
201
- }
202
- }
203
-
204
- let learningInstance = null;
205
-
206
- export function getLearning() {
207
- if (!learningInstance) {
208
- learningInstance = new LearningModule();
209
- }
210
- return learningInstance;
211
- }
212
-
213
- export { SCORE_WEIGHTS, AUTONOMY_THRESHOLD };
214
- export default LearningModule;
1
+ // core/learning.js
2
+ // Reinforcement Learning Module for Vantuz OS V2
3
+ // Weighted scoring system — tracks AI decisions and adjusts behavior.
4
+
5
+ import fs from 'fs';
6
+ import path from 'path';
7
+ import os from 'os';
8
+ import { log } from './ai-provider.js';
9
+
10
+ const LEARNING_FILE = path.join(os.homedir(), '.vantuz', 'memory', 'learning.json');
11
+
12
+ // ═══════════════════════════════════════════════════════════════════════════
13
+ // WEIGHTED SCORE DEFINITIONS
14
+ // ═══════════════════════════════════════════════════════════════════════════
15
+
16
+ const SCORE_WEIGHTS = {
17
+ // Positive Outcomes (Ödül)
18
+ 'successful_price_update': +1,
19
+ 'successful_stock_update': +1,
20
+ 'good_prediction': +2,
21
+ 'user_approval': +3,
22
+ 'successful_auto_reply': +1,
23
+ 'sale_after_optimization': +2,
24
+
25
+ // Negative Outcomes (Ceza)
26
+ 'price_increase_rejected': -2,
27
+ 'stock_error': -5, // Stok hataları kritik
28
+ 'user_rejection': -3,
29
+ 'wrong_prediction': -1,
30
+ 'listing_error': -2,
31
+ 'kill_switch_triggered': -4,
32
+ 'escalated_customer': -2,
33
+
34
+ // Custom (Kullanıcı tanımlı)
35
+ 'custom_positive': +1,
36
+ 'custom_negative': -1
37
+ };
38
+
39
+ // ═══════════════════════════════════════════════════════════════════════════
40
+ // AUTONOMOUS MODE CONTROL
41
+ // ═══════════════════════════════════════════════════════════════════════════
42
+
43
+ const AUTONOMY_THRESHOLD = -10; // Below this → manual mode
44
+
45
+ // ═══════════════════════════════════════════════════════════════════════════
46
+ // LEARNING MODULE
47
+ // ═══════════════════════════════════════════════════════════════════════════
48
+
49
+ class LearningModule {
50
+ constructor() {
51
+ this.data = this._load();
52
+ log('INFO', 'LearningModule initialized', {
53
+ netScore: this.data.netScore,
54
+ totalEvents: this.data.events.length,
55
+ autonomousMode: this.isAutonomous()
56
+ });
57
+ }
58
+
59
+ _load() {
60
+ try {
61
+ if (fs.existsSync(LEARNING_FILE)) {
62
+ return JSON.parse(fs.readFileSync(LEARNING_FILE, 'utf-8'));
63
+ }
64
+ } catch (e) { /* ignore */ }
65
+ return {
66
+ netScore: 0,
67
+ events: [],
68
+ autonomousModeOverride: null, // null = auto, true/false = manual override
69
+ categoryScores: {} // per-category running totals
70
+ };
71
+ }
72
+
73
+ _save() {
74
+ const dir = path.dirname(LEARNING_FILE);
75
+ if (!fs.existsSync(dir)) fs.mkdirSync(dir, { recursive: true });
76
+ const tmp = LEARNING_FILE + '.tmp';
77
+ fs.writeFileSync(tmp, JSON.stringify(this.data, null, 2), 'utf-8');
78
+ fs.renameSync(tmp, LEARNING_FILE);
79
+ }
80
+
81
+ /**
82
+ * Record a learning event.
83
+ * @param {string} eventType - Event type (must be in SCORE_WEIGHTS or 'custom_*').
84
+ * @param {string} context - Human-readable context.
85
+ * @param {string} category - Category for grouping (e.g., 'pricing', 'stock').
86
+ */
87
+ record(eventType, context = '', category = 'general') {
88
+ const weight = SCORE_WEIGHTS[eventType];
89
+ if (weight === undefined) {
90
+ log('WARN', `Unknown learning event type: ${eventType}`);
91
+ return;
92
+ }
93
+
94
+ const event = {
95
+ type: eventType,
96
+ weight,
97
+ context,
98
+ category,
99
+ timestamp: new Date().toISOString()
100
+ };
101
+
102
+ this.data.events.push(event);
103
+ this.data.netScore += weight;
104
+
105
+ // Category scoring
106
+ if (!this.data.categoryScores[category]) {
107
+ this.data.categoryScores[category] = 0;
108
+ }
109
+ this.data.categoryScores[category] += weight;
110
+
111
+ // Trim old events (keep last 500)
112
+ if (this.data.events.length > 500) {
113
+ this.data.events = this.data.events.slice(-500);
114
+ }
115
+
116
+ this._save();
117
+
118
+ // Check autonomy
119
+ if (!this.isAutonomous()) {
120
+ log('WARN', `⚠️ OTONOM MOD KAPANDI! Net skor: ${this.data.netScore} (eşik: ${AUTONOMY_THRESHOLD}). Manuel onay gerekiyor.`);
121
+ }
122
+
123
+ log('INFO', `Learning: ${eventType} (${weight > 0 ? '+' : ''}${weight})`, {
124
+ context, netScore: this.data.netScore
125
+ });
126
+
127
+ return event;
128
+ }
129
+
130
+ /**
131
+ * Is the system in autonomous mode?
132
+ */
133
+ isAutonomous() {
134
+ // Manual override takes precedence
135
+ if (this.data.autonomousModeOverride !== null) {
136
+ return this.data.autonomousModeOverride;
137
+ }
138
+ return this.data.netScore >= AUTONOMY_THRESHOLD;
139
+ }
140
+
141
+ /**
142
+ * Force autonomous mode on/off (manual override).
143
+ */
144
+ setAutonomousMode(enabled) {
145
+ this.data.autonomousModeOverride = enabled;
146
+ this._save();
147
+ log('INFO', `Autonomous mode manually set to: ${enabled}`);
148
+ }
149
+
150
+ /**
151
+ * Clear the manual override (revert to score-based control).
152
+ */
153
+ clearOverride() {
154
+ this.data.autonomousModeOverride = null;
155
+ this._save();
156
+ log('INFO', 'Autonomous mode override cleared — score-based control active');
157
+ }
158
+
159
+ /**
160
+ * Get net score.
161
+ */
162
+ getNetScore() {
163
+ return this.data.netScore;
164
+ }
165
+
166
+ /**
167
+ * Get per-category breakdown.
168
+ */
169
+ getCategoryScores() {
170
+ return { ...this.data.categoryScores };
171
+ }
172
+
173
+ /**
174
+ * Get recent events.
175
+ */
176
+ getRecentEvents(limit = 20) {
177
+ return this.data.events.slice(-limit);
178
+ }
179
+
180
+ /**
181
+ * Reset score (nuclear option).
182
+ */
183
+ reset() {
184
+ this.data.netScore = 0;
185
+ this.data.events = [];
186
+ this.data.categoryScores = {};
187
+ this.data.autonomousModeOverride = null;
188
+ this._save();
189
+ log('INFO', 'Learning module reset');
190
+ }
191
+
192
+ getStatus() {
193
+ return {
194
+ netScore: this.data.netScore,
195
+ autonomous: this.isAutonomous(),
196
+ threshold: AUTONOMY_THRESHOLD,
197
+ override: this.data.autonomousModeOverride,
198
+ totalEvents: this.data.events.length,
199
+ categoryScores: this.data.categoryScores
200
+ };
201
+ }
202
+ }
203
+
204
+ let learningInstance = null;
205
+
206
+ export function getLearning() {
207
+ if (!learningInstance) {
208
+ learningInstance = new LearningModule();
209
+ }
210
+ return learningInstance;
211
+ }
212
+
213
+ export { SCORE_WEIGHTS, AUTONOMY_THRESHOLD };
214
+ export default LearningModule;
@@ -0,0 +1,113 @@
1
+
2
+ import fs from 'fs';
3
+ import path from 'path';
4
+ import crypto from 'crypto';
5
+ import { log } from './ai-provider.js';
6
+ import os from 'os';
7
+
8
+ const LICENSE_FILE = path.join(os.homedir(), '.vantuz', 'license.json');
9
+
10
+ // PUBLIC KEY (Müşteriye giden kodun içine gömülü)
11
+ // Sadece senin Private Key'inle imzalanmış veriyi doğrular.
12
+ const PUBLIC_KEY = `-----BEGIN PUBLIC KEY-----
13
+ MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAnOaEFB+3s2ouGnbfGlbE
14
+ XO55/RFjoifn2dMNTLt49Ul6CsDES0VaKOQ3+Vmyw8OjYwy773Z/wunX09qCEXDE
15
+ vKHAhxxBa3RQafIbQ/2MIyGTjvxrGelDPzB6yStSwLgShcXtRvAh69aXpFjXCLaW
16
+ svNq+7vcnNdXeZ2c0ipWbnqjpPiFKDe+wZ//gkx70zYXc4WijyLtTQWC6BobhpOA
17
+ isx5uykTzr+LLtMb2n1TpxEopSRbkLQQD4NMskH9Eb1Nx3znl+PjZooUXvr+8eJr
18
+ jQp0PTDTL32LHo2iaWwkKZ38PDc/hfSuu3Kt31t0SIxAwObcCmO2OtiZ7wTKxDow
19
+ RwIDAQAB
20
+ -----END PUBLIC KEY-----`;
21
+
22
+ export class LicenseManager {
23
+ constructor() {
24
+ this.data = this._load();
25
+ }
26
+
27
+ _load() {
28
+ try {
29
+ if (fs.existsSync(LICENSE_FILE)) {
30
+ return JSON.parse(fs.readFileSync(LICENSE_FILE, 'utf-8'));
31
+ }
32
+ } catch (e) {}
33
+ return { key: null, activatedAt: null, type: 'DEMO', expiresAt: null };
34
+ }
35
+
36
+ _save() {
37
+ fs.writeFileSync(LICENSE_FILE, JSON.stringify(this.data, null, 2));
38
+ }
39
+
40
+ /**
41
+ * Lisans anahtarını doğrula (Signature Verification)
42
+ * Format: BASE64_PAYLOAD.BASE64_SIGNATURE
43
+ */
44
+ activate(licenseString) {
45
+ try {
46
+ const [payloadB64, signatureB64] = licenseString.split('.');
47
+ if (!payloadB64 || !signatureB64) {
48
+ return { success: false, message: 'Geçersiz lisans formatı.' };
49
+ }
50
+
51
+ // 1. İmzayı Doğrula
52
+ const verify = crypto.createVerify('SHA256');
53
+ verify.update(payloadB64);
54
+ verify.end();
55
+ const isValid = verify.verify(PUBLIC_KEY, signatureB64, 'base64');
56
+
57
+ if (!isValid) {
58
+ return { success: false, message: '❌ SAHTE LİSANS! İmza doğrulanamadı.' };
59
+ }
60
+
61
+ // 2. İçeriği Çöz
62
+ const payload = JSON.parse(Buffer.from(payloadB64, 'base64').toString('utf-8'));
63
+
64
+ // 3. Son Kullanma Tarihini Kontrol Et (Payload içinden gelir)
65
+ // Payload: { type: 'ANNUAL', expires: '2027-01-01', user: '...' }
66
+
67
+ this.data = {
68
+ key: licenseString,
69
+ activatedAt: new Date().toISOString(),
70
+ expiresAt: payload.expires,
71
+ type: payload.type || 'PRO'
72
+ };
73
+ this._save();
74
+
75
+ return { success: true, message: `Lisans aktif! Bitiş: ${payload.expires}` };
76
+
77
+ } catch (e) {
78
+ return { success: false, message: 'Lisans işlenirken hata oluştu: ' + e.message };
79
+ }
80
+ }
81
+
82
+ check() {
83
+ if (!this.data.key || !this.data.expiresAt) {
84
+ return { valid: false, reason: 'NO_LICENSE', message: 'Lisans bulunamadı.' };
85
+ }
86
+
87
+ const now = new Date();
88
+ const expires = new Date(this.data.expiresAt);
89
+ const daysLeft = Math.ceil((expires - now) / (1000 * 60 * 60 * 24));
90
+
91
+ if (daysLeft <= 0) {
92
+ return { valid: false, reason: 'EXPIRED', message: 'Lisans süresi doldu.' };
93
+ }
94
+
95
+ return {
96
+ valid: true,
97
+ type: this.data.type,
98
+ daysLeft: daysLeft,
99
+ expiresAt: this.data.expiresAt
100
+ };
101
+ }
102
+
103
+ getInfo() {
104
+ const check = this.check();
105
+ return {
106
+ ...this.data,
107
+ valid: check.valid,
108
+ daysLeft: check.daysLeft || 0
109
+ };
110
+ }
111
+ }
112
+
113
+ export const licenseManager = new LicenseManager();