open-agents-ai 0.187.161 → 0.187.163

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/dist/index.js +528 -7
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -3680,7 +3680,7 @@ var init_memory_search = __esm({
3680
3680
  "use strict";
3681
3681
  MemorySearchTool = class {
3682
3682
  name = "memory_search";
3683
- description = "Search across all memory entries by relevance. Unlike memory_read (exact topic+key), this finds relevant memories using text matching. Use when you don't know the exact topic or key, or want to find all memories related to a concept.";
3683
+ description = "Search across all memory entries by relevance. Unlike memory_read (exact topic+key), this finds relevant memories using text matching or associative graph traversal. Use when you don't know the exact topic or key, or want to find all memories related to a concept. Mode 'graph' uses knowledge graph traversal for multi-hop associative queries (e.g. 'what caused the auth error?').";
3684
3684
  parameters = {
3685
3685
  type: "object",
3686
3686
  properties: {
@@ -3691,6 +3691,11 @@ var init_memory_search = __esm({
3691
3691
  max_results: {
3692
3692
  type: "number",
3693
3693
  description: "Maximum number of results to return (default: 10)"
3694
+ },
3695
+ mode: {
3696
+ type: "string",
3697
+ enum: ["text", "graph", "episodes"],
3698
+ description: "Search mode: 'text' (default \u2014 TF-IDF), 'graph' (PPR traversal), 'episodes' (recent episodes). Default: text."
3694
3699
  }
3695
3700
  },
3696
3701
  required: ["query"]
@@ -3702,7 +3707,87 @@ var init_memory_search = __esm({
3702
3707
  async execute(args) {
3703
3708
  const query = args["query"];
3704
3709
  const maxResults = args["max_results"] ?? 10;
3710
+ const mode = args["mode"] ?? "text";
3705
3711
  const start2 = performance.now();
3712
+ if (mode === "graph" || mode === "episodes") {
3713
+ try {
3714
+ const { join: pathJoin } = await import("node:path");
3715
+ const { existsSync: pathExists } = await import("node:fs");
3716
+ const { createRequire: createRequire7 } = await import("node:module");
3717
+ const oaDir = pathJoin(this.workingDir, ".oa");
3718
+ const epDbPath = pathJoin(oaDir, "episodes.db");
3719
+ const kgDbPath = pathJoin(oaDir, "knowledge.db");
3720
+ if (!pathExists(epDbPath)) {
3721
+ return { success: true, output: `No episode store found. Run tasks to build the knowledge graph.`, durationMs: performance.now() - start2 };
3722
+ }
3723
+ const req2 = createRequire7(import.meta.url);
3724
+ const Database2 = req2("better-sqlite3");
3725
+ if (mode === "episodes") {
3726
+ const db = new Database2(epDbPath, { readonly: true });
3727
+ const queryLower = query.toLowerCase();
3728
+ const rows = db.prepare(`
3729
+ SELECT * FROM episodes
3730
+ WHERE content LIKE ? OR tool_name LIKE ?
3731
+ ORDER BY importance DESC, timestamp DESC
3732
+ LIMIT ?
3733
+ `).all(`%${queryLower}%`, `%${queryLower}%`, maxResults);
3734
+ db.close();
3735
+ if (rows.length === 0) {
3736
+ return { success: true, output: `No episodes found for "${query}".`, durationMs: performance.now() - start2 };
3737
+ }
3738
+ const lines = rows.map((r2) => `[${r2.tool_name ?? r2.modality}] (importance: ${r2.importance}, decay: ${r2.decay_class})
3739
+ ${r2.content.slice(0, 200)}`);
3740
+ return {
3741
+ success: true,
3742
+ output: `Episode search for "${query}" (${rows.length} results):
3743
+
3744
+ ${lines.join("\n\n")}`,
3745
+ durationMs: performance.now() - start2
3746
+ };
3747
+ }
3748
+ if (mode === "graph" && pathExists(kgDbPath)) {
3749
+ const db = new Database2(kgDbPath, { readonly: true });
3750
+ const queryLower = query.toLowerCase();
3751
+ const nodes = db.prepare(`
3752
+ SELECT * FROM kg_nodes WHERE text LIKE ? ORDER BY mention_count DESC LIMIT 20
3753
+ `).all(`%${queryLower}%`);
3754
+ const episodeIds = /* @__PURE__ */ new Set();
3755
+ const nodeInfo = [];
3756
+ for (const node of nodes.slice(0, 5)) {
3757
+ const edges = db.prepare(`
3758
+ SELECT * FROM kg_edges WHERE (src_id = ? OR dst_id = ?) AND valid_until IS NULL
3759
+ `).all(node.id, node.id);
3760
+ nodeInfo.push(`${node.text} (${node.node_type}, ${node.mention_count} mentions, ${edges.length} edges)`);
3761
+ for (const edge of edges) {
3762
+ if (edge.source_episode_id)
3763
+ episodeIds.add(edge.source_episode_id);
3764
+ }
3765
+ }
3766
+ db.close();
3767
+ const epLines = [];
3768
+ if (episodeIds.size > 0 && pathExists(epDbPath)) {
3769
+ const epDb = new Database2(epDbPath, { readonly: true });
3770
+ for (const epId of [...episodeIds].slice(0, maxResults)) {
3771
+ const ep = epDb.prepare("SELECT * FROM episodes WHERE id = ?").get(epId);
3772
+ if (ep)
3773
+ epLines.push(`[${ep.tool_name ?? ep.modality}] ${ep.content.slice(0, 150)}`);
3774
+ }
3775
+ epDb.close();
3776
+ }
3777
+ const output = [
3778
+ `Knowledge graph search for "${query}":`,
3779
+ `
3780
+ Nodes found: ${nodes.length}`,
3781
+ nodeInfo.length > 0 ? nodeInfo.map((n2) => ` - ${n2}`).join("\n") : " (no matching nodes)",
3782
+ epLines.length > 0 ? `
3783
+ Linked episodes (${epLines.length}):
3784
+ ${epLines.map((l2) => ` ${l2}`).join("\n")}` : ""
3785
+ ].filter(Boolean).join("\n");
3786
+ return { success: true, output, durationMs: performance.now() - start2 };
3787
+ }
3788
+ } catch {
3789
+ }
3790
+ }
3706
3791
  try {
3707
3792
  const allEntries = await this.loadAllMemories();
3708
3793
  if (allEntries.length === 0) {
@@ -265041,9 +265126,405 @@ var init_temporalGraph = __esm({
265041
265126
  }
265042
265127
  });
265043
265128
 
265129
+ // packages/memory/dist/zettelkasten.js
265130
+ function cosineSimilarity2(a2, b) {
265131
+ if (a2.length !== b.length || a2.length === 0)
265132
+ return 0;
265133
+ let dot = 0, normA = 0, normB = 0;
265134
+ for (let i2 = 0; i2 < a2.length; i2++) {
265135
+ dot += a2[i2] * b[i2];
265136
+ normA += a2[i2] * a2[i2];
265137
+ normB += b[i2] * b[i2];
265138
+ }
265139
+ const denom = Math.sqrt(normA) * Math.sqrt(normB);
265140
+ return denom > 0 ? dot / denom : 0;
265141
+ }
265142
+ function findNeighbors(episode, candidates, topK, minSimilarity) {
265143
+ if (!episode.embedding)
265144
+ return [];
265145
+ const scored = [];
265146
+ for (const candidate of candidates) {
265147
+ if (candidate.id === episode.id)
265148
+ continue;
265149
+ if (!candidate.embedding)
265150
+ continue;
265151
+ const sim = cosineSimilarity2(episode.embedding, candidate.embedding);
265152
+ if (sim >= minSimilarity) {
265153
+ scored.push({ episode: candidate, similarity: sim });
265154
+ }
265155
+ }
265156
+ scored.sort((a2, b) => b.similarity - a2.similarity);
265157
+ return scored.slice(0, topK);
265158
+ }
265159
+ function linkEpisode(episode, episodeStore, graph, config) {
265160
+ const cfg = { ...DEFAULT_CONFIG4, ...config };
265161
+ const result = { episodeId: episode.id, linkedTo: [], linksCreated: 0 };
265162
+ if (!episode.embedding)
265163
+ return result;
265164
+ const candidates = episodeStore.recent(500).filter((e2) => e2.embedding != null);
265165
+ const neighbors2 = findNeighbors(episode, candidates, cfg.topK, cfg.minSimilarity);
265166
+ for (const { episode: neighbor, similarity } of neighbors2) {
265167
+ if (result.linksCreated >= cfg.maxLinksPerEpisode)
265168
+ break;
265169
+ const srcNodeId = graph.upsertNode({
265170
+ text: episode.content.slice(0, 100),
265171
+ nodeType: "event"
265172
+ });
265173
+ const dstNodeId = graph.upsertNode({
265174
+ text: neighbor.content.slice(0, 100),
265175
+ nodeType: "event"
265176
+ });
265177
+ graph.addEdge({
265178
+ srcId: srcNodeId,
265179
+ dstId: dstNodeId,
265180
+ relation: "related_to",
265181
+ fact: `Associated: ${episode.content.slice(0, 50)} \u2194 ${neighbor.content.slice(0, 50)}`,
265182
+ edgeType: "synonym",
265183
+ confidence: similarity,
265184
+ sourceEpisodeId: episode.id
265185
+ });
265186
+ result.linkedTo.push({ neighborId: neighbor.id, similarity, linked: true });
265187
+ result.linksCreated++;
265188
+ if (similarity >= cfg.evolutionThreshold && neighbor.gist !== episode.content.slice(0, 200)) {
265189
+ const evolvedGist = neighbor.gist ? `${neighbor.gist} | Also related: ${episode.content.slice(0, 100)}` : `Related context: ${episode.content.slice(0, 150)}`;
265190
+ episodeStore.setGist(neighbor.id, evolvedGist.slice(0, 500));
265191
+ }
265192
+ }
265193
+ return result;
265194
+ }
265195
+ function batchLink(episodeStore, graph, config) {
265196
+ const episodes = episodeStore.recent(200).filter((e2) => e2.embedding != null);
265197
+ let totalLinks = 0;
265198
+ let processed = 0;
265199
+ for (const ep of episodes) {
265200
+ const result = linkEpisode(ep, episodeStore, graph, config);
265201
+ totalLinks += result.linksCreated;
265202
+ if (result.linksCreated > 0)
265203
+ processed++;
265204
+ }
265205
+ return { processed, linksCreated: totalLinks };
265206
+ }
265207
+ var DEFAULT_CONFIG4;
265208
+ var init_zettelkasten = __esm({
265209
+ "packages/memory/dist/zettelkasten.js"() {
265210
+ "use strict";
265211
+ DEFAULT_CONFIG4 = {
265212
+ topK: 3,
265213
+ minSimilarity: 0.3,
265214
+ evolutionThreshold: 0.6,
265215
+ maxLinksPerEpisode: 10
265216
+ };
265217
+ }
265218
+ });
265219
+
265220
+ // packages/memory/dist/gistCompressor.js
265221
+ function compressToGist(episodes, taskDescription) {
265222
+ if (episodes.length === 0) {
265223
+ return {
265224
+ gist: "Empty task \u2014 no actions taken.",
265225
+ sourceEpisodeIds: [],
265226
+ episodeType: "mixed",
265227
+ turnCount: 0,
265228
+ toolsUsed: [],
265229
+ filesModified: [],
265230
+ errorsEncountered: [],
265231
+ timestamp: Date.now()
265232
+ };
265233
+ }
265234
+ const toolsUsed = [...new Set(episodes.map((e2) => e2.toolName).filter(Boolean))];
265235
+ const filesModified = extractFilePaths(episodes, ["file_write", "file_edit", "file_patch", "batch_edit"]);
265236
+ const filesRead = extractFilePaths(episodes, ["file_read"]);
265237
+ const errorsEncountered = episodes.filter((e2) => e2.content.toLowerCase().includes("error") || e2.content.toLowerCase().includes("failed")).map((e2) => e2.content.slice(0, 80)).slice(0, 3);
265238
+ const episodeType = classifyTrajectory(episodes, errorsEncountered);
265239
+ const parts = [];
265240
+ const taskSnippet = taskDescription.slice(0, 100).replace(/\n/g, " ");
265241
+ parts.push(`Task: "${taskSnippet}"`);
265242
+ if (filesModified.length > 0) {
265243
+ parts.push(`Modified ${filesModified.length} file(s): ${filesModified.slice(0, 3).join(", ")}`);
265244
+ }
265245
+ if (errorsEncountered.length > 0 && episodeType === "error_recovery") {
265246
+ parts.push(`Encountered ${errorsEncountered.length} error(s), recovered successfully`);
265247
+ } else if (errorsEncountered.length > 0) {
265248
+ parts.push(`${errorsEncountered.length} error(s) encountered`);
265249
+ }
265250
+ parts.push(`Used ${toolsUsed.length} tools across ${episodes.length} steps`);
265251
+ const lastEp = episodes[episodes.length - 1];
265252
+ if (lastEp.toolName === "task_complete") {
265253
+ parts.push("Completed successfully");
265254
+ } else if (lastEp.content.toLowerCase().includes("error")) {
265255
+ parts.push("Ended with errors");
265256
+ }
265257
+ const gist = parts.join(". ") + ".";
265258
+ return {
265259
+ gist,
265260
+ sourceEpisodeIds: episodes.map((e2) => e2.id),
265261
+ episodeType,
265262
+ turnCount: Math.max(...episodes.map((e2) => e2.turnNumber ?? 0)),
265263
+ toolsUsed,
265264
+ filesModified,
265265
+ errorsEncountered,
265266
+ timestamp: episodes[episodes.length - 1]?.timestamp ?? Date.now()
265267
+ };
265268
+ }
265269
+ function compressAndStore(episodeStore, sessionId, taskDescription, minTurns = 10) {
265270
+ const episodes = episodeStore.recent(500, sessionId);
265271
+ const maxTurn = Math.max(0, ...episodes.map((e2) => e2.turnNumber ?? 0));
265272
+ if (maxTurn < minTurns)
265273
+ return null;
265274
+ const gistRecord = compressToGist(episodes.reverse(), taskDescription);
265275
+ episodeStore.insert({
265276
+ sessionId,
265277
+ modality: "gist",
265278
+ content: gistRecord.gist,
265279
+ importance: 8,
265280
+ decayClass: "procedural",
265281
+ sourceEpisodeId: gistRecord.sourceEpisodeIds[0]
265282
+ });
265283
+ return gistRecord;
265284
+ }
265285
+ function extractFilePaths(episodes, toolNames) {
265286
+ const paths = [];
265287
+ for (const ep of episodes) {
265288
+ if (!ep.toolName || !toolNames.includes(ep.toolName))
265289
+ continue;
265290
+ if (ep.metadata) {
265291
+ const fp = ep.metadata.args_fingerprint;
265292
+ if (fp) {
265293
+ const pathMatch = fp.match(/path=([^,]+)/);
265294
+ if (pathMatch)
265295
+ paths.push(pathMatch[1]);
265296
+ }
265297
+ }
265298
+ }
265299
+ return [...new Set(paths)];
265300
+ }
265301
+ function classifyTrajectory(episodes, errors) {
265302
+ const hasErrors = errors.length > 0;
265303
+ const lastSuccess = episodes.some((e2) => e2.toolName === "task_complete");
265304
+ const hasFileEdits = episodes.some((e2) => ["file_write", "file_edit"].includes(e2.toolName ?? ""));
265305
+ const hasSearch = episodes.some((e2) => ["grep_search", "find_files", "web_search"].includes(e2.toolName ?? ""));
265306
+ if (hasErrors && lastSuccess)
265307
+ return "error_recovery";
265308
+ if (hasSearch && !hasFileEdits)
265309
+ return "discovery";
265310
+ if (!hasErrors && hasFileEdits)
265311
+ return "tool_sequence";
265312
+ return "mixed";
265313
+ }
265314
+ var init_gistCompressor = __esm({
265315
+ "packages/memory/dist/gistCompressor.js"() {
265316
+ "use strict";
265317
+ }
265318
+ });
265319
+
265320
+ // packages/memory/dist/pprRetrieval.js
265321
+ function extractQueryEntities(query) {
265322
+ const entities = [];
265323
+ const seen = /* @__PURE__ */ new Set();
265324
+ const add2 = (text) => {
265325
+ const normalized = text.trim().toLowerCase();
265326
+ if (normalized.length < 2 || seen.has(normalized))
265327
+ return;
265328
+ seen.add(normalized);
265329
+ entities.push(text.trim());
265330
+ };
265331
+ const filePattern = /(?:[\w./-]+\/[\w./-]+|[\w-]+\.\w{1,5})\b/g;
265332
+ for (const match of query.matchAll(filePattern)) {
265333
+ if (match[0].includes(".") || match[0].includes("/"))
265334
+ add2(match[0]);
265335
+ }
265336
+ const errorPattern = /\b[A-Z][a-z]+(?:[A-Z][a-z]+)+\b|\b\w+(?:Error|Exception|Failed|Failure)\b/g;
265337
+ for (const match of query.matchAll(errorPattern))
265338
+ add2(match[0]);
265339
+ const toolPattern = /\b(?:file_read|file_write|file_edit|shell|grep_search|find_files|memory_\w+|web_\w+|camera_\w+|audio_\w+|wifi_\w+|bluetooth_\w+|sdr_\w+|flipper_\w+|meshtastic|gps_\w+|visual_\w+)\b/g;
265340
+ for (const match of query.matchAll(toolPattern))
265341
+ add2(match[0]);
265342
+ const quotedPattern = /["']([^"']{2,50})["']/g;
265343
+ for (const match of query.matchAll(quotedPattern))
265344
+ add2(match[1]);
265345
+ const STOP_WORDS2 = /* @__PURE__ */ new Set([
265346
+ "the",
265347
+ "and",
265348
+ "for",
265349
+ "was",
265350
+ "are",
265351
+ "not",
265352
+ "but",
265353
+ "had",
265354
+ "has",
265355
+ "have",
265356
+ "this",
265357
+ "that",
265358
+ "with",
265359
+ "from",
265360
+ "what",
265361
+ "when",
265362
+ "where",
265363
+ "how",
265364
+ "why",
265365
+ "which",
265366
+ "who",
265367
+ "did",
265368
+ "does",
265369
+ "can",
265370
+ "could",
265371
+ "would",
265372
+ "should",
265373
+ "will",
265374
+ "been",
265375
+ "being",
265376
+ "were",
265377
+ "about",
265378
+ "than",
265379
+ "then",
265380
+ "also",
265381
+ "just",
265382
+ "more",
265383
+ "some",
265384
+ "only",
265385
+ "into",
265386
+ "over"
265387
+ ]);
265388
+ const words = query.split(/\s+/).filter((w) => w.length >= 4 && !STOP_WORDS2.has(w.toLowerCase()));
265389
+ for (const word2 of words) {
265390
+ if (/^[A-Z]/.test(word2) || /[._-]/.test(word2) || /\d/.test(word2)) {
265391
+ add2(word2.replace(/[.,;:!?]+$/, ""));
265392
+ }
265393
+ }
265394
+ return entities;
265395
+ }
265396
+ function personalizedPageRank(graph, seedNodeIds, config) {
265397
+ const cfg = { ...DEFAULT_CONFIG5, ...config };
265398
+ const scores = /* @__PURE__ */ new Map();
265399
+ if (seedNodeIds.length === 0)
265400
+ return scores;
265401
+ const nodeCount = graph.nodeCount();
265402
+ if (nodeCount === 0)
265403
+ return scores;
265404
+ const teleportProb = 1 / seedNodeIds.length;
265405
+ const seedSet = new Set(seedNodeIds);
265406
+ const allNodes = /* @__PURE__ */ new Set();
265407
+ for (const seedId of seedNodeIds) {
265408
+ allNodes.add(seedId);
265409
+ const neighbors2 = graph.neighbors(seedId);
265410
+ for (const { node } of neighbors2) {
265411
+ allNodes.add(node.id);
265412
+ const hop2 = graph.neighbors(node.id);
265413
+ for (const { node: n2 } of hop2)
265414
+ allNodes.add(n2.id);
265415
+ }
265416
+ }
265417
+ for (const nodeId of allNodes) {
265418
+ scores.set(nodeId, seedSet.has(nodeId) ? teleportProb : 0);
265419
+ }
265420
+ for (let iter = 0; iter < cfg.maxIterations; iter++) {
265421
+ const newScores = /* @__PURE__ */ new Map();
265422
+ let maxDelta = 0;
265423
+ for (const nodeId of allNodes) {
265424
+ const teleport = seedSet.has(nodeId) ? (1 - cfg.damping) * teleportProb : 0;
265425
+ let walkSum = 0;
265426
+ const inEdges = graph.currentEdges(nodeId);
265427
+ for (const edge of inEdges) {
265428
+ const neighborId = edge.srcId === nodeId ? edge.dstId : edge.srcId;
265429
+ const neighborScore = scores.get(neighborId) ?? 0;
265430
+ const neighborOutDegree = graph.currentEdges(neighborId).length || 1;
265431
+ walkSum += neighborScore / neighborOutDegree;
265432
+ }
265433
+ const newScore = teleport + cfg.damping * walkSum;
265434
+ newScores.set(nodeId, newScore);
265435
+ const delta = Math.abs(newScore - (scores.get(nodeId) ?? 0));
265436
+ if (delta > maxDelta)
265437
+ maxDelta = delta;
265438
+ }
265439
+ for (const [id, score] of newScores)
265440
+ scores.set(id, score);
265441
+ if (maxDelta < cfg.convergenceThreshold) {
265442
+ return scores;
265443
+ }
265444
+ }
265445
+ return scores;
265446
+ }
265447
+ function retrieveByPPR(query, graph, episodeStore, config) {
265448
+ const cfg = { ...DEFAULT_CONFIG5, ...config };
265449
+ const queryEntities = extractQueryEntities(query);
265450
+ if (queryEntities.length === 0) {
265451
+ return { episodes: [], queryEntities: [], seedNodes: [], iterations: 0 };
265452
+ }
265453
+ const seedNodes = [];
265454
+ for (const entity of queryEntities) {
265455
+ const node = graph.findNode(entity);
265456
+ if (node) {
265457
+ seedNodes.push(node.id);
265458
+ continue;
265459
+ }
265460
+ for (const nodeType of ["file", "error", "tool", "entity", "event", "concept", "person"]) {
265461
+ const candidates = graph.nodesByType(nodeType, 50);
265462
+ for (const candidate of candidates) {
265463
+ if (candidate.text.toLowerCase().includes(entity.toLowerCase()) || entity.toLowerCase().includes(candidate.text.toLowerCase())) {
265464
+ seedNodes.push(candidate.id);
265465
+ break;
265466
+ }
265467
+ }
265468
+ if (seedNodes.length > queryEntities.indexOf(entity))
265469
+ break;
265470
+ }
265471
+ }
265472
+ if (seedNodes.length === 0) {
265473
+ return { episodes: [], queryEntities, seedNodes: [], iterations: 0 };
265474
+ }
265475
+ const pprScores = personalizedPageRank(graph, seedNodes, cfg);
265476
+ const episodeScores = /* @__PURE__ */ new Map();
265477
+ for (const [nodeId, score] of pprScores) {
265478
+ if (score < 1e-3)
265479
+ continue;
265480
+ const node = graph.getNode(nodeId);
265481
+ if (!node)
265482
+ continue;
265483
+ const edges = graph.currentEdges(nodeId);
265484
+ for (const edge of edges) {
265485
+ if (edge.sourceEpisodeId) {
265486
+ const existing = episodeScores.get(edge.sourceEpisodeId);
265487
+ if (existing) {
265488
+ existing.score += score;
265489
+ existing.matchedNodes.push(node.text);
265490
+ } else {
265491
+ episodeScores.set(edge.sourceEpisodeId, { score, matchedNodes: [node.text] });
265492
+ }
265493
+ }
265494
+ }
265495
+ }
265496
+ const ranked = [...episodeScores.entries()].sort((a2, b) => b[1].score - a2[1].score).slice(0, cfg.topK);
265497
+ const episodes = [];
265498
+ for (const [epId, { score, matchedNodes }] of ranked) {
265499
+ const episode = episodeStore.get(epId);
265500
+ if (episode) {
265501
+ episodes.push({ episode, pprScore: score, matchedNodes: [...new Set(matchedNodes)] });
265502
+ }
265503
+ }
265504
+ return {
265505
+ episodes,
265506
+ queryEntities,
265507
+ seedNodes,
265508
+ iterations: cfg.maxIterations
265509
+ };
265510
+ }
265511
+ var DEFAULT_CONFIG5;
265512
+ var init_pprRetrieval = __esm({
265513
+ "packages/memory/dist/pprRetrieval.js"() {
265514
+ "use strict";
265515
+ init_zettelkasten();
265516
+ DEFAULT_CONFIG5 = {
265517
+ damping: 0.5,
265518
+ maxIterations: 50,
265519
+ convergenceThreshold: 1e-6,
265520
+ topK: 10
265521
+ };
265522
+ }
265523
+ });
265524
+
265044
265525
  // packages/memory/dist/embeddings.js
265045
265526
  async function generateEmbedding(text, config) {
265046
- const cfg = { ...DEFAULT_CONFIG4, ...config };
265527
+ const cfg = { ...DEFAULT_CONFIG6, ...config };
265047
265528
  try {
265048
265529
  const url = `${cfg.baseUrl}/api/embed`;
265049
265530
  const resp = await fetch(url, {
@@ -265078,7 +265559,7 @@ async function generateEmbedding(text, config) {
265078
265559
  }
265079
265560
  }
265080
265561
  async function checkEmbeddingAvailable(config) {
265081
- const cfg = { ...DEFAULT_CONFIG4, ...config };
265562
+ const cfg = { ...DEFAULT_CONFIG6, ...config };
265082
265563
  try {
265083
265564
  const resp = await fetch(`${cfg.baseUrl}/api/tags`, {
265084
265565
  signal: AbortSignal.timeout(5e3)
@@ -265105,11 +265586,11 @@ async function pullEmbeddingModel(baseUrl, model, timeoutMs) {
265105
265586
  return false;
265106
265587
  }
265107
265588
  }
265108
- var DEFAULT_CONFIG4;
265589
+ var DEFAULT_CONFIG6;
265109
265590
  var init_embeddings = __esm({
265110
265591
  "packages/memory/dist/embeddings.js"() {
265111
265592
  "use strict";
265112
- DEFAULT_CONFIG4 = {
265593
+ DEFAULT_CONFIG6 = {
265113
265594
  baseUrl: "http://localhost:11434",
265114
265595
  model: "nomic-embed-text",
265115
265596
  timeoutMs: 3e4
@@ -265139,6 +265620,9 @@ var init_dist7 = __esm({
265139
265620
  init_toolPatternStore();
265140
265621
  init_episodeStore();
265141
265622
  init_temporalGraph();
265623
+ init_zettelkasten();
265624
+ init_gistCompressor();
265625
+ init_pprRetrieval();
265142
265626
  init_embeddings();
265143
265627
  init_proceduralMemoryStore();
265144
265628
  }
@@ -265898,6 +266382,15 @@ var init_agenticRunner = __esm({
265898
266382
  const embResult = await generateEmbedding(content, { baseUrl });
265899
266383
  if (embResult?.vector) {
265900
266384
  this._episodeStore.setEmbedding(id, embResult.vector);
266385
+ if (this._temporalGraph) {
266386
+ const episode = this._episodeStore.get(id);
266387
+ if (episode?.embedding) {
266388
+ try {
266389
+ linkEpisode(episode, this._episodeStore, this._temporalGraph);
266390
+ } catch {
266391
+ }
266392
+ }
266393
+ }
265901
266394
  }
265902
266395
  } catch {
265903
266396
  }
@@ -266798,6 +267291,21 @@ If you're stuck, try a completely different approach. Do NOT repeat what failed
266798
267291
  if (compacted.length < prevLen)
266799
267292
  recentToolResults.clear();
266800
267293
  }
267294
+ if (turn > 0 && turn % 3 === 0 && this._temporalGraph && this._episodeStore) {
267295
+ try {
267296
+ const taskGoal = this._taskState.goal || task.slice(0, 200);
267297
+ const pprResult = retrieveByPPR(taskGoal, this._temporalGraph, this._episodeStore, { topK: 3 });
267298
+ if (pprResult.episodes.length > 0) {
267299
+ const memoryLines = pprResult.episodes.map(({ episode, pprScore, matchedNodes }) => `- [${episode.toolName ?? episode.modality}] ${episode.content.slice(0, 120)} (via: ${matchedNodes.slice(0, 2).join(", ")})`);
267300
+ compacted.push({
267301
+ role: "system",
267302
+ content: `[Associative Memory \u2014 related prior experience]
267303
+ ${memoryLines.join("\n")}`
267304
+ });
267305
+ }
267306
+ } catch {
267307
+ }
267308
+ }
266801
267309
  if (this.options.environmentProvider) {
266802
267310
  try {
266803
267311
  const envStr = this.options.environmentProvider();
@@ -268138,6 +268646,19 @@ Full content available via: repl_exec(code="data = retrieve('${handleId}')") or
268138
268646
  await this.processPendingEmbeddings();
268139
268647
  }
268140
268648
  this.stopEmbeddingPipeline();
268649
+ const gist = compressAndStore(this._episodeStore, this._sessionId, task, 10);
268650
+ if (gist) {
268651
+ this.emit({ type: "status", content: `Gist compressed: "${gist.gist.slice(0, 100)}..."`, timestamp: (/* @__PURE__ */ new Date()).toISOString() });
268652
+ }
268653
+ if (this._temporalGraph) {
268654
+ try {
268655
+ const linkResult = batchLink(this._episodeStore, this._temporalGraph);
268656
+ if (linkResult.linksCreated > 0) {
268657
+ this.emit({ type: "status", content: `Zettelkasten: ${linkResult.linksCreated} associative links created`, timestamp: (/* @__PURE__ */ new Date()).toISOString() });
268658
+ }
268659
+ } catch {
268660
+ }
268661
+ }
268141
268662
  if (this._temporalGraph) {
268142
268663
  const nodes = this._temporalGraph.nodeCount();
268143
268664
  const edges = this._temporalGraph.activeEdgeCount();
@@ -303382,7 +303903,7 @@ function createEditHistoryLogger(repoRoot, sessionId) {
303382
303903
  const entry = {
303383
303904
  ts: (/* @__PURE__ */ new Date()).toISOString(),
303384
303905
  tool: toolName,
303385
- files: extractFilePaths(toolName, toolArgs),
303906
+ files: extractFilePaths2(toolName, toolArgs),
303386
303907
  summary: buildSummary(toolName, toolArgs),
303387
303908
  success,
303388
303909
  session: sessionId,
@@ -303395,7 +303916,7 @@ function createEditHistoryLogger(repoRoot, sessionId) {
303395
303916
  }
303396
303917
  return { logToolCall, logPath: logPath2 };
303397
303918
  }
303398
- function extractFilePaths(tool, args) {
303919
+ function extractFilePaths2(tool, args) {
303399
303920
  if (tool === "batch_edit") {
303400
303921
  const edits = args["edits"];
303401
303922
  if (Array.isArray(edits)) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "open-agents-ai",
3
- "version": "0.187.161",
3
+ "version": "0.187.163",
4
4
  "description": "AI coding agent powered by open-source models (Ollama/vLLM) — interactive TUI with agentic tool-calling loop",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",