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.
- 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 -37
- 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 -5
- package/platforms/pttavm.js +14 -14
- package/plugins/vantuz/index.js +528 -528
- package/plugins/vantuz/memory/hippocampus.js +465 -465
- 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
|
@@ -1,465 +1,465 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* π§ HIPPOCAMPUS - GeliΕmiΕ HafΔ±za Sistemi
|
|
3
|
-
*
|
|
4
|
-
* Beyin'in hippocampus bΓΆlgesinden ilham alΔ±narak tasarlanmΔ±Ε,
|
|
5
|
-
* uzun sΓΌreli hafΔ±za yΓΆnetimi ve baΔlamsal hatΔ±rlama sistemi.
|
|
6
|
-
*
|
|
7
|
-
* Γzellikler:
|
|
8
|
-
* - Episodik hafΔ±za (olaylar, kararlar)
|
|
9
|
-
* - Semantik hafΔ±za (ΓΌrΓΌn bilgileri, kurallar)
|
|
10
|
-
* - VektΓΆr tabanlΔ± benzerlik aramasΔ±
|
|
11
|
-
* - Otomatik hafΔ±za konsolidasyonu
|
|
12
|
-
* - Γnem bazlΔ± unutma mekanizmasΔ±
|
|
13
|
-
*/
|
|
14
|
-
|
|
15
|
-
import { Sequelize, DataTypes, Op } from 'sequelize';
|
|
16
|
-
import path from 'path';
|
|
17
|
-
import crypto from 'crypto';
|
|
18
|
-
|
|
19
|
-
export class Hippocampus {
|
|
20
|
-
constructor(api) {
|
|
21
|
-
this.api = api;
|
|
22
|
-
this.logger = api.logger;
|
|
23
|
-
this.db = null;
|
|
24
|
-
this.models = {};
|
|
25
|
-
this.initialized = false;
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
async initialize() {
|
|
29
|
-
const dbPath = path.join(process.cwd(), '.vantuz', 'hippocampus.sqlite');
|
|
30
|
-
|
|
31
|
-
this.db = new Sequelize({
|
|
32
|
-
dialect: 'sqlite',
|
|
33
|
-
storage: dbPath,
|
|
34
|
-
dialectModule: require('better-sqlite3'),
|
|
35
|
-
logging: false
|
|
36
|
-
});
|
|
37
|
-
|
|
38
|
-
// HafΔ±za Modelleri
|
|
39
|
-
this.models.Memory = this.db.define('Memory', {
|
|
40
|
-
id: {
|
|
41
|
-
type: DataTypes.UUID,
|
|
42
|
-
defaultValue: DataTypes.UUIDV4,
|
|
43
|
-
primaryKey: true
|
|
44
|
-
},
|
|
45
|
-
type: {
|
|
46
|
-
type: DataTypes.STRING,
|
|
47
|
-
allowNull: false,
|
|
48
|
-
// decision, price_change, product, conversation, insight, rule
|
|
49
|
-
},
|
|
50
|
-
content: {
|
|
51
|
-
type: DataTypes.TEXT,
|
|
52
|
-
allowNull: false
|
|
53
|
-
},
|
|
54
|
-
context: {
|
|
55
|
-
type: DataTypes.JSON,
|
|
56
|
-
// Δ°liΕkili veriler: productId, platform, userId, etc.
|
|
57
|
-
},
|
|
58
|
-
embedding: {
|
|
59
|
-
type: DataTypes.TEXT,
|
|
60
|
-
// VektΓΆr gΓΆmme (JSON olarak saklanΔ±r)
|
|
61
|
-
},
|
|
62
|
-
importance: {
|
|
63
|
-
type: DataTypes.FLOAT,
|
|
64
|
-
defaultValue: 0.5,
|
|
65
|
-
// 0-1 arasΔ± ΓΆnem skoru
|
|
66
|
-
},
|
|
67
|
-
accessCount: {
|
|
68
|
-
type: DataTypes.INTEGER,
|
|
69
|
-
defaultValue: 0
|
|
70
|
-
},
|
|
71
|
-
lastAccessed: {
|
|
72
|
-
type: DataTypes.DATE
|
|
73
|
-
},
|
|
74
|
-
expiresAt: {
|
|
75
|
-
type: DataTypes.DATE,
|
|
76
|
-
// null = kalΔ±cΔ± hafΔ±za
|
|
77
|
-
},
|
|
78
|
-
tags: {
|
|
79
|
-
type: DataTypes.JSON,
|
|
80
|
-
defaultValue: []
|
|
81
|
-
}
|
|
82
|
-
});
|
|
83
|
-
|
|
84
|
-
// Fiyat Karar GeΓ§miΕi
|
|
85
|
-
this.models.PricingDecision = this.db.define('PricingDecision', {
|
|
86
|
-
id: {
|
|
87
|
-
type: DataTypes.UUID,
|
|
88
|
-
defaultValue: DataTypes.UUIDV4,
|
|
89
|
-
primaryKey: true
|
|
90
|
-
},
|
|
91
|
-
productId: DataTypes.STRING,
|
|
92
|
-
barcode: DataTypes.STRING,
|
|
93
|
-
platform: DataTypes.STRING,
|
|
94
|
-
previousPrice: DataTypes.FLOAT,
|
|
95
|
-
newPrice: DataTypes.FLOAT,
|
|
96
|
-
reason: DataTypes.TEXT,
|
|
97
|
-
factors: {
|
|
98
|
-
type: DataTypes.JSON,
|
|
99
|
-
// { competitorPrice, competitorStock, ourStock, margin, velocity }
|
|
100
|
-
},
|
|
101
|
-
outcome: {
|
|
102
|
-
type: DataTypes.STRING,
|
|
103
|
-
// applied, rejected, pending
|
|
104
|
-
},
|
|
105
|
-
profitImpact: DataTypes.FLOAT
|
|
106
|
-
});
|
|
107
|
-
|
|
108
|
-
// ΓrΓΌn BaΔlamΔ±
|
|
109
|
-
this.models.ProductContext = this.db.define('ProductContext', {
|
|
110
|
-
id: {
|
|
111
|
-
type: DataTypes.UUID,
|
|
112
|
-
defaultValue: DataTypes.UUIDV4,
|
|
113
|
-
primaryKey: true
|
|
114
|
-
},
|
|
115
|
-
barcode: {
|
|
116
|
-
type: DataTypes.STRING,
|
|
117
|
-
unique: true
|
|
118
|
-
},
|
|
119
|
-
name: DataTypes.STRING,
|
|
120
|
-
category: DataTypes.STRING,
|
|
121
|
-
avgSalePrice: DataTypes.FLOAT,
|
|
122
|
-
avgCost: DataTypes.FLOAT,
|
|
123
|
-
seasonality: DataTypes.JSON,
|
|
124
|
-
competitorHistory: DataTypes.JSON,
|
|
125
|
-
customerSentiment: {
|
|
126
|
-
type: DataTypes.JSON,
|
|
127
|
-
// { positive: 0.8, negative: 0.2, topComplaints: [] }
|
|
128
|
-
},
|
|
129
|
-
priceElasticity: DataTypes.FLOAT,
|
|
130
|
-
optimalPriceRange: DataTypes.JSON
|
|
131
|
-
});
|
|
132
|
-
|
|
133
|
-
// KonuΕma GeΓ§miΕi (Session bazlΔ±)
|
|
134
|
-
this.models.ConversationMemory = this.db.define('ConversationMemory', {
|
|
135
|
-
id: {
|
|
136
|
-
type: DataTypes.UUID,
|
|
137
|
-
defaultValue: DataTypes.UUIDV4,
|
|
138
|
-
primaryKey: true
|
|
139
|
-
},
|
|
140
|
-
sessionKey: DataTypes.STRING,
|
|
141
|
-
userId: DataTypes.STRING,
|
|
142
|
-
channel: DataTypes.STRING,
|
|
143
|
-
role: {
|
|
144
|
-
type: DataTypes.STRING,
|
|
145
|
-
// user, assistant
|
|
146
|
-
},
|
|
147
|
-
content: DataTypes.TEXT,
|
|
148
|
-
intent: DataTypes.STRING,
|
|
149
|
-
entities: DataTypes.JSON,
|
|
150
|
-
actionTaken: DataTypes.STRING
|
|
151
|
-
});
|
|
152
|
-
|
|
153
|
-
// ΓΔrenilen Kurallar
|
|
154
|
-
this.models.LearnedRule = this.db.define('LearnedRule', {
|
|
155
|
-
id: {
|
|
156
|
-
type: DataTypes.UUID,
|
|
157
|
-
defaultValue: DataTypes.UUIDV4,
|
|
158
|
-
primaryKey: true
|
|
159
|
-
},
|
|
160
|
-
trigger: DataTypes.TEXT,
|
|
161
|
-
condition: DataTypes.JSON,
|
|
162
|
-
action: DataTypes.TEXT,
|
|
163
|
-
confidence: {
|
|
164
|
-
type: DataTypes.FLOAT,
|
|
165
|
-
defaultValue: 0.5
|
|
166
|
-
},
|
|
167
|
-
usageCount: {
|
|
168
|
-
type: DataTypes.INTEGER,
|
|
169
|
-
defaultValue: 0
|
|
170
|
-
},
|
|
171
|
-
successRate: {
|
|
172
|
-
type: DataTypes.FLOAT,
|
|
173
|
-
defaultValue: 0.5
|
|
174
|
-
}
|
|
175
|
-
});
|
|
176
|
-
|
|
177
|
-
await this.db.sync({ alter: true });
|
|
178
|
-
this.initialized = true;
|
|
179
|
-
this.logger.info('π§ Hippocampus veritabanΔ± hazΔ±r.');
|
|
180
|
-
|
|
181
|
-
// HafΔ±za konsolidasyonu zamanlayΔ±cΔ±sΔ± (her gece)
|
|
182
|
-
this._startConsolidation();
|
|
183
|
-
}
|
|
184
|
-
|
|
185
|
-
// βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
|
186
|
-
// HAFIZA KAYDETME
|
|
187
|
-
// βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
|
188
|
-
|
|
189
|
-
async remember(type, content, context = {}, options = {}) {
|
|
190
|
-
const memory = await this.models.Memory.create({
|
|
191
|
-
type,
|
|
192
|
-
content: typeof content === 'string' ? content : JSON.stringify(content),
|
|
193
|
-
context,
|
|
194
|
-
importance: options.importance || this._calculateImportance(type, content),
|
|
195
|
-
tags: options.tags || [],
|
|
196
|
-
expiresAt: options.temporary ? new Date(Date.now() + 24 * 60 * 60 * 1000) : null
|
|
197
|
-
});
|
|
198
|
-
|
|
199
|
-
this.logger.debug(`πΎ HafΔ±za kaydedildi: ${type} - ${memory.id}`);
|
|
200
|
-
return memory;
|
|
201
|
-
}
|
|
202
|
-
|
|
203
|
-
async recordPricingDecision(decision) {
|
|
204
|
-
return await this.models.PricingDecision.create(decision);
|
|
205
|
-
}
|
|
206
|
-
|
|
207
|
-
async updateProductContext(barcode, updates) {
|
|
208
|
-
const [context, created] = await this.models.ProductContext.findOrCreate({
|
|
209
|
-
where: { barcode },
|
|
210
|
-
defaults: { barcode, ...updates }
|
|
211
|
-
});
|
|
212
|
-
|
|
213
|
-
if (!created) {
|
|
214
|
-
await context.update(updates);
|
|
215
|
-
}
|
|
216
|
-
|
|
217
|
-
return context;
|
|
218
|
-
}
|
|
219
|
-
|
|
220
|
-
async recordConversation(sessionKey, userId, channel, role, content, metadata = {}) {
|
|
221
|
-
return await this.models.ConversationMemory.create({
|
|
222
|
-
sessionKey,
|
|
223
|
-
userId,
|
|
224
|
-
channel,
|
|
225
|
-
role,
|
|
226
|
-
content,
|
|
227
|
-
intent: metadata.intent,
|
|
228
|
-
entities: metadata.entities,
|
|
229
|
-
actionTaken: metadata.action
|
|
230
|
-
});
|
|
231
|
-
}
|
|
232
|
-
|
|
233
|
-
// βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
|
234
|
-
// HAFIZA ARAMA
|
|
235
|
-
// βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
|
236
|
-
|
|
237
|
-
async search({ query, type, limit = 10, minImportance = 0 }) {
|
|
238
|
-
const where = {};
|
|
239
|
-
|
|
240
|
-
if (type && type !== 'all') {
|
|
241
|
-
where.type = type;
|
|
242
|
-
}
|
|
243
|
-
|
|
244
|
-
if (minImportance > 0) {
|
|
245
|
-
where.importance = { [Op.gte]: minImportance };
|
|
246
|
-
}
|
|
247
|
-
|
|
248
|
-
// Basit metin aramasΔ± (ileride vektΓΆr aramasΔ± eklenebilir)
|
|
249
|
-
if (query) {
|
|
250
|
-
where.content = { [Op.like]: `%${query}%` };
|
|
251
|
-
}
|
|
252
|
-
|
|
253
|
-
const memories = await this.models.Memory.findAll({
|
|
254
|
-
where,
|
|
255
|
-
order: [['importance', 'DESC'], ['createdAt', 'DESC']],
|
|
256
|
-
limit
|
|
257
|
-
});
|
|
258
|
-
|
|
259
|
-
// EriΕim sayacΔ±nΔ± gΓΌncelle
|
|
260
|
-
for (const mem of memories) {
|
|
261
|
-
await mem.update({
|
|
262
|
-
accessCount: mem.accessCount + 1,
|
|
263
|
-
lastAccessed: new Date()
|
|
264
|
-
});
|
|
265
|
-
}
|
|
266
|
-
|
|
267
|
-
return memories.map(m => ({
|
|
268
|
-
id: m.id,
|
|
269
|
-
type: m.type,
|
|
270
|
-
content: m.content,
|
|
271
|
-
context: m.context,
|
|
272
|
-
importance: m.importance,
|
|
273
|
-
createdAt: m.createdAt
|
|
274
|
-
}));
|
|
275
|
-
}
|
|
276
|
-
|
|
277
|
-
async getProductContext(barcode) {
|
|
278
|
-
return await this.models.ProductContext.findOne({ where: { barcode } });
|
|
279
|
-
}
|
|
280
|
-
|
|
281
|
-
async getPricingHistory(barcode, limit = 10) {
|
|
282
|
-
return await this.models.PricingDecision.findAll({
|
|
283
|
-
where: { barcode },
|
|
284
|
-
order: [['createdAt', 'DESC']],
|
|
285
|
-
limit
|
|
286
|
-
});
|
|
287
|
-
}
|
|
288
|
-
|
|
289
|
-
async getRecentConversations(sessionKey, limit = 20) {
|
|
290
|
-
return await this.models.ConversationMemory.findAll({
|
|
291
|
-
where: { sessionKey },
|
|
292
|
-
order: [['createdAt', 'DESC']],
|
|
293
|
-
limit
|
|
294
|
-
});
|
|
295
|
-
}
|
|
296
|
-
|
|
297
|
-
async getLearnedRules(trigger) {
|
|
298
|
-
return await this.models.LearnedRule.findAll({
|
|
299
|
-
where: {
|
|
300
|
-
trigger: { [Op.like]: `%${trigger}%` },
|
|
301
|
-
confidence: { [Op.gte]: 0.6 }
|
|
302
|
-
},
|
|
303
|
-
order: [['confidence', 'DESC'], ['usageCount', 'DESC']]
|
|
304
|
-
});
|
|
305
|
-
}
|
|
306
|
-
|
|
307
|
-
// βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
|
308
|
-
// BAΔLAMSAL HATIRLATMA
|
|
309
|
-
// βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
|
310
|
-
|
|
311
|
-
async getRelevantContext(input, options = {}) {
|
|
312
|
-
const context = {
|
|
313
|
-
recentDecisions: [],
|
|
314
|
-
productHistory: null,
|
|
315
|
-
relatedMemories: [],
|
|
316
|
-
applicableRules: []
|
|
317
|
-
};
|
|
318
|
-
|
|
319
|
-
// ΓrΓΌn barkodu varsa ΓΌrΓΌn baΔlamΔ±nΔ± al
|
|
320
|
-
if (options.barcode) {
|
|
321
|
-
context.productHistory = await this.getProductContext(options.barcode);
|
|
322
|
-
context.recentDecisions = await this.getPricingHistory(options.barcode, 5);
|
|
323
|
-
}
|
|
324
|
-
|
|
325
|
-
// Δ°lgili hafΔ±zalarΔ± ara
|
|
326
|
-
context.relatedMemories = await this.search({
|
|
327
|
-
query: input,
|
|
328
|
-
type: options.type || 'all',
|
|
329
|
-
limit: 5,
|
|
330
|
-
minImportance: 0.3
|
|
331
|
-
});
|
|
332
|
-
|
|
333
|
-
// Uygulanabilir kurallarΔ± bul
|
|
334
|
-
context.applicableRules = await this.getLearnedRules(input);
|
|
335
|
-
|
|
336
|
-
return context;
|
|
337
|
-
}
|
|
338
|
-
|
|
339
|
-
// βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
|
340
|
-
// ΓΔRENME & KONSOLΔ°DASYON
|
|
341
|
-
// βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
|
342
|
-
|
|
343
|
-
async learnRule(trigger, condition, action) {
|
|
344
|
-
const existing = await this.models.LearnedRule.findOne({
|
|
345
|
-
where: { trigger, action }
|
|
346
|
-
});
|
|
347
|
-
|
|
348
|
-
if (existing) {
|
|
349
|
-
await existing.update({
|
|
350
|
-
usageCount: existing.usageCount + 1,
|
|
351
|
-
confidence: Math.min(1, existing.confidence + 0.05)
|
|
352
|
-
});
|
|
353
|
-
return existing;
|
|
354
|
-
}
|
|
355
|
-
|
|
356
|
-
return await this.models.LearnedRule.create({
|
|
357
|
-
trigger,
|
|
358
|
-
condition,
|
|
359
|
-
action,
|
|
360
|
-
confidence: 0.5
|
|
361
|
-
});
|
|
362
|
-
}
|
|
363
|
-
|
|
364
|
-
async recordRuleOutcome(ruleId, success) {
|
|
365
|
-
const rule = await this.models.LearnedRule.findByPk(ruleId);
|
|
366
|
-
if (!rule) return;
|
|
367
|
-
|
|
368
|
-
const newSuccessRate = (rule.successRate * rule.usageCount + (success ? 1 : 0)) / (rule.usageCount + 1);
|
|
369
|
-
const newConfidence = success
|
|
370
|
-
? Math.min(1, rule.confidence + 0.1)
|
|
371
|
-
: Math.max(0, rule.confidence - 0.1);
|
|
372
|
-
|
|
373
|
-
await rule.update({
|
|
374
|
-
usageCount: rule.usageCount + 1,
|
|
375
|
-
successRate: newSuccessRate,
|
|
376
|
-
confidence: newConfidence
|
|
377
|
-
});
|
|
378
|
-
}
|
|
379
|
-
|
|
380
|
-
_startConsolidation() {
|
|
381
|
-
// Her gece saat 3'te Γ§alΔ±Ε
|
|
382
|
-
const now = new Date();
|
|
383
|
-
const night = new Date(now);
|
|
384
|
-
night.setHours(3, 0, 0, 0);
|
|
385
|
-
if (night <= now) night.setDate(night.getDate() + 1);
|
|
386
|
-
|
|
387
|
-
const delay = night - now;
|
|
388
|
-
|
|
389
|
-
setTimeout(() => {
|
|
390
|
-
this._consolidate();
|
|
391
|
-
// Sonra her 24 saatte bir
|
|
392
|
-
setInterval(() => this._consolidate(), 24 * 60 * 60 * 1000);
|
|
393
|
-
}, delay);
|
|
394
|
-
}
|
|
395
|
-
|
|
396
|
-
async _consolidate() {
|
|
397
|
-
this.logger.info('π§ HafΔ±za konsolidasyonu baΕlΔ±yor...');
|
|
398
|
-
|
|
399
|
-
// 1. SΓΌresi dolmuΕ hafΔ±zalarΔ± sil
|
|
400
|
-
await this.models.Memory.destroy({
|
|
401
|
-
where: {
|
|
402
|
-
expiresAt: { [Op.lt]: new Date() }
|
|
403
|
-
}
|
|
404
|
-
});
|
|
405
|
-
|
|
406
|
-
// 2. DΓΌΕΓΌk ΓΆnemli ve eriΕilmeyen hafΔ±zalarΔ± "unut"
|
|
407
|
-
const oldDate = new Date(Date.now() - 90 * 24 * 60 * 60 * 1000); // 90 gΓΌn
|
|
408
|
-
await this.models.Memory.destroy({
|
|
409
|
-
where: {
|
|
410
|
-
importance: { [Op.lt]: 0.3 },
|
|
411
|
-
accessCount: { [Op.lt]: 3 },
|
|
412
|
-
lastAccessed: { [Op.lt]: oldDate }
|
|
413
|
-
}
|
|
414
|
-
});
|
|
415
|
-
|
|
416
|
-
// 3. DΓΌΕΓΌk gΓΌvenilirlikli kurallarΔ± sil
|
|
417
|
-
await this.models.LearnedRule.destroy({
|
|
418
|
-
where: {
|
|
419
|
-
confidence: { [Op.lt]: 0.2 },
|
|
420
|
-
usageCount: { [Op.gt]: 10 }
|
|
421
|
-
}
|
|
422
|
-
});
|
|
423
|
-
|
|
424
|
-
this.logger.info('π§ HafΔ±za konsolidasyonu tamamlandΔ±.');
|
|
425
|
-
}
|
|
426
|
-
|
|
427
|
-
_calculateImportance(type, content) {
|
|
428
|
-
// Tip bazlΔ± temel ΓΆnem
|
|
429
|
-
const baseImportance = {
|
|
430
|
-
decision: 0.8,
|
|
431
|
-
price_change: 0.7,
|
|
432
|
-
insight: 0.6,
|
|
433
|
-
rule: 0.9,
|
|
434
|
-
product: 0.5,
|
|
435
|
-
conversation: 0.3
|
|
436
|
-
};
|
|
437
|
-
|
|
438
|
-
return baseImportance[type] || 0.5;
|
|
439
|
-
}
|
|
440
|
-
|
|
441
|
-
// βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
|
442
|
-
// Δ°STATΔ°STΔ°KLER
|
|
443
|
-
// βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
|
444
|
-
|
|
445
|
-
async getStats() {
|
|
446
|
-
const memoryCount = await this.models.Memory.count();
|
|
447
|
-
const decisionCount = await this.models.PricingDecision.count();
|
|
448
|
-
const productCount = await this.models.ProductContext.count();
|
|
449
|
-
const ruleCount = await this.models.LearnedRule.count();
|
|
450
|
-
|
|
451
|
-
return {
|
|
452
|
-
memories: memoryCount,
|
|
453
|
-
decisions: decisionCount,
|
|
454
|
-
products: productCount,
|
|
455
|
-
rules: ruleCount,
|
|
456
|
-
initialized: this.initialized
|
|
457
|
-
};
|
|
458
|
-
}
|
|
459
|
-
|
|
460
|
-
async close() {
|
|
461
|
-
if (this.db) {
|
|
462
|
-
await this.db.close();
|
|
463
|
-
}
|
|
464
|
-
}
|
|
465
|
-
}
|
|
1
|
+
/**
|
|
2
|
+
* π§ HIPPOCAMPUS - GeliΕmiΕ HafΔ±za Sistemi
|
|
3
|
+
*
|
|
4
|
+
* Beyin'in hippocampus bΓΆlgesinden ilham alΔ±narak tasarlanmΔ±Ε,
|
|
5
|
+
* uzun sΓΌreli hafΔ±za yΓΆnetimi ve baΔlamsal hatΔ±rlama sistemi.
|
|
6
|
+
*
|
|
7
|
+
* Γzellikler:
|
|
8
|
+
* - Episodik hafΔ±za (olaylar, kararlar)
|
|
9
|
+
* - Semantik hafΔ±za (ΓΌrΓΌn bilgileri, kurallar)
|
|
10
|
+
* - VektΓΆr tabanlΔ± benzerlik aramasΔ±
|
|
11
|
+
* - Otomatik hafΔ±za konsolidasyonu
|
|
12
|
+
* - Γnem bazlΔ± unutma mekanizmasΔ±
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
import { Sequelize, DataTypes, Op } from 'sequelize';
|
|
16
|
+
import path from 'path';
|
|
17
|
+
import crypto from 'crypto';
|
|
18
|
+
|
|
19
|
+
export class Hippocampus {
|
|
20
|
+
constructor(api) {
|
|
21
|
+
this.api = api;
|
|
22
|
+
this.logger = api.logger;
|
|
23
|
+
this.db = null;
|
|
24
|
+
this.models = {};
|
|
25
|
+
this.initialized = false;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
async initialize() {
|
|
29
|
+
const dbPath = path.join(process.cwd(), '.vantuz', 'hippocampus.sqlite');
|
|
30
|
+
|
|
31
|
+
this.db = new Sequelize({
|
|
32
|
+
dialect: 'sqlite',
|
|
33
|
+
storage: dbPath,
|
|
34
|
+
dialectModule: require('better-sqlite3'),
|
|
35
|
+
logging: false
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
// HafΔ±za Modelleri
|
|
39
|
+
this.models.Memory = this.db.define('Memory', {
|
|
40
|
+
id: {
|
|
41
|
+
type: DataTypes.UUID,
|
|
42
|
+
defaultValue: DataTypes.UUIDV4,
|
|
43
|
+
primaryKey: true
|
|
44
|
+
},
|
|
45
|
+
type: {
|
|
46
|
+
type: DataTypes.STRING,
|
|
47
|
+
allowNull: false,
|
|
48
|
+
// decision, price_change, product, conversation, insight, rule
|
|
49
|
+
},
|
|
50
|
+
content: {
|
|
51
|
+
type: DataTypes.TEXT,
|
|
52
|
+
allowNull: false
|
|
53
|
+
},
|
|
54
|
+
context: {
|
|
55
|
+
type: DataTypes.JSON,
|
|
56
|
+
// Δ°liΕkili veriler: productId, platform, userId, etc.
|
|
57
|
+
},
|
|
58
|
+
embedding: {
|
|
59
|
+
type: DataTypes.TEXT,
|
|
60
|
+
// VektΓΆr gΓΆmme (JSON olarak saklanΔ±r)
|
|
61
|
+
},
|
|
62
|
+
importance: {
|
|
63
|
+
type: DataTypes.FLOAT,
|
|
64
|
+
defaultValue: 0.5,
|
|
65
|
+
// 0-1 arasΔ± ΓΆnem skoru
|
|
66
|
+
},
|
|
67
|
+
accessCount: {
|
|
68
|
+
type: DataTypes.INTEGER,
|
|
69
|
+
defaultValue: 0
|
|
70
|
+
},
|
|
71
|
+
lastAccessed: {
|
|
72
|
+
type: DataTypes.DATE
|
|
73
|
+
},
|
|
74
|
+
expiresAt: {
|
|
75
|
+
type: DataTypes.DATE,
|
|
76
|
+
// null = kalΔ±cΔ± hafΔ±za
|
|
77
|
+
},
|
|
78
|
+
tags: {
|
|
79
|
+
type: DataTypes.JSON,
|
|
80
|
+
defaultValue: []
|
|
81
|
+
}
|
|
82
|
+
});
|
|
83
|
+
|
|
84
|
+
// Fiyat Karar GeΓ§miΕi
|
|
85
|
+
this.models.PricingDecision = this.db.define('PricingDecision', {
|
|
86
|
+
id: {
|
|
87
|
+
type: DataTypes.UUID,
|
|
88
|
+
defaultValue: DataTypes.UUIDV4,
|
|
89
|
+
primaryKey: true
|
|
90
|
+
},
|
|
91
|
+
productId: DataTypes.STRING,
|
|
92
|
+
barcode: DataTypes.STRING,
|
|
93
|
+
platform: DataTypes.STRING,
|
|
94
|
+
previousPrice: DataTypes.FLOAT,
|
|
95
|
+
newPrice: DataTypes.FLOAT,
|
|
96
|
+
reason: DataTypes.TEXT,
|
|
97
|
+
factors: {
|
|
98
|
+
type: DataTypes.JSON,
|
|
99
|
+
// { competitorPrice, competitorStock, ourStock, margin, velocity }
|
|
100
|
+
},
|
|
101
|
+
outcome: {
|
|
102
|
+
type: DataTypes.STRING,
|
|
103
|
+
// applied, rejected, pending
|
|
104
|
+
},
|
|
105
|
+
profitImpact: DataTypes.FLOAT
|
|
106
|
+
});
|
|
107
|
+
|
|
108
|
+
// ΓrΓΌn BaΔlamΔ±
|
|
109
|
+
this.models.ProductContext = this.db.define('ProductContext', {
|
|
110
|
+
id: {
|
|
111
|
+
type: DataTypes.UUID,
|
|
112
|
+
defaultValue: DataTypes.UUIDV4,
|
|
113
|
+
primaryKey: true
|
|
114
|
+
},
|
|
115
|
+
barcode: {
|
|
116
|
+
type: DataTypes.STRING,
|
|
117
|
+
unique: true
|
|
118
|
+
},
|
|
119
|
+
name: DataTypes.STRING,
|
|
120
|
+
category: DataTypes.STRING,
|
|
121
|
+
avgSalePrice: DataTypes.FLOAT,
|
|
122
|
+
avgCost: DataTypes.FLOAT,
|
|
123
|
+
seasonality: DataTypes.JSON,
|
|
124
|
+
competitorHistory: DataTypes.JSON,
|
|
125
|
+
customerSentiment: {
|
|
126
|
+
type: DataTypes.JSON,
|
|
127
|
+
// { positive: 0.8, negative: 0.2, topComplaints: [] }
|
|
128
|
+
},
|
|
129
|
+
priceElasticity: DataTypes.FLOAT,
|
|
130
|
+
optimalPriceRange: DataTypes.JSON
|
|
131
|
+
});
|
|
132
|
+
|
|
133
|
+
// KonuΕma GeΓ§miΕi (Session bazlΔ±)
|
|
134
|
+
this.models.ConversationMemory = this.db.define('ConversationMemory', {
|
|
135
|
+
id: {
|
|
136
|
+
type: DataTypes.UUID,
|
|
137
|
+
defaultValue: DataTypes.UUIDV4,
|
|
138
|
+
primaryKey: true
|
|
139
|
+
},
|
|
140
|
+
sessionKey: DataTypes.STRING,
|
|
141
|
+
userId: DataTypes.STRING,
|
|
142
|
+
channel: DataTypes.STRING,
|
|
143
|
+
role: {
|
|
144
|
+
type: DataTypes.STRING,
|
|
145
|
+
// user, assistant
|
|
146
|
+
},
|
|
147
|
+
content: DataTypes.TEXT,
|
|
148
|
+
intent: DataTypes.STRING,
|
|
149
|
+
entities: DataTypes.JSON,
|
|
150
|
+
actionTaken: DataTypes.STRING
|
|
151
|
+
});
|
|
152
|
+
|
|
153
|
+
// ΓΔrenilen Kurallar
|
|
154
|
+
this.models.LearnedRule = this.db.define('LearnedRule', {
|
|
155
|
+
id: {
|
|
156
|
+
type: DataTypes.UUID,
|
|
157
|
+
defaultValue: DataTypes.UUIDV4,
|
|
158
|
+
primaryKey: true
|
|
159
|
+
},
|
|
160
|
+
trigger: DataTypes.TEXT,
|
|
161
|
+
condition: DataTypes.JSON,
|
|
162
|
+
action: DataTypes.TEXT,
|
|
163
|
+
confidence: {
|
|
164
|
+
type: DataTypes.FLOAT,
|
|
165
|
+
defaultValue: 0.5
|
|
166
|
+
},
|
|
167
|
+
usageCount: {
|
|
168
|
+
type: DataTypes.INTEGER,
|
|
169
|
+
defaultValue: 0
|
|
170
|
+
},
|
|
171
|
+
successRate: {
|
|
172
|
+
type: DataTypes.FLOAT,
|
|
173
|
+
defaultValue: 0.5
|
|
174
|
+
}
|
|
175
|
+
});
|
|
176
|
+
|
|
177
|
+
await this.db.sync({ alter: true });
|
|
178
|
+
this.initialized = true;
|
|
179
|
+
this.logger.info('π§ Hippocampus veritabanΔ± hazΔ±r.');
|
|
180
|
+
|
|
181
|
+
// HafΔ±za konsolidasyonu zamanlayΔ±cΔ±sΔ± (her gece)
|
|
182
|
+
this._startConsolidation();
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
// βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
|
186
|
+
// HAFIZA KAYDETME
|
|
187
|
+
// βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
|
188
|
+
|
|
189
|
+
async remember(type, content, context = {}, options = {}) {
|
|
190
|
+
const memory = await this.models.Memory.create({
|
|
191
|
+
type,
|
|
192
|
+
content: typeof content === 'string' ? content : JSON.stringify(content),
|
|
193
|
+
context,
|
|
194
|
+
importance: options.importance || this._calculateImportance(type, content),
|
|
195
|
+
tags: options.tags || [],
|
|
196
|
+
expiresAt: options.temporary ? new Date(Date.now() + 24 * 60 * 60 * 1000) : null
|
|
197
|
+
});
|
|
198
|
+
|
|
199
|
+
this.logger.debug(`πΎ HafΔ±za kaydedildi: ${type} - ${memory.id}`);
|
|
200
|
+
return memory;
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
async recordPricingDecision(decision) {
|
|
204
|
+
return await this.models.PricingDecision.create(decision);
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
async updateProductContext(barcode, updates) {
|
|
208
|
+
const [context, created] = await this.models.ProductContext.findOrCreate({
|
|
209
|
+
where: { barcode },
|
|
210
|
+
defaults: { barcode, ...updates }
|
|
211
|
+
});
|
|
212
|
+
|
|
213
|
+
if (!created) {
|
|
214
|
+
await context.update(updates);
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
return context;
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
async recordConversation(sessionKey, userId, channel, role, content, metadata = {}) {
|
|
221
|
+
return await this.models.ConversationMemory.create({
|
|
222
|
+
sessionKey,
|
|
223
|
+
userId,
|
|
224
|
+
channel,
|
|
225
|
+
role,
|
|
226
|
+
content,
|
|
227
|
+
intent: metadata.intent,
|
|
228
|
+
entities: metadata.entities,
|
|
229
|
+
actionTaken: metadata.action
|
|
230
|
+
});
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
// βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
|
234
|
+
// HAFIZA ARAMA
|
|
235
|
+
// βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
|
236
|
+
|
|
237
|
+
async search({ query, type, limit = 10, minImportance = 0 }) {
|
|
238
|
+
const where = {};
|
|
239
|
+
|
|
240
|
+
if (type && type !== 'all') {
|
|
241
|
+
where.type = type;
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
if (minImportance > 0) {
|
|
245
|
+
where.importance = { [Op.gte]: minImportance };
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
// Basit metin aramasΔ± (ileride vektΓΆr aramasΔ± eklenebilir)
|
|
249
|
+
if (query) {
|
|
250
|
+
where.content = { [Op.like]: `%${query}%` };
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
const memories = await this.models.Memory.findAll({
|
|
254
|
+
where,
|
|
255
|
+
order: [['importance', 'DESC'], ['createdAt', 'DESC']],
|
|
256
|
+
limit
|
|
257
|
+
});
|
|
258
|
+
|
|
259
|
+
// EriΕim sayacΔ±nΔ± gΓΌncelle
|
|
260
|
+
for (const mem of memories) {
|
|
261
|
+
await mem.update({
|
|
262
|
+
accessCount: mem.accessCount + 1,
|
|
263
|
+
lastAccessed: new Date()
|
|
264
|
+
});
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
return memories.map(m => ({
|
|
268
|
+
id: m.id,
|
|
269
|
+
type: m.type,
|
|
270
|
+
content: m.content,
|
|
271
|
+
context: m.context,
|
|
272
|
+
importance: m.importance,
|
|
273
|
+
createdAt: m.createdAt
|
|
274
|
+
}));
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
async getProductContext(barcode) {
|
|
278
|
+
return await this.models.ProductContext.findOne({ where: { barcode } });
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
async getPricingHistory(barcode, limit = 10) {
|
|
282
|
+
return await this.models.PricingDecision.findAll({
|
|
283
|
+
where: { barcode },
|
|
284
|
+
order: [['createdAt', 'DESC']],
|
|
285
|
+
limit
|
|
286
|
+
});
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
async getRecentConversations(sessionKey, limit = 20) {
|
|
290
|
+
return await this.models.ConversationMemory.findAll({
|
|
291
|
+
where: { sessionKey },
|
|
292
|
+
order: [['createdAt', 'DESC']],
|
|
293
|
+
limit
|
|
294
|
+
});
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
async getLearnedRules(trigger) {
|
|
298
|
+
return await this.models.LearnedRule.findAll({
|
|
299
|
+
where: {
|
|
300
|
+
trigger: { [Op.like]: `%${trigger}%` },
|
|
301
|
+
confidence: { [Op.gte]: 0.6 }
|
|
302
|
+
},
|
|
303
|
+
order: [['confidence', 'DESC'], ['usageCount', 'DESC']]
|
|
304
|
+
});
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
// βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
|
308
|
+
// BAΔLAMSAL HATIRLATMA
|
|
309
|
+
// βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
|
310
|
+
|
|
311
|
+
async getRelevantContext(input, options = {}) {
|
|
312
|
+
const context = {
|
|
313
|
+
recentDecisions: [],
|
|
314
|
+
productHistory: null,
|
|
315
|
+
relatedMemories: [],
|
|
316
|
+
applicableRules: []
|
|
317
|
+
};
|
|
318
|
+
|
|
319
|
+
// ΓrΓΌn barkodu varsa ΓΌrΓΌn baΔlamΔ±nΔ± al
|
|
320
|
+
if (options.barcode) {
|
|
321
|
+
context.productHistory = await this.getProductContext(options.barcode);
|
|
322
|
+
context.recentDecisions = await this.getPricingHistory(options.barcode, 5);
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
// Δ°lgili hafΔ±zalarΔ± ara
|
|
326
|
+
context.relatedMemories = await this.search({
|
|
327
|
+
query: input,
|
|
328
|
+
type: options.type || 'all',
|
|
329
|
+
limit: 5,
|
|
330
|
+
minImportance: 0.3
|
|
331
|
+
});
|
|
332
|
+
|
|
333
|
+
// Uygulanabilir kurallarΔ± bul
|
|
334
|
+
context.applicableRules = await this.getLearnedRules(input);
|
|
335
|
+
|
|
336
|
+
return context;
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
// βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
|
340
|
+
// ΓΔRENME & KONSOLΔ°DASYON
|
|
341
|
+
// βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
|
342
|
+
|
|
343
|
+
async learnRule(trigger, condition, action) {
|
|
344
|
+
const existing = await this.models.LearnedRule.findOne({
|
|
345
|
+
where: { trigger, action }
|
|
346
|
+
});
|
|
347
|
+
|
|
348
|
+
if (existing) {
|
|
349
|
+
await existing.update({
|
|
350
|
+
usageCount: existing.usageCount + 1,
|
|
351
|
+
confidence: Math.min(1, existing.confidence + 0.05)
|
|
352
|
+
});
|
|
353
|
+
return existing;
|
|
354
|
+
}
|
|
355
|
+
|
|
356
|
+
return await this.models.LearnedRule.create({
|
|
357
|
+
trigger,
|
|
358
|
+
condition,
|
|
359
|
+
action,
|
|
360
|
+
confidence: 0.5
|
|
361
|
+
});
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
async recordRuleOutcome(ruleId, success) {
|
|
365
|
+
const rule = await this.models.LearnedRule.findByPk(ruleId);
|
|
366
|
+
if (!rule) return;
|
|
367
|
+
|
|
368
|
+
const newSuccessRate = (rule.successRate * rule.usageCount + (success ? 1 : 0)) / (rule.usageCount + 1);
|
|
369
|
+
const newConfidence = success
|
|
370
|
+
? Math.min(1, rule.confidence + 0.1)
|
|
371
|
+
: Math.max(0, rule.confidence - 0.1);
|
|
372
|
+
|
|
373
|
+
await rule.update({
|
|
374
|
+
usageCount: rule.usageCount + 1,
|
|
375
|
+
successRate: newSuccessRate,
|
|
376
|
+
confidence: newConfidence
|
|
377
|
+
});
|
|
378
|
+
}
|
|
379
|
+
|
|
380
|
+
_startConsolidation() {
|
|
381
|
+
// Her gece saat 3'te Γ§alΔ±Ε
|
|
382
|
+
const now = new Date();
|
|
383
|
+
const night = new Date(now);
|
|
384
|
+
night.setHours(3, 0, 0, 0);
|
|
385
|
+
if (night <= now) night.setDate(night.getDate() + 1);
|
|
386
|
+
|
|
387
|
+
const delay = night - now;
|
|
388
|
+
|
|
389
|
+
setTimeout(() => {
|
|
390
|
+
this._consolidate();
|
|
391
|
+
// Sonra her 24 saatte bir
|
|
392
|
+
setInterval(() => this._consolidate(), 24 * 60 * 60 * 1000);
|
|
393
|
+
}, delay);
|
|
394
|
+
}
|
|
395
|
+
|
|
396
|
+
async _consolidate() {
|
|
397
|
+
this.logger.info('π§ HafΔ±za konsolidasyonu baΕlΔ±yor...');
|
|
398
|
+
|
|
399
|
+
// 1. SΓΌresi dolmuΕ hafΔ±zalarΔ± sil
|
|
400
|
+
await this.models.Memory.destroy({
|
|
401
|
+
where: {
|
|
402
|
+
expiresAt: { [Op.lt]: new Date() }
|
|
403
|
+
}
|
|
404
|
+
});
|
|
405
|
+
|
|
406
|
+
// 2. DΓΌΕΓΌk ΓΆnemli ve eriΕilmeyen hafΔ±zalarΔ± "unut"
|
|
407
|
+
const oldDate = new Date(Date.now() - 90 * 24 * 60 * 60 * 1000); // 90 gΓΌn
|
|
408
|
+
await this.models.Memory.destroy({
|
|
409
|
+
where: {
|
|
410
|
+
importance: { [Op.lt]: 0.3 },
|
|
411
|
+
accessCount: { [Op.lt]: 3 },
|
|
412
|
+
lastAccessed: { [Op.lt]: oldDate }
|
|
413
|
+
}
|
|
414
|
+
});
|
|
415
|
+
|
|
416
|
+
// 3. DΓΌΕΓΌk gΓΌvenilirlikli kurallarΔ± sil
|
|
417
|
+
await this.models.LearnedRule.destroy({
|
|
418
|
+
where: {
|
|
419
|
+
confidence: { [Op.lt]: 0.2 },
|
|
420
|
+
usageCount: { [Op.gt]: 10 }
|
|
421
|
+
}
|
|
422
|
+
});
|
|
423
|
+
|
|
424
|
+
this.logger.info('π§ HafΔ±za konsolidasyonu tamamlandΔ±.');
|
|
425
|
+
}
|
|
426
|
+
|
|
427
|
+
_calculateImportance(type, content) {
|
|
428
|
+
// Tip bazlΔ± temel ΓΆnem
|
|
429
|
+
const baseImportance = {
|
|
430
|
+
decision: 0.8,
|
|
431
|
+
price_change: 0.7,
|
|
432
|
+
insight: 0.6,
|
|
433
|
+
rule: 0.9,
|
|
434
|
+
product: 0.5,
|
|
435
|
+
conversation: 0.3
|
|
436
|
+
};
|
|
437
|
+
|
|
438
|
+
return baseImportance[type] || 0.5;
|
|
439
|
+
}
|
|
440
|
+
|
|
441
|
+
// βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
|
442
|
+
// Δ°STATΔ°STΔ°KLER
|
|
443
|
+
// βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
|
444
|
+
|
|
445
|
+
async getStats() {
|
|
446
|
+
const memoryCount = await this.models.Memory.count();
|
|
447
|
+
const decisionCount = await this.models.PricingDecision.count();
|
|
448
|
+
const productCount = await this.models.ProductContext.count();
|
|
449
|
+
const ruleCount = await this.models.LearnedRule.count();
|
|
450
|
+
|
|
451
|
+
return {
|
|
452
|
+
memories: memoryCount,
|
|
453
|
+
decisions: decisionCount,
|
|
454
|
+
products: productCount,
|
|
455
|
+
rules: ruleCount,
|
|
456
|
+
initialized: this.initialized
|
|
457
|
+
};
|
|
458
|
+
}
|
|
459
|
+
|
|
460
|
+
async close() {
|
|
461
|
+
if (this.db) {
|
|
462
|
+
await this.db.close();
|
|
463
|
+
}
|
|
464
|
+
}
|
|
465
|
+
}
|