@yugenlab/vaayu 0.1.11 → 0.1.12
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/chunks/{agentic-tool-loop-O3NUV7KG.js → agentic-tool-loop-NQESOBLC.js} +2 -2
- package/chunks/akasha-5C5Q6NMP.js +12 -0
- package/chunks/{chunk-7XV5ISV7.js → chunk-26K6DS6N.js} +2 -2
- package/chunks/chunk-5E3ZS5SW.js +529 -0
- package/chunks/{chunk-D46QTN3G.js → chunk-ARZCIITZ.js} +47 -18
- package/chunks/{chunk-ZYY6N3SP.js → chunk-FEDPZOZ5.js} +548 -389
- package/chunks/{chunk-3AYSJ7WB.js → chunk-GWYC7R2L.js} +13 -7
- package/chunks/chunk-H46F2Y6R.js +134 -0
- package/chunks/{chunk-QV4GPIPT.js → chunk-HXHDP2PZ.js} +8 -4
- package/chunks/chunk-KVQH4LE7.js +396 -0
- package/chunks/{chunk-Z576WVLG.js → chunk-LJCT7UYP.js} +17 -7
- package/chunks/{chunk-LJUEMPLG.js → chunk-M2RLX5LU.js} +32 -14
- package/chunks/{chunk-IGKYKEKT.js → chunk-NAQKA54E.js} +8 -2
- package/chunks/{chunk-F6RNEGFX.js → chunk-PZ4AQ22L.js} +78 -13
- package/chunks/{chunk-G2QREGXK.js → chunk-R273KC7J.js} +275 -2
- package/chunks/{chunk-A3HOZBC5.js → chunk-RVKTGKFD.js} +2 -2
- package/chunks/{chunk-VCUJES75.js → chunk-TSOQ2CT3.js} +763 -620
- package/chunks/{chunk-V2ZIKDN4.js → chunk-VEZ2DI2M.js} +16 -5
- package/chunks/{chunk-W4PVGBUH.js → chunk-XP3NIH5F.js} +7 -3
- package/chunks/{chunk-7AYYXHYZ.js → chunk-Y6IZH6FT.js} +19 -4
- package/chunks/{chunk-JZTFJE7M.js → chunk-YRTGGYJU.js} +14 -10
- package/chunks/{consolidation-indexer-VIWOP6VO.js → consolidation-indexer-KPXORCJ4.js} +9 -9
- package/chunks/database-BX3LVYXS.js +11 -0
- package/chunks/{day-consolidation-HMHSXIOM.js → day-consolidation-CR3TJFAL.js} +5 -5
- package/chunks/{dist-CY5NX2IK.js → dist-ESCM3CP5.js} +31 -21
- package/chunks/graphrag-73XA7LBX.js +14 -0
- package/chunks/hierarchical-temporal-search-GHKVKNZ6.js +8 -0
- package/chunks/hybrid-search-OD756RDV.js +20 -0
- package/chunks/{memory-store-LEERUQGL.js → memory-store-4GCBR2DZ.js} +4 -4
- package/chunks/periodic-consolidation-IINCHP6L.js +11 -0
- package/chunks/{postgres-7GZDDX77.js → postgres-YLCUNVPQ.js} +2 -2
- package/chunks/recall-64RROTUC.js +21 -0
- package/chunks/search-JVCDNTAJ.js +19 -0
- package/chunks/{session-store-O3TS7DUY.js → session-store-3EDQZEDS.js} +12 -6
- package/chunks/{sqlite-7BC4DJTN.js → sqlite-4N7YH2KK.js} +2 -2
- package/chunks/{src-6GVZTUH6.js → src-OPSDZEFI.js} +2 -2
- package/chunks/{suncalc-NOHGYHDU.js → suncalc-RM7URNUR.js} +2 -2
- package/chunks/{tree-RSHKDTCR.js → tree-FIUVGJ5J.js} +2 -2
- package/chunks/{vasana-engine-BJFHJVGM.js → vasana-engine-W4PYWT5H.js} +5 -5
- package/gateway.js +2358 -768
- package/package.json +1 -1
- package/pair-cli.js +2 -2
- package/chunks/chunk-2OBLQJYJ.js +0 -198
- package/chunks/chunk-67DXWEKG.js +0 -123
- package/chunks/graphrag-T2QWNX57.js +0 -14
- package/chunks/hierarchical-temporal-search-U6DG74IR.js +0 -8
- package/chunks/hybrid-search-BYTXCOXP.js +0 -20
- package/chunks/periodic-consolidation-D6SSKZ7H.js +0 -11
- package/chunks/recall-LNRQVATQ.js +0 -21
- package/chunks/search-BIODUW2P.js +0 -19
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import "./chunk-
|
|
1
|
+
import "./chunk-NAQKA54E.js";
|
|
2
2
|
|
|
3
3
|
// apps/gateway/dist/agent/agentic-tool-loop.js
|
|
4
4
|
async function runAgenticToolLoop(params) {
|
|
@@ -144,4 +144,4 @@ async function runAgenticToolLoop(params) {
|
|
|
144
144
|
export {
|
|
145
145
|
runAgenticToolLoop
|
|
146
146
|
};
|
|
147
|
-
//# sourceMappingURL=agentic-tool-loop-
|
|
147
|
+
//# sourceMappingURL=agentic-tool-loop-NQESOBLC.js.map
|
|
@@ -7,7 +7,7 @@ var DEPTH_BOOST = {
|
|
|
7
7
|
async function hierarchicalTemporalSearch(query, options) {
|
|
8
8
|
const limit = options?.limit ?? 10;
|
|
9
9
|
const results = [];
|
|
10
|
-
const { searchConsolidationSummaries } = await import("./consolidation-indexer-
|
|
10
|
+
const { searchConsolidationSummaries } = await import("./consolidation-indexer-KPXORCJ4.js");
|
|
11
11
|
const yearlyHits = await searchConsolidationSummaries(query, "yearly", {
|
|
12
12
|
limit: 3,
|
|
13
13
|
project: options?.project
|
|
@@ -122,4 +122,4 @@ function deduplicateAndSort(results, limit) {
|
|
|
122
122
|
export {
|
|
123
123
|
hierarchicalTemporalSearch
|
|
124
124
|
};
|
|
125
|
-
//# sourceMappingURL=chunk-
|
|
125
|
+
//# sourceMappingURL=chunk-26K6DS6N.js.map
|
|
@@ -0,0 +1,529 @@
|
|
|
1
|
+
// ../chitragupta/packages/smriti/dist/akasha-integration.js
|
|
2
|
+
var CREATE_TABLE_SQL = `
|
|
3
|
+
CREATE TABLE IF NOT EXISTS akasha_traces (
|
|
4
|
+
id TEXT PRIMARY KEY,
|
|
5
|
+
agent_id TEXT NOT NULL,
|
|
6
|
+
trace_type TEXT NOT NULL,
|
|
7
|
+
topic TEXT NOT NULL,
|
|
8
|
+
content TEXT NOT NULL,
|
|
9
|
+
strength REAL NOT NULL,
|
|
10
|
+
reinforcements INTEGER NOT NULL DEFAULT 0,
|
|
11
|
+
metadata TEXT,
|
|
12
|
+
created_at INTEGER NOT NULL,
|
|
13
|
+
last_reinforced_at INTEGER NOT NULL
|
|
14
|
+
);
|
|
15
|
+
CREATE INDEX IF NOT EXISTS idx_akasha_topic ON akasha_traces(topic);
|
|
16
|
+
CREATE INDEX IF NOT EXISTS idx_akasha_strength ON akasha_traces(strength DESC);
|
|
17
|
+
`;
|
|
18
|
+
var UPSERT_SQL = `
|
|
19
|
+
INSERT OR REPLACE INTO akasha_traces
|
|
20
|
+
(id, agent_id, trace_type, topic, content, strength,
|
|
21
|
+
reinforcements, metadata, created_at, last_reinforced_at)
|
|
22
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
23
|
+
`;
|
|
24
|
+
var ENSURE_TABLE_SQL = `
|
|
25
|
+
CREATE TABLE IF NOT EXISTS akasha_traces (
|
|
26
|
+
id TEXT PRIMARY KEY,
|
|
27
|
+
agent_id TEXT NOT NULL,
|
|
28
|
+
trace_type TEXT NOT NULL,
|
|
29
|
+
topic TEXT NOT NULL,
|
|
30
|
+
content TEXT NOT NULL,
|
|
31
|
+
strength REAL NOT NULL,
|
|
32
|
+
reinforcements INTEGER NOT NULL DEFAULT 0,
|
|
33
|
+
metadata TEXT,
|
|
34
|
+
created_at INTEGER NOT NULL,
|
|
35
|
+
last_reinforced_at INTEGER NOT NULL
|
|
36
|
+
);
|
|
37
|
+
`;
|
|
38
|
+
function safeParseJson(raw) {
|
|
39
|
+
if (!raw)
|
|
40
|
+
return {};
|
|
41
|
+
try {
|
|
42
|
+
const parsed = JSON.parse(raw);
|
|
43
|
+
return typeof parsed === "object" && parsed !== null ? parsed : {};
|
|
44
|
+
} catch {
|
|
45
|
+
return {};
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
function persistTraces(traces, db) {
|
|
49
|
+
db.exec(CREATE_TABLE_SQL);
|
|
50
|
+
const upsert = db.prepare(UPSERT_SQL);
|
|
51
|
+
for (const trace of traces.values()) {
|
|
52
|
+
upsert.run(trace.id, trace.agentId, trace.traceType, trace.topic, trace.content, trace.strength, trace.reinforcements, JSON.stringify(trace.metadata), trace.createdAt, trace.lastReinforcedAt);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
function restoreTraces(db, config) {
|
|
56
|
+
db.exec(ENSURE_TABLE_SQL);
|
|
57
|
+
const rows = db.prepare("SELECT * FROM akasha_traces").all();
|
|
58
|
+
const traces = /* @__PURE__ */ new Map();
|
|
59
|
+
const reinforcedBy = /* @__PURE__ */ new Map();
|
|
60
|
+
for (const row of rows) {
|
|
61
|
+
if (row.strength < config.minStrength)
|
|
62
|
+
continue;
|
|
63
|
+
const trace = {
|
|
64
|
+
id: row.id,
|
|
65
|
+
agentId: row.agent_id,
|
|
66
|
+
traceType: row.trace_type,
|
|
67
|
+
topic: row.topic,
|
|
68
|
+
content: row.content,
|
|
69
|
+
strength: row.strength,
|
|
70
|
+
reinforcements: row.reinforcements,
|
|
71
|
+
metadata: safeParseJson(row.metadata),
|
|
72
|
+
createdAt: row.created_at,
|
|
73
|
+
lastReinforcedAt: row.last_reinforced_at
|
|
74
|
+
};
|
|
75
|
+
traces.set(trace.id, trace);
|
|
76
|
+
reinforcedBy.set(trace.id, /* @__PURE__ */ new Set([trace.agentId]));
|
|
77
|
+
}
|
|
78
|
+
return { traces, reinforcedBy };
|
|
79
|
+
}
|
|
80
|
+
function tracesToGraphNodes(traces, minStrength) {
|
|
81
|
+
const nodes = [];
|
|
82
|
+
for (const trace of traces.values()) {
|
|
83
|
+
if (trace.strength < minStrength)
|
|
84
|
+
continue;
|
|
85
|
+
nodes.push({
|
|
86
|
+
id: trace.id,
|
|
87
|
+
label: `[${trace.traceType}] ${trace.topic}`,
|
|
88
|
+
content: trace.content,
|
|
89
|
+
type: "akasha",
|
|
90
|
+
weight: trace.strength
|
|
91
|
+
});
|
|
92
|
+
}
|
|
93
|
+
return nodes;
|
|
94
|
+
}
|
|
95
|
+
function boostResultsWithTraces(traces, config, results, query) {
|
|
96
|
+
const queryTokens = new Set(tokenize(query));
|
|
97
|
+
const matchingTraces = [];
|
|
98
|
+
if (queryTokens.size > 0) {
|
|
99
|
+
for (const trace of traces.values()) {
|
|
100
|
+
if (trace.strength < config.minStrength)
|
|
101
|
+
continue;
|
|
102
|
+
const traceTokens = /* @__PURE__ */ new Set([
|
|
103
|
+
...tokenize(trace.topic),
|
|
104
|
+
...tokenize(trace.content)
|
|
105
|
+
]);
|
|
106
|
+
const sim = jaccardSimilarity(queryTokens, traceTokens);
|
|
107
|
+
if (sim > 0) {
|
|
108
|
+
matchingTraces.push({ trace, similarity: sim });
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
matchingTraces.sort((a, b) => b.similarity - a.similarity);
|
|
112
|
+
}
|
|
113
|
+
return results.map((result) => {
|
|
114
|
+
let traceBoost = 0;
|
|
115
|
+
if (queryTokens.size > 0 && matchingTraces.length > 0) {
|
|
116
|
+
const resultTokens = result.content ? new Set(tokenize(result.content)) : /* @__PURE__ */ new Set();
|
|
117
|
+
let bestBoost = 0;
|
|
118
|
+
for (const { trace, similarity } of matchingTraces) {
|
|
119
|
+
if (result.id === trace.id) {
|
|
120
|
+
bestBoost = Math.max(bestBoost, trace.strength);
|
|
121
|
+
break;
|
|
122
|
+
}
|
|
123
|
+
if (resultTokens.size > 0) {
|
|
124
|
+
const traceTokens = /* @__PURE__ */ new Set([
|
|
125
|
+
...tokenize(trace.topic),
|
|
126
|
+
...tokenize(trace.content)
|
|
127
|
+
]);
|
|
128
|
+
const resultSim = jaccardSimilarity(resultTokens, traceTokens);
|
|
129
|
+
if (resultSim > 0.1) {
|
|
130
|
+
bestBoost = Math.max(bestBoost, similarity * trace.strength);
|
|
131
|
+
}
|
|
132
|
+
} else {
|
|
133
|
+
bestBoost = Math.max(bestBoost, similarity * trace.strength);
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
traceBoost = bestBoost * config.traceBoostFactor;
|
|
137
|
+
}
|
|
138
|
+
return {
|
|
139
|
+
...result,
|
|
140
|
+
score: result.score * (1 + traceBoost),
|
|
141
|
+
traceBoost
|
|
142
|
+
};
|
|
143
|
+
});
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
// ../chitragupta/packages/smriti/dist/akasha.js
|
|
147
|
+
var STOP_WORDS = /* @__PURE__ */ new Set([
|
|
148
|
+
"a",
|
|
149
|
+
"an",
|
|
150
|
+
"the",
|
|
151
|
+
"and",
|
|
152
|
+
"or",
|
|
153
|
+
"but",
|
|
154
|
+
"in",
|
|
155
|
+
"on",
|
|
156
|
+
"at",
|
|
157
|
+
"to",
|
|
158
|
+
"for",
|
|
159
|
+
"of",
|
|
160
|
+
"with",
|
|
161
|
+
"by",
|
|
162
|
+
"from",
|
|
163
|
+
"is",
|
|
164
|
+
"it",
|
|
165
|
+
"its",
|
|
166
|
+
"this",
|
|
167
|
+
"that",
|
|
168
|
+
"was",
|
|
169
|
+
"are",
|
|
170
|
+
"be",
|
|
171
|
+
"been",
|
|
172
|
+
"being",
|
|
173
|
+
"have",
|
|
174
|
+
"has",
|
|
175
|
+
"had",
|
|
176
|
+
"do",
|
|
177
|
+
"does",
|
|
178
|
+
"did",
|
|
179
|
+
"will",
|
|
180
|
+
"would",
|
|
181
|
+
"could",
|
|
182
|
+
"should",
|
|
183
|
+
"not",
|
|
184
|
+
"no",
|
|
185
|
+
"so",
|
|
186
|
+
"if",
|
|
187
|
+
"then",
|
|
188
|
+
"than",
|
|
189
|
+
"too",
|
|
190
|
+
"very",
|
|
191
|
+
"can",
|
|
192
|
+
"just",
|
|
193
|
+
"about",
|
|
194
|
+
"into",
|
|
195
|
+
"over",
|
|
196
|
+
"after"
|
|
197
|
+
]);
|
|
198
|
+
var FNV_OFFSET = 2166136261;
|
|
199
|
+
var FNV_PRIME = 16777619;
|
|
200
|
+
function fnv1a(input) {
|
|
201
|
+
let hash = FNV_OFFSET;
|
|
202
|
+
for (let i = 0; i < input.length; i++) {
|
|
203
|
+
hash ^= input.charCodeAt(i);
|
|
204
|
+
hash = Math.imul(hash, FNV_PRIME) >>> 0;
|
|
205
|
+
}
|
|
206
|
+
return hash.toString(16).padStart(8, "0");
|
|
207
|
+
}
|
|
208
|
+
function tokenize(text) {
|
|
209
|
+
return text.toLowerCase().replace(/[^a-z0-9\s]/g, " ").split(/\s+/).filter((t) => t.length >= 2 && !STOP_WORDS.has(t));
|
|
210
|
+
}
|
|
211
|
+
function jaccardSimilarity(a, b) {
|
|
212
|
+
if (a.size === 0 && b.size === 0)
|
|
213
|
+
return 1;
|
|
214
|
+
let intersection = 0;
|
|
215
|
+
for (const token of a) {
|
|
216
|
+
if (b.has(token))
|
|
217
|
+
intersection++;
|
|
218
|
+
}
|
|
219
|
+
const union = a.size + b.size - intersection;
|
|
220
|
+
return union === 0 ? 0 : intersection / union;
|
|
221
|
+
}
|
|
222
|
+
var DAY_MS = 864e5;
|
|
223
|
+
var DEFAULT_CONFIG = {
|
|
224
|
+
decayHalfLife: 7 * DAY_MS,
|
|
225
|
+
minStrength: 0.01,
|
|
226
|
+
maxTraces: 5e3,
|
|
227
|
+
reinforcementBoost: 0.15,
|
|
228
|
+
initialStrength: 0.5,
|
|
229
|
+
topKRetrieval: 10,
|
|
230
|
+
traceBoostFactor: 0.3,
|
|
231
|
+
diminishingAlpha: 0.3,
|
|
232
|
+
frequencyDecayBeta: 0.5
|
|
233
|
+
};
|
|
234
|
+
var HARD_CEILINGS = { maxTraces: 5e4, minDecayHalfLife: 36e5, maxContentSize: 1e4 };
|
|
235
|
+
var AkashaField = class {
|
|
236
|
+
config;
|
|
237
|
+
traces = /* @__PURE__ */ new Map();
|
|
238
|
+
/** Tracks which agents reinforced which traces (prevents self/duplicate). */
|
|
239
|
+
reinforcedBy = /* @__PURE__ */ new Map();
|
|
240
|
+
onEvent;
|
|
241
|
+
constructor(config) {
|
|
242
|
+
this.config = {
|
|
243
|
+
...DEFAULT_CONFIG,
|
|
244
|
+
...config,
|
|
245
|
+
maxTraces: Math.min(config?.maxTraces ?? DEFAULT_CONFIG.maxTraces, HARD_CEILINGS.maxTraces),
|
|
246
|
+
decayHalfLife: Math.max(config?.decayHalfLife ?? DEFAULT_CONFIG.decayHalfLife, HARD_CEILINGS.minDecayHalfLife)
|
|
247
|
+
};
|
|
248
|
+
}
|
|
249
|
+
/** Set a callback for trace lifecycle events. */
|
|
250
|
+
setOnEvent(handler) {
|
|
251
|
+
this.onEvent = handler;
|
|
252
|
+
}
|
|
253
|
+
// ─── Leaving Traces ─────────────────────────────────────────────────
|
|
254
|
+
/**
|
|
255
|
+
* Agent leaves a stigmergic trace after solving or discovering something.
|
|
256
|
+
*
|
|
257
|
+
* @param agentId - Which agent is leaving this trace.
|
|
258
|
+
* @param type - The category of knowledge.
|
|
259
|
+
* @param topic - What the trace is about (used for matching).
|
|
260
|
+
* @param content - The actual knowledge or solution.
|
|
261
|
+
* @param metadata - Optional metadata for the trace.
|
|
262
|
+
* @returns The created StigmergicTrace.
|
|
263
|
+
*/
|
|
264
|
+
leave(agentId, type, topic, content, metadata) {
|
|
265
|
+
const truncatedContent = content.length > HARD_CEILINGS.maxContentSize ? content.slice(0, HARD_CEILINGS.maxContentSize) : content;
|
|
266
|
+
const id = `aks-${fnv1a(agentId + ":" + type + ":" + topic + ":" + truncatedContent)}`;
|
|
267
|
+
const now = Date.now();
|
|
268
|
+
const trace = {
|
|
269
|
+
id,
|
|
270
|
+
agentId,
|
|
271
|
+
traceType: type,
|
|
272
|
+
topic,
|
|
273
|
+
content: truncatedContent,
|
|
274
|
+
strength: this.config.initialStrength,
|
|
275
|
+
reinforcements: 0,
|
|
276
|
+
metadata: metadata ?? {},
|
|
277
|
+
createdAt: now,
|
|
278
|
+
lastReinforcedAt: now
|
|
279
|
+
};
|
|
280
|
+
this.traces.set(id, trace);
|
|
281
|
+
this.reinforcedBy.set(id, /* @__PURE__ */ new Set([agentId]));
|
|
282
|
+
if (this.traces.size > this.config.maxTraces)
|
|
283
|
+
this.evictWeakest();
|
|
284
|
+
this.onEvent?.({ type: "trace:created", traceId: id, topic });
|
|
285
|
+
return trace;
|
|
286
|
+
}
|
|
287
|
+
/**
|
|
288
|
+
* Reinforce an existing trace -- another agent found it useful.
|
|
289
|
+
*
|
|
290
|
+
* @param traceId - The trace to reinforce.
|
|
291
|
+
* @param agentId - The agent reinforcing it.
|
|
292
|
+
* @returns The updated trace, or null if not found / already reinforced.
|
|
293
|
+
*/
|
|
294
|
+
reinforce(traceId, agentId) {
|
|
295
|
+
const trace = this.traces.get(traceId);
|
|
296
|
+
if (!trace)
|
|
297
|
+
return null;
|
|
298
|
+
const agents = this.reinforcedBy.get(traceId);
|
|
299
|
+
if (agents?.has(agentId))
|
|
300
|
+
return null;
|
|
301
|
+
const alpha = this.config.diminishingAlpha;
|
|
302
|
+
const effectiveBoost = this.config.reinforcementBoost / (1 + alpha * trace.reinforcements);
|
|
303
|
+
trace.strength = Math.min(1, trace.strength + effectiveBoost);
|
|
304
|
+
trace.reinforcements++;
|
|
305
|
+
trace.lastReinforcedAt = Date.now();
|
|
306
|
+
if (!agents) {
|
|
307
|
+
this.reinforcedBy.set(traceId, /* @__PURE__ */ new Set([agentId]));
|
|
308
|
+
} else {
|
|
309
|
+
agents.add(agentId);
|
|
310
|
+
}
|
|
311
|
+
this.onEvent?.({ type: "trace:reinforced", traceId, topic: trace.topic });
|
|
312
|
+
return trace;
|
|
313
|
+
}
|
|
314
|
+
// ─── Following Traces ────────────────────────────────────────────────
|
|
315
|
+
/**
|
|
316
|
+
* Find relevant traces by Jaccard similarity on topic/content tokens.
|
|
317
|
+
*
|
|
318
|
+
* @param topic - The query to match against trace topics and content.
|
|
319
|
+
* @param opts - Optional filters: type, minStrength, limit.
|
|
320
|
+
* @returns Matching traces sorted by relevance score.
|
|
321
|
+
*/
|
|
322
|
+
query(topic, opts) {
|
|
323
|
+
const queryTokens = new Set(tokenize(topic));
|
|
324
|
+
if (queryTokens.size === 0)
|
|
325
|
+
return [];
|
|
326
|
+
const minStr = opts?.minStrength ?? this.config.minStrength;
|
|
327
|
+
const limit = opts?.limit ?? this.config.topKRetrieval;
|
|
328
|
+
const scored = [];
|
|
329
|
+
for (const trace of this.traces.values()) {
|
|
330
|
+
if (trace.strength < minStr)
|
|
331
|
+
continue;
|
|
332
|
+
if (opts?.type && trace.traceType !== opts.type)
|
|
333
|
+
continue;
|
|
334
|
+
const traceTokens = /* @__PURE__ */ new Set([...tokenize(trace.topic), ...tokenize(trace.content)]);
|
|
335
|
+
const similarity = jaccardSimilarity(queryTokens, traceTokens);
|
|
336
|
+
if (similarity <= 0)
|
|
337
|
+
continue;
|
|
338
|
+
scored.push({ trace, score: similarity * trace.strength });
|
|
339
|
+
}
|
|
340
|
+
scored.sort((a, b) => b.score - a.score);
|
|
341
|
+
return scored.slice(0, limit).map((s) => s.trace);
|
|
342
|
+
}
|
|
343
|
+
/**
|
|
344
|
+
* Get the strongest traces overall -- the "highways" of collective knowledge.
|
|
345
|
+
*
|
|
346
|
+
* @param limit - Maximum number of traces to return.
|
|
347
|
+
* @returns Traces sorted by strength descending.
|
|
348
|
+
*/
|
|
349
|
+
strongest(limit) {
|
|
350
|
+
const all = [...this.traces.values()];
|
|
351
|
+
all.sort((a, b) => b.strength - a.strength);
|
|
352
|
+
return all.slice(0, limit ?? this.config.topKRetrieval);
|
|
353
|
+
}
|
|
354
|
+
/**
|
|
355
|
+
* Get traces left by a specific agent.
|
|
356
|
+
*
|
|
357
|
+
* @param agentId - The agent whose traces to retrieve.
|
|
358
|
+
* @param limit - Maximum results.
|
|
359
|
+
* @returns Traces by the agent, sorted by creation time descending.
|
|
360
|
+
*/
|
|
361
|
+
byAgent(agentId, limit) {
|
|
362
|
+
const results = [];
|
|
363
|
+
for (const trace of this.traces.values()) {
|
|
364
|
+
if (trace.agentId === agentId)
|
|
365
|
+
results.push(trace);
|
|
366
|
+
}
|
|
367
|
+
results.sort((a, b) => b.createdAt - a.createdAt);
|
|
368
|
+
return results.slice(0, limit ?? this.config.topKRetrieval);
|
|
369
|
+
}
|
|
370
|
+
// ─── Decay & Maintenance ─────────────────────────────────────────────
|
|
371
|
+
/**
|
|
372
|
+
* Apply temporal decay to all traces. Traces that fall below `minStrength`
|
|
373
|
+
* after decay are pruned automatically.
|
|
374
|
+
*
|
|
375
|
+
* @returns Counts of decayed and pruned traces.
|
|
376
|
+
*/
|
|
377
|
+
decay() {
|
|
378
|
+
const now = Date.now();
|
|
379
|
+
const baseHalfLife = this.config.decayHalfLife;
|
|
380
|
+
const beta = this.config.frequencyDecayBeta;
|
|
381
|
+
let decayed = 0;
|
|
382
|
+
const toPrune = [];
|
|
383
|
+
for (const [id, trace] of this.traces) {
|
|
384
|
+
const elapsed = now - trace.lastReinforcedAt;
|
|
385
|
+
if (elapsed <= 0)
|
|
386
|
+
continue;
|
|
387
|
+
const effectiveHalfLife = baseHalfLife * (1 + beta * Math.log(1 + trace.reinforcements));
|
|
388
|
+
const factor = Math.exp(-Math.LN2 * elapsed / effectiveHalfLife);
|
|
389
|
+
const newStrength = trace.strength * factor;
|
|
390
|
+
if (Math.abs(newStrength - trace.strength) > 1e-10) {
|
|
391
|
+
trace.strength = newStrength;
|
|
392
|
+
decayed++;
|
|
393
|
+
}
|
|
394
|
+
if (trace.strength < this.config.minStrength)
|
|
395
|
+
toPrune.push(id);
|
|
396
|
+
}
|
|
397
|
+
for (const id of toPrune) {
|
|
398
|
+
this.traces.delete(id);
|
|
399
|
+
this.reinforcedBy.delete(id);
|
|
400
|
+
}
|
|
401
|
+
return { decayed, pruned: toPrune.length };
|
|
402
|
+
}
|
|
403
|
+
/**
|
|
404
|
+
* Remove traces below the minStrength threshold.
|
|
405
|
+
*
|
|
406
|
+
* @returns The number of traces pruned.
|
|
407
|
+
*/
|
|
408
|
+
prune() {
|
|
409
|
+
const toPrune = [];
|
|
410
|
+
for (const [id, trace] of this.traces) {
|
|
411
|
+
if (trace.strength < this.config.minStrength)
|
|
412
|
+
toPrune.push(id);
|
|
413
|
+
}
|
|
414
|
+
for (const id of toPrune) {
|
|
415
|
+
this.traces.delete(id);
|
|
416
|
+
this.reinforcedBy.delete(id);
|
|
417
|
+
}
|
|
418
|
+
return toPrune.length;
|
|
419
|
+
}
|
|
420
|
+
// ─── Persistence (delegated to akasha-integration) ───────────────────
|
|
421
|
+
/**
|
|
422
|
+
* Persist all traces to a SQLite database.
|
|
423
|
+
*
|
|
424
|
+
* @param db - A duck-typed database handle with prepare/exec methods.
|
|
425
|
+
*/
|
|
426
|
+
persist(db) {
|
|
427
|
+
persistTraces(this.traces, db);
|
|
428
|
+
}
|
|
429
|
+
/**
|
|
430
|
+
* Restore traces from a SQLite database.
|
|
431
|
+
*
|
|
432
|
+
* @param db - A duck-typed database handle with prepare/exec methods.
|
|
433
|
+
*/
|
|
434
|
+
restore(db) {
|
|
435
|
+
const result = restoreTraces(db, this.config);
|
|
436
|
+
this.traces.clear();
|
|
437
|
+
this.reinforcedBy.clear();
|
|
438
|
+
for (const [k, v] of result.traces)
|
|
439
|
+
this.traces.set(k, v);
|
|
440
|
+
for (const [k, v] of result.reinforcedBy)
|
|
441
|
+
this.reinforcedBy.set(k, v);
|
|
442
|
+
}
|
|
443
|
+
// ─── GraphRAG (delegated to akasha-integration) ──────────────────────
|
|
444
|
+
/**
|
|
445
|
+
* Register traces as graph nodes suitable for GraphRAG retrieval.
|
|
446
|
+
*
|
|
447
|
+
* @returns An array of graph-compatible node objects.
|
|
448
|
+
*/
|
|
449
|
+
toGraphNodes() {
|
|
450
|
+
return tracesToGraphNodes(this.traces, this.config.minStrength);
|
|
451
|
+
}
|
|
452
|
+
/**
|
|
453
|
+
* Boost graph search results that have matching stigmergic traces.
|
|
454
|
+
*
|
|
455
|
+
* @param results - The original search results with id and score.
|
|
456
|
+
* @param query - The search query used for topic matching.
|
|
457
|
+
* @returns Results with boosted scores and traceBoost metadata.
|
|
458
|
+
*/
|
|
459
|
+
boostResults(results, query) {
|
|
460
|
+
return boostResultsWithTraces(this.traces, this.config, results, query);
|
|
461
|
+
}
|
|
462
|
+
// ─── Stats ───────────────────────────────────────────────────────────
|
|
463
|
+
/**
|
|
464
|
+
* Return statistics about the current state of the Akasha field.
|
|
465
|
+
*
|
|
466
|
+
* @returns Total/active counts, per-type breakdown, average strength,
|
|
467
|
+
* strongest topic, and total reinforcements.
|
|
468
|
+
*/
|
|
469
|
+
stats() {
|
|
470
|
+
const byType = {
|
|
471
|
+
solution: 0,
|
|
472
|
+
warning: 0,
|
|
473
|
+
shortcut: 0,
|
|
474
|
+
pattern: 0,
|
|
475
|
+
correction: 0,
|
|
476
|
+
preference: 0
|
|
477
|
+
};
|
|
478
|
+
let totalStrength = 0;
|
|
479
|
+
let activeCount = 0;
|
|
480
|
+
let totalReinforcements = 0;
|
|
481
|
+
let strongestTrace = null;
|
|
482
|
+
for (const trace of this.traces.values()) {
|
|
483
|
+
byType[trace.traceType]++;
|
|
484
|
+
totalStrength += trace.strength;
|
|
485
|
+
totalReinforcements += trace.reinforcements;
|
|
486
|
+
if (trace.strength >= this.config.minStrength)
|
|
487
|
+
activeCount++;
|
|
488
|
+
if (!strongestTrace || trace.strength > strongestTrace.strength) {
|
|
489
|
+
strongestTrace = trace;
|
|
490
|
+
}
|
|
491
|
+
}
|
|
492
|
+
return {
|
|
493
|
+
totalTraces: this.traces.size,
|
|
494
|
+
activeTraces: activeCount,
|
|
495
|
+
byType,
|
|
496
|
+
avgStrength: this.traces.size > 0 ? totalStrength / this.traces.size : 0,
|
|
497
|
+
strongestTopic: strongestTrace?.topic ?? null,
|
|
498
|
+
totalReinforcements
|
|
499
|
+
};
|
|
500
|
+
}
|
|
501
|
+
// ─── Internal Helpers ────────────────────────────────────────────────
|
|
502
|
+
/** Evict the weakest trace. Ties broken by oldest createdAt. */
|
|
503
|
+
evictWeakest() {
|
|
504
|
+
let weakestId = null;
|
|
505
|
+
let weakestStrength = Infinity;
|
|
506
|
+
let weakestCreatedAt = Infinity;
|
|
507
|
+
for (const [id, trace] of this.traces) {
|
|
508
|
+
if (trace.strength < weakestStrength || trace.strength === weakestStrength && trace.createdAt < weakestCreatedAt) {
|
|
509
|
+
weakestId = id;
|
|
510
|
+
weakestStrength = trace.strength;
|
|
511
|
+
weakestCreatedAt = trace.createdAt;
|
|
512
|
+
}
|
|
513
|
+
}
|
|
514
|
+
if (!weakestId && this.traces.size > 0) {
|
|
515
|
+
weakestId = this.traces.keys().next().value;
|
|
516
|
+
}
|
|
517
|
+
if (weakestId) {
|
|
518
|
+
this.traces.delete(weakestId);
|
|
519
|
+
this.reinforcedBy.delete(weakestId);
|
|
520
|
+
}
|
|
521
|
+
}
|
|
522
|
+
};
|
|
523
|
+
|
|
524
|
+
export {
|
|
525
|
+
tokenize,
|
|
526
|
+
jaccardSimilarity,
|
|
527
|
+
AkashaField
|
|
528
|
+
};
|
|
529
|
+
//# sourceMappingURL=chunk-5E3ZS5SW.js.map
|