mycai 1.0.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.
@@ -0,0 +1,2703 @@
1
+ // core/morphology.js
2
+ var TurkishMorphology = class {
3
+ constructor(roots = []) {
4
+ this.onVowels = /* @__PURE__ */ new Set(["e", "i", "\xF6", "\xFC"]);
5
+ this.backVowels = /* @__PURE__ */ new Set(["a", "\u0131", "o", "u"]);
6
+ this.allVowels = /* @__PURE__ */ new Set(["a", "e", "\u0131", "i", "o", "\xF6", "u", "\xFC"]);
7
+ this.customRoots = roots;
8
+ this.suffixFeatures = {
9
+ // Plural
10
+ "ler": { number: "plural" },
11
+ "lar": { number: "plural" },
12
+ // Cases
13
+ "den": { case: "ablative" },
14
+ "dan": { case: "ablative" },
15
+ "ten": { case: "ablative" },
16
+ "tan": { case: "ablative" },
17
+ "de": { case: "locative" },
18
+ "da": { case: "locative" },
19
+ "te": { case: "locative" },
20
+ "ta": { case: "locative" },
21
+ "e": { case: "dative" },
22
+ "a": { case: "dative" },
23
+ "in": { case: "genitive" },
24
+ "\u0131n": { case: "genitive" },
25
+ "un": { case: "genitive" },
26
+ "\xFCn": { case: "genitive" },
27
+ // Possessions
28
+ "im": { possession: "1sg" },
29
+ "\u0131m": { possession: "1sg" },
30
+ "um": { possession: "1sg" },
31
+ "\xFCm": { possession: "1sg" },
32
+ "in": { possession: "2sg" },
33
+ // overlaps with genitive, handled dynamically
34
+ "\u0131n": { possession: "2sg" },
35
+ "un": { possession: "2sg" },
36
+ "\xFCn": { possession: "2sg" },
37
+ "i": { possession: "3sg" },
38
+ "\u0131": { possession: "3sg" },
39
+ "u": { possession: "3sg" },
40
+ "\xFC": { possession: "3sg" },
41
+ "imiz": { possession: "1pl" },
42
+ "\u0131m\u0131z": { possession: "1pl" },
43
+ "umuz": { possession: "1pl" },
44
+ "\xFCm\xFCz": { possession: "1pl" },
45
+ "iniz": { possession: "2pl" },
46
+ "\u0131n\u0131z": { possession: "2pl" },
47
+ "\xFCn\xFCz": { possession: "2pl" },
48
+ "unuz": { possession: "2pl" },
49
+ "leri": { possession: "3pl" },
50
+ "lar\u0131": { possession: "3pl" },
51
+ // Tense/Aspect/Mood
52
+ "iyor": { tense: "present" },
53
+ "\u0131yor": { tense: "present" },
54
+ "uyor": { tense: "present" },
55
+ "\xFCyor": { tense: "present" },
56
+ "ecek": { tense: "future" },
57
+ "acak": { tense: "future" },
58
+ "mi\u015F": { tense: "narrative_past" },
59
+ "m\u0131\u015F": { tense: "narrative_past" },
60
+ "m\xFC\u015F": { tense: "narrative_past" },
61
+ "mu\u015F": { tense: "narrative_past" },
62
+ "di": { tense: "past" },
63
+ "d\u0131": { tense: "past" },
64
+ "du": { tense: "past" },
65
+ "d\xFC": { tense: "past" },
66
+ "ti": { tense: "past" },
67
+ "t\u0131": { tense: "past" },
68
+ "tu": { tense: "past" },
69
+ "t\xFC": { tense: "past" },
70
+ // Infinitives and derivations
71
+ "mek": { aspect: "infinitive" },
72
+ "mak": { aspect: "infinitive" },
73
+ "lik": { derivation: "noun" },
74
+ "l\u0131k": { derivation: "noun" },
75
+ "luk": { derivation: "noun" },
76
+ "l\xFCk": { derivation: "noun" },
77
+ "li": { derivation: "with" },
78
+ "l\u0131": { derivation: "with" },
79
+ "lu": { derivation: "with" },
80
+ "l\xFC": { derivation: "with" },
81
+ "siz": { derivation: "without" },
82
+ "s\u0131z": { derivation: "without" },
83
+ "suz": { derivation: "without" },
84
+ "s\xFCz": { derivation: "without" },
85
+ "ce": { case: "equative" },
86
+ "ca": { case: "equative" },
87
+ "\xE7a": { case: "equative" },
88
+ "\xE7e": { case: "equative" },
89
+ // Copula (Assertive)
90
+ "dir": { copula: "assertive" },
91
+ "d\u0131r": { copula: "assertive" },
92
+ "dur": { copula: "assertive" },
93
+ "d\xFCr": { copula: "assertive" },
94
+ "tir": { copula: "assertive" },
95
+ "t\u0131r": { copula: "assertive" },
96
+ "tur": { copula: "assertive" },
97
+ "t\xFCr": { copula: "assertive" },
98
+ // Relative Modifier
99
+ "ki": { pronoun: "relative" },
100
+ "kiler": { pronoun: "relative_plural" },
101
+ // Adverbial / Manner
102
+ "cesine": { aspect: "manner" },
103
+ "cas\u0131na": { aspect: "manner" },
104
+ "ken": { adverb: "temporal" },
105
+ // Moods
106
+ "meli": { mood: "necessity" },
107
+ "mal\u0131": { mood: "necessity" },
108
+ "se": { mood: "conditional" },
109
+ "sa": { mood: "conditional" }
110
+ };
111
+ this.suffixesKnown = Object.keys(this.suffixFeatures).sort((a, b) => b.length - a.length);
112
+ }
113
+ // Allow dynamic roots fallback
114
+ get roots() {
115
+ if (this.customRoots && this.customRoots.length > 0) {
116
+ return this.customRoots;
117
+ }
118
+ if (typeof globalThis !== "undefined" && globalThis.TR_CORPUS_ROOTS) {
119
+ return globalThis.TR_CORPUS_ROOTS;
120
+ }
121
+ return [
122
+ // Genel yaygın kökler
123
+ "ev",
124
+ "g\xF6l",
125
+ "araba",
126
+ "kitap",
127
+ "el",
128
+ "ba\u015F",
129
+ "git",
130
+ "gel",
131
+ "yap",
132
+ "al",
133
+ "ver",
134
+ "g\xF6r",
135
+ "bilgisayar",
136
+ "bil",
137
+ "\xF6\u011Fren",
138
+ "anla",
139
+ "d\xFC\u015F\xFCn",
140
+ "b\xFCy\xFCk",
141
+ "k\xFC\xE7\xFCk",
142
+ "g\xFCzel",
143
+ "iyi",
144
+ "k\xF6t\xFC",
145
+ "yapay",
146
+ "zeka",
147
+ "beyin",
148
+ "sinir",
149
+ "dil",
150
+ "kelime",
151
+ "c\xFCmle",
152
+ "t\xFCrk\xE7e",
153
+ "bilim",
154
+ "teknik",
155
+ "okul",
156
+ "\xF6\u011Frenci",
157
+ "\xF6\u011Fretmen",
158
+ "yaz\u0131l\u0131m",
159
+ "donan\u0131m",
160
+ "renk",
161
+ // Vücut / anatomi
162
+ "ayak",
163
+ "g\xF6z",
164
+ "kulak",
165
+ "diz",
166
+ "omuz",
167
+ "kar\u0131n",
168
+ "g\xF6\u011F\xFCs",
169
+ "s\u0131rt",
170
+ "boyun",
171
+ "kol",
172
+ "bacak",
173
+ "parmak",
174
+ "bilek",
175
+ "topuk",
176
+ "al\u0131n",
177
+ "bel",
178
+ "di\u015F",
179
+ "burun",
180
+ "a\u011F\u0131z",
181
+ "ci\u011Fer",
182
+ "kalp",
183
+ "akci\u011Fer",
184
+ "mide",
185
+ "b\xF6brek",
186
+ "karaci\u011Fer",
187
+ "damar",
188
+ // Tıbbi terimler
189
+ "hasta",
190
+ "doktor",
191
+ "hem\u015Fire",
192
+ "ila\xE7",
193
+ "doz",
194
+ "tan\u0131",
195
+ "tedavi",
196
+ "ameliyat",
197
+ "hastal\u0131k",
198
+ "a\u011Fr\u0131",
199
+ "\u015Fi\u015Flik",
200
+ "ate\u015F",
201
+ "nab\u0131z",
202
+ "tansiyon",
203
+ "kan",
204
+ "idrar",
205
+ "re\xE7ete",
206
+ "a\u015F\u0131",
207
+ "vir\xFCs",
208
+ "enfeksiyon",
209
+ "yara",
210
+ "k\u0131r\u0131k",
211
+ "\xF6dem",
212
+ "alerji",
213
+ "\u015Feker",
214
+ "diyabet",
215
+ "gebelik",
216
+ "do\u011Fum",
217
+ "\xF6l\xE7\xFCm",
218
+ "muayene",
219
+ "rapor",
220
+ "tahlil",
221
+ // Genel isimler
222
+ "yol",
223
+ "su",
224
+ "ekmek",
225
+ "para",
226
+ "i\u015F",
227
+ "g\xFCn",
228
+ "y\u0131l",
229
+ "saat",
230
+ "hafta",
231
+ "ay",
232
+ "yer",
233
+ "\u015Fehir",
234
+ "\xFClke",
235
+ "k\xF6y",
236
+ "insan",
237
+ "kad\u0131n",
238
+ "erkek",
239
+ "\xE7ocuk",
240
+ "anne",
241
+ "baba",
242
+ "ad",
243
+ "isim",
244
+ "aile",
245
+ "soru",
246
+ "cevap",
247
+ "kay\u0131t",
248
+ "bilgi",
249
+ "durum",
250
+ "sonu\xE7",
251
+ // Sıfatlar ve zarflar
252
+ "yeni",
253
+ "eski",
254
+ "uzun",
255
+ "k\u0131sa",
256
+ "s\u0131k",
257
+ "az",
258
+ "\xE7ok",
259
+ "son",
260
+ "ilk",
261
+ "her",
262
+ // Fiiller (ek kökler)
263
+ "oku",
264
+ "yaz",
265
+ "bak",
266
+ "\xE7al\u0131\u015F",
267
+ "ye",
268
+ "i\xE7",
269
+ "uyu",
270
+ "kalk",
271
+ "otur",
272
+ "ko\u015F",
273
+ "sor",
274
+ "s\xF6yle",
275
+ "dinle",
276
+ "bekle",
277
+ "ba\u015Fla",
278
+ "bitir",
279
+ "a\xE7",
280
+ "kapat",
281
+ "getir",
282
+ "g\xF6t\xFCr",
283
+ "koy",
284
+ "\xE7\u0131kar",
285
+ "kaydet",
286
+ "g\xFCncelle",
287
+ "kontrol"
288
+ ];
289
+ }
290
+ determineVowelHarmony(root) {
291
+ const lv = this.getLastVowel(root);
292
+ return lv && this.onVowels.has(lv) ? "front" : "back";
293
+ }
294
+ getLastVowel(word) {
295
+ for (let i = word.length - 1; i >= 0; i--) {
296
+ if (this.allVowels.has(word[i])) return word[i];
297
+ }
298
+ return null;
299
+ }
300
+ normalize(text) {
301
+ return text.toLowerCase().trim().replace(/i̇/g, "i").replace(/[^a-zçgğıoöşuüâîû\s]/g, "");
302
+ }
303
+ analyze(word) {
304
+ const w = this.normalize(word).split(/\s+/)[0];
305
+ const result = {
306
+ word: w,
307
+ root: w,
308
+ suffixes: [],
309
+ harmony: this.determineVowelHarmony(w),
310
+ morphemes: [],
311
+ features: {},
312
+ vowelCount: 0,
313
+ syllables: []
314
+ };
315
+ if (!w) return result;
316
+ result.vowelCount = [...w].filter((c) => this.allVowels.has(c)).length;
317
+ result.syllables = this.syllabify(w);
318
+ let foundRoot = w;
319
+ let foundSuffs = [];
320
+ for (const root of this.roots) {
321
+ let isMatch = false;
322
+ let matchedLength = root.length;
323
+ if (w.startsWith(root)) {
324
+ isMatch = true;
325
+ } else {
326
+ const last = root[root.length - 1];
327
+ if (["p", "\xE7", "t", "k"].includes(last)) {
328
+ const stem = root.slice(0, -1);
329
+ let mutatedStem = "";
330
+ if (last === "p") mutatedStem = stem + "b";
331
+ else if (last === "\xE7") mutatedStem = stem + "c";
332
+ else if (last === "t") mutatedStem = stem + "d";
333
+ else if (last === "k") mutatedStem = stem + "\u011F";
334
+ if (root === "renk") mutatedStem = stem + "g";
335
+ if (w.startsWith(mutatedStem) && w.length > root.length) {
336
+ const nextChar = w[mutatedStem.length];
337
+ if (this.allVowels.has(nextChar)) {
338
+ isMatch = true;
339
+ matchedLength = mutatedStem.length;
340
+ }
341
+ }
342
+ }
343
+ }
344
+ if (isMatch && root.length >= 2 && root.length < w.length) {
345
+ const suffix = w.slice(matchedLength);
346
+ if (root.length > (foundRoot === w ? 0 : foundRoot.length)) {
347
+ foundRoot = root;
348
+ foundSuffs = this.splitSuffix(suffix);
349
+ }
350
+ }
351
+ }
352
+ result.root = foundRoot;
353
+ result.suffixes = foundSuffs;
354
+ result.morphemes = [foundRoot, ...foundSuffs].filter(Boolean);
355
+ result.harmony = this.determineVowelHarmony(foundRoot);
356
+ foundSuffs.forEach((suff) => {
357
+ const feat = this.suffixFeatures[suff];
358
+ if (feat) {
359
+ Object.assign(result.features, feat);
360
+ }
361
+ });
362
+ return result;
363
+ }
364
+ splitSuffix(suffix) {
365
+ if (!suffix) return [];
366
+ const result = [];
367
+ let rem = suffix;
368
+ while (rem.length > 0) {
369
+ let matched = false;
370
+ for (const s of this.suffixesKnown) {
371
+ if (rem.endsWith(s)) {
372
+ result.unshift(s);
373
+ rem = rem.slice(0, rem.length - s.length);
374
+ matched = true;
375
+ break;
376
+ }
377
+ }
378
+ if (!matched) {
379
+ result.unshift(rem);
380
+ break;
381
+ }
382
+ }
383
+ return result;
384
+ }
385
+ syllabify(word) {
386
+ const w = this.normalize(word);
387
+ if (!w) return [];
388
+ const vowelIndices = [];
389
+ for (let i = 0; i < w.length; i++) {
390
+ if (this.allVowels.has(w[i])) {
391
+ vowelIndices.push(i);
392
+ }
393
+ }
394
+ if (vowelIndices.length <= 1) {
395
+ return [w];
396
+ }
397
+ const syllables = [];
398
+ let start = 0;
399
+ for (let k = 0; k < vowelIndices.length - 1; k++) {
400
+ const v1 = vowelIndices[k];
401
+ const v2 = vowelIndices[k + 1];
402
+ const consonantCount = v2 - v1 - 1;
403
+ let splitPoint;
404
+ if (consonantCount === 0) {
405
+ splitPoint = v1 + 1;
406
+ } else if (consonantCount === 1) {
407
+ splitPoint = v1 + 1;
408
+ } else if (consonantCount === 2) {
409
+ splitPoint = v1 + 2;
410
+ } else {
411
+ splitPoint = v2 - 1;
412
+ }
413
+ syllables.push(w.slice(start, splitPoint));
414
+ start = splitPoint;
415
+ }
416
+ syllables.push(w.slice(start));
417
+ return syllables.filter(Boolean);
418
+ }
419
+ syllabifyPhrase(phrase) {
420
+ const words = phrase.toLowerCase().trim().split(/\s+/).filter(Boolean);
421
+ if (words.length === 0) return [];
422
+ if (words.length === 1) return this.syllabify(words[0]);
423
+ const resultSyllables = [];
424
+ const processedWords = [...words];
425
+ for (let i = 0; i < processedWords.length - 1; i++) {
426
+ const w1 = processedWords[i];
427
+ const w2 = processedWords[i + 1];
428
+ if (w1.length === 0 || w2.length === 0) continue;
429
+ const lastChar = w1[w1.length - 1];
430
+ const firstChar = w2[0];
431
+ if (!this.allVowels.has(lastChar) && this.allVowels.has(firstChar)) {
432
+ processedWords[i] = w1.slice(0, -1);
433
+ processedWords[i + 1] = lastChar + w2;
434
+ }
435
+ }
436
+ for (const w of processedWords) {
437
+ if (w.length > 0) {
438
+ resultSyllables.push(...this.syllabify(w));
439
+ }
440
+ }
441
+ return resultSyllables;
442
+ }
443
+ };
444
+
445
+ // core/hdc.js
446
+ var Representation = class {
447
+ constructor(type, values, D) {
448
+ this.type = type;
449
+ this.values = values;
450
+ this.D = D;
451
+ }
452
+ // Calculate memory footprint in bytes
453
+ memorySize() {
454
+ return this.values.byteLength;
455
+ }
456
+ };
457
+ var HDCEngine = class {
458
+ constructor(D = 8192) {
459
+ this.D = D;
460
+ }
461
+ // ── GENERATION / RANDOM RANDOM VECTORS ─────────────────────
462
+ generateRandom(type) {
463
+ if (type === "binary") {
464
+ const vals2 = new Uint8Array(this.D);
465
+ for (let i = 0; i < this.D; i++) {
466
+ vals2[i] = Math.random() < 0.5 ? 0 : 1;
467
+ }
468
+ return new Representation("binary", vals2, this.D);
469
+ }
470
+ if (type === "bipolar") {
471
+ const vals2 = new Float32Array(this.D);
472
+ for (let i = 0; i < this.D; i++) {
473
+ vals2[i] = Math.random() < 0.5 ? -1 : 1;
474
+ }
475
+ return new Representation("bipolar", vals2, this.D);
476
+ }
477
+ if (type === "real") {
478
+ const vals2 = new Float32Array(this.D);
479
+ for (let i = 0; i < this.D; i++) {
480
+ let u = 0, v = 0;
481
+ while (u === 0) u = Math.random();
482
+ while (v === 0) v = Math.random();
483
+ vals2[i] = Math.sqrt(-2 * Math.log(u)) * Math.cos(2 * Math.PI * v);
484
+ }
485
+ return new Representation("real", vals2, this.D);
486
+ }
487
+ const vals = new Float32Array(this.D);
488
+ for (let i = 0; i < this.D; i++) {
489
+ vals[i] = Math.random() * 2 * Math.PI;
490
+ }
491
+ return new Representation("complex", vals, this.D);
492
+ }
493
+ generateSeeded(type, key) {
494
+ let seed = 0;
495
+ for (let i = 0; i < key.length; i++) {
496
+ seed = seed * 31 + key.charCodeAt(i) >>> 0;
497
+ }
498
+ const nextRand = () => {
499
+ seed = seed * 1664525 + 1013904223 >>> 0;
500
+ return (seed >>> 8) / 16777216;
501
+ };
502
+ if (type === "binary") {
503
+ const vals2 = new Uint8Array(this.D);
504
+ for (let i = 0; i < this.D; i++) {
505
+ vals2[i] = nextRand() < 0.5 ? 0 : 1;
506
+ }
507
+ return new Representation("binary", vals2, this.D);
508
+ }
509
+ if (type === "bipolar") {
510
+ const vals2 = new Float32Array(this.D);
511
+ for (let i = 0; i < this.D; i++) {
512
+ vals2[i] = nextRand() < 0.5 ? -1 : 1;
513
+ }
514
+ return new Representation("bipolar", vals2, this.D);
515
+ }
516
+ if (type === "real") {
517
+ const vals2 = new Float32Array(this.D);
518
+ for (let i = 0; i < this.D; i++) {
519
+ let u = 0, v = 0;
520
+ while (u === 0) u = nextRand();
521
+ while (v === 0) v = nextRand();
522
+ vals2[i] = Math.sqrt(-2 * Math.log(u)) * Math.cos(2 * Math.PI * v);
523
+ }
524
+ return new Representation("real", vals2, this.D);
525
+ }
526
+ const vals = new Float32Array(this.D);
527
+ for (let i = 0; i < this.D; i++) {
528
+ vals[i] = nextRand() * 2 * Math.PI;
529
+ }
530
+ return new Representation("complex", vals, this.D);
531
+ }
532
+ // ── BINDING (Morfem Binding / Variable-Value Association) ──
533
+ bind(a, b) {
534
+ if (a.type !== b.type || a.D !== b.D) {
535
+ throw new Error("Representation mismatch for bind operation.");
536
+ }
537
+ const D = a.D;
538
+ if (a.type === "binary") {
539
+ const o2 = new Uint8Array(D);
540
+ for (let i = 0; i < D; i++) {
541
+ o2[i] = a.values[i] ^ b.values[i];
542
+ }
543
+ return new Representation("binary", o2, D);
544
+ }
545
+ if (a.type === "bipolar") {
546
+ const o2 = new Float32Array(D);
547
+ for (let i = 0; i < D; i++) {
548
+ o2[i] = a.values[i] * b.values[i];
549
+ }
550
+ return new Representation("bipolar", o2, D);
551
+ }
552
+ if (a.type === "real") {
553
+ const o2 = new Float32Array(D);
554
+ for (let i = 0; i < D; i++) {
555
+ o2[i] = a.values[i] * b.values[i];
556
+ }
557
+ return new Representation("real", o2, D);
558
+ }
559
+ const o = new Float32Array(D);
560
+ for (let i = 0; i < D; i++) {
561
+ o[i] = (a.values[i] + b.values[i]) % (2 * Math.PI);
562
+ }
563
+ return new Representation("complex", o, D);
564
+ }
565
+ unbind(a, b) {
566
+ if (a.type !== b.type || a.D !== b.D) {
567
+ throw new Error("Representation mismatch for unbind operation.");
568
+ }
569
+ const D = a.D;
570
+ if (a.type === "binary") {
571
+ return this.bind(a, b);
572
+ }
573
+ if (a.type === "bipolar") {
574
+ return this.bind(a, b);
575
+ }
576
+ if (a.type === "real") {
577
+ const o2 = new Float32Array(D);
578
+ for (let i = 0; i < D; i++) {
579
+ o2[i] = Math.abs(b.values[i]) > 1e-6 ? a.values[i] / b.values[i] : a.values[i];
580
+ }
581
+ return new Representation("real", o2, D);
582
+ }
583
+ const o = new Float32Array(D);
584
+ for (let i = 0; i < D; i++) {
585
+ let v = a.values[i] - b.values[i];
586
+ if (v < 0) v += 2 * Math.PI;
587
+ o[i] = v % (2 * Math.PI);
588
+ }
589
+ return new Representation("complex", o, D);
590
+ }
591
+ // ── BUNDLING (Superposition / Memory Accumulation) ──────────
592
+ bundle(reps) {
593
+ if (!reps || reps.length === 0) {
594
+ throw new Error("No representations to bundle.");
595
+ }
596
+ const type = reps[0].type;
597
+ const D = reps[0].D;
598
+ if (type === "binary") {
599
+ const o2 = new Uint8Array(D);
600
+ const counts = new Int32Array(D);
601
+ for (const r of reps) {
602
+ for (let i = 0; i < D; i++) {
603
+ counts[i] += r.values[i] === 1 ? 1 : -1;
604
+ }
605
+ }
606
+ for (let i = 0; i < D; i++) {
607
+ o2[i] = counts[i] >= 0 ? 1 : 0;
608
+ }
609
+ return new Representation("binary", o2, D);
610
+ }
611
+ if (type === "bipolar") {
612
+ const o2 = new Float32Array(D);
613
+ for (const r of reps) {
614
+ for (let i = 0; i < D; i++) {
615
+ o2[i] += r.values[i];
616
+ }
617
+ }
618
+ for (let i = 0; i < D; i++) {
619
+ o2[i] = o2[i] >= 0 ? 1 : -1;
620
+ }
621
+ return new Representation("bipolar", o2, D);
622
+ }
623
+ if (type === "real") {
624
+ const o2 = new Float32Array(D);
625
+ for (const r of reps) {
626
+ for (let i = 0; i < D; i++) {
627
+ o2[i] += r.values[i];
628
+ }
629
+ }
630
+ const n = reps.length;
631
+ for (let i = 0; i < D; i++) {
632
+ o2[i] /= n;
633
+ }
634
+ return new Representation("real", o2, D);
635
+ }
636
+ const re = new Float32Array(D);
637
+ const im = new Float32Array(D);
638
+ for (const r of reps) {
639
+ for (let i = 0; i < D; i++) {
640
+ re[i] += Math.cos(r.values[i]);
641
+ im[i] += Math.sin(r.values[i]);
642
+ }
643
+ }
644
+ const o = new Float32Array(D);
645
+ for (let i = 0; i < D; i++) {
646
+ let v = Math.atan2(im[i], re[i]);
647
+ if (v < 0) v += 2 * Math.PI;
648
+ o[i] = v;
649
+ }
650
+ return new Representation("complex", o, D);
651
+ }
652
+ // ── PERMUTATION (Shift operation / Order / Position binding) ─
653
+ permute(a, sh) {
654
+ const D = a.D;
655
+ const shift = (sh % D + D) % D;
656
+ const vals = new a.values.constructor(D);
657
+ for (let i = 0; i < D; i++) {
658
+ vals[(i + shift) % D] = a.values[i];
659
+ }
660
+ return new Representation(a.type, vals, D);
661
+ }
662
+ // ── SIMILARITY (Measured closeness) ──────────────────────────
663
+ similarity(a, b) {
664
+ if (a.type !== b.type || a.D !== b.D) {
665
+ return 0;
666
+ }
667
+ const D = a.D;
668
+ if (a.type === "binary") {
669
+ let hamming = 0;
670
+ for (let i = 0; i < D; i++) {
671
+ if (a.values[i] !== b.values[i]) hamming++;
672
+ }
673
+ return 1 - hamming / D;
674
+ }
675
+ if (a.type === "bipolar") {
676
+ let dot = 0;
677
+ for (let i = 0; i < D; i++) {
678
+ dot += a.values[i] * b.values[i];
679
+ }
680
+ return dot / D;
681
+ }
682
+ if (a.type === "real") {
683
+ let dot = 0, normA = 0, normB = 0;
684
+ for (let i = 0; i < D; i++) {
685
+ dot += a.values[i] * b.values[i];
686
+ normA += a.values[i] * a.values[i];
687
+ normB += b.values[i] * b.values[i];
688
+ }
689
+ const denom = Math.sqrt(normA) * Math.sqrt(normB);
690
+ return denom > 0 ? dot / denom : 0;
691
+ }
692
+ let sum = 0;
693
+ for (let i = 0; i < D; i++) {
694
+ sum += Math.cos(a.values[i] - b.values[i]);
695
+ }
696
+ return sum / D;
697
+ }
698
+ };
699
+
700
+ // core/memory_engine.js
701
+ import fs from "fs";
702
+
703
+ // core/spectral.js
704
+ var SpectralEngine = class {
705
+ constructor() {
706
+ }
707
+ // ── FFT CORE ALGORITHMS ────────────────────────────────────
708
+ _bitReverse(re, im) {
709
+ const n = re.length;
710
+ let j = 0;
711
+ for (let i = 0; i < n; i++) {
712
+ if (i < j) {
713
+ let temp = re[i];
714
+ re[i] = re[j];
715
+ re[j] = temp;
716
+ temp = im[i];
717
+ im[i] = im[j];
718
+ im[j] = temp;
719
+ }
720
+ let m = n >> 1;
721
+ while (m >= 2 && j >= m) {
722
+ j -= m;
723
+ m >>= 1;
724
+ }
725
+ j += m;
726
+ }
727
+ }
728
+ _fftCore(re, im, inverse = false) {
729
+ const n = re.length;
730
+ this._bitReverse(re, im);
731
+ for (let len = 2; len <= n; len <<= 1) {
732
+ const angle = 2 * Math.PI / len * (inverse ? 1 : -1);
733
+ const wlen_re = Math.cos(angle);
734
+ const wlen_im = Math.sin(angle);
735
+ for (let i = 0; i < n; i += len) {
736
+ let w_re = 1;
737
+ let w_im = 0;
738
+ const half = len >> 1;
739
+ for (let j = 0; j < half; j++) {
740
+ const u_re = re[i + j];
741
+ const u_im = im[i + j];
742
+ const t_re = re[i + j + half];
743
+ const t_im = im[i + j + half];
744
+ const v_re = t_re * w_re - t_im * w_im;
745
+ const v_im = t_re * w_im + t_im * w_re;
746
+ re[i + j] = u_re + v_re;
747
+ im[i + j] = u_im + v_im;
748
+ re[i + j + half] = u_re - v_re;
749
+ im[i + j + half] = u_im - v_im;
750
+ const next_w_re = w_re * wlen_re - w_im * wlen_im;
751
+ const next_w_im = w_re * wlen_im + w_im * wlen_re;
752
+ w_re = next_w_re;
753
+ w_im = next_w_im;
754
+ }
755
+ }
756
+ }
757
+ if (inverse) {
758
+ for (let i = 0; i < n; i++) {
759
+ re[i] /= n;
760
+ im[i] /= n;
761
+ }
762
+ }
763
+ }
764
+ // ── EXTERNAL API ───────────────────────────────────────────
765
+ spectralTransform(representation) {
766
+ const D = representation.D;
767
+ const re = new Float32Array(D);
768
+ const im = new Float32Array(D);
769
+ if (representation.type === "complex") {
770
+ for (let i = 0; i < D; i++) {
771
+ re[i] = Math.cos(representation.values[i]);
772
+ im[i] = Math.sin(representation.values[i]);
773
+ }
774
+ } else if (representation.type === "bipolar" || representation.type === "real") {
775
+ for (let i = 0; i < D; i++) {
776
+ re[i] = representation.values[i];
777
+ im[i] = 0;
778
+ }
779
+ } else if (representation.type === "binary") {
780
+ for (let i = 0; i < D; i++) {
781
+ re[i] = representation.values[i] === 1 ? 1 : -1;
782
+ im[i] = 0;
783
+ }
784
+ }
785
+ this._fftCore(re, im, false);
786
+ const magnitude = new Float32Array(D);
787
+ const phase = new Float32Array(D);
788
+ for (let i = 0; i < D; i++) {
789
+ magnitude[i] = Math.sqrt(re[i] * re[i] + im[i] * im[i]);
790
+ phase[i] = Math.atan2(im[i], re[i]);
791
+ }
792
+ return {
793
+ type: representation.type,
794
+ D,
795
+ re,
796
+ im,
797
+ magnitude,
798
+ phase
799
+ };
800
+ }
801
+ inverseSpectralTransform(spectrum) {
802
+ const D = spectrum.D;
803
+ const re = new Float32Array(spectrum.re);
804
+ const im = new Float32Array(spectrum.im);
805
+ this._fftCore(re, im, true);
806
+ if (spectrum.type === "complex") {
807
+ const vals2 = new Float32Array(D);
808
+ for (let i = 0; i < D; i++) {
809
+ let v = Math.atan2(im[i], re[i]);
810
+ if (v < 0) v += 2 * Math.PI;
811
+ vals2[i] = v;
812
+ }
813
+ return new Representation("complex", vals2, D);
814
+ }
815
+ if (spectrum.type === "binary") {
816
+ const vals2 = new Uint8Array(D);
817
+ for (let i = 0; i < D; i++) {
818
+ vals2[i] = re[i] >= 0 ? 1 : 0;
819
+ }
820
+ return new Representation("binary", vals2, D);
821
+ }
822
+ if (spectrum.type === "bipolar") {
823
+ const vals2 = new Float32Array(D);
824
+ for (let i = 0; i < D; i++) {
825
+ vals2[i] = re[i] >= 0 ? 1 : -1;
826
+ }
827
+ return new Representation("bipolar", vals2, D);
828
+ }
829
+ const vals = new Float32Array(D);
830
+ for (let i = 0; i < D; i++) {
831
+ vals[i] = re[i];
832
+ }
833
+ return new Representation("real", vals, D);
834
+ }
835
+ extractDominantFrequencies(spectrum, k = 10) {
836
+ const n = spectrum.D;
837
+ const items = [];
838
+ for (let i = 0; i < n; i++) {
839
+ items.push({ freq: i, mag: spectrum.magnitude[i] });
840
+ }
841
+ items.sort((a, b) => b.mag - a.mag);
842
+ return items.slice(0, k);
843
+ }
844
+ spectralEnergy(spectrum) {
845
+ let energy = 0;
846
+ const n = spectrum.D;
847
+ for (let i = 0; i < n; i++) {
848
+ energy += spectrum.magnitude[i] * spectrum.magnitude[i];
849
+ }
850
+ return energy;
851
+ }
852
+ spectralEntropy(spectrum) {
853
+ const n = spectrum.D;
854
+ const power = new Float32Array(n);
855
+ let totalPower = 0;
856
+ for (let i = 0; i < n; i++) {
857
+ power[i] = spectrum.magnitude[i] * spectrum.magnitude[i];
858
+ totalPower += power[i];
859
+ }
860
+ if (totalPower === 0) return 0;
861
+ let entropy = 0;
862
+ for (let i = 0; i < n; i++) {
863
+ const p = power[i] / totalPower;
864
+ if (p > 0) {
865
+ entropy -= p * Math.log2(p);
866
+ }
867
+ }
868
+ return entropy / Math.log2(n);
869
+ }
870
+ spectralSparsity(spectrum) {
871
+ const n = spectrum.D;
872
+ let l1 = 0;
873
+ let l2Sq = 0;
874
+ for (let i = 0; i < n; i++) {
875
+ l1 += spectrum.magnitude[i];
876
+ l2Sq += spectrum.magnitude[i] * spectrum.magnitude[i];
877
+ }
878
+ const l2 = Math.sqrt(l2Sq);
879
+ if (l2 === 0) return 0;
880
+ const sqrtN = Math.sqrt(n);
881
+ return (sqrtN - l1 / l2) / (sqrtN - 1);
882
+ }
883
+ lowFrequencyEnergy(spectrum) {
884
+ let energy = 0;
885
+ const half = Math.floor(spectrum.D / 2);
886
+ const quarter = Math.floor(half / 2);
887
+ for (let i = 0; i < quarter; i++) {
888
+ energy += spectrum.magnitude[i] * spectrum.magnitude[i];
889
+ }
890
+ return energy;
891
+ }
892
+ highFrequencyEnergy(spectrum) {
893
+ let energy = 0;
894
+ const half = Math.floor(spectrum.D / 2);
895
+ const quarter = Math.floor(half / 2);
896
+ for (let i = quarter; i < half; i++) {
897
+ energy += spectrum.magnitude[i] * spectrum.magnitude[i];
898
+ }
899
+ return energy;
900
+ }
901
+ spectralSimilarity(a, b) {
902
+ if (a.D !== b.D) return 0;
903
+ let dot = 0, normA = 0, normB = 0;
904
+ const n = a.D;
905
+ for (let i = 0; i < n; i++) {
906
+ dot += a.magnitude[i] * b.magnitude[i];
907
+ normA += a.magnitude[i] * a.magnitude[i];
908
+ normB += b.magnitude[i] * b.magnitude[i];
909
+ }
910
+ const denom = Math.sqrt(normA) * Math.sqrt(normB);
911
+ return denom > 0 ? dot / denom : 0;
912
+ }
913
+ };
914
+
915
+ // core/memory_engine.js
916
+ var MemoryEngine = class {
917
+ /**
918
+ * @param {Object} config
919
+ * @param {number} [config.alpha=0.3] - Reinforcement saturating factor
920
+ * @param {number} [config.lambda=0.01] - Base decay rate per hour
921
+ * @param {number} [config.ws=0.4] - Semantic similarity weight
922
+ * @param {number} [config.wr=0.2] - Spectral resonance weight
923
+ * @param {number} [config.wc=0.1] - Confidence weight
924
+ * @param {number} [config.wf=0.1] - Reinforcement frequency weight
925
+ * @param {number} [config.wd=0.1] - Decay penalty weight
926
+ * @param {number} [config.wx=0.1] - Contradiction penalty weight
927
+ */
928
+ constructor(config = {}) {
929
+ this.records = /* @__PURE__ */ new Map();
930
+ this.recordsList = [];
931
+ this.spectral = new SpectralEngine();
932
+ this.alpha = config.alpha !== void 0 ? config.alpha : 0.3;
933
+ this.lambda = config.lambda !== void 0 ? config.lambda : 0.01;
934
+ this.ws = config.ws !== void 0 ? config.ws : 0.4;
935
+ this.wr = config.wr !== void 0 ? config.wr : 0.2;
936
+ this.wc = config.wc !== void 0 ? config.wc : 0.1;
937
+ this.wf = config.wf !== void 0 ? config.wf : 0.1;
938
+ this.wd = config.wd !== void 0 ? config.wd : 0.1;
939
+ this.wx = config.wx !== void 0 ? config.wx : 0.1;
940
+ this.numTables = 4;
941
+ this.numProjections = 8;
942
+ this.tablesProjections = null;
943
+ this.tablesBuckets = null;
944
+ this.highPriorityRecords = /* @__PURE__ */ new Map();
945
+ this._saveTimeout = null;
946
+ this._savePromise = Promise.resolve();
947
+ }
948
+ _initLSH(D) {
949
+ this.D = D;
950
+ this.tablesProjections = [];
951
+ this.tablesBuckets = [];
952
+ for (let t = 0; t < this.numTables; t++) {
953
+ const projections = [];
954
+ for (let i = 0; i < this.numProjections; i++) {
955
+ const vec = new Float32Array(D);
956
+ for (let j = 0; j < D; j++) {
957
+ vec[j] = Math.random() * 2 - 1;
958
+ }
959
+ projections.push(vec);
960
+ }
961
+ this.tablesProjections.push(projections);
962
+ this.tablesBuckets.push(Array.from({ length: 256 }, () => []));
963
+ }
964
+ }
965
+ _hash(vector, tableIndex) {
966
+ let hash = 0;
967
+ const projections = this.tablesProjections[tableIndex];
968
+ for (let i = 0; i < this.numProjections; i++) {
969
+ let dot = 0;
970
+ const p = projections[i];
971
+ for (let j = 0; j < this.D; j++) {
972
+ dot += vector[j] * p[j];
973
+ }
974
+ if (dot > 0) {
975
+ hash |= 1 << i;
976
+ }
977
+ }
978
+ return hash;
979
+ }
980
+ /**
981
+ * Add a new MemoryRecord and index it in the LSH tables
982
+ * @param {Object} item
983
+ * @returns {Object} Added memory record
984
+ */
985
+ addRecord(item) {
986
+ const t = Date.now();
987
+ const id = item.id || Math.random().toString(36).substring(2, 11);
988
+ let repr = item.representation;
989
+ if (!repr || repr.length === 0) {
990
+ repr = new Float32Array(this.D || 8192);
991
+ } else if (!(repr instanceof Float32Array)) {
992
+ repr = new Float32Array(repr);
993
+ }
994
+ const record = {
995
+ id,
996
+ representation: repr,
997
+ content: item.content,
998
+ confidence: item.confidence !== void 0 ? item.confidence : 1,
999
+ reinforcement: item.reinforcement !== void 0 ? item.reinforcement : 1,
1000
+ createdAt: item.createdAt || t,
1001
+ lastAccessedAt: item.lastAccessedAt || t,
1002
+ lastReinforcedAt: item.lastReinforcedAt || t,
1003
+ source: item.source || "user",
1004
+ sourceType: item.sourceType || "user",
1005
+ status: item.status || "active",
1006
+ contradictionIds: item.contradictionIds || [],
1007
+ priority: item.priority || "normal"
1008
+ // Support priority field
1009
+ };
1010
+ const recordIndex = this.recordsList.length;
1011
+ this.recordsList.push(record);
1012
+ this.records.set(id, record);
1013
+ if (record.priority === "high") {
1014
+ this.highPriorityRecords.set(id, recordIndex);
1015
+ }
1016
+ if (!this.tablesProjections) {
1017
+ this._initLSH(record.representation.length);
1018
+ }
1019
+ for (let t2 = 0; t2 < this.numTables; t2++) {
1020
+ const hash = this._hash(record.representation, t2);
1021
+ this.tablesBuckets[t2][hash].push(recordIndex);
1022
+ }
1023
+ this._checkAndFlagContradictions(record);
1024
+ return record;
1025
+ }
1026
+ /**
1027
+ * Reinforce a memory record using saturating Hebbian confidence updates
1028
+ * @param {string} id - Record ID
1029
+ * @param {number} [alpha=this.alpha] - Custom alpha
1030
+ */
1031
+ reinforce(id, alpha = this.alpha) {
1032
+ const record = this.records.get(id);
1033
+ if (!record) return;
1034
+ const t = Date.now();
1035
+ const currentC = this.getDecayedConfidence(record, t);
1036
+ record.confidence = currentC + alpha * (1 - currentC);
1037
+ record.reinforcement += 1;
1038
+ record.lastReinforcedAt = t;
1039
+ }
1040
+ /**
1041
+ * Get dynamically decayed confidence at a specific timestamp
1042
+ * @param {Object} record
1043
+ * @param {number} [currentTime=Date.now()]
1044
+ * @returns {number} Decayed confidence in [0.0, 1.0]
1045
+ */
1046
+ getDecayedConfidence(record, currentTime = Date.now()) {
1047
+ const dtMs = currentTime - record.lastReinforcedAt;
1048
+ const dtHours = dtMs / (1e3 * 3600);
1049
+ const logReinforce = Math.log2(record.reinforcement + 1);
1050
+ const effLambda = this.lambda / (logReinforce || 1);
1051
+ return record.confidence * Math.exp(-effLambda * dtHours);
1052
+ }
1053
+ /**
1054
+ * Set dynamic contradiction status on two conflicting memory records
1055
+ * @param {string} idA
1056
+ * @param {string} idB
1057
+ */
1058
+ flagContradiction(idA, idB) {
1059
+ const recA = this.records.get(idA);
1060
+ const recB = this.records.get(idB);
1061
+ if (recA && recB) {
1062
+ if (!recA.contradictionIds.includes(idB)) recA.contradictionIds.push(idB);
1063
+ if (!recB.contradictionIds.includes(idA)) recB.contradictionIds.push(idA);
1064
+ recA.status = "conflicted";
1065
+ recB.status = "conflicted";
1066
+ }
1067
+ }
1068
+ /**
1069
+ * Retrieve matched memory candidates using Multi-Table LSH and Multi-Probe Hamming search
1070
+ * @param {Float32Array} queryRepr - Query FHRR vector
1071
+ * @param {number} [limit=5]
1072
+ * @param {number} [currentTime=Date.now()]
1073
+ * @returns {Array} List of matched candidates and scores
1074
+ */
1075
+ retrieve(queryRepr, limit = 5, currentTime = Date.now()) {
1076
+ const D = queryRepr.length;
1077
+ if (!this.tablesProjections) {
1078
+ this._initLSH(D);
1079
+ }
1080
+ const candidateIndices = /* @__PURE__ */ new Set();
1081
+ for (const [id, recordIndex] of this.highPriorityRecords.entries()) {
1082
+ candidateIndices.add(recordIndex);
1083
+ }
1084
+ let lshFoundCount = 0;
1085
+ for (let t = 0; t < this.numTables; t++) {
1086
+ const queryHash = this._hash(queryRepr, t);
1087
+ const bucket = this.tablesBuckets[t][queryHash];
1088
+ for (let i = 0; i < bucket.length; i++) {
1089
+ candidateIndices.add(bucket[i]);
1090
+ lshFoundCount++;
1091
+ }
1092
+ for (let bit = 0; bit < this.numProjections; bit++) {
1093
+ const neighborHash = queryHash ^ 1 << bit;
1094
+ const neighborBucket = this.tablesBuckets[t][neighborHash];
1095
+ for (let i = 0; i < neighborBucket.length; i++) {
1096
+ candidateIndices.add(neighborBucket[i]);
1097
+ lshFoundCount++;
1098
+ }
1099
+ }
1100
+ }
1101
+ let fallbackTriggered = false;
1102
+ if (lshFoundCount === 0) {
1103
+ fallbackTriggered = true;
1104
+ } else {
1105
+ let maxC = -1;
1106
+ let maxSim = -1;
1107
+ for (const idx of candidateIndices) {
1108
+ const record = this.recordsList[idx];
1109
+ const C = this.getDecayedConfidence(record, currentTime);
1110
+ if (C > maxC) maxC = C;
1111
+ const sim = this._cosineSimilarity(queryRepr, record.representation);
1112
+ if (sim > maxSim) maxSim = sim;
1113
+ }
1114
+ if (maxC < 0.45 || maxSim < 0.35) {
1115
+ fallbackTriggered = true;
1116
+ }
1117
+ }
1118
+ let indicesToSearch = candidateIndices;
1119
+ if (fallbackTriggered) {
1120
+ indicesToSearch = new Set(Array.from({ length: this.recordsList.length }, (_, i) => i));
1121
+ }
1122
+ const results = [];
1123
+ const specQuery = this.spectral.spectralTransform({ type: "real", values: queryRepr, D });
1124
+ for (const idx of indicesToSearch) {
1125
+ const record = this.recordsList[idx];
1126
+ const sSem = this._cosineSimilarity(queryRepr, record.representation);
1127
+ const specRecord = record.spectralTransform || (record.spectralTransform = this.spectral.spectralTransform({ type: "real", values: record.representation, D }));
1128
+ const sRes = this.spectral.spectralSimilarity(specQuery, specRecord);
1129
+ const C = this.getDecayedConfidence(record, currentTime);
1130
+ const F = Math.min(1, Math.log10(record.reinforcement + 1));
1131
+ const D_penalty = record.confidence - C;
1132
+ const X = record.status === "conflicted" || record.contradictionIds.length > 0 ? 1 : 0;
1133
+ const score = this.ws * sSem + this.wr * sRes + this.wc * C + this.wf * F - this.wd * D_penalty - this.wx * X;
1134
+ results.push({ record, score });
1135
+ }
1136
+ results.sort((a, b) => b.score - a.score);
1137
+ const sliced = results.slice(0, limit);
1138
+ for (const item of sliced) {
1139
+ item.record.lastAccessedAt = currentTime;
1140
+ }
1141
+ return sliced.map((item) => ({
1142
+ record: item.record,
1143
+ score: item.score
1144
+ }));
1145
+ }
1146
+ /**
1147
+ * Non-blocking debounced save to file system
1148
+ * @param {string} filePath
1149
+ */
1150
+ saveToFile(filePath) {
1151
+ if (this._saveTimeout) clearTimeout(this._saveTimeout);
1152
+ const data = [];
1153
+ for (const record of this.recordsList) {
1154
+ data.push({
1155
+ id: record.id,
1156
+ representation: Array.from(record.representation),
1157
+ content: record.content,
1158
+ confidence: record.confidence,
1159
+ reinforcement: record.reinforcement,
1160
+ createdAt: record.createdAt,
1161
+ lastAccessedAt: record.lastAccessedAt,
1162
+ lastReinforcedAt: record.lastReinforcedAt,
1163
+ source: record.source,
1164
+ sourceType: record.sourceType,
1165
+ status: record.status,
1166
+ contradictionIds: record.contradictionIds
1167
+ });
1168
+ }
1169
+ this._savePromise = new Promise((resolve) => {
1170
+ this._saveTimeout = setTimeout(async () => {
1171
+ try {
1172
+ await fs.promises.writeFile(filePath, JSON.stringify(data, null, 2), "utf8");
1173
+ } catch (e) {
1174
+ console.error("MemoryEngine: Asynchronous write failed:", e.message);
1175
+ }
1176
+ resolve();
1177
+ }, 50);
1178
+ });
1179
+ }
1180
+ /**
1181
+ * Load memory records synchronously and rebuild LSH tables
1182
+ * @param {string} filePath
1183
+ */
1184
+ loadFromFile(filePath) {
1185
+ if (!fs.existsSync(filePath)) return;
1186
+ try {
1187
+ const raw = fs.readFileSync(filePath, "utf8");
1188
+ const data = JSON.parse(raw);
1189
+ this.records.clear();
1190
+ this.recordsList = [];
1191
+ this.tablesProjections = null;
1192
+ this.tablesBuckets = null;
1193
+ for (const item of data) {
1194
+ this.addRecord({
1195
+ id: item.id,
1196
+ representation: new Float32Array(item.representation),
1197
+ content: item.content,
1198
+ confidence: item.confidence,
1199
+ reinforcement: item.reinforcement,
1200
+ createdAt: item.createdAt,
1201
+ lastAccessedAt: item.lastAccessedAt,
1202
+ lastReinforcedAt: item.lastReinforcedAt,
1203
+ source: item.source,
1204
+ sourceType: item.sourceType,
1205
+ status: item.status,
1206
+ contradictionIds: item.contradictionIds
1207
+ });
1208
+ }
1209
+ } catch (e) {
1210
+ console.error("MemoryEngine: Failed to load from file:", e.message);
1211
+ }
1212
+ }
1213
+ _cosineSimilarity(a, b) {
1214
+ let sum = 0;
1215
+ const D = a.length;
1216
+ for (let i = 0; i < D; i++) {
1217
+ sum += Math.cos(a[i] - b[i]);
1218
+ }
1219
+ return sum / D;
1220
+ }
1221
+ _checkAndFlagContradictions(record) {
1222
+ if (this.recordsList.length <= 1) return;
1223
+ const existingResults = this.retrieve(record.representation, 3);
1224
+ for (const existing of existingResults) {
1225
+ const sim = this._cosineSimilarity(record.representation, existing.record.representation);
1226
+ const isContra = this._isContradictory(record.content, existing.record.content);
1227
+ if (sim > 0.35 && existing.record.id !== record.id && existing.record.content !== record.content) {
1228
+ if (isContra) {
1229
+ this.flagContradiction(record.id, existing.record.id);
1230
+ }
1231
+ }
1232
+ }
1233
+ }
1234
+ _isContradictory(t1, t2) {
1235
+ const getBloodType = (t) => {
1236
+ if (t.includes("a pozitif") || t.includes("a+") || t.includes("a poz")) return "A+";
1237
+ if (t.includes("b negatif") || t.includes("b-") || t.includes("b neg")) return "B-";
1238
+ if (t.includes("0") || t.includes("s\u0131f\u0131r")) return "0";
1239
+ if (t.includes("ab")) return "AB";
1240
+ return null;
1241
+ };
1242
+ const getRisk = (t) => {
1243
+ if (t.includes("y\xFCksek") || t.includes("riskli")) return "high";
1244
+ if (t.includes("normal") || t.includes("d\xFC\u015F\xFCk") || t.includes("risk yok")) return "normal";
1245
+ return null;
1246
+ };
1247
+ const l1 = t1.toLowerCase();
1248
+ const l2 = t2.toLowerCase();
1249
+ if ((l1.includes("kan grubu") || l1.includes("grubu")) && (l2.includes("kan grubu") || l2.includes("grubu"))) {
1250
+ const b1 = getBloodType(l1);
1251
+ const b2 = getBloodType(l2);
1252
+ if (b1 && b2 && b1 !== b2) return true;
1253
+ }
1254
+ if (l1.includes("risk") && l2.includes("risk")) {
1255
+ const r1 = getRisk(l1);
1256
+ const r2 = getRisk(l2);
1257
+ if (r1 && r2 && r1 !== r2) return true;
1258
+ }
1259
+ if ((l1.includes("tansiyon") || l1.includes("bas\u0131nc\u0131")) && (l2.includes("tansiyon") || l2.includes("bas\u0131nc\u0131"))) {
1260
+ const nums1 = l1.match(/\d+/g);
1261
+ const nums2 = l2.match(/\d+/g);
1262
+ if (nums1 && nums2 && nums1[0] !== nums2[0]) return true;
1263
+ }
1264
+ return false;
1265
+ }
1266
+ resolveConflict(winnerId, loserId) {
1267
+ const winner = this.records.get(winnerId);
1268
+ const loser = this.records.get(loserId);
1269
+ if (winner) {
1270
+ const t = Date.now();
1271
+ const currentC = this.getDecayedConfidence(winner, t);
1272
+ winner.confidence = Math.min(1, currentC + 0.3 * (1 - currentC));
1273
+ winner.status = "active";
1274
+ winner.contradictionIds = [];
1275
+ winner.lastReinforcedAt = t;
1276
+ }
1277
+ if (loser) {
1278
+ loser.confidence = 0;
1279
+ loser.status = "rejected";
1280
+ loser.contradictionIds = [];
1281
+ }
1282
+ }
1283
+ };
1284
+
1285
+ // core/reasoning_router.js
1286
+ function evaluateMath(expr) {
1287
+ const tokens = [];
1288
+ let i = 0;
1289
+ while (i < expr.length) {
1290
+ const char = expr[i];
1291
+ if (/\s/.test(char)) {
1292
+ i++;
1293
+ continue;
1294
+ }
1295
+ if (/[0-9.]/.test(char)) {
1296
+ let numStr = "";
1297
+ while (i < expr.length && /[0-9.]/.test(expr[i])) {
1298
+ numStr += expr[i];
1299
+ i++;
1300
+ }
1301
+ tokens.push({ type: "NUMBER", value: parseFloat(numStr) });
1302
+ continue;
1303
+ }
1304
+ if (char === "+" || char === "-" || char === "*" || char === "/" || char === "%" || char === "^" || char === "(" || char === ")") {
1305
+ tokens.push({ type: "OP", value: char });
1306
+ i++;
1307
+ continue;
1308
+ }
1309
+ throw new Error("Invalid character in math expression: " + char);
1310
+ }
1311
+ let tokenIndex = 0;
1312
+ function peek() {
1313
+ return tokens[tokenIndex];
1314
+ }
1315
+ function consume(expectedValue) {
1316
+ const t = tokens[tokenIndex];
1317
+ if (!t) throw new Error("Unexpected end of expression");
1318
+ if (expectedValue !== void 0 && t.value !== expectedValue) {
1319
+ throw new Error(`Expected ${expectedValue} but got ${t.value}`);
1320
+ }
1321
+ tokenIndex++;
1322
+ return t;
1323
+ }
1324
+ function parseExpression() {
1325
+ let val = parseTerm();
1326
+ while (true) {
1327
+ const t = peek();
1328
+ if (t && t.type === "OP" && (t.value === "+" || t.value === "-")) {
1329
+ consume();
1330
+ const nextVal = parseTerm();
1331
+ if (t.value === "+") val += nextVal;
1332
+ else val -= nextVal;
1333
+ } else {
1334
+ break;
1335
+ }
1336
+ }
1337
+ return val;
1338
+ }
1339
+ function parseTerm() {
1340
+ let val = parseFactor();
1341
+ while (true) {
1342
+ const t = peek();
1343
+ if (t && t.type === "OP" && (t.value === "*" || t.value === "/" || t.value === "%")) {
1344
+ consume();
1345
+ const nextVal = parseFactor();
1346
+ if (t.value === "*") val *= nextVal;
1347
+ else if (t.value === "/") {
1348
+ if (nextVal === 0) throw new Error("Division by zero");
1349
+ val /= nextVal;
1350
+ } else val %= nextVal;
1351
+ } else {
1352
+ break;
1353
+ }
1354
+ }
1355
+ return val;
1356
+ }
1357
+ function parseFactor() {
1358
+ let val = parsePrimary();
1359
+ while (true) {
1360
+ const t = peek();
1361
+ if (t && t.type === "OP" && t.value === "^") {
1362
+ consume();
1363
+ const nextVal = parseFactor();
1364
+ val = Math.pow(val, nextVal);
1365
+ } else {
1366
+ break;
1367
+ }
1368
+ }
1369
+ return val;
1370
+ }
1371
+ function parsePrimary() {
1372
+ const t = peek();
1373
+ if (!t) throw new Error("Unexpected end of expression");
1374
+ if (t.type === "NUMBER") {
1375
+ consume();
1376
+ return t.value;
1377
+ }
1378
+ if (t.type === "OP" && t.value === "(") {
1379
+ consume("(");
1380
+ const val = parseExpression();
1381
+ consume(")");
1382
+ return val;
1383
+ }
1384
+ if (t.type === "OP" && t.value === "-") {
1385
+ consume("-");
1386
+ return -parsePrimary();
1387
+ }
1388
+ if (t.type === "OP" && t.value === "+") {
1389
+ consume("+");
1390
+ return parsePrimary();
1391
+ }
1392
+ throw new Error(`Unexpected token: ${t.value}`);
1393
+ }
1394
+ const result = parseExpression();
1395
+ if (tokenIndex < tokens.length) {
1396
+ throw new Error("Unexpected trailing tokens at end of expression");
1397
+ }
1398
+ return result;
1399
+ }
1400
+ var ReasoningRouter = class {
1401
+ /**
1402
+ * @param {Object} memoryEngine
1403
+ * @param {Object} sdkInstance
1404
+ */
1405
+ constructor(memoryEngine, sdkInstance) {
1406
+ this.memory = memoryEngine;
1407
+ this.sdk = sdkInstance;
1408
+ this.D = sdkInstance ? sdkInstance.D : 4096;
1409
+ if (this.sdk && this.sdk.hdc) {
1410
+ const memReps = ["hat\u0131rla", "hat\u0131rl\u0131yor", "favori", "nerede", "kim", "haf\u0131za", "hasta", "kay\u0131t", "bilgi", "durum"].map((w) => this.sdk.hdc.generateSeeded("complex", w));
1411
+ this.memoryIntentVec = this.sdk.hdc.bundle(memReps).values;
1412
+ const ruleReps = ["\xE7eli\u015Fki", "kural", "kar\u015F\u0131la\u015Ft\u0131r", "do\u011Fru", "yasak", "uygun"].map((w) => this.sdk.hdc.generateSeeded("complex", w));
1413
+ this.ruleIntentVec = this.sdk.hdc.bundle(ruleReps).values;
1414
+ const mathReps = ["hesapla", "toplam", "\xE7arp", "b\xF6l", "ka\xE7", "say\u0131", "doz", "miktar"].map((w) => this.sdk.hdc.generateSeeded("complex", w));
1415
+ this.mathIntentVec = this.sdk.hdc.bundle(mathReps).values;
1416
+ } else {
1417
+ this.memoryIntentVec = new Float32Array(this.D);
1418
+ this.ruleIntentVec = new Float32Array(this.D);
1419
+ this.mathIntentVec = new Float32Array(this.D);
1420
+ }
1421
+ this.chatState = "idle";
1422
+ this.pendingRecord = null;
1423
+ }
1424
+ /**
1425
+ * Self-vectorize text input using SDK's HDC engine (runs in < 0.1 ms)
1426
+ * @param {string} text
1427
+ * @returns {Float32Array}
1428
+ */
1429
+ vectorize(text) {
1430
+ const clean = text.toLowerCase().trim().replace(/[^a-zçgğıoöşuüâîû\s]/g, "");
1431
+ const words = clean.split(/\s+/).filter(Boolean);
1432
+ if (this.sdk && this.sdk.hdc) {
1433
+ if (words.length === 0) {
1434
+ return new Float32Array(this.D);
1435
+ }
1436
+ if (words.length === 1) {
1437
+ return this.sdk.hdc.generateSeeded("complex", words[0]).values;
1438
+ }
1439
+ const reps = words.map((w) => this.sdk.hdc.generateSeeded("complex", w));
1440
+ return this.sdk.hdc.bundle(reps).values;
1441
+ }
1442
+ return new Float32Array(this.D);
1443
+ }
1444
+ /**
1445
+ * 8-Axis Verification Suite
1446
+ * @param {Object} result - Candidate routed result
1447
+ * @param {number} axis - Axis index [1-8]
1448
+ * @returns {boolean} True if pass
1449
+ */
1450
+ validateAxis(result, axis) {
1451
+ if (!result) return false;
1452
+ if (axis === 1 && result.route === "math") {
1453
+ const match = result.input.match(/^\s*([0-9.]+)\s*([+\-*/%^])\s*([0-9.]+)\s*$/);
1454
+ if (match) {
1455
+ const a = parseFloat(match[1]);
1456
+ const op = match[2];
1457
+ const b = parseFloat(match[3]);
1458
+ const c = parseFloat(result.output);
1459
+ if (op === "*") {
1460
+ if (b !== 0 && Math.abs(c / b - a) > 1e-4) return false;
1461
+ } else if (op === "+") {
1462
+ if (Math.abs(c - b - a) > 1e-4) return false;
1463
+ } else if (op === "-") {
1464
+ if (Math.abs(c + b - a) > 1e-4) return false;
1465
+ } else if (op === "/") {
1466
+ if (b !== 0 && Math.abs(c * b - a) > 1e-4) return false;
1467
+ }
1468
+ }
1469
+ return true;
1470
+ }
1471
+ if (axis === 2 && result.route === "math") {
1472
+ const val = parseFloat(result.output);
1473
+ if (isNaN(val) || !isFinite(val)) return false;
1474
+ if (result.input.includes("/0")) return false;
1475
+ return true;
1476
+ }
1477
+ if (axis === 3 && result.route === "memory") {
1478
+ if (!result.results || result.results.length === 0) return false;
1479
+ const topRecord = result.results[0].record;
1480
+ if (topRecord.status === "conflicted" || topRecord.contradictionIds.length > 0) {
1481
+ return false;
1482
+ }
1483
+ return true;
1484
+ }
1485
+ if (axis === 4 && result.route === "memory") {
1486
+ if (!result.results || result.results.length === 0) return false;
1487
+ const topRecord = result.results[0].record;
1488
+ const C = this.memory.getDecayedConfidence(topRecord);
1489
+ if (C < 0.5) return false;
1490
+ return true;
1491
+ }
1492
+ if (axis === 5 && result.route === "memory") {
1493
+ if (!result.results || result.results.length === 0) return false;
1494
+ const queryVec = this.vectorize(result.input);
1495
+ const sSem = this._cosineSimilarity(queryVec, result.results[0].record.representation);
1496
+ if (sSem < 0.15) return false;
1497
+ return true;
1498
+ }
1499
+ if (axis === 6 && (result.route === "llm" || result.route === "memory")) {
1500
+ if (this.sdk && this.sdk.morphology) {
1501
+ const words = result.output.split(/\s+/).filter(Boolean);
1502
+ for (const w of words) {
1503
+ const cleanWord = w.toLowerCase().replace(/[^a-zçgğıoöşuüâîû]/g, "");
1504
+ if (cleanWord.length >= 2) {
1505
+ const harmony = this.sdk.morphology.determineVowelHarmony(cleanWord);
1506
+ if (harmony !== "front" && harmony !== "back") return false;
1507
+ }
1508
+ }
1509
+ }
1510
+ return true;
1511
+ }
1512
+ if (axis === 7 && result.route === "llm") {
1513
+ const words = result.output.split(/\s+/).filter(Boolean);
1514
+ for (const w of words) {
1515
+ const clean = w.toLowerCase().replace(/[^a-zçgğıoöşuüâîû]/g, "");
1516
+ if (/(kitapı|bebeki|çiçeki|ağacı)/.test(clean)) return false;
1517
+ }
1518
+ return true;
1519
+ }
1520
+ if (axis === 8 && result.route === "memory") {
1521
+ const queryWords = result.input.toLowerCase().split(/\s+/).filter((w) => w.length > 3);
1522
+ const contentLower = result.output.toLowerCase();
1523
+ if (queryWords.length > 0) {
1524
+ const matchesQueryWord = queryWords.some((qw) => contentLower.includes(qw));
1525
+ if (!matchesQueryWord) return false;
1526
+ }
1527
+ return true;
1528
+ }
1529
+ return true;
1530
+ }
1531
+ /**
1532
+ * Run all 8 verification axes
1533
+ */
1534
+ validateAllAxes(result) {
1535
+ for (let axis = 1; axis <= 8; axis++) {
1536
+ if (!this.validateAxis(result, axis)) return false;
1537
+ }
1538
+ return true;
1539
+ }
1540
+ /**
1541
+ * Route the query dynamically using safe parser, self-vectorization, and hybrid classification
1542
+ * @param {string} input
1543
+ * @returns {Object} Route result
1544
+ */
1545
+ route(input, options = {}) {
1546
+ const cleanInput = input.trim();
1547
+ const saveIntentRegex = /kaydet|ekle|yaz|not al|sakla|sisteme gir|oluştur/i;
1548
+ const confirmRegex = /^(evet|tamam|doğru|olur|kaydet|kabul|onay|evet kaydet)$/i;
1549
+ const rejectRegex = /^(hayır|iptal|vazgeç|yanlış|dur|bekle)$/i;
1550
+ if (this.chatState === "pending_confirmation") {
1551
+ if (confirmRegex.test(cleanInput)) {
1552
+ this.chatState = "recording";
1553
+ const r = this.pendingRecord;
1554
+ const searchableText = [r.baslik, r.kategori, r.aciklama, r.etiketler].filter(Boolean).join(" ");
1555
+ const representation = this.vectorize(searchableText);
1556
+ const newRecord = this.memory.addRecord({
1557
+ content: `${r.baslik} \u2014 ${r.aciklama}`,
1558
+ representation,
1559
+ priority: "normal"
1560
+ });
1561
+ this.chatState = "idle";
1562
+ this.pendingRecord = null;
1563
+ return {
1564
+ input: cleanInput,
1565
+ route: "memory",
1566
+ llmBypassed: true,
1567
+ output: "Haf\u0131za kayd\u0131 ba\u015Far\u0131yla eklendi.",
1568
+ reason: "Chat state machine confirm and record"
1569
+ };
1570
+ } else if (rejectRegex.test(cleanInput)) {
1571
+ this.chatState = "idle";
1572
+ this.pendingRecord = null;
1573
+ return {
1574
+ input: cleanInput,
1575
+ route: "memory",
1576
+ llmBypassed: true,
1577
+ output: "Kay\u0131t iptal edildi.",
1578
+ reason: "Chat state machine reject"
1579
+ };
1580
+ } else {
1581
+ this.chatState = "idle";
1582
+ this.pendingRecord = null;
1583
+ const normalResult = this._routeNormal(input, options);
1584
+ normalResult.output = "\xD6nceki kayd\u0131 iptal ettim. " + normalResult.output;
1585
+ return normalResult;
1586
+ }
1587
+ }
1588
+ if (this.chatState === "idle" && saveIntentRegex.test(cleanInput)) {
1589
+ const data = this._extractDataFromText(cleanInput);
1590
+ if (data.baslik && data.aciklama) {
1591
+ this.chatState = "pending_confirmation";
1592
+ this.pendingRecord = data;
1593
+ return {
1594
+ input: cleanInput,
1595
+ route: "memory",
1596
+ llmBypassed: true,
1597
+ output: `\u015Eunu kaydediyorum:
1598
+ Ba\u015Fl\u0131k: ${data.baslik}
1599
+ Not: ${data.aciklama}
1600
+ Do\u011Fru mu?`,
1601
+ reason: "Chat state machine save intent detected"
1602
+ };
1603
+ }
1604
+ }
1605
+ return this._routeNormal(input, options);
1606
+ }
1607
+ _extractDataFromText(text) {
1608
+ const clean = text.replace(/kaydet|ekle|yaz|not al|sakla|sisteme gir|oluştur/ig, "").trim();
1609
+ const parts = clean.split(",").map((p) => p.trim()).filter(Boolean);
1610
+ let baslik = "";
1611
+ let aciklama = "";
1612
+ let kategori = "";
1613
+ let etiketler = "";
1614
+ if (parts.length >= 2) {
1615
+ baslik = parts[0];
1616
+ aciklama = parts[1];
1617
+ if (parts.length >= 3) kategori = parts[2];
1618
+ if (parts.length >= 4) etiketler = parts.slice(3).join(", ");
1619
+ } else {
1620
+ const words = clean.split(/\s+/);
1621
+ if (words.length > 2) {
1622
+ baslik = words.slice(0, 2).join(" ");
1623
+ aciklama = words.slice(2).join(" ");
1624
+ } else {
1625
+ baslik = clean;
1626
+ aciklama = clean;
1627
+ }
1628
+ }
1629
+ baslik = baslik.replace(/[,.;!]+$/, "").trim();
1630
+ aciklama = aciklama.replace(/[,.;!]+$/, "").trim();
1631
+ if (!baslik) baslik = clean || "Yeni Kay\u0131t";
1632
+ if (!aciklama) aciklama = clean || "Detay girilmedi";
1633
+ return { baslik, aciklama, kategori, etiketler };
1634
+ }
1635
+ _routeNormal(input, options = {}) {
1636
+ const cleanInput = input.trim();
1637
+ const mathRegex = /^[0-9+\-*/().\s%^]+$/;
1638
+ const hasOperator = /[+\-*/%^]/.test(cleanInput);
1639
+ if (mathRegex.test(cleanInput) && hasOperator) {
1640
+ try {
1641
+ const val = evaluateMath(cleanInput);
1642
+ const candidateResult = {
1643
+ input: cleanInput,
1644
+ route: "math",
1645
+ llmBypassed: true,
1646
+ output: val.toString(),
1647
+ reason: "Deterministic arithmetic evaluation"
1648
+ };
1649
+ if (this.validateAllAxes(candidateResult)) {
1650
+ return candidateResult;
1651
+ } else {
1652
+ return {
1653
+ input: cleanInput,
1654
+ route: "math",
1655
+ llmBypassed: true,
1656
+ output: "Hata: Ge\xE7ersiz aritmetik i\u015Flem (S\u0131f\u0131ra b\xF6lme veya tan\u0131ms\u0131z sonu\xE7)",
1657
+ reason: "Math verifier failure recovery"
1658
+ };
1659
+ }
1660
+ } catch (e) {
1661
+ }
1662
+ }
1663
+ const queryVec = this.vectorize(cleanInput);
1664
+ const memorySimilarity = this._cosineSimilarity(queryVec, this.memoryIntentVec);
1665
+ const ruleSimilarity = this._cosineSimilarity(queryVec, this.ruleIntentVec);
1666
+ const memoryRegex = /hatırlıyor\s*musun|benim\s*favori|nerede|hatırla|kayıt|hasta|durumu|kaydı|geçmiş|bilgi|var\s*mı|söyle|kim|yaşı|şikayeti|tanı|ilaç|doz|kan\s*grubu|risk|gebelik|diyabet|tansiyon|unuttun|hâlâ|güncelle|seviye|ölçüm|ne\s*zaman|değişti|sonuç|nedir|kaydı\s*var/i;
1667
+ const ruleRegex = /çelişki|kural|karşılaştır|doğru\s*mu|yasak|uygun/i;
1668
+ if (memoryRegex.test(cleanInput) || memorySimilarity > 0.18) {
1669
+ const results = this.memory ? this.memory.retrieve(queryVec, 5) : [];
1670
+ console.log(`[Router DBG] Memory triggered. Query: "${cleanInput}". Results count: ${results.length}`);
1671
+ if (results.length > 0) {
1672
+ console.log(`[Router DBG] Candidate list:`);
1673
+ results.forEach((res, i) => {
1674
+ const sSem = this._cosineSimilarity(queryVec, res.record.representation);
1675
+ console.log(` #${i}: "${res.record.content}" | score: ${res.score.toFixed(4)} | sSem: ${sSem.toFixed(4)} | status: ${res.record.status}`);
1676
+ });
1677
+ let conflictedResult = null;
1678
+ for (const res of results) {
1679
+ const sim = this._cosineSimilarity(queryVec, res.record.representation);
1680
+ if (sim > 0.15 && (res.record.status === "conflicted" || res.record.contradictionIds.length > 0)) {
1681
+ conflictedResult = res.record;
1682
+ break;
1683
+ }
1684
+ }
1685
+ if (conflictedResult) {
1686
+ const conflictRecords = [conflictedResult];
1687
+ for (const cId of conflictedResult.contradictionIds) {
1688
+ const cRec = this.memory.records.get(cId);
1689
+ if (cRec) conflictRecords.push(cRec);
1690
+ }
1691
+ const conflictSummary = conflictRecords.map((r) => r.content).join(" | ");
1692
+ console.log(`[Router DBG] Contradiction detected!`);
1693
+ return {
1694
+ input: cleanInput,
1695
+ route: "memory",
1696
+ llmBypassed: true,
1697
+ output: `\xC7eli\u015Fen kay\u0131tlar tespit edildi: ${conflictSummary}. L\xFCtfen do\u011Fru olan\u0131 belirtin.`,
1698
+ conflict: {
1699
+ detected: true,
1700
+ records: conflictRecords.map((r) => ({ id: r.id, content: r.content, confidence: this.memory.getDecayedConfidence(r) })),
1701
+ message: "Bu kay\u0131tta \xE7eli\u015Fen bilgi var. L\xFCtfen do\u011Fru olan\u0131 belirtin."
1702
+ },
1703
+ results: results.slice(0, 3),
1704
+ reason: "Contradiction detected in memory"
1705
+ };
1706
+ }
1707
+ const candidate = {
1708
+ input: cleanInput,
1709
+ route: "memory",
1710
+ llmBypassed: true,
1711
+ output: results[0].record.content,
1712
+ results: [results[0]],
1713
+ reason: "Semantic memory query candidate"
1714
+ };
1715
+ const isValid = this.validateAllAxes(candidate);
1716
+ console.log(`[Router DBG] Candidate isValid: ${isValid}`);
1717
+ if (!isValid) {
1718
+ for (let axis = 1; axis <= 8; axis++) {
1719
+ console.log(` Axis ${axis}: ${this.validateAxis(candidate, axis)}`);
1720
+ }
1721
+ }
1722
+ if (isValid) {
1723
+ return candidate;
1724
+ } else {
1725
+ for (let i = 1; i < results.length; i++) {
1726
+ const nextCandidate = {
1727
+ input: cleanInput,
1728
+ route: "memory",
1729
+ llmBypassed: true,
1730
+ output: results[i].record.content,
1731
+ results: [results[i]],
1732
+ reason: "Replan candidate"
1733
+ };
1734
+ if (this.validateAllAxes(nextCandidate)) {
1735
+ console.log(`[Router DBG] Replan candidate ${i} is valid.`);
1736
+ return nextCandidate;
1737
+ }
1738
+ }
1739
+ return {
1740
+ input: cleanInput,
1741
+ route: "memory",
1742
+ llmBypassed: true,
1743
+ output: "Bu bilgi haf\u0131zada bulunamad\u0131. Hen\xFCz kay\u0131t edilmemi\u015F olabilir.",
1744
+ results: [],
1745
+ reason: "Memory candidates failed validation (low similarity)"
1746
+ };
1747
+ }
1748
+ } else {
1749
+ return {
1750
+ input: cleanInput,
1751
+ route: "memory",
1752
+ llmBypassed: true,
1753
+ output: "Bu bilgi haf\u0131zada bulunamad\u0131. Hen\xFCz kay\u0131t edilmemi\u015F olabilir.",
1754
+ results: [],
1755
+ reason: "Memory triggered but empty"
1756
+ };
1757
+ }
1758
+ }
1759
+ if (ruleRegex.test(cleanInput) || ruleSimilarity > 0.28) {
1760
+ return {
1761
+ route: "rules",
1762
+ llmBypassed: true,
1763
+ output: "Kural de\u011Ferlendirmesi bilgi graf\u0131 / kural katman\u0131na aktar\u0131ld\u0131.",
1764
+ reason: `Rule structure detected (Match Sim: ${ruleSimilarity.toFixed(4)})`
1765
+ };
1766
+ }
1767
+ const mathSimilarity = this._cosineSimilarity(queryVec, this.mathIntentVec);
1768
+ const allSimilarities = [
1769
+ mathSimilarity,
1770
+ memorySimilarity,
1771
+ ruleSimilarity
1772
+ ];
1773
+ const maxSimilarity = Math.max(...allSimilarities);
1774
+ if (maxSimilarity < 0.12) {
1775
+ return {
1776
+ input: cleanInput,
1777
+ route: "boundary",
1778
+ output: "Bu konuda bilgim yok. Ba\u015Fka bir konuda yard\u0131mc\u0131 olabilir miyim?",
1779
+ llmBypassed: true,
1780
+ confidence: maxSimilarity,
1781
+ reason: `Capability boundary \u2014 no intent matched (max similarity: ${maxSimilarity.toFixed(4)})`
1782
+ };
1783
+ }
1784
+ let outputText = "";
1785
+ let sdkResult = null;
1786
+ if (this.sdk && typeof this.sdk.generate === "function") {
1787
+ sdkResult = this.sdk.generate(cleanInput, {
1788
+ temperature: options.temperature !== void 0 ? options.temperature : 0,
1789
+ maxLength: options.maxLength !== void 0 ? options.maxLength : this.sdk.maxLength
1790
+ });
1791
+ outputText = sdkResult.generatedText;
1792
+ } else {
1793
+ outputText = `[SLM Fallback] ${cleanInput}`;
1794
+ }
1795
+ const candidateGenResult = {
1796
+ input: cleanInput,
1797
+ route: "llm",
1798
+ llmBypassed: false,
1799
+ output: outputText,
1800
+ sdkResult,
1801
+ reason: "Generative language synthesis required"
1802
+ };
1803
+ if (this.validateAllAxes(candidateGenResult)) {
1804
+ return candidateGenResult;
1805
+ }
1806
+ candidateGenResult.output = `${outputText}.`;
1807
+ return candidateGenResult;
1808
+ }
1809
+ _cosineSimilarity(a, b) {
1810
+ let sum = 0;
1811
+ const D = a.length;
1812
+ for (let i = 0; i < D; i++) {
1813
+ sum += Math.cos(a[i] - b[i]);
1814
+ }
1815
+ return sum / D;
1816
+ }
1817
+ };
1818
+
1819
+ // core/sovereign_agent.js
1820
+ var SovereignAgent = class {
1821
+ /**
1822
+ * @param {Object} sdkInstance - The ResonanceSDK instance containing hdc, memory, router, morphology
1823
+ */
1824
+ constructor(sdkInstance) {
1825
+ this.sdk = sdkInstance;
1826
+ this.memory = sdkInstance ? sdkInstance.memory : null;
1827
+ this.morphology = sdkInstance ? sdkInstance.morphology : null;
1828
+ this.router = sdkInstance ? sdkInstance.router : null;
1829
+ this.tools = {
1830
+ memory_lookup: (query) => {
1831
+ if (!this.memory) return "Hata: Bellek motoru y\xFCkl\xFC de\u011Fil.";
1832
+ const vec = this.router ? this.router.vectorize(query) : new Float32Array(1024);
1833
+ const results = this.memory.retrieve(vec, 1);
1834
+ if (results.length === 0) return "Bulunamad\u0131.";
1835
+ return results[0].record.content;
1836
+ },
1837
+ math_eval: (expr) => {
1838
+ try {
1839
+ return evaluateMath(expr).toString();
1840
+ } catch (e) {
1841
+ return `Hata: Matematiksel hesaplama ba\u015Far\u0131s\u0131z. ${e.message}`;
1842
+ }
1843
+ },
1844
+ morphology_analyze: (word) => {
1845
+ if (!this.morphology) return "Hata: Morfoloji motoru y\xFCkl\xFC de\u011Fil.";
1846
+ const analysis = this.morphology.analyze(word);
1847
+ return JSON.stringify({
1848
+ root: analysis.root,
1849
+ suffixes: analysis.suffixes,
1850
+ harmony: analysis.harmony,
1851
+ syllables: analysis.syllables
1852
+ });
1853
+ },
1854
+ spectral_transform: (text) => {
1855
+ if (!this.sdk || !this.sdk.spectral) return "Hata: Spektral motor y\xFCkl\xFC de\u011Fil.";
1856
+ const vec = this.router ? this.router.vectorize(text) : new Float32Array(1024);
1857
+ const spec = this.sdk.spectral.spectralTransform({ type: "real", values: vec, D: vec.length });
1858
+ return `Energy: ${spec.magnitude.reduce((a, b) => a + b, 0).toFixed(2)}`;
1859
+ },
1860
+ system_time: () => {
1861
+ return (/* @__PURE__ */ new Date()).toISOString();
1862
+ }
1863
+ };
1864
+ }
1865
+ /**
1866
+ * Run the ReAct autonomous execution loop
1867
+ * @param {string} goal - The user prompt/objective
1868
+ * @param {number} [maxSteps=5] - Maximum execution steps
1869
+ * @returns {Promise<Object>} Execution log and final answer
1870
+ */
1871
+ async execute(goal, maxSteps = 5) {
1872
+ const logs = [];
1873
+ let step = 1;
1874
+ let finished = false;
1875
+ let finalAnswer = "";
1876
+ const lowerGoal = goal.toLowerCase();
1877
+ while (step <= maxSteps && !finished) {
1878
+ let thought = "";
1879
+ let action = "";
1880
+ let actionArg = "";
1881
+ if (lowerGoal.includes("hat\u0131rla") || lowerGoal.includes("haf\u0131za") || lowerGoal.includes("favori")) {
1882
+ if (step === 1) {
1883
+ thought = "Kullan\u0131c\u0131n\u0131n sordu\u011Fu favori veya bellek kayd\u0131n\u0131 bulmak i\xE7in haf\u0131zada arama yapmal\u0131y\u0131m.";
1884
+ action = "memory_lookup";
1885
+ actionArg = lowerGoal.includes("renk") ? "favori renk" : "haf\u0131za sorgusu";
1886
+ } else if (step === 2) {
1887
+ const prevObs = logs[0].observation;
1888
+ thought = `Haf\u0131zadan '${prevObs}' bilgisini ald\u0131m. Bu kelimeyi morfolojik olarak analiz etmeliyim.`;
1889
+ action = "morphology_analyze";
1890
+ actionArg = prevObs.split(/\s+/).pop().replace(/[^a-zçgğıoöşuüâîû]/g, "");
1891
+ } else {
1892
+ const prevObs = logs[1].observation;
1893
+ thought = "Gerekli aramalar\u0131 ve analizleri tamamlad\u0131m. Sonucu kullan\u0131c\u0131ya sunuyorum.";
1894
+ finished = true;
1895
+ finalAnswer = `Otonom ReAct G\xF6revi Ba\u015Far\u0131yla Tamamland\u0131.
1896
+ - Haf\u0131za Kayd\u0131: ${logs[0].observation}
1897
+ - Morfolojik Yap\u0131: ${prevObs}`;
1898
+ }
1899
+ } else if (lowerGoal.includes("hesapla") || /[0-9+\-*/%^]/.test(lowerGoal)) {
1900
+ if (step === 1) {
1901
+ thought = "Matematiksel ifadeyi deterministik parser ile hesaplamal\u0131y\u0131m.";
1902
+ action = "math_eval";
1903
+ const match = goal.match(/[0-9+\-*/%^().\s]+/);
1904
+ actionArg = match ? match[0].trim() : "0";
1905
+ } else if (step === 2) {
1906
+ const val = logs[0].observation;
1907
+ thought = `Hesaplanan '${val}' sonucunun spektral enerji yo\u011Funlu\u011Funu kontrol etmeliyim.`;
1908
+ action = "spectral_transform";
1909
+ actionArg = val;
1910
+ } else {
1911
+ thought = "Hesaplama ve spektral d\xF6n\xFC\u015F\xFCm ad\u0131mlar\u0131 bitti. Sonucu d\xF6n\xFCyorum.";
1912
+ finished = true;
1913
+ finalAnswer = `Hesaplama Sonucu: ${logs[0].observation} | Spektral Temsiliyet: ${logs[1].observation}`;
1914
+ }
1915
+ } else {
1916
+ if (step === 1) {
1917
+ thought = "Sistem saatini alarak g\xFCncel zaman\u0131 kontrol etmeliyim.";
1918
+ action = "system_time";
1919
+ actionArg = "";
1920
+ } else {
1921
+ thought = "Varsay\u0131lan otonom ak\u0131\u015F tamamland\u0131.";
1922
+ finished = true;
1923
+ finalAnswer = `Mevcut Zaman Dilimi: ${logs[0].observation}`;
1924
+ }
1925
+ }
1926
+ if (!finished) {
1927
+ let observation = "";
1928
+ const toolFn = this.tools[action];
1929
+ if (toolFn) {
1930
+ observation = toolFn(actionArg);
1931
+ } else {
1932
+ observation = `Hata: '${action}' arac\u0131 tan\u0131ml\u0131 de\u011Fil.`;
1933
+ }
1934
+ logs.push({
1935
+ step,
1936
+ thought,
1937
+ action,
1938
+ argument: actionArg,
1939
+ observation
1940
+ });
1941
+ step++;
1942
+ } else {
1943
+ logs.push({
1944
+ step,
1945
+ thought,
1946
+ action: "final_answer",
1947
+ argument: "",
1948
+ observation: finalAnswer
1949
+ });
1950
+ }
1951
+ }
1952
+ return {
1953
+ goal,
1954
+ stepsRun: step - 1,
1955
+ logs,
1956
+ finalAnswer
1957
+ };
1958
+ }
1959
+ };
1960
+
1961
+ // sdk/resonance_sdk.js
1962
+ function generateDerivations(root, morphology) {
1963
+ const harmony = morphology.determineVowelHarmony(root);
1964
+ const lastChar = root[root.length - 1];
1965
+ const isVowel = morphology.allVowels.has(lastChar);
1966
+ const derivations = [root];
1967
+ const hardConsonants = /* @__PURE__ */ new Set(["t", "k", "\xE7", "p", "s", "\u015F", "h", "f"]);
1968
+ const isHard = hardConsonants.has(lastChar);
1969
+ const mutateRoot = (r, suffix) => {
1970
+ if (!suffix) return r;
1971
+ const startsWithVowel = morphology.allVowels.has(suffix[0]);
1972
+ if (startsWithVowel) {
1973
+ const last = r[r.length - 1];
1974
+ let mutated = r.slice(0, -1);
1975
+ if (last === "p") return mutated + "b" + suffix;
1976
+ if (last === "\xE7") return mutated + "c" + suffix;
1977
+ if (last === "t") return mutated + "d" + suffix;
1978
+ if (last === "k") {
1979
+ if (r === "renk") return mutated + "g" + suffix;
1980
+ return mutated + "\u011F" + suffix;
1981
+ }
1982
+ }
1983
+ return r + suffix;
1984
+ };
1985
+ if (harmony === "front") {
1986
+ derivations.push(root + "ler");
1987
+ derivations.push(isVowel ? root + "nin" : mutateRoot(root, "in"));
1988
+ derivations.push(isVowel ? root + "ye" : mutateRoot(root, "e"));
1989
+ derivations.push(isVowel ? root + "yi" : mutateRoot(root, "i"));
1990
+ derivations.push(root + (isHard ? "te" : "de"));
1991
+ derivations.push(root + (isHard ? "ten" : "den"));
1992
+ derivations.push(isVowel ? root + "m" : mutateRoot(root, "im"));
1993
+ } else {
1994
+ derivations.push(root + "lar");
1995
+ derivations.push(isVowel ? root + "n\u0131n" : mutateRoot(root, "\u0131n"));
1996
+ derivations.push(isVowel ? root + "ya" : mutateRoot(root, "a"));
1997
+ derivations.push(isVowel ? root + "y\u0131" : mutateRoot(root, "\u0131"));
1998
+ derivations.push(root + (isHard ? "ta" : "da"));
1999
+ derivations.push(root + (isHard ? "tan" : "dan"));
2000
+ derivations.push(isVowel ? root + "m" : mutateRoot(root, "\u0131m"));
2001
+ }
2002
+ return derivations;
2003
+ }
2004
+ var ResonanceSDK = class {
2005
+ /**
2006
+ * @param {Object} config - SDK configuration
2007
+ * @param {number} [config.D=4096] - Hyperdimensional vector dimension
2008
+ * @param {number} [config.temperature=0.7] - Default sampling temperature
2009
+ * @param {number} [config.maxLength=10] - Default max generation length
2010
+ */
2011
+ constructor(config = {}) {
2012
+ this.D = config.D || 4096;
2013
+ this.hdc = new HDCEngine(this.D);
2014
+ this.morphology = new TurkishMorphology();
2015
+ this.spectral = new SpectralEngine();
2016
+ this.memory = new MemoryEngine(config.memory || {});
2017
+ this.router = new ReasoningRouter(this.memory, this);
2018
+ this.temperature = config.temperature !== void 0 ? config.temperature : 0.7;
2019
+ this.maxLength = config.maxLength || 10;
2020
+ this.vocab = [];
2021
+ this.vocabMap = /* @__PURE__ */ new Map();
2022
+ this.embeddings = /* @__PURE__ */ new Map();
2023
+ this.wordCounts = /* @__PURE__ */ new Map();
2024
+ this.freqIndices = [];
2025
+ this.wordDerivationIndices = /* @__PURE__ */ new Map();
2026
+ this.transitionCounts = /* @__PURE__ */ new Map();
2027
+ this.sparseWeightsSpec = null;
2028
+ this.wasmInstance = null;
2029
+ this.wasmMemory = null;
2030
+ this.vocabCosPtr = 0;
2031
+ this.vocabSinPtr = 0;
2032
+ this.scoresPtr = 0;
2033
+ this.candidateIndicesPtr = 0;
2034
+ this._initialized = false;
2035
+ this._runtime = typeof window !== "undefined" ? "browser" : "node";
2036
+ }
2037
+ // ── PUBLIC API ──────────────────────────────────────────────
2038
+ /**
2039
+ * Initialize the SDK. Must be called before generate() or analyze().
2040
+ * @param {Object} [options]
2041
+ * @param {ArrayBuffer} [options.wasmBinary] - Pre-loaded WASM binary buffer
2042
+ * @param {string} [options.wasmUrl] - URL to fetch WASM (browser mode)
2043
+ * @param {string} [options.wasmPath] - File path to WASM (Node.js mode)
2044
+ * @param {string} [options.corpusUrl] - URL to tr_corpus_embed.js (browser mode)
2045
+ * @param {string} [options.corpusPath] - File path to tr_corpus_embed.js (Node.js mode)
2046
+ */
2047
+ async init(options = {}) {
2048
+ if (this._initialized) return;
2049
+ await this._loadWasm(options);
2050
+ await this._buildVocabulary(options);
2051
+ this._initialized = true;
2052
+ }
2053
+ /**
2054
+ * Generate text autoregressively from a prompt.
2055
+ * @param {string} prompt - Input Turkish text prompt
2056
+ * @param {Object} [options]
2057
+ * @param {number} [options.maxLength] - Override default max tokens
2058
+ * @param {number} [options.temperature] - Override default temperature
2059
+ * @param {function} [options.onToken] - Streaming callback: (word, step) => void
2060
+ * @returns {Object} { prompt, generatedText, newTokens, steps, totalLatencyMs, finishReason, vocabSize }
2061
+ */
2062
+ generate(prompt, options = {}) {
2063
+ this._assertInit();
2064
+ const maxLen = options.maxLength || this.maxLength;
2065
+ const temp = options.temperature !== void 0 ? options.temperature : this.temperature;
2066
+ const onToken = options.onToken || null;
2067
+ const cleanPrompt = this.morphology.normalize(prompt);
2068
+ const tokens = cleanPrompt.split(/\s+/).filter(Boolean);
2069
+ if (tokens.length === 0) tokens.push("ev");
2070
+ const promptLength = tokens.length;
2071
+ const steps = [];
2072
+ let stopReason = "length";
2073
+ const startTime = performance.now();
2074
+ for (let step = 0; step < maxLen; step++) {
2075
+ const stepStart = performance.now();
2076
+ const nextObj = this._predictNext(tokens, temp, promptLength);
2077
+ const stepEnd = performance.now();
2078
+ tokens.push(nextObj.word);
2079
+ const stepInfo = { word: nextObj.word, score: nextObj.score, latencyMs: stepEnd - stepStart };
2080
+ steps.push(stepInfo);
2081
+ if (onToken) onToken(nextObj.word, stepInfo);
2082
+ if (this._isTerminal(nextObj.word)) {
2083
+ stopReason = "stop";
2084
+ break;
2085
+ }
2086
+ if (tokens.length > promptLength + 2 && tokens.slice(-3).every((v) => v === tokens[tokens.length - 1])) {
2087
+ stopReason = "stop";
2088
+ break;
2089
+ }
2090
+ }
2091
+ return {
2092
+ prompt,
2093
+ generatedText: tokens.join(" "),
2094
+ newTokens: tokens.slice(promptLength),
2095
+ steps,
2096
+ totalLatencyMs: performance.now() - startTime,
2097
+ finishReason: stopReason,
2098
+ vocabSize: this.vocab.length
2099
+ };
2100
+ }
2101
+ /**
2102
+ * Analyze Turkish word morphology.
2103
+ * @param {string} word - Turkish word to analyze
2104
+ * @returns {Object} { word, root, suffixes, morphemes, harmony, syllables }
2105
+ */
2106
+ analyze(word) {
2107
+ return this.morphology.analyze(word);
2108
+ }
2109
+ /**
2110
+ * Get SDK runtime metrics.
2111
+ * @returns {Object} { runtime, vocabSize, dimension, wasmActive, initialized }
2112
+ */
2113
+ getMetrics() {
2114
+ return {
2115
+ runtime: this._runtime,
2116
+ vocabSize: this.vocab.length,
2117
+ dimension: this.D,
2118
+ wasmActive: this.wasmInstance !== null,
2119
+ initialized: this._initialized
2120
+ };
2121
+ }
2122
+ /**
2123
+ * Instantiate an autonomous SovereignAgent.
2124
+ * @returns {SovereignAgent}
2125
+ */
2126
+ createAgent() {
2127
+ return new SovereignAgent(this);
2128
+ }
2129
+ // ── PRIVATE: WASM LOADER ───────────────────────────────────
2130
+ async _loadWasm(options) {
2131
+ const imports = { env: { cosf: Math.cos, sinf: Math.sin, atan2f: Math.atan2, expf: Math.exp, sqrtf: Math.sqrt } };
2132
+ try {
2133
+ if (options.wasmBinary) {
2134
+ const mod = new WebAssembly.Module(options.wasmBinary);
2135
+ this.wasmInstance = new WebAssembly.Instance(mod, imports);
2136
+ this.wasmMemory = this.wasmInstance.exports.memory;
2137
+ } else if (this._runtime === "browser") {
2138
+ const url = options.wasmUrl || "../wasm/spectral_core.wasm";
2139
+ const res = await fetch(url);
2140
+ const buf = await res.arrayBuffer();
2141
+ const mod = new WebAssembly.Module(buf);
2142
+ this.wasmInstance = new WebAssembly.Instance(mod, imports);
2143
+ this.wasmMemory = this.wasmInstance.exports.memory;
2144
+ } else {
2145
+ const fs2 = await import("fs");
2146
+ const path = await import("path");
2147
+ const { fileURLToPath } = await import("url");
2148
+ const __dirname = path.dirname(fileURLToPath(import.meta.url));
2149
+ const wasmPath = options.wasmPath || path.join(__dirname, "..", "wasm", "spectral_core.wasm");
2150
+ if (fs2.existsSync(wasmPath)) {
2151
+ const buf = fs2.readFileSync(wasmPath);
2152
+ const mod = new WebAssembly.Module(buf);
2153
+ this.wasmInstance = new WebAssembly.Instance(mod, imports);
2154
+ this.wasmMemory = this.wasmInstance.exports.memory;
2155
+ }
2156
+ }
2157
+ } catch (e) {
2158
+ console.warn("ResonanceSDK: WASM load failed, Pure JS fallback active.", e.message);
2159
+ }
2160
+ }
2161
+ // ── PRIVATE: VOCABULARY BUILDER ────────────────────────────
2162
+ async _buildVocabulary(options) {
2163
+ const corpus = [
2164
+ // ── Orijinal genel corpus ──
2165
+ "evimizden yeni \xE7\u0131kt\u0131k",
2166
+ "yeni bir kitap ald\u0131m",
2167
+ "bilimsel ara\u015Ft\u0131rmalar yapay zeka ile h\u0131zland\u0131",
2168
+ "g\xFCzel bir g\xFCn ba\u015Flad\u0131",
2169
+ "iyi bir insan olmak \xF6nemlidir",
2170
+ "t\xFCrk\xE7e dil yap\u0131s\u0131 \xE7ok zengindir",
2171
+ "yapay zeka insan beyni gibi \xE7al\u0131\u015F\u0131r",
2172
+ "\xF6\u011Frenmek ve d\xFC\u015F\xFCnmek zihni geli\u015Ftirir",
2173
+ "b\xFCy\xFCk bir ad\u0131m att\u0131k",
2174
+ "yeni projeler \xFCzerinde \xE7al\u0131\u015F\u0131yoruz",
2175
+ "okuma al\u0131\u015Fkanl\u0131\u011F\u0131 kazanmak \xF6nemlidir",
2176
+ "bilim ve teknik d\xFCnyay\u0131 de\u011Fi\u015Ftiriyor",
2177
+ "evimizden okula kadar y\xFCr\xFCd\xFCk",
2178
+ "yapay zeka dil modelleri \xFCzerine kuruludur",
2179
+ "yeni bir d\xFCnya bizi bekliyor",
2180
+ "kitaplar en iyi arkada\u015Ft\u0131r",
2181
+ "g\xFCzel bir gelecek in\u015Fa ediyoruz",
2182
+ "iyi bir e\u011Fitim almak \xF6nemlidir",
2183
+ "t\xFCrk\xE7e konu\u015Fmak ve yazmak \xE7ok g\xFCzel",
2184
+ "bilimsel ger\xE7ekler her zaman kazan\u0131r",
2185
+ "yapay sinir a\u011Flar\u0131 karma\u015F\u0131k modellerdir",
2186
+ "beyin ve zihin ara\u015Ft\u0131rmalar\u0131 s\xFCr\xFCyor",
2187
+ "evimizden yeni bir yola \xE7\u0131kt\u0131k",
2188
+ "yeni bir ba\u015Flang\u0131\xE7 yapmak iyidir",
2189
+ "bilimsel okuma yapmak zihni a\xE7ar",
2190
+ "okuma yapmak insan\u0131 geli\u015Ftirir",
2191
+ "evimizden \xE7\u0131kt\u0131k ve okula gittik",
2192
+ "yeni bir g\xFCne uyand\u0131k",
2193
+ "bilim insanlar\u0131 yapay zeka geli\u015Ftiriyor",
2194
+ "t\xFCrk\xE7e dil bilgisi kurallar\u0131 \xF6nemlidir",
2195
+ "evimizden okula gittik yeni bir kitap ald\u0131k",
2196
+ "televizyonu a\xE7\u0131p haberleri izledik",
2197
+ "arabaya binip okula gittik",
2198
+ "bilgisayar\u0131 kapat\u0131p uyudum",
2199
+ "bilgisayar\u0131 kapat\u0131p yatt\u0131m",
2200
+ "yaz\u0131l\u0131m m\xFChendisleri yapay zeka modelleri \xFCzerine ara\u015Ft\u0131rma yap\u0131yor",
2201
+ "bilgi teknolojileri ve veri analizi i\u015F s\xFCre\xE7lerini kolayla\u015Ft\u0131r\u0131r",
2202
+ "sa\u011Fl\u0131kl\u0131 beslenme ve spor yapmak ya\u015Fam kalitesini art\u0131r\u0131r",
2203
+ "do\u011Fal ya\u015Fam\u0131 ve \xE7evreyi korumak hepimizin sorumlulu\u011Fundad\u0131r",
2204
+ "sanat ve edebiyat toplumun k\xFClt\xFCrel zenginli\u011Fini besler ve geli\u015Ftirir",
2205
+ "e\u011Fitim sistemi yeni nesillerin gelece\u011Fini ve ba\u015Far\u0131s\u0131n\u0131 belirler",
2206
+ "bilgisayar a\u011Flar\u0131 veri g\xFCvenli\u011Fi ve h\u0131zl\u0131 bilgi ak\u0131\u015F\u0131 sa\u011Flar",
2207
+ // ── Selamlama ve bağlam kurma ──
2208
+ "merhaba size nas\u0131l yard\u0131mc\u0131 olabilirim",
2209
+ "g\xFCnayd\u0131n bug\xFCn size nas\u0131l yard\u0131mc\u0131 olay\u0131m",
2210
+ "iyi g\xFCnler l\xFCtfen sorunuzu belirtin",
2211
+ "ho\u015F geldiniz nas\u0131l yard\u0131mc\u0131 olabilirim",
2212
+ "merhaba buyurun nas\u0131l yard\u0131mc\u0131 olay\u0131m",
2213
+ "iyi ak\u015Famlar size nas\u0131l yard\u0131mc\u0131 olabilirim",
2214
+ // ── Hasta kaydı kalıpları ──
2215
+ "hasta kayd\u0131 olu\u015Fturuldu",
2216
+ "kay\u0131t sisteme ba\u015Far\u0131yla eklendi",
2217
+ "hastan\u0131n bilgileri g\xFCncellendi",
2218
+ "bu hasta daha \xF6nce kay\u0131t edilmemi\u015F",
2219
+ "hastan\u0131n ad\u0131 ve ya\u015F\u0131 kaydedildi",
2220
+ "hasta bilgileri sisteme girildi",
2221
+ "yeni hasta kayd\u0131 a\xE7\u0131ld\u0131",
2222
+ "hasta \u015Fikayeti sisteme i\u015Flendi",
2223
+ "kay\u0131t ba\u015Far\u0131yla g\xFCncellendi",
2224
+ "hastan\u0131n ge\xE7mi\u015F kay\u0131tlar\u0131 bulundu",
2225
+ "bu hasta i\xE7in kay\u0131t bulunamad\u0131",
2226
+ "hastan\u0131n durumu kaydedildi",
2227
+ // ── Belirsizlik ve yönlendirme ──
2228
+ "bu soruyu yan\u0131tlayacak bilgiye sahip de\u011Filim",
2229
+ "bu konuda bilgim yok ba\u015Fka bir soru sorabilirsiniz",
2230
+ "l\xFCtfen daha fazla bilgi verir misiniz",
2231
+ "hangi hastay\u0131 soruyorsunuz",
2232
+ "bu bilgi haf\u0131zada bulunamad\u0131",
2233
+ "hen\xFCz bu konuda kay\u0131t yok",
2234
+ "bu i\u015Flemi yapabilmem i\xE7in daha fazla bilgiye ihtiyac\u0131m var",
2235
+ "maalesef bu konuda yard\u0131mc\u0131 olam\u0131yorum",
2236
+ // ── Sağlık domain kalıpları ──
2237
+ "hastan\u0131n \u015Fikayeti ba\u015F a\u011Fr\u0131s\u0131 ve tansiyon y\xFCksekli\u011Fi",
2238
+ "kan bas\u0131nc\u0131 de\u011Feri y\xFCz k\u0131rk b\xF6l\xFC doksan olarak \xF6l\xE7\xFCld\xFC",
2239
+ "ila\xE7 dozu hesapland\u0131 ve re\xE7eteye yaz\u0131ld\u0131",
2240
+ "risk durumu y\xFCksek riskli olarak i\u015Faretlendi",
2241
+ "hastan\u0131n kan \u015Fekeri y\xFCz seksen olarak \xF6l\xE7\xFCld\xFC",
2242
+ "diyabet hastas\u0131 olarak kay\u0131t edildi",
2243
+ "gebelik takibi i\xE7in kontrol randevusu olu\u015Fturuldu",
2244
+ "hastan\u0131n ate\u015Fi otuz sekiz derece \xF6l\xE7\xFCld\xFC",
2245
+ "tansiyon \xF6l\xE7\xFCm\xFC yap\u0131ld\u0131 ve kaydedildi",
2246
+ "ila\xE7lardan hangisinin verilmesi gerekti\u011Fi belirlendi",
2247
+ "doktorlar\u0131m\u0131zdan birini \xE7a\u011F\u0131rabilir misiniz",
2248
+ "hastan\u0131n ayaklar\u0131ndan birinde \u015Fi\u015Flik tespit edildi",
2249
+ "kan grubu belirlenmesi i\xE7in tahlil istendi",
2250
+ "hastaya g\xFCnde \xFC\xE7 kez ila\xE7 verilecek",
2251
+ "haftal\u0131k toplam doz hesapland\u0131",
2252
+ "ameliyat \xF6ncesi haz\u0131rl\u0131klar tamamland\u0131",
2253
+ "hastan\u0131n nabz\u0131 ve tansiyonu normal s\u0131n\u0131rlarda",
2254
+ "tedavi plan\u0131 olu\u015Fturuldu ve hastaya bildirildi",
2255
+ "a\u015F\u0131 takvimi kontrol edildi",
2256
+ "acil m\xFCdahale gerekli de\u011Fil hasta stabil",
2257
+ // ── Çelişki ve doğrulama ──
2258
+ "kay\u0131tlarda \xE7eli\u015Fen bilgi tespit edildi",
2259
+ "l\xFCtfen do\u011Fru bilgiyi belirtin",
2260
+ "iki farkl\u0131 kay\u0131t bulundu hangisi do\u011Fru",
2261
+ "bu bilgi \xF6nceki kay\u0131tla \xE7eli\u015Fiyor",
2262
+ "\xE7eli\u015Fen kay\u0131tlar kullan\u0131c\u0131ya sunuldu",
2263
+ // ── Morfoloji zenginleştirme ──
2264
+ "evlerimizden geliyoruz hasta getirdik",
2265
+ "hastan\u0131n ayaklar\u0131ndan birinde \u015Fi\u015Flik var",
2266
+ "ila\xE7lardan hangisini vermemiz gerekiyor",
2267
+ "doktorlar\u0131m\u0131zdan birini \xE7a\u011F\u0131rabilir misiniz",
2268
+ "bu hastal\u0131klardan kurtulabilir mi",
2269
+ "k\xF6ylerden gelen hastalar muayene edildi",
2270
+ "\xE7ocuklar\u0131n a\u015F\u0131lar\u0131 yap\u0131ld\u0131",
2271
+ "hastalar\u0131n kay\u0131tlar\u0131 g\xFCncellendi"
2272
+ ];
2273
+ let initialVocab = [];
2274
+ try {
2275
+ if (this._runtime === "browser") {
2276
+ const url = options.corpusUrl || "../tr_corpus_embed.js";
2277
+ const res = await fetch(url);
2278
+ const txt = await res.text();
2279
+ const m = txt.match(/const TR_CORPUS_ROOTS\s*=\s*(\[[\s\S]*?\]);/);
2280
+ if (m) initialVocab = JSON.parse(m[1]);
2281
+ } else {
2282
+ const fs2 = await import("fs");
2283
+ const path = await import("path");
2284
+ const { fileURLToPath } = await import("url");
2285
+ const __dirname = path.dirname(fileURLToPath(import.meta.url));
2286
+ const corpusPath = options.corpusPath || path.join(__dirname, "..", "tr_corpus_embed.js");
2287
+ if (fs2.existsSync(corpusPath)) {
2288
+ const txt = fs2.readFileSync(corpusPath, "utf8");
2289
+ const m = txt.match(/const TR_CORPUS_ROOTS\s*=\s*(\[[\s\S]*?\]);/);
2290
+ if (m) initialVocab = JSON.parse(m[1]);
2291
+ }
2292
+ }
2293
+ } catch (e) {
2294
+ }
2295
+ const turkishRe = /^[a-zçgğıoöşuüâîû]+$/;
2296
+ const words = /* @__PURE__ */ new Set([
2297
+ "ev",
2298
+ "yeni",
2299
+ "bir",
2300
+ "kitap",
2301
+ "okul",
2302
+ "\xE7\u0131kt\u0131k",
2303
+ "ald\u0131m",
2304
+ "g\xFCzel",
2305
+ "iyi",
2306
+ "yapay",
2307
+ "zeka",
2308
+ "bilimsel",
2309
+ "okuma",
2310
+ "\xF6\u011Frenmek",
2311
+ "dil",
2312
+ "t\xFCrk\xE7e",
2313
+ "insan",
2314
+ "olmak",
2315
+ "\xF6nemlidir",
2316
+ "geli\u015Ftirir",
2317
+ "de\u011Fi\u015Ftiriyor",
2318
+ "y\xFCr\xFCd\xFCk",
2319
+ "gittik",
2320
+ "yola",
2321
+ "ba\u015Flang\u0131\xE7",
2322
+ "g\xFCne",
2323
+ "uyand\u0131k",
2324
+ "kuruludur",
2325
+ "televizyonu",
2326
+ "a\xE7\u0131p",
2327
+ "izledik",
2328
+ "izledim",
2329
+ "arabaya",
2330
+ "binip",
2331
+ "bilgisayar\u0131",
2332
+ "kapat\u0131p",
2333
+ "uyudum",
2334
+ "yatt\u0131m"
2335
+ ]);
2336
+ this.wordCounts.clear();
2337
+ for (const s of corpus) {
2338
+ for (const w of s.split(/\s+/)) {
2339
+ const c = w.trim().toLowerCase().replace(/[^a-zçgğıoöşuüâîû]/g, "");
2340
+ if (c.length >= 2 && turkishRe.test(c)) {
2341
+ this.wordCounts.set(c, (this.wordCounts.get(c) || 0) + 1);
2342
+ }
2343
+ }
2344
+ }
2345
+ for (const [w, cnt] of this.wordCounts) {
2346
+ if (cnt >= 2) words.add(w);
2347
+ }
2348
+ for (const w of initialVocab) {
2349
+ const c = w.trim().toLowerCase().replace(/[^a-zçgğıoöşuüâîû]/g, "");
2350
+ if (c.length >= 2 && turkishRe.test(c)) {
2351
+ for (const d of generateDerivations(c, this.morphology)) words.add(d);
2352
+ }
2353
+ }
2354
+ this.vocab = ["<unk>", ...Array.from(words)];
2355
+ this.vocabMap.clear();
2356
+ for (let i = 0; i < this.vocab.length; i++) this.vocabMap.set(this.vocab[i], i);
2357
+ this.freqIndices = this.vocab.map((w, idx) => ({ w, idx })).sort((a, b) => (this.wordCounts.get(b.w) || 0) - (this.wordCounts.get(a.w) || 0)).slice(0, 15).map((x) => x.idx);
2358
+ this.wordDerivationIndices.clear();
2359
+ for (const root of this.vocab) {
2360
+ const indices = [];
2361
+ for (const d of generateDerivations(root, this.morphology)) {
2362
+ const idx = this.vocabMap.get(d);
2363
+ if (idx !== void 0) indices.push(idx);
2364
+ }
2365
+ this.wordDerivationIndices.set(root, indices);
2366
+ }
2367
+ for (const word of this.vocab) {
2368
+ const emb = this.hdc.generateSeeded("complex", word);
2369
+ emb.values = new Float32Array(emb.values);
2370
+ const cos = new Float32Array(this.D);
2371
+ const sin = new Float32Array(this.D);
2372
+ for (let i = 0; i < this.D; i++) {
2373
+ cos[i] = Math.cos(emb.values[i]);
2374
+ sin[i] = Math.sin(emb.values[i]);
2375
+ }
2376
+ this.embeddings.set(word, { emb, cosVals: cos, sinVals: sin });
2377
+ }
2378
+ if (this.wasmInstance) {
2379
+ const V = this.vocab.length, DD = this.D;
2380
+ this.vocabCosPtr = this.wasmInstance.exports.malloc(V * DD * 4);
2381
+ this.vocabSinPtr = this.wasmInstance.exports.malloc(V * DD * 4);
2382
+ this.scoresPtr = this.wasmInstance.exports.malloc(V * 4);
2383
+ this.transIndicesPtr = this.wasmInstance.exports.malloc(64 * 4);
2384
+ this.transMultipliersPtr = this.wasmInstance.exports.malloc(64 * 4);
2385
+ this.topIndicesPtr = this.wasmInstance.exports.malloc(5 * 4);
2386
+ this.topScoresPtr = this.wasmInstance.exports.malloc(5 * 4);
2387
+ this.candidateIndicesPtr = this.wasmInstance.exports.malloc(1024 * 4);
2388
+ if (this.vocabCosPtr && this.vocabSinPtr && this.scoresPtr && this.transIndicesPtr && this.transMultipliersPtr && this.topIndicesPtr && this.topScoresPtr && this.candidateIndicesPtr) {
2389
+ const mem = this.wasmMemory.buffer;
2390
+ const cosView = new Float32Array(mem, this.vocabCosPtr, V * DD);
2391
+ const sinView = new Float32Array(mem, this.vocabSinPtr, V * DD);
2392
+ for (let v = 0; v < V; v++) {
2393
+ const data = this.embeddings.get(this.vocab[v]);
2394
+ cosView.set(data.cosVals, v * DD);
2395
+ sinView.set(data.sinVals, v * DD);
2396
+ }
2397
+ } else {
2398
+ console.warn("ResonanceSDK: WASM malloc failed, falling back to Pure JS.");
2399
+ this.wasmInstance = null;
2400
+ }
2401
+ }
2402
+ this.transitionCounts = /* @__PURE__ */ new Map();
2403
+ const re = new Float32Array(this.D), im = new Float32Array(this.D);
2404
+ let tCount = 0;
2405
+ for (const s of corpus) {
2406
+ const ws = s.split(/\s+/).map((w) => w.trim().toLowerCase().replace(/[^a-zçgğıoöşuüâîû]/g, "")).filter((w) => w.length >= 2);
2407
+ for (let i = 0; i < ws.length - 1; i++) {
2408
+ const w1 = ws[i], w2 = ws[i + 1];
2409
+ if (!this.transitionCounts.has(w1)) this.transitionCounts.set(w1, /* @__PURE__ */ new Map());
2410
+ this.transitionCounts.get(w1).set(w2, (this.transitionCounts.get(w1).get(w2) || 0) + 1);
2411
+ const d1 = this.embeddings.get(w1), d2 = this.embeddings.get(w2);
2412
+ if (d1 && d2) {
2413
+ const wt = 1 / Math.sqrt(this.wordCounts.get(w2) || 1);
2414
+ for (let j = 0; j < this.D; j++) {
2415
+ let diff = d2.emb.values[j] - d1.emb.values[j];
2416
+ if (diff < 0) diff += 2 * Math.PI;
2417
+ re[j] += wt * Math.cos(diff % (2 * Math.PI));
2418
+ im[j] += wt * Math.sin(diff % (2 * Math.PI));
2419
+ }
2420
+ tCount++;
2421
+ }
2422
+ }
2423
+ }
2424
+ if (tCount > 0) {
2425
+ const vals = new Float32Array(this.D);
2426
+ for (let j = 0; j < this.D; j++) {
2427
+ let v = Math.atan2(im[j], re[j]);
2428
+ if (v < 0) v += 2 * Math.PI;
2429
+ vals[j] = v;
2430
+ }
2431
+ this.sparseWeightsSpec = new Representation("complex", vals, this.D);
2432
+ } else {
2433
+ this.sparseWeightsSpec = this.hdc.generateSeeded("complex", "fallback_transitions");
2434
+ }
2435
+ if (this.wasmInstance && this.sparseWeightsSpec) {
2436
+ const mem = this.wasmMemory.buffer;
2437
+ const trRe = new Float32Array(mem, this.wasmInstance.exports.get_transition_spec_re_ptr(), this.D);
2438
+ const trIm = new Float32Array(mem, this.wasmInstance.exports.get_transition_spec_im_ptr(), this.D);
2439
+ for (let j = 0; j < this.D; j++) {
2440
+ trRe[j] = Math.cos(this.sparseWeightsSpec.values[j]);
2441
+ trIm[j] = Math.sin(this.sparseWeightsSpec.values[j]);
2442
+ }
2443
+ }
2444
+ }
2445
+ _predictNext(tokens, temperature, promptLength) {
2446
+ if (this.wasmInstance && this.wasmMemory) {
2447
+ return this._predictWasm(tokens, temperature, promptLength);
2448
+ }
2449
+ return this._predictJS(tokens, temperature, promptLength);
2450
+ }
2451
+ _predictWasm(tokens, temperature, promptLength) {
2452
+ const mem = this.wasmMemory.buffer;
2453
+ const ctxPtr = this.wasmInstance.exports.get_context_angles_ptr();
2454
+ const ctxView = new Float32Array(mem, ctxPtr, this.D);
2455
+ if (promptLength > 0 && tokens.length > promptLength) {
2456
+ let pIdx = this.vocabMap.get(tokens[promptLength - 1]) ?? 0;
2457
+ let gIdx = this.vocabMap.get(tokens[tokens.length - 1]) ?? 0;
2458
+ this.wasmInstance.exports.combine_phases_by_indices(
2459
+ pIdx,
2460
+ 0.4,
2461
+ gIdx,
2462
+ 0.6,
2463
+ this.vocabCosPtr,
2464
+ this.vocabSinPtr,
2465
+ ctxPtr
2466
+ );
2467
+ } else {
2468
+ const lastData = this.embeddings.get(tokens[tokens.length - 1]) || this.embeddings.get("<unk>");
2469
+ ctxView.set(lastData.emb.values);
2470
+ }
2471
+ this.wasmInstance.exports.spectral_predict();
2472
+ const candView = new Int32Array(mem, this.candidateIndicesPtr, 1024);
2473
+ const freqLen = this.freqIndices.length;
2474
+ for (let i = 0; i < freqLen; i++) {
2475
+ candView[i] = this.freqIndices[i];
2476
+ }
2477
+ let numCandidates = freqLen;
2478
+ for (let i = 0; i < promptLength; i++) {
2479
+ const idx = this.vocabMap.get(tokens[i]);
2480
+ if (idx !== void 0 && numCandidates < 1024) {
2481
+ candView[numCandidates++] = idx;
2482
+ }
2483
+ }
2484
+ const lastToken = tokens[tokens.length - 1];
2485
+ let numTransitions = -1;
2486
+ if (lastToken) {
2487
+ const m = this.transitionCounts.get(lastToken);
2488
+ if (!m) {
2489
+ numTransitions = 0;
2490
+ } else {
2491
+ const transIndices = new Int32Array(mem, this.transIndicesPtr, m.size);
2492
+ const transMultipliers = new Float32Array(mem, this.transMultipliersPtr, m.size);
2493
+ let idx = 0;
2494
+ for (const [nextWord, count] of m.entries()) {
2495
+ const wordIdx = this.vocabMap.get(nextWord);
2496
+ if (wordIdx !== void 0) {
2497
+ transIndices[idx] = wordIdx;
2498
+ transMultipliers[idx] = 1.5 + count * 2;
2499
+ idx++;
2500
+ if (numCandidates < 1024) {
2501
+ candView[numCandidates++] = wordIdx;
2502
+ }
2503
+ const derivationsIndices = this.wordDerivationIndices.get(nextWord);
2504
+ if (derivationsIndices) {
2505
+ const derivLen = derivationsIndices.length;
2506
+ for (let d = 0; d < derivLen; d++) {
2507
+ if (numCandidates < 1024) {
2508
+ candView[numCandidates++] = derivationsIndices[d];
2509
+ }
2510
+ }
2511
+ }
2512
+ }
2513
+ }
2514
+ numTransitions = idx;
2515
+ }
2516
+ }
2517
+ this.wasmInstance.exports.compute_similarity_for_candidates(
2518
+ this.candidateIndicesPtr,
2519
+ numCandidates,
2520
+ this.vocabCosPtr,
2521
+ this.vocabSinPtr,
2522
+ this.transIndicesPtr,
2523
+ this.transMultipliersPtr,
2524
+ numTransitions,
2525
+ this.topIndicesPtr,
2526
+ this.topScoresPtr
2527
+ );
2528
+ const topIndicesView = new Int32Array(mem, this.topIndicesPtr, 5);
2529
+ const topScoresView = new Float32Array(mem, this.topScoresPtr, 5);
2530
+ const candidates = [];
2531
+ const lastHarmony = lastToken ? this.morphology.determineVowelHarmony(lastToken) : null;
2532
+ const recentK = tokens.slice(-4);
2533
+ for (let i = 0; i < 5; i++) {
2534
+ const wordIdx = topIndicesView[i];
2535
+ if (wordIdx === -1) continue;
2536
+ const word = this.vocab[wordIdx];
2537
+ let score = topScoresView[i];
2538
+ if (tokens.length >= 1) {
2539
+ const last1 = tokens[tokens.length - 1];
2540
+ for (let idx = 0; idx < tokens.length - 1; idx++) {
2541
+ if (tokens[idx] === last1 && tokens[idx + 1] === word) {
2542
+ score = 0;
2543
+ break;
2544
+ }
2545
+ }
2546
+ }
2547
+ if (tokens.length >= 2) {
2548
+ const last2 = tokens[tokens.length - 2];
2549
+ const last1 = tokens[tokens.length - 1];
2550
+ for (let idx = 0; idx < tokens.length - 2; idx++) {
2551
+ if (tokens[idx] === last2 && tokens[idx + 1] === last1 && tokens[idx + 2] === word) {
2552
+ score = 0;
2553
+ break;
2554
+ }
2555
+ }
2556
+ }
2557
+ if (recentK.includes(word)) {
2558
+ score *= 0.1;
2559
+ }
2560
+ if (lastHarmony && this.morphology.suffixFeatures.hasOwnProperty(word)) {
2561
+ const suffixHarmony = this.morphology.determineVowelHarmony(word);
2562
+ if (suffixHarmony !== lastHarmony) score = 0;
2563
+ } else if (lastHarmony) {
2564
+ const candidateHarmony = this.morphology.determineVowelHarmony(word);
2565
+ if (candidateHarmony === lastHarmony) score *= 1.15;
2566
+ }
2567
+ candidates.push({ word, score });
2568
+ }
2569
+ candidates.sort((a, b) => b.score - a.score);
2570
+ return this._sample(candidates, temperature);
2571
+ }
2572
+ _predictJS(tokens, temperature, promptLength) {
2573
+ const ctx = new Float32Array(this.D);
2574
+ if (promptLength > 0 && tokens.length > promptLength) {
2575
+ const pD = this.embeddings.get(tokens[promptLength - 1]) || this.embeddings.get("<unk>");
2576
+ const gD = this.embeddings.get(tokens[tokens.length - 1]) || this.embeddings.get("<unk>");
2577
+ for (let j = 0; j < this.D; j++) {
2578
+ let v = pD.emb.values[j] + gD.emb.values[j];
2579
+ if (v < 0) v += 2 * Math.PI;
2580
+ ctx[j] = v % (2 * Math.PI);
2581
+ }
2582
+ } else {
2583
+ const ld = this.embeddings.get(tokens[tokens.length - 1]) || this.embeddings.get("<unk>");
2584
+ ctx.set(ld.emb.values);
2585
+ }
2586
+ const query = new Float32Array(this.D);
2587
+ for (let j = 0; j < this.D; j++) {
2588
+ let v = ctx[j] + (this.sparseWeightsSpec ? this.sparseWeightsSpec.values[j] : 0);
2589
+ if (v < 0) v += 2 * Math.PI;
2590
+ query[j] = v % (2 * Math.PI);
2591
+ }
2592
+ const cosY = new Float32Array(this.D);
2593
+ const sinY = new Float32Array(this.D);
2594
+ for (let i = 0; i < this.D; i++) {
2595
+ cosY[i] = Math.cos(query[i]);
2596
+ sinY[i] = Math.sin(query[i]);
2597
+ }
2598
+ const candidates = [];
2599
+ const lastToken = tokens[tokens.length - 1];
2600
+ const lastHarmony = lastToken ? this.morphology.determineVowelHarmony(lastToken) : null;
2601
+ const recentK = tokens.slice(-4);
2602
+ for (const [word, data] of this.embeddings.entries()) {
2603
+ let sumCos = 0;
2604
+ const cosEmb = data.cosVals;
2605
+ const sinEmb = data.sinVals;
2606
+ for (let i = 0; i < this.D; i++) {
2607
+ sumCos += cosY[i] * cosEmb[i] + sinY[i] * sinEmb[i];
2608
+ }
2609
+ let score = sumCos / this.D;
2610
+ score = Math.max(1e-4, (score + 1) / 2);
2611
+ if (lastToken) {
2612
+ const m = this.transitionCounts.get(lastToken);
2613
+ if (m) {
2614
+ const count = m.get(word) || 0;
2615
+ score *= count > 0 ? 1.5 + count * 2 : 0.1;
2616
+ } else {
2617
+ score *= 0.5;
2618
+ }
2619
+ }
2620
+ if (tokens.length >= 1) {
2621
+ const last1 = tokens[tokens.length - 1];
2622
+ for (let i = 0; i < tokens.length - 1; i++) {
2623
+ if (tokens[i] === last1 && tokens[i + 1] === word) {
2624
+ score = 0;
2625
+ break;
2626
+ }
2627
+ }
2628
+ }
2629
+ if (tokens.length >= 2) {
2630
+ const last2 = tokens[tokens.length - 2];
2631
+ const last1 = tokens[tokens.length - 1];
2632
+ for (let i = 0; i < tokens.length - 2; i++) {
2633
+ if (tokens[i] === last2 && tokens[i + 1] === last1 && tokens[i + 2] === word) {
2634
+ score = 0;
2635
+ break;
2636
+ }
2637
+ }
2638
+ }
2639
+ if (recentK.includes(word)) {
2640
+ score *= 0.1;
2641
+ }
2642
+ if (lastHarmony && this.morphology.suffixFeatures.hasOwnProperty(word)) {
2643
+ const suffixHarmony = this.morphology.determineVowelHarmony(word);
2644
+ if (suffixHarmony !== lastHarmony) score = 0;
2645
+ } else if (lastHarmony) {
2646
+ const candidateHarmony = this.morphology.determineVowelHarmony(word);
2647
+ if (candidateHarmony === lastHarmony) score *= 1.15;
2648
+ }
2649
+ candidates.push({ word, score });
2650
+ }
2651
+ candidates.sort((a, b) => b.score - a.score);
2652
+ return this._sample(candidates.slice(0, 5), temperature);
2653
+ }
2654
+ _sample(candidates, temperature) {
2655
+ if (!candidates.length) return { word: "<unk>", score: 0 };
2656
+ if (temperature <= 0.05) return candidates[0];
2657
+ const max = candidates[0].score;
2658
+ const exp = candidates.map((c) => Math.exp((c.score - max) / temperature));
2659
+ const sum = exp.reduce((a, v) => a + v, 0);
2660
+ const probs = exp.map((v) => v / sum);
2661
+ const r = Math.random();
2662
+ let cum = 0;
2663
+ for (let i = 0; i < candidates.length; i++) {
2664
+ cum += probs[i];
2665
+ if (r <= cum) return candidates[i];
2666
+ }
2667
+ return candidates[0];
2668
+ }
2669
+ _isTerminal(word) {
2670
+ const terminals = /* @__PURE__ */ new Set([
2671
+ ".",
2672
+ "gittik",
2673
+ "ald\u0131m",
2674
+ "ald\u0131k",
2675
+ "geli\u015Ftirir",
2676
+ "uyand\u0131k",
2677
+ "kuruludur",
2678
+ "\xE7\u0131kt\u0131k",
2679
+ "izledim",
2680
+ "izledik",
2681
+ "uyudum",
2682
+ "yatt\u0131m",
2683
+ "gittim",
2684
+ "yapt\u0131m",
2685
+ "\xF6\u011Frendim"
2686
+ ]);
2687
+ return terminals.has(word) || word.endsWith(".");
2688
+ }
2689
+ _assertInit() {
2690
+ if (!this._initialized) throw new Error("ResonanceSDK: Not initialized. Call await sdk.init() first.");
2691
+ }
2692
+ };
2693
+ export {
2694
+ ResonanceSDK
2695
+ };
2696
+ /**
2697
+ * Resonance SDK v1.0 - B2B Commercial Edge AI Engine
2698
+ * Unified SDK interface wrapping the Turkish Resonance AI Core (v5.2).
2699
+ * Supports both Browser (fetch/streaming) and Node.js environments.
2700
+ *
2701
+ * @license Commercial - Per-device licensing
2702
+ * @author Turkish Resonance AI Core Team
2703
+ */