@desplega.ai/agent-swarm 1.109.0 → 1.111.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (104) hide show
  1. package/README.md +1 -1
  2. package/dist/{actions-c67n3jxb.js → actions-a4crgvtd.js} +6 -6
  3. package/dist/{app-16zmk3px.js → app-va5mr9yw.js} +3 -3
  4. package/dist/{assistant-5wzbdcqf.js → assistant-0jm4vy8r.js} +9 -9
  5. package/dist/{boot-reembed-3af9vms0.js → boot-reembed-0t815mmm.js} +3 -3
  6. package/dist/{boot-reembed-jd82hb59.js → boot-reembed-50zzk97q.js} +4 -4
  7. package/dist/{boot-scrub-logs-858c7xqe.js → boot-scrub-logs-r99nbmxh.js} +2 -2
  8. package/dist/{claude-managed-setup-yhbcx0bz.js → claude-managed-setup-cm05wtek.js} +1 -1
  9. package/dist/{cli-dn44vqyb.js → cli-0d404x64.js} +1 -1
  10. package/dist/{cli-0wbkrrky.js → cli-0d5xddf1.js} +7 -2
  11. package/dist/{cli-06p7cfcg.js → cli-1aqc46he.js} +5 -5
  12. package/dist/{cli-efaejv9v.js → cli-2b0ew5v8.js} +1 -1
  13. package/dist/{cli-pqgd2rd1.js → cli-3cm8ar1c.js} +1 -1
  14. package/dist/{cli-4hapc9v6.js → cli-4f6vw5vy.js} +2 -2
  15. package/dist/{cli-ng2k7kwa.js → cli-4ke1amr9.js} +2 -2
  16. package/dist/{cli-72vm595k.js → cli-6tfm5fr1.js} +1 -1
  17. package/dist/{cli-m3enfr8q.js → cli-6wscj9z0.js} +4 -4
  18. package/dist/{cli-68aqqrmf.js → cli-8j1h9627.js} +14 -14
  19. package/dist/{cli-wjsj96hh.js → cli-aqr96mny.js} +1 -1
  20. package/dist/{cli-w6zp4qcx.js → cli-ceewqajw.js} +37 -39
  21. package/dist/{cli-aenr2vrd.js → cli-dza5039b.js} +317 -30
  22. package/dist/{cli-rk3snywa.js → cli-ee3fkebs.js} +2 -2
  23. package/dist/{cli-rtqc5r54.js → cli-f1f82qgv.js} +5 -5
  24. package/dist/{cli-ef1wbkhh.js → cli-fdnpymsv.js} +2 -2
  25. package/dist/{cli-wdp73c7w.js → cli-gchg43wt.js} +15 -5
  26. package/dist/{cli-7d38eycj.js → cli-h3vhr1gj.js} +2 -2
  27. package/dist/{cli-q95b16kk.js → cli-jrmjxsnk.js} +3 -3
  28. package/dist/{cli-eqq99cyd.js → cli-kavm2cv5.js} +2 -2
  29. package/dist/{cli-987a9zvn.js → cli-r3y5chyg.js} +4 -4
  30. package/dist/{cli-3s560caw.js → cli-t8m00q3b.js} +3 -3
  31. package/dist/{cli-amncg1dq.js → cli-tk9vyqzh.js} +66 -9
  32. package/dist/{cli-wgbsdhjc.js → cli-xqzvygxp.js} +1 -1
  33. package/dist/{cli-phe0nm59.js → cli-y7v6e7yr.js} +4 -4
  34. package/dist/{cli-4cgfsn4h.js → cli-z626gjqj.js} +1 -1
  35. package/dist/cli.js +12 -12
  36. package/dist/{codex-adapter-ebs12jef.js → codex-adapter-5cmy858w.js} +3 -3
  37. package/dist/{codex-login-4sywkz6v.js → codex-login-0h18cy3e.js} +1 -1
  38. package/dist/{codex-session-runner-3bx0b1hn.js → codex-session-runner-46q8mrba.js} +3 -3
  39. package/dist/{commands-0racez18.js → commands-t3rdvb55.js} +2 -2
  40. package/dist/{db-dt0zx0jq.js → db-mjqc8hj6.js} +2 -2
  41. package/dist/{handlers-aca9z23r.js → handlers-mcmg5qgc.js} +9 -9
  42. package/dist/{hook-twh1eb6a.js → hook-0p4q1tym.js} +3 -3
  43. package/dist/{http-p2vvn9m1.js → http-gs6fk9sg.js} +232 -37
  44. package/dist/{index-md9ke5yd.js → index-20mf9wvc.js} +8 -8
  45. package/dist/{index-kax7pt3w.js → index-6zpajd9e.js} +7 -11
  46. package/dist/{index-jw00ycgg.js → index-744yvc8x.js} +9 -9
  47. package/dist/{index-nbh8s0gd.js → index-w15fk28m.js} +7 -7
  48. package/dist/{keepalive-54awap1s.js → keepalive-3gvnbxaj.js} +4 -4
  49. package/dist/{lead-xqf6mzb8.js → lead-yjbmhj3g.js} +20 -20
  50. package/dist/{maintenance-1eqnnqwz.js → maintenance-jbvy2bfg.js} +4 -4
  51. package/dist/{onboard-jwhd9g2q.js → onboard-sexatejh.js} +2 -2
  52. package/dist/{otel-impl-zx1b8yr9.js → otel-impl-sgqvcw0f.js} +1 -1
  53. package/dist/{pi-mono-adapter-ayr3akk8.js → pi-mono-adapter-kxjxpfgy.js} +2 -2
  54. package/dist/{pricing-refresh-q3yep8w5.js → pricing-refresh-rat240yg.js} +4 -4
  55. package/dist/{seed-pricing-1af3yh3p.js → seed-pricing-7yfaf123.js} +3 -3
  56. package/dist/{setup-10f473wc.js → setup-vm5vcc6c.js} +2 -2
  57. package/dist/{worker-exyz0652.js → worker-02y2r0r2.js} +20 -20
  58. package/openapi.json +1010 -2
  59. package/package.json +2 -2
  60. package/src/be/db.ts +11 -11
  61. package/src/be/memory/constants.ts +7 -0
  62. package/src/be/memory/graph-expansion.ts +167 -0
  63. package/src/be/memory/link-resolver.ts +81 -17
  64. package/src/be/memory/links-store.ts +208 -0
  65. package/src/be/memory/providers/sqlite-store.ts +2 -2
  66. package/src/be/memory/raters/retrieval.ts +2 -1
  67. package/src/be/memory/types.ts +1 -1
  68. package/src/be/memory/usefulness-stats.ts +259 -0
  69. package/src/be/migrations/107_memory_usefulness_indexes.sql +12 -0
  70. package/src/be/seed-scripts/catalog/smart-recall.ts +1 -5
  71. package/src/github/mentions-aliases.test.ts +4 -3
  72. package/src/http/codex-oauth-keep-warm.ts +107 -0
  73. package/src/http/index.ts +2 -0
  74. package/src/http/memory.ts +73 -6
  75. package/src/providers/codex-adapter.ts +66 -2
  76. package/src/providers/codex-oauth/auth-json.ts +18 -9
  77. package/src/providers/codex-oauth/flow.ts +1 -1
  78. package/src/providers/codex-oauth/storage.ts +88 -6
  79. package/src/providers/codex-oauth/types.ts +1 -1
  80. package/src/tasks/worker-follow-up.ts +47 -23
  81. package/src/tests/codex-adapter-pool-auth-revalidate.test.ts +113 -11
  82. package/src/tests/codex-adapter.test.ts +27 -0
  83. package/src/tests/codex-oauth-keep-warm.test.ts +268 -0
  84. package/src/tests/codex-oauth-refresh-lock.test.ts +4 -4
  85. package/src/tests/codex-oauth-storage.test.ts +149 -6
  86. package/src/tests/codex-oauth.test.ts +12 -0
  87. package/src/tests/create-page-tool.test.ts +7 -0
  88. package/src/tests/entrypoint-codex-oauth-seed.test.ts +124 -0
  89. package/src/tests/heartbeat-reroute-decision.test.ts +49 -0
  90. package/src/tests/jira-webhook-lifecycle.test.ts +7 -0
  91. package/src/tests/memory-edit.test.ts +95 -0
  92. package/src/tests/memory-get-tool.test.ts +138 -0
  93. package/src/tests/memory-graph-expansion.test.ts +421 -0
  94. package/src/tests/memory-http-recall-gating.test.ts +13 -0
  95. package/src/tests/memory-link-resolver.test.ts +228 -2
  96. package/src/tests/memory-usefulness-endpoint.test.ts +392 -0
  97. package/src/tests/script-workflows-runtime-e2e.test.ts +1 -0
  98. package/src/tests/slack-upload-file.test.ts +135 -0
  99. package/src/tests/task-supersede-resume.test.ts +83 -6
  100. package/src/tools/inject-learning.ts +1 -0
  101. package/src/tools/memory-edit.ts +3 -2
  102. package/src/tools/memory-get.ts +66 -1
  103. package/src/tools/memory-search.ts +13 -3
  104. package/src/tools/slack-upload-file.ts +11 -1
@@ -14,13 +14,13 @@ import {
14
14
  getOAuthApp,
15
15
  getOAuthTokens,
16
16
  upsertOAuthApp
17
- } from "./cli-pqgd2rd1.js";
17
+ } from "./cli-3cm8ar1c.js";
18
18
  import {
19
19
  startPricingRefreshLoop
20
- } from "./cli-rk3snywa.js";
20
+ } from "./cli-ee3fkebs.js";
21
21
  import {
22
22
  seedPricingFromModelsDev
23
- } from "./cli-72vm595k.js";
23
+ } from "./cli-6tfm5fr1.js";
24
24
  import {
25
25
  createTrackerAgentMapping,
26
26
  createTrackerSync,
@@ -35,7 +35,7 @@ import {
35
35
  repointTrackerSyncBySwarmId,
36
36
  updateTrackerSync,
37
37
  updateTrackerSyncSwarmId
38
- } from "./cli-wdp73c7w.js";
38
+ } from "./cli-gchg43wt.js";
39
39
  import {
40
40
  ZodFirstPartyTypeKind,
41
41
  objectType
@@ -45,7 +45,7 @@ import {
45
45
  ensure,
46
46
  require_dist,
47
47
  runScheduleNow
48
- } from "./cli-987a9zvn.js";
48
+ } from "./cli-r3y5chyg.js";
49
49
  import {
50
50
  TriggerSchemaError,
51
51
  applyDefinitionPatch,
@@ -57,7 +57,7 @@ import {
57
57
  startWorkflowExecution,
58
58
  validateDefinition,
59
59
  validateJsonSchema
60
- } from "./cli-06p7cfcg.js";
60
+ } from "./cli-1aqc46he.js";
61
61
  import {
62
62
  getApiKey
63
63
  } from "./cli-f14fvzag.js";
@@ -73,24 +73,28 @@ import {
73
73
  setScriptConnectionEnabled,
74
74
  upsertCredentialBinding,
75
75
  upsertScriptConnection
76
- } from "./cli-4hapc9v6.js";
76
+ } from "./cli-4f6vw5vy.js";
77
77
  import {
78
78
  CANDIDATE_SET_MULTIPLIER,
79
+ computeScore,
79
80
  getEmbeddingProvider,
80
81
  getMemoryStore,
81
82
  init_constants,
82
83
  init_reranker,
83
- rerank
84
- } from "./cli-0wbkrrky.js";
84
+ init_sqlite_store,
85
+ isGraphExpansionEnabled,
86
+ rerank,
87
+ rowToCandidate
88
+ } from "./cli-0d5xddf1.js";
85
89
  import {
86
90
  createAdditiveBuffer,
87
91
  extractSlackMessageText
88
- } from "./cli-wgbsdhjc.js";
92
+ } from "./cli-xqzvygxp.js";
89
93
  import {
90
94
  getSlackApp,
91
95
  startSlackApp,
92
96
  stopSlackApp
93
- } from "./cli-rtqc5r54.js";
97
+ } from "./cli-f1f82qgv.js";
94
98
  import {
95
99
  findOrCreateUserByEmail,
96
100
  findUserByEmail,
@@ -102,7 +106,7 @@ import {
102
106
  recordIdentityEvent,
103
107
  resolveUserByToken,
104
108
  unlinkIdentity
105
- } from "./cli-dn44vqyb.js";
109
+ } from "./cli-0d404x64.js";
106
110
  import {
107
111
  markdownToSlack
108
112
  } from "./cli-6xd0bvf8.js";
@@ -113,7 +117,7 @@ import {
113
117
  createTaskWithSiblingAwareness,
114
118
  githubContextKey,
115
119
  linearContextKey
116
- } from "./cli-wjsj96hh.js";
120
+ } from "./cli-aqr96mny.js";
117
121
  import {
118
122
  getAppUrl,
119
123
  getMcpBaseUrl,
@@ -342,7 +346,7 @@ import {
342
346
  upsertService,
343
347
  upsertSwarmConfig,
344
348
  validateConfigValue
345
- } from "./cli-ng2k7kwa.js";
349
+ } from "./cli-4ke1amr9.js";
346
350
  import {
347
351
  init_zod
348
352
  } from "./cli-q21d49ac.js";
@@ -386,7 +390,7 @@ import {
386
390
  import {
387
391
  init_package,
388
392
  package_default
389
- } from "./cli-eqq99cyd.js";
393
+ } from "./cli-kavm2cv5.js";
390
394
  import {
391
395
  init_secret_scrubber,
392
396
  refreshSecretScrubberCache,
@@ -19668,7 +19672,7 @@ async function initOtel(serviceRole = process.env.AGENT_ROLE || "api") {
19668
19672
  return;
19669
19673
  initialized2 = true;
19670
19674
  try {
19671
- const impl = await import("./otel-impl-zx1b8yr9.js");
19675
+ const impl = await import("./otel-impl-sgqvcw0f.js");
19672
19676
  await impl.boot(serviceRole);
19673
19677
  realWithSpan = impl.withSpan;
19674
19678
  realStartSpan = impl.startSpan;
@@ -21616,7 +21620,8 @@ ${learning}`;
21616
21620
  scope: "swarm",
21617
21621
  name: `Lead feedback: ${category} — ${learning.slice(0, 60)}`,
21618
21622
  content,
21619
- source: "manual"
21623
+ source: "manual",
21624
+ tags: [category]
21620
21625
  });
21621
21626
  try {
21622
21627
  const provider = getEmbeddingProvider();
@@ -23341,6 +23346,24 @@ function resolveWikilinksToMemoryIds(agentId, links) {
23341
23346
  return link;
23342
23347
  });
23343
23348
  }
23349
+ var INSERT_LINK_SQL = `INSERT OR IGNORE INTO memory_link
23350
+ (id, from_memory_id, linkType, targetKind, targetId, strength, resolver, sourceText, metadata, createdAt, updatedAt)
23351
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`;
23352
+ function insertLinkArgs(memoryId, link, now) {
23353
+ return [
23354
+ crypto.randomUUID(),
23355
+ memoryId,
23356
+ link.linkType,
23357
+ link.targetKind,
23358
+ link.targetId,
23359
+ link.strength,
23360
+ link.resolver,
23361
+ link.sourceText,
23362
+ link.metadata ? JSON.stringify(link.metadata) : null,
23363
+ now,
23364
+ now
23365
+ ];
23366
+ }
23344
23367
  function storeLinks(memoryId, agentId, content) {
23345
23368
  const links = resolveLinks(content);
23346
23369
  if (links.length === 0)
@@ -23348,12 +23371,34 @@ function storeLinks(memoryId, agentId, content) {
23348
23371
  const resolved = resolveWikilinksToMemoryIds(agentId, links);
23349
23372
  const db = getDb();
23350
23373
  const now = new Date().toISOString();
23351
- const insert = db.prepare(`INSERT OR IGNORE INTO memory_link
23352
- (id, from_memory_id, linkType, targetKind, targetId, strength, resolver, sourceText, metadata, createdAt, updatedAt)
23353
- VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`);
23374
+ const insert = db.prepare(INSERT_LINK_SQL);
23354
23375
  db.transaction(() => {
23355
23376
  for (const link of resolved) {
23356
- insert.run(crypto.randomUUID(), memoryId, link.linkType, link.targetKind, link.targetId, link.strength, link.resolver, link.sourceText, link.metadata ? JSON.stringify(link.metadata) : null, now, now);
23377
+ insert.run(...insertLinkArgs(memoryId, link, now));
23378
+ }
23379
+ })();
23380
+ }
23381
+ function linkIdentity2(link) {
23382
+ return JSON.stringify([link.linkType, link.targetKind, link.targetId, link.sourceText ?? null]);
23383
+ }
23384
+ function refreshLinks(memoryId, agentId, content) {
23385
+ const resolved = resolveWikilinksToMemoryIds(agentId, resolveLinks(content));
23386
+ const nextIdentities = new Set(resolved.map((link) => linkIdentity2(link)));
23387
+ const db = getDb();
23388
+ const now = new Date().toISOString();
23389
+ const selectExisting = db.prepare(`SELECT id, linkType, targetKind, targetId, sourceText
23390
+ FROM memory_link
23391
+ WHERE from_memory_id = ? AND linkType != 'sequel'`);
23392
+ const deleteById = db.prepare("DELETE FROM memory_link WHERE id = ?");
23393
+ const insert = db.prepare(INSERT_LINK_SQL);
23394
+ db.transaction(() => {
23395
+ for (const row of selectExisting.all(memoryId)) {
23396
+ if (!nextIdentities.has(linkIdentity2(row))) {
23397
+ deleteById.run(row.id);
23398
+ }
23399
+ }
23400
+ for (const link of resolved) {
23401
+ insert.run(...insertLinkArgs(memoryId, link, now));
23357
23402
  }
23358
23403
  })();
23359
23404
  }
@@ -23427,7 +23472,7 @@ var registerMemoryEditTool = (server) => {
23427
23472
  if (embedding)
23428
23473
  store.updateEmbedding(result.memory.id, embedding, provider.name);
23429
23474
  try {
23430
- storeLinks(result.memory.id, requestInfo.agentId, result.memory.content);
23475
+ refreshLinks(result.memory.id, requestInfo.agentId, result.memory.content);
23431
23476
  } catch (err) {
23432
23477
  console.error(`[memory-edit] Link resolution failed for ${result.memory.id}:`, err.message);
23433
23478
  }
@@ -23464,12 +23509,99 @@ var registerMemoryEditTool = (server) => {
23464
23509
 
23465
23510
  // src/tools/memory-get.ts
23466
23511
  init_zod();
23512
+ init_db();
23467
23513
 
23468
23514
  // src/be/memory/access.ts
23469
23515
  function canReadMemory(memory, agentId) {
23470
23516
  return memory.scope === "swarm" || memory.agentId === agentId;
23471
23517
  }
23472
23518
 
23519
+ // src/be/memory/links-store.ts
23520
+ init_db();
23521
+ function redactedTargetId(sourceText) {
23522
+ const wikilink = /^\[\[(.+)\]\]$/.exec(sourceText ?? "");
23523
+ return wikilink?.[1] ?? "";
23524
+ }
23525
+ function getLinksForMemory(memoryId, options = {}) {
23526
+ const { viewerAgentId, isLead = false } = options;
23527
+ const db = getDb();
23528
+ const outgoing = db.prepare(`SELECT ml.id, ml.linkType, ml.targetKind, ml.targetId, ml.strength,
23529
+ ml.resolver, ml.sourceText, ml.createdAt,
23530
+ m.id AS targetMemoryId, m.name AS targetName,
23531
+ m.scope AS targetScope, m.agentId AS targetAgentId
23532
+ FROM memory_link ml
23533
+ LEFT JOIN agent_memory m
23534
+ ON ml.targetKind = 'memory'
23535
+ AND m.id = ml.targetId
23536
+ AND (m.expiresAt IS NULL OR m.expiresAt > datetime('now'))
23537
+ WHERE ml.from_memory_id = ?
23538
+ ORDER BY ml.createdAt ASC, ml.id ASC`).all(memoryId);
23539
+ const links = outgoing.map((row) => {
23540
+ if (row.targetKind !== "memory") {
23541
+ return {
23542
+ id: row.id,
23543
+ linkType: row.linkType,
23544
+ targetKind: row.targetKind,
23545
+ targetId: row.targetId,
23546
+ strength: row.strength,
23547
+ resolver: row.resolver,
23548
+ sourceText: row.sourceText,
23549
+ createdAt: row.createdAt,
23550
+ resolved: true
23551
+ };
23552
+ }
23553
+ const live = row.targetMemoryId !== null;
23554
+ const visible = live && (isLead || row.targetScope === "swarm" || (row.targetAgentId ?? "") === viewerAgentId);
23555
+ const base = {
23556
+ id: row.id,
23557
+ linkType: row.linkType,
23558
+ targetKind: row.targetKind,
23559
+ targetId: visible ? row.targetId : redactedTargetId(row.sourceText),
23560
+ strength: row.strength,
23561
+ resolver: row.resolver,
23562
+ sourceText: row.sourceText,
23563
+ createdAt: row.createdAt,
23564
+ resolved: false
23565
+ };
23566
+ if (!visible)
23567
+ return base;
23568
+ return {
23569
+ ...base,
23570
+ resolved: true,
23571
+ target: {
23572
+ id: row.targetMemoryId,
23573
+ name: row.targetName ?? "",
23574
+ scope: row.targetScope ?? ""
23575
+ }
23576
+ };
23577
+ });
23578
+ const conditions = [
23579
+ "ml.targetKind = 'memory'",
23580
+ "ml.targetId = ?",
23581
+ "(m.expiresAt IS NULL OR m.expiresAt > datetime('now'))"
23582
+ ];
23583
+ const params = [memoryId];
23584
+ if (!isLead) {
23585
+ conditions.push("(m.agentId = ? OR m.scope = 'swarm')");
23586
+ params.push(viewerAgentId ?? null);
23587
+ }
23588
+ const inbound = db.prepare(`SELECT ml.id, ml.linkType, ml.strength, ml.sourceText, ml.createdAt,
23589
+ m.id AS fromId, m.name AS fromName, m.scope AS fromScope
23590
+ FROM memory_link ml
23591
+ JOIN agent_memory m ON m.id = ml.from_memory_id
23592
+ WHERE ${conditions.join(" AND ")}
23593
+ ORDER BY ml.createdAt ASC, ml.id ASC`).all(...params);
23594
+ const backlinks = inbound.map((row) => ({
23595
+ id: row.id,
23596
+ linkType: row.linkType,
23597
+ strength: row.strength,
23598
+ sourceText: row.sourceText,
23599
+ createdAt: row.createdAt,
23600
+ from: { id: row.fromId, name: row.fromName, scope: row.fromScope }
23601
+ }));
23602
+ return { links, backlinks };
23603
+ }
23604
+
23473
23605
  // src/be/memory/raters/retrieval.ts
23474
23606
  init_db();
23475
23607
  function recordRetrievals(taskId, agentId, results, sessionId, extras) {
@@ -23508,6 +23640,31 @@ function getRetrievalsForTask(taskId) {
23508
23640
  // src/tools/memory-get.ts
23509
23641
  init_types();
23510
23642
  var NUDGE_ELIGIBLE_SOURCES = new Set(["manual", "file_index"]);
23643
+ var LinkedMemoryRefSchema = object({
23644
+ id: string(),
23645
+ name: string(),
23646
+ scope: string()
23647
+ });
23648
+ var MemoryLinkSchema = object({
23649
+ id: string(),
23650
+ linkType: string(),
23651
+ targetKind: string(),
23652
+ targetId: string(),
23653
+ strength: number(),
23654
+ resolver: string(),
23655
+ sourceText: string().nullable(),
23656
+ createdAt: string(),
23657
+ resolved: boolean().describe("For memory-kind targets: whether targetId points at a live memory you may read. Non-memory kinds (pr, agent-fs-file, …) are always resolved."),
23658
+ target: LinkedMemoryRefSchema.optional().describe("Linked memory metadata — present only for resolved memory-kind links.")
23659
+ });
23660
+ var MemoryBacklinkSchema = object({
23661
+ id: string(),
23662
+ linkType: string(),
23663
+ strength: number(),
23664
+ sourceText: string().nullable(),
23665
+ createdAt: string(),
23666
+ from: LinkedMemoryRefSchema.describe("The memory whose content links here.")
23667
+ });
23511
23668
  var registerMemoryGetTool = (server) => {
23512
23669
  createToolRegistrar(server)("memory-get", {
23513
23670
  title: "Get memory details",
@@ -23522,6 +23679,8 @@ var registerMemoryGetTool = (server) => {
23522
23679
  success: boolean(),
23523
23680
  message: string(),
23524
23681
  memory: AgentMemorySchema.optional(),
23682
+ links: array(MemoryLinkSchema).optional().describe("Outgoing memory_link rows resolved from this memory's content."),
23683
+ backlinks: array(MemoryBacklinkSchema).optional().describe("Other memories whose content links to this one (ACL-filtered)."),
23525
23684
  rateHint: string().optional()
23526
23685
  })
23527
23686
  }, async ({ memoryId, intent }, requestInfo, _meta) => {
@@ -23557,13 +23716,26 @@ var registerMemoryGetTool = (server) => {
23557
23716
  }
23558
23717
  const inTaskContext = !!requestInfo.sourceTaskId;
23559
23718
  const rateHint = inTaskContext && NUDGE_ELIGIBLE_SOURCES.has(memory.source) ? `memory_rate(id="${memory.id}", useful=true|false)` : undefined;
23719
+ let linkBlocks = { links: [], backlinks: [] };
23720
+ try {
23721
+ const agent = requestInfo.agentId ? getAgentById(requestInfo.agentId) : undefined;
23722
+ linkBlocks = getLinksForMemory(memory.id, {
23723
+ viewerAgentId: requestInfo.agentId,
23724
+ isLead: agent?.isLead ?? false
23725
+ });
23726
+ } catch (err) {
23727
+ console.error("[memory-get] link traversal failed:", err.message);
23728
+ }
23729
+ const linksSummary = linkBlocks.links.length > 0 || linkBlocks.backlinks.length > 0 ? `
23730
+
23731
+ [${linkBlocks.links.length} outgoing link(s), ${linkBlocks.backlinks.length} backlink(s) — see structured output]` : "";
23560
23732
  return {
23561
23733
  content: [
23562
23734
  {
23563
23735
  type: "text",
23564
23736
  text: `Memory "${memory.name}" retrieved.
23565
23737
 
23566
- ${memory.content}`
23738
+ ${memory.content}${linksSummary}`
23567
23739
  }
23568
23740
  ],
23569
23741
  structuredContent: {
@@ -23571,6 +23743,8 @@ ${memory.content}`
23571
23743
  success: true,
23572
23744
  message: `Memory "${memory.name}" retrieved.`,
23573
23745
  memory,
23746
+ links: linkBlocks.links,
23747
+ backlinks: linkBlocks.backlinks,
23574
23748
  rateHint
23575
23749
  }
23576
23750
  };
@@ -23688,6 +23862,103 @@ var registerMemoryRateTool = (server) => {
23688
23862
  init_zod();
23689
23863
  init_db();
23690
23864
  init_constants();
23865
+
23866
+ // src/be/memory/graph-expansion.ts
23867
+ init_db();
23868
+ init_constants();
23869
+ init_sqlite_store();
23870
+ init_reranker();
23871
+ function addNeighborScopeConditions(conditions, params, agentId, scope, isLead) {
23872
+ if (!isLead) {
23873
+ if (scope === "agent") {
23874
+ conditions.push("m.agentId = ? AND m.scope = 'agent'");
23875
+ params.push(agentId);
23876
+ } else if (scope === "swarm") {
23877
+ conditions.push("m.scope = 'swarm'");
23878
+ } else {
23879
+ conditions.push("(m.agentId = ? OR m.scope = 'swarm')");
23880
+ params.push(agentId);
23881
+ }
23882
+ } else {
23883
+ if (scope === "agent") {
23884
+ conditions.push("m.scope = 'agent'");
23885
+ } else if (scope === "swarm") {
23886
+ conditions.push("m.scope = 'swarm'");
23887
+ }
23888
+ }
23889
+ }
23890
+ function expandCandidatesWithGraph(candidates, agentId, options = {}) {
23891
+ if (!isGraphExpansionEnabled())
23892
+ return candidates;
23893
+ const { cap = 5, damping = 0.7, scope = "all", source, isLead = false } = options;
23894
+ if (candidates.length === 0 || cap <= 0)
23895
+ return candidates;
23896
+ const parentById = new Map(candidates.map((c) => [c.id, c]));
23897
+ const parentIds = [...parentById.keys()];
23898
+ const conditions = [
23899
+ `ml.from_memory_id IN (${parentIds.map(() => "?").join(", ")})`,
23900
+ "ml.targetKind = 'memory'",
23901
+ "(m.expiresAt IS NULL OR m.expiresAt > datetime('now'))"
23902
+ ];
23903
+ const params = [...parentIds];
23904
+ addNeighborScopeConditions(conditions, params, agentId, scope, isLead);
23905
+ if (source) {
23906
+ conditions.push("m.source = ?");
23907
+ params.push(source);
23908
+ }
23909
+ let rows;
23910
+ try {
23911
+ rows = getDb().prepare(`SELECT m.*, ml.from_memory_id AS fromMemoryId, ml.strength AS linkStrength
23912
+ FROM memory_link ml
23913
+ JOIN agent_memory m ON m.id = ml.targetId
23914
+ WHERE ${conditions.join(" AND ")}`).all(...params);
23915
+ } catch (err) {
23916
+ console.warn("[memory-graph] expansion query failed:", err.message);
23917
+ return candidates;
23918
+ }
23919
+ if (rows.length === 0)
23920
+ return candidates;
23921
+ const neighbors = new Map;
23922
+ for (const row of rows) {
23923
+ const parent = parentById.get(row.fromMemoryId);
23924
+ if (!parent)
23925
+ continue;
23926
+ const strength = typeof row.linkStrength === "number" ? row.linkStrength : 1;
23927
+ const parentBase = parent.rawSimilarity ?? parent.similarity;
23928
+ const similarity = parentBase * strength * damping;
23929
+ const existing = neighbors.get(row.id);
23930
+ if (existing && existing.similarity >= similarity)
23931
+ continue;
23932
+ neighbors.set(row.id, {
23933
+ ...rowToCandidate(row, similarity),
23934
+ retrievalSource: "graph",
23935
+ recencyDecayApplied: false
23936
+ });
23937
+ }
23938
+ if (neighbors.size === 0)
23939
+ return candidates;
23940
+ const result = [...candidates];
23941
+ const indexById = new Map(result.map((c, i) => [c.id, i]));
23942
+ let added = 0;
23943
+ const now = new Date;
23944
+ const ranked = [...neighbors.values()].sort((a, b) => computeScore(b, now) - computeScore(a, now));
23945
+ for (const neighbor of ranked) {
23946
+ const existingIndex = indexById.get(neighbor.id);
23947
+ if (existingIndex !== undefined) {
23948
+ if (computeScore(neighbor, now) > computeScore(result[existingIndex], now)) {
23949
+ result[existingIndex] = neighbor;
23950
+ }
23951
+ continue;
23952
+ }
23953
+ if (added >= cap)
23954
+ continue;
23955
+ result.push(neighbor);
23956
+ added += 1;
23957
+ }
23958
+ return result;
23959
+ }
23960
+
23961
+ // src/tools/memory-search.ts
23691
23962
  init_reranker();
23692
23963
  init_types();
23693
23964
  var NUDGE_ELIGIBLE_SOURCES2 = new Set(["manual", "file_index"]);
@@ -23717,7 +23988,8 @@ var registerMemorySearchTool = (server) => {
23717
23988
  source: AgentMemorySourceSchema,
23718
23989
  scope: AgentMemoryScopeSchema,
23719
23990
  similarity: number().optional(),
23720
- retrievalSource: _enum(["vec", "fts", "hybrid", "fallback"]).optional(),
23991
+ retrievalSource: _enum(["vec", "fts", "hybrid", "fallback", "graph"]).optional(),
23992
+ tags: array(string()).optional(),
23721
23993
  createdAt: string(),
23722
23994
  rateHint: string().optional()
23723
23995
  })).optional(),
@@ -23747,8 +24019,13 @@ var registerMemorySearchTool = (server) => {
23747
24019
  isLead,
23748
24020
  queryText: query
23749
24021
  });
23750
- if (candidates.length > 0) {
23751
- const ranked = rerank(candidates, { limit });
24022
+ const expanded = expandCandidatesWithGraph(candidates, requestInfo.agentId, {
24023
+ scope,
24024
+ source,
24025
+ isLead
24026
+ });
24027
+ if (expanded.length > 0) {
24028
+ const ranked = rerank(expanded, { limit });
23752
24029
  if (requestInfo.sourceTaskId) {
23753
24030
  try {
23754
24031
  recordRetrievals(requestInfo.sourceTaskId, requestInfo.agentId, ranked.map((r) => ({
@@ -23769,6 +24046,7 @@ var registerMemorySearchTool = (server) => {
23769
24046
  scope: r.scope,
23770
24047
  similarity: r.similarity,
23771
24048
  retrievalSource: r.retrievalSource,
24049
+ tags: r.tags,
23772
24050
  createdAt: r.createdAt,
23773
24051
  ...inTaskContext && NUDGE_ELIGIBLE_SOURCES2.has(r.source) ? { rateHint: rateHintFor(r.id) } : {}
23774
24052
  }));
@@ -23802,6 +24080,7 @@ var registerMemorySearchTool = (server) => {
23802
24080
  summary: r.summary,
23803
24081
  source: r.source,
23804
24082
  scope: r.scope,
24083
+ tags: r.tags,
23805
24084
  createdAt: r.createdAt
23806
24085
  }));
23807
24086
  return {
@@ -29691,6 +29970,14 @@ var registerSlackStartThreadTool = (server) => {
29691
29970
  init_zod();
29692
29971
  init_db();
29693
29972
  var WORKSPACE_DIR = "/workspace";
29973
+ function resolveTaskUploadThreadTs(task) {
29974
+ if (!task)
29975
+ return;
29976
+ if (task.slackChannelId?.startsWith("D")) {
29977
+ return task.slackTreeRootMessageTs ?? task.slackProgressMessageTs ?? task.slackThreadTs;
29978
+ }
29979
+ return task.slackThreadTs;
29980
+ }
29694
29981
  async function resolveAndValidateFilePath(filePath) {
29695
29982
  const triedPaths = [];
29696
29983
  const fileExists = async (path2) => {
@@ -29798,7 +30085,7 @@ var registerSlackUploadFileTool = (server) => {
29798
30085
  };
29799
30086
  }
29800
30087
  slackChannelId = task.slackChannelId;
29801
- slackThreadTs = task.slackThreadTs;
30088
+ slackThreadTs = resolveTaskUploadThreadTs(task);
29802
30089
  } else if (channelId) {
29803
30090
  if (!agent.isLead) {
29804
30091
  return {
@@ -32884,7 +33171,7 @@ async function notifySlack(text) {
32884
33171
  return;
32885
33172
  }
32886
33173
  try {
32887
- const { getSlackApp: getSlackApp2 } = await import("./app-16zmk3px.js");
33174
+ const { getSlackApp: getSlackApp2 } = await import("./app-va5mr9yw.js");
32888
33175
  const app = getSlackApp2();
32889
33176
  if (!app) {
32890
33177
  console.warn("[Jira webhook keepalive] Slack not available, cannot send notification");
@@ -32953,7 +33240,7 @@ async function deleteJiraWebhook(webhookId) {
32953
33240
  console.log(`[Jira webhook keepalive] Deleted webhook id=${webhookId}`);
32954
33241
  }
32955
33242
  async function overwriteWebhookIds(next) {
32956
- const { getDb: getDb2 } = await import("./db-dt0zx0jq.js");
33243
+ const { getDb: getDb2 } = await import("./db-mjqc8hj6.js");
32957
33244
  const db = getDb2();
32958
33245
  const txn = db.transaction(() => {
32959
33246
  const row = db.query("SELECT metadata FROM oauth_apps WHERE provider = 'jira'").get();
@@ -110240,4 +110527,4 @@ function writeSkillsToFilesystem(entries, harnessType = "all", home) {
110240
110527
  return { synced, removed, errors };
110241
110528
  }
110242
110529
 
110243
- export { DEFAULT_NEGOTIATED_PROTOCOL_VERSION, SUPPORTED_PROTOCOL_VERSIONS, isJSONRPCRequest, isJSONRPCResultResponse, isJSONRPCErrorResponse, JSONRPCMessageSchema, isInitializeRequest, McpServer, isGitHubEnabled, initGitHub, verifyWebhookSignature, userCtx, isPollTracingEnabled, initOtel, withSpan, startSpan, withSpanContext, withRemoteContext, injectTraceContext, recordSessionCost, createToolRegistrar, cancelTaskInputSchema, cancelTaskOutputSchema, cancelTaskHandler, setCorsHeaders, parseQueryParams, getPathSegments, safeRequestUrlForLog, agentWithCapacity, parseBody, BODY_TOO_LARGE, enforceContentLengthCap, json, jsonError, triggerSchemaErrorResponse, deriveApiBaseUrl, httpServerSemconvAttributes, describeRequestRoute, route, assertSelectOnlyQuery, executeReadOnlyQuery, handleDbQuery, snapshotMetric, snapshotPage, getTaskDetailsInputSchema, getTaskDetailsOutputSchema, getTaskDetailsHandler, getTasksInputSchema, getTasksOutputSchema, getTasksHandler, storeLinks, canReadMemory, recordRetrievals, markKapsoMessageRead, sendKapsoReaction, getKapsoConfig, getKapsoNumberMapping, markKapsoMessageSeen, resolveHttpAuditUserId, createEvent, createEventsBatch, getEventCountsFiltered, getEventsFiltered, mergeScheduleTiming, validateRecurringTiming, sendTaskOutputSchema, sendTaskHandler, parseSkillContent, ExplicitSelfDuplicateError, applyRating, shouldPersistAutomaticTaskMemory, isAgentMailEnabled, initAgentMail, verifyAgentMailWebhook, isInboxAllowed, isSenderAllowed, handleMessageReceived, handlePullRequest, handleIssue, handleComment, handlePullRequestReview, handleCheckRun, handleCheckSuite, handleWorkflowRun, getJiraMetadata, updateJiraMetadata, clearJiraMetadata, registerJiraWebhook, deleteJiraWebhook, isJiraEnabled, initJira, handleJiraWebhook, handleAgentSessionEvent, handleIssueUpdate, handleIssueDelete, handleAgentSessionPrompted, isLinearEnabled, initLinear, loadGlobalConfigsIntoEnv, reloadGlobalConfigsAndIntegrations, scheduleIntegrationsReload, handleCore, canClaim, emitBudgetRefusalSideEffects, taskActionInputSchema, taskActionOutputSchema, taskActionHandler, hasCapability, getEnabledCapabilities, createServer, writeSkillsToFilesystem };
110530
+ export { DEFAULT_NEGOTIATED_PROTOCOL_VERSION, SUPPORTED_PROTOCOL_VERSIONS, isJSONRPCRequest, isJSONRPCResultResponse, isJSONRPCErrorResponse, JSONRPCMessageSchema, isInitializeRequest, McpServer, isGitHubEnabled, initGitHub, verifyWebhookSignature, userCtx, isPollTracingEnabled, initOtel, withSpan, startSpan, withSpanContext, withRemoteContext, injectTraceContext, recordSessionCost, createToolRegistrar, cancelTaskInputSchema, cancelTaskOutputSchema, cancelTaskHandler, setCorsHeaders, parseQueryParams, getPathSegments, safeRequestUrlForLog, agentWithCapacity, parseBody, BODY_TOO_LARGE, enforceContentLengthCap, json, jsonError, triggerSchemaErrorResponse, deriveApiBaseUrl, httpServerSemconvAttributes, describeRequestRoute, route, assertSelectOnlyQuery, executeReadOnlyQuery, handleDbQuery, snapshotMetric, snapshotPage, getTaskDetailsInputSchema, getTaskDetailsOutputSchema, getTaskDetailsHandler, getTasksInputSchema, getTasksOutputSchema, getTasksHandler, storeLinks, refreshLinks, canReadMemory, getLinksForMemory, recordRetrievals, expandCandidatesWithGraph, markKapsoMessageRead, sendKapsoReaction, getKapsoConfig, getKapsoNumberMapping, markKapsoMessageSeen, resolveHttpAuditUserId, createEvent, createEventsBatch, getEventCountsFiltered, getEventsFiltered, mergeScheduleTiming, validateRecurringTiming, sendTaskOutputSchema, sendTaskHandler, parseSkillContent, ExplicitSelfDuplicateError, applyRating, shouldPersistAutomaticTaskMemory, isAgentMailEnabled, initAgentMail, verifyAgentMailWebhook, isInboxAllowed, isSenderAllowed, handleMessageReceived, handlePullRequest, handleIssue, handleComment, handlePullRequestReview, handleCheckRun, handleCheckSuite, handleWorkflowRun, getJiraMetadata, updateJiraMetadata, clearJiraMetadata, registerJiraWebhook, deleteJiraWebhook, isJiraEnabled, initJira, handleJiraWebhook, handleAgentSessionEvent, handleIssueUpdate, handleIssueDelete, handleAgentSessionPrompted, isLinearEnabled, initLinear, loadGlobalConfigsIntoEnv, reloadGlobalConfigsAndIntegrations, scheduleIntegrationsReload, handleCore, canClaim, emitBudgetRefusalSideEffects, taskActionInputSchema, taskActionOutputSchema, taskActionHandler, hasCapability, getEnabledCapabilities, createServer, writeSkillsToFilesystem };
@@ -1,13 +1,13 @@
1
1
  import {
2
2
  buildModelsDevSeedRows
3
- } from "./cli-72vm595k.js";
3
+ } from "./cli-6tfm5fr1.js";
4
4
  import {
5
5
  createLogEntry,
6
6
  getActivePricingRow,
7
7
  getDb,
8
8
  init_db,
9
9
  insertPricingRow
10
- } from "./cli-ng2k7kwa.js";
10
+ } from "./cli-4ke1amr9.js";
11
11
  import {
12
12
  init_secret_scrubber,
13
13
  scrubSecrets
@@ -25,7 +25,7 @@ import {
25
25
  getTaskById,
26
26
  init_db,
27
27
  setSlackMessageTracking
28
- } from "./cli-ng2k7kwa.js";
28
+ } from "./cli-4ke1amr9.js";
29
29
  import {
30
30
  require_receiver,
31
31
  require_sender,
@@ -54988,13 +54988,13 @@ async function initSlackApp() {
54988
54988
  socketMode: true,
54989
54989
  logLevel: import_bolt.LogLevel.DEBUG
54990
54990
  });
54991
- const { registerMessageHandler } = await import("./handlers-aca9z23r.js");
54992
- const { registerCommandHandler } = await import("./commands-0racez18.js");
54993
- const { registerActionHandlers } = await import("./actions-c67n3jxb.js");
54991
+ const { registerMessageHandler } = await import("./handlers-mcmg5qgc.js");
54992
+ const { registerCommandHandler } = await import("./commands-t3rdvb55.js");
54993
+ const { registerActionHandlers } = await import("./actions-a4crgvtd.js");
54994
54994
  registerMessageHandler(app);
54995
54995
  registerCommandHandler(app);
54996
54996
  registerActionHandlers(app);
54997
- const { createAssistant } = await import("./assistant-5wzbdcqf.js");
54997
+ const { createAssistant } = await import("./assistant-0jm4vy8r.js");
54998
54998
  app.assistant(createAssistant());
54999
54999
  return app;
55000
55000
  }
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  getScriptApiTypes,
3
3
  require_typescript
4
- } from "./cli-4hapc9v6.js";
4
+ } from "./cli-4f6vw5vy.js";
5
5
  import {
6
6
  deleteSwarmConfigByKey,
7
7
  getAgentById,
@@ -10,7 +10,7 @@ import {
10
10
  getSwarmConfigs,
11
11
  init_db,
12
12
  upsertSwarmConfig
13
- } from "./cli-ng2k7kwa.js";
13
+ } from "./cli-4ke1amr9.js";
14
14
  import {
15
15
  init_secret_scrubber,
16
16
  scrubSecrets