@desplega.ai/agent-swarm 1.110.0 → 1.112.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 (119) hide show
  1. package/README.md +1 -1
  2. package/dist/{actions-837ktebk.js → actions-eckb4g8r.js} +6 -6
  3. package/dist/{app-85h97pg2.js → app-b05sgm02.js} +3 -3
  4. package/dist/{assistant-yhrta0c5.js → assistant-7255sbyw.js} +9 -9
  5. package/dist/{boot-reembed-5sd1t9r4.js → boot-reembed-y1bt3ttn.js} +4 -4
  6. package/dist/{boot-reembed-8xmfv2pq.js → boot-reembed-yv7awg4y.js} +3 -3
  7. package/dist/{boot-scrub-logs-fdw8wbtq.js → boot-scrub-logs-ddyaeqar.js} +2 -2
  8. package/dist/{claude-managed-setup-yhbcx0bz.js → claude-managed-setup-cm05wtek.js} +1 -1
  9. package/dist/{cli-8ps5wsk9.js → cli-0c3n0eba.js} +1 -1
  10. package/dist/{cli-kna0r84e.js → cli-15598a4k.js} +599 -51
  11. package/dist/{cli-8s0swp2t.js → cli-30d2ct3k.js} +3 -3
  12. package/dist/{cli-2h86bsfe.js → cli-3r5y6ayj.js} +2 -2
  13. package/dist/{cli-6ttdv68b.js → cli-52tbq17n.js} +1 -1
  14. package/dist/{cli-k6ssh5dk.js → cli-56s4ehzw.js} +1 -1
  15. package/dist/{cli-m3enfr8q.js → cli-6wscj9z0.js} +4 -4
  16. package/dist/{cli-5kav4x1a.js → cli-709t753c.js} +7 -2
  17. package/dist/{cli-g44ffxk5.js → cli-76d1vtvq.js} +11 -2
  18. package/dist/{cli-gb7dqnna.js → cli-7xkwgkrs.js} +1 -1
  19. package/dist/{cli-kg9v8h1w.js → cli-8f0dwca2.js} +1 -1
  20. package/dist/{cli-zw3cmjh6.js → cli-94vzr3nq.js} +4 -4
  21. package/dist/{cli-d8vmtyyr.js → cli-951w7c79.js} +1 -1
  22. package/dist/{cli-dhph6q98.js → cli-9p0qhead.js} +1 -1
  23. package/dist/{cli-vfyhrk9k.js → cli-a5e8n5hg.js} +1 -1
  24. package/dist/{cli-w6zp4qcx.js → cli-ceewqajw.js} +37 -39
  25. package/dist/{cli-r19ttke3.js → cli-h9jx5mag.js} +4 -4
  26. package/dist/{cli-4trfcacj.js → cli-hm27prrc.js} +5 -5
  27. package/dist/{cli-gtt1f14h.js → cli-pt7c7qxz.js} +3 -3
  28. package/dist/{cli-sjm0e1pa.js → cli-r1btc895.js} +2 -2
  29. package/dist/{cli-3baz70yp.js → cli-rp8pca98.js} +1 -1
  30. package/dist/{cli-dy01kwxk.js → cli-s9pj3c7z.js} +2 -2
  31. package/dist/{cli-0pzg1f8z.js → cli-tch0ypp6.js} +71 -24
  32. package/dist/{cli-3t97r3y1.js → cli-tg0f2wmz.js} +5 -5
  33. package/dist/{cli-amncg1dq.js → cli-tk9vyqzh.js} +66 -9
  34. package/dist/{cli-cwety9qq.js → cli-tp7e60s3.js} +4 -2
  35. package/dist/cli.js +11 -11
  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-3fh75nzv.js → commands-14g7taf4.js} +2 -2
  40. package/dist/{db-kwfxkhpw.js → db-3tge4jrn.js} +2 -2
  41. package/dist/{handlers-jj8rzetb.js → handlers-sy64egg6.js} +9 -9
  42. package/dist/{hook-1b45zzz1.js → hook-rnkzw8vp.js} +3 -3
  43. package/dist/{http-71964f7a.js → http-xx9xptcs.js} +234 -37
  44. package/dist/{index-e01wmtj0.js → index-3wr6v2mm.js} +7 -7
  45. package/dist/{index-464v93y6.js → index-brma88d4.js} +9 -9
  46. package/dist/{index-c35g752k.js → index-ha8e9xn2.js} +7 -11
  47. package/dist/{index-zm0x6vmf.js → index-zfx5p959.js} +8 -8
  48. package/dist/{keepalive-2gxqjgrx.js → keepalive-rbz05zad.js} +4 -4
  49. package/dist/{lead-twm4zp8y.js → lead-s790v7r0.js} +20 -20
  50. package/dist/{maintenance-1htsnyz6.js → maintenance-420rmadb.js} +4 -4
  51. package/dist/{onboard-1y1pdzt5.js → onboard-jgqamqnw.js} +2 -2
  52. package/dist/{otel-impl-pw9tnc80.js → otel-impl-ch3n3783.js} +1 -1
  53. package/dist/{pi-mono-adapter-ayr3akk8.js → pi-mono-adapter-kxjxpfgy.js} +2 -2
  54. package/dist/{pricing-refresh-tqvvrk7a.js → pricing-refresh-rmtrby6h.js} +4 -4
  55. package/dist/{seed-pricing-f23sehzq.js → seed-pricing-1szjzfj1.js} +3 -3
  56. package/dist/{setup-jtw9rz9t.js → setup-8jfzkyzv.js} +2 -2
  57. package/dist/{worker-jxrmzwb9.js → worker-40vq0pm8.js} +20 -20
  58. package/openapi.json +1010 -2
  59. package/package.json +1 -1
  60. package/src/be/memory/constants.ts +7 -0
  61. package/src/be/memory/graph-expansion.ts +167 -0
  62. package/src/be/memory/link-resolver.ts +81 -17
  63. package/src/be/memory/links-store.ts +208 -0
  64. package/src/be/memory/providers/sqlite-store.ts +2 -2
  65. package/src/be/memory/raters/retrieval.ts +2 -1
  66. package/src/be/memory/types.ts +1 -1
  67. package/src/be/memory/usefulness-stats.ts +259 -0
  68. package/src/be/migrations/107_memory_usefulness_indexes.sql +12 -0
  69. package/src/be/scripts/typecheck.ts +2 -0
  70. package/src/be/seed-scripts/catalog/smart-recall.ts +1 -5
  71. package/src/commands/runner.ts +154 -8
  72. package/src/github/handlers.ts +128 -25
  73. package/src/github/mentions-aliases.test.ts +4 -3
  74. package/src/http/codex-oauth-keep-warm.ts +107 -0
  75. package/src/http/index.ts +2 -0
  76. package/src/http/memory.ts +73 -6
  77. package/src/providers/codex-adapter.ts +66 -2
  78. package/src/providers/codex-oauth/auth-json.ts +18 -9
  79. package/src/providers/codex-oauth/flow.ts +1 -1
  80. package/src/providers/codex-oauth/storage.ts +88 -6
  81. package/src/providers/codex-oauth/types.ts +1 -1
  82. package/src/scripts-runtime/sdk-allowlist.ts +2 -0
  83. package/src/scripts-runtime/types/swarm-sdk.d.ts +2 -0
  84. package/src/server.ts +4 -0
  85. package/src/slack/message-text.ts +25 -0
  86. package/src/tests/codex-adapter-pool-auth-revalidate.test.ts +113 -11
  87. package/src/tests/codex-adapter.test.ts +27 -0
  88. package/src/tests/codex-oauth-keep-warm.test.ts +268 -0
  89. package/src/tests/codex-oauth-refresh-lock.test.ts +4 -4
  90. package/src/tests/codex-oauth-storage.test.ts +149 -6
  91. package/src/tests/codex-oauth.test.ts +12 -0
  92. package/src/tests/create-page-tool.test.ts +7 -0
  93. package/src/tests/entrypoint-codex-oauth-seed.test.ts +124 -0
  94. package/src/tests/github-event-filter.test.ts +3 -2
  95. package/src/tests/github-handlers-inline-comments.test.ts +114 -24
  96. package/src/tests/jira-webhook-lifecycle.test.ts +7 -0
  97. package/src/tests/memory-edit.test.ts +95 -0
  98. package/src/tests/memory-get-tool.test.ts +138 -0
  99. package/src/tests/memory-graph-expansion.test.ts +421 -0
  100. package/src/tests/memory-http-recall-gating.test.ts +13 -0
  101. package/src/tests/memory-link-resolver.test.ts +228 -2
  102. package/src/tests/memory-usefulness-endpoint.test.ts +392 -0
  103. package/src/tests/runner-repo-autostash.test.ts +168 -1
  104. package/src/tests/script-workflows-runtime-e2e.test.ts +1 -0
  105. package/src/tests/slack-delete.test.ts +157 -0
  106. package/src/tests/slack-message-text.test.ts +37 -1
  107. package/src/tests/slack-update.test.ts +167 -0
  108. package/src/tests/slack-upload-file.test.ts +135 -0
  109. package/src/tests/tool-annotations.test.ts +3 -0
  110. package/src/tools/inject-learning.ts +1 -0
  111. package/src/tools/memory-edit.ts +3 -2
  112. package/src/tools/memory-get.ts +66 -1
  113. package/src/tools/memory-search.ts +13 -3
  114. package/src/tools/slack-delete.ts +102 -0
  115. package/src/tools/slack-reply.ts +11 -3
  116. package/src/tools/slack-start-thread.ts +2 -0
  117. package/src/tools/slack-update.ts +127 -0
  118. package/src/tools/slack-upload-file.ts +11 -1
  119. package/src/tools/tool-config.ts +3 -1
@@ -24,12 +24,14 @@ import {
24
24
  emitBudgetRefusalSideEffects,
25
25
  enforceContentLengthCap,
26
26
  executeReadOnlyQuery,
27
+ expandCandidatesWithGraph,
27
28
  getEnabledCapabilities,
28
29
  getEventCountsFiltered,
29
30
  getEventsFiltered,
30
31
  getJiraMetadata,
31
32
  getKapsoConfig,
32
33
  getKapsoNumberMapping,
34
+ getLinksForMemory,
33
35
  getPathSegments,
34
36
  getTaskDetailsHandler,
35
37
  getTaskDetailsInputSchema,
@@ -81,6 +83,7 @@ import {
81
83
  parseSkillContent,
82
84
  recordRetrievals,
83
85
  recordSessionCost,
86
+ refreshLinks,
84
87
  registerJiraWebhook,
85
88
  reloadGlobalConfigsAndIntegrations,
86
89
  resolveHttpAuditUserId,
@@ -108,7 +111,7 @@ import {
108
111
  withRemoteContext,
109
112
  withSpanContext,
110
113
  writeSkillsToFilesystem
111
- } from "./cli-kna0r84e.js";
114
+ } from "./cli-15598a4k.js";
112
115
  import {
113
116
  BROWSER_SDK_JS,
114
117
  SWARM_UI_JS
@@ -118,6 +121,11 @@ import {
118
121
  REFERENCES_SOURCE_MAX_LENGTH,
119
122
  sanitizeReferencesSource
120
123
  } from "./cli-dcfyyh3t.js";
124
+ import {
125
+ deriveCodexKeySuffix,
126
+ getValidCodexOAuth,
127
+ loadAllCodexOAuthSlots
128
+ } from "./cli-tk9vyqzh.js";
121
129
  import {
122
130
  Anthropic
123
131
  } from "./cli-gz9sbyk3.js";
@@ -136,11 +144,11 @@ import {
136
144
  getOAuthApp,
137
145
  getOAuthTokens,
138
146
  releaseOAuthRefreshLock
139
- } from "./cli-6ttdv68b.js";
140
- import"./cli-sjm0e1pa.js";
147
+ } from "./cli-52tbq17n.js";
148
+ import"./cli-r1btc895.js";
141
149
  import {
142
150
  normalizeModelKey
143
- } from "./cli-3baz70yp.js";
151
+ } from "./cli-rp8pca98.js";
144
152
  import {
145
153
  SCRIPT_STDLIB_TYPES,
146
154
  ensureAgentFsCredentialsForAgent,
@@ -148,16 +156,16 @@ import {
148
156
  extractScriptSignature,
149
157
  scriptSdkTypesWithGeneratedApis,
150
158
  typecheckScript
151
- } from "./cli-cwety9qq.js";
159
+ } from "./cli-tp7e60s3.js";
152
160
  import {
153
161
  checkHeartbeatChecklist,
154
162
  runHeartbeatSweep,
155
163
  stopHeartbeat
156
- } from "./cli-gtt1f14h.js";
164
+ } from "./cli-pt7c7qxz.js";
157
165
  import {
158
166
  createResumeFollowUp,
159
167
  createWorkerTaskFollowUp
160
- } from "./cli-k6ssh5dk.js";
168
+ } from "./cli-56s4ehzw.js";
161
169
  import"./cli-fad8m16k.js";
162
170
  import {
163
171
  calculateNextRun,
@@ -165,7 +173,7 @@ import {
165
173
  ensure,
166
174
  initialize,
167
175
  require_dist
168
- } from "./cli-zw3cmjh6.js";
176
+ } from "./cli-94vzr3nq.js";
169
177
  import {
170
178
  RawLlmConfigSchema,
171
179
  TriggerSchemaError,
@@ -185,7 +193,7 @@ import {
185
193
  validateDefinition,
186
194
  validateJsonSchema,
187
195
  verifyHmacSignature
188
- } from "./cli-3t97r3y1.js";
196
+ } from "./cli-tg0f2wmz.js";
189
197
  import {
190
198
  getApiKey
191
199
  } from "./cli-f14fvzag.js";
@@ -206,10 +214,10 @@ import {
206
214
  rotateScriptApiSecret,
207
215
  updateScriptApi,
208
216
  upsertScriptByName
209
- } from "./cli-2h86bsfe.js";
217
+ } from "./cli-3r5y6ayj.js";
210
218
  import {
211
219
  searchScripts
212
- } from "./cli-dy01kwxk.js";
220
+ } from "./cli-s9pj3c7z.js";
213
221
  import {
214
222
  CANDIDATE_SET_MULTIPLIER,
215
223
  getEmbeddingProvider,
@@ -217,19 +225,19 @@ import {
217
225
  init_constants,
218
226
  init_reranker,
219
227
  rerank
220
- } from "./cli-5kav4x1a.js";
228
+ } from "./cli-709t753c.js";
221
229
  import"./cli-q25ejbyn.js";
222
- import"./cli-g44ffxk5.js";
230
+ import"./cli-76d1vtvq.js";
223
231
  import {
224
232
  getSlackApp,
225
233
  startSlackApp,
226
234
  stopSlackApp
227
- } from "./cli-4trfcacj.js";
235
+ } from "./cli-hm27prrc.js";
228
236
  import"./cli-rkndnn90.js";
229
237
  import"./cli-b0p7rfnd.js";
230
238
  import {
231
239
  recordUnmappedIdentity
232
- } from "./cli-dhph6q98.js";
240
+ } from "./cli-9p0qhead.js";
233
241
  import {
234
242
  findOrCreateUserByEmail,
235
243
  findUserByExternalId,
@@ -243,7 +251,7 @@ import {
243
251
  resolveUserByToken,
244
252
  revokeToken,
245
253
  unlinkIdentity
246
- } from "./cli-gb7dqnna.js";
254
+ } from "./cli-7xkwgkrs.js";
247
255
  import"./cli-6xd0bvf8.js";
248
256
  import"./cli-wspgs9bt.js";
249
257
  import {
@@ -251,7 +259,7 @@ import {
251
259
  createTaskWithSiblingAwareness,
252
260
  gitlabContextKey,
253
261
  pageContextKey
254
- } from "./cli-8ps5wsk9.js";
262
+ } from "./cli-0c3n0eba.js";
255
263
  import {
256
264
  getAppUrl,
257
265
  getConfiguredAppUrls,
@@ -563,7 +571,7 @@ import {
563
571
  upsertSwarmConfig,
564
572
  validateConfigValue,
565
573
  withFavoriteFlags
566
- } from "./cli-d8vmtyyr.js";
574
+ } from "./cli-951w7c79.js";
567
575
  import"./cli-z2zcxes1.js";
568
576
  import {
569
577
  init_zod
@@ -578,7 +586,7 @@ import {
578
586
  import {
579
587
  init_package,
580
588
  package_default
581
- } from "./cli-kg9v8h1w.js";
589
+ } from "./cli-8f0dwca2.js";
582
590
  import {
583
591
  init_secret_scrubber,
584
592
  registerVolatileSecret,
@@ -2778,6 +2786,61 @@ async function handleBudgets(req, res, pathSegments, queryParams, _myAgentId) {
2778
2786
  return false;
2779
2787
  }
2780
2788
 
2789
+ // src/http/codex-oauth-keep-warm.ts
2790
+ init_db();
2791
+ var KEEP_WARM_MAX_AGE_MS = 7 * 24 * 60 * 60 * 1000;
2792
+ var AUTH_WATCH_NAMESPACE = "codex-auth-watch";
2793
+ var keepWarmRoute = route({
2794
+ method: "post",
2795
+ path: "/api/oauth/keep-warm/codex",
2796
+ pattern: ["api", "oauth", "keep-warm", "codex"],
2797
+ summary: "Locked keep-warm refresh sweep across all Codex OAuth pool slots",
2798
+ description: "Enumerates codex_oauth_* slots and refreshes any older than ~7 days through the same locked getValidCodexOAuth path used at task time. Skips slots already benched by codex-auth-expiry-watch.",
2799
+ tags: ["OAuth"],
2800
+ responses: {
2801
+ 200: { description: "Per-slot keep-warm outcomes" }
2802
+ }
2803
+ });
2804
+ async function handleCodexOAuthKeepWarm(req, res, pathSegments) {
2805
+ if (!keepWarmRoute.match(req.method, pathSegments))
2806
+ return false;
2807
+ const parsed = await keepWarmRoute.parse(req, res, pathSegments, new URLSearchParams);
2808
+ if (!parsed)
2809
+ return true;
2810
+ const apiUrl = deriveApiBaseUrl(req);
2811
+ const apiKey = getApiKey();
2812
+ const slots = await loadAllCodexOAuthSlots(apiUrl, apiKey);
2813
+ const results = [];
2814
+ for (const { slot, creds } of slots) {
2815
+ const keySuffix = deriveCodexKeySuffix(creds.access, creds.accountId);
2816
+ if (getKv(AUTH_WATCH_NAMESPACE, `bench:${keySuffix}`)) {
2817
+ results.push({ slot, keySuffix, outcome: "skipped-benched" });
2818
+ continue;
2819
+ }
2820
+ try {
2821
+ const beforeAccess = creds.access;
2822
+ const refreshed = await getValidCodexOAuth(apiUrl, apiKey, slot, {
2823
+ maxAgeMs: KEEP_WARM_MAX_AGE_MS
2824
+ });
2825
+ if (!refreshed) {
2826
+ results.push({ slot, outcome: "no-credentials" });
2827
+ } else {
2828
+ results.push({
2829
+ slot,
2830
+ keySuffix,
2831
+ outcome: refreshed.access === beforeAccess ? "warm" : "refreshed"
2832
+ });
2833
+ }
2834
+ } catch (err) {
2835
+ const reason = err instanceof Error ? err.message : String(err);
2836
+ results.push({ slot, keySuffix, outcome: "failed", reason });
2837
+ }
2838
+ await new Promise((resolve2) => setTimeout(resolve2, 100 + Math.random() * 200));
2839
+ }
2840
+ json(res, { results });
2841
+ return true;
2842
+ }
2843
+
2781
2844
  // src/http/config.ts
2782
2845
  init_zod();
2783
2846
  init_db();
@@ -6251,6 +6314,8 @@ var SDK_TOOL_NAME_MAP = {
6251
6314
  slack_startThread: "slack-start-thread",
6252
6315
  slack_uploadFile: "slack-upload-file",
6253
6316
  slack_downloadFile: "slack-download-file",
6317
+ slack_delete: "slack-delete",
6318
+ slack_update: "slack-update",
6254
6319
  message_read: "read-messages",
6255
6320
  message_post: "post-message",
6256
6321
  profile_update: "update-profile",
@@ -8184,6 +8249,98 @@ function hasRetrievalForTask(taskId, memoryId) {
8184
8249
  return row != null;
8185
8250
  }
8186
8251
 
8252
+ // src/be/memory/usefulness-stats.ts
8253
+ init_db();
8254
+ function getUsefulnessStats(options = {}) {
8255
+ const days = options.days ?? 30;
8256
+ const threshold = options.threshold ?? 0.6;
8257
+ const cutoff = new Date(Date.now() - days * 24 * 60 * 60 * 1000).toISOString();
8258
+ const db = getDb();
8259
+ const volumeRow = db.prepare(`SELECT COUNT(*) AS retrievals,
8260
+ COUNT(DISTINCT memoryId) AS distinctMemories,
8261
+ COUNT(DISTINCT retrievalId) AS retrievalGroups,
8262
+ SUM(CASE WHEN eventType = 'search' THEN 1 ELSE 0 END) AS searchEvents,
8263
+ SUM(CASE WHEN eventType = 'get' THEN 1 ELSE 0 END) AS getEvents
8264
+ FROM memory_retrieval
8265
+ WHERE retrievedAt > ?`).get(cutoff);
8266
+ const armRows = db.prepare(`SELECT mr.retrievalSource AS retrievalSource,
8267
+ COUNT(*) AS retrievals,
8268
+ COUNT(DISTINCT mr.memoryId) AS distinctMemories,
8269
+ SUM(CASE WHEN EXISTS (
8270
+ SELECT 1
8271
+ FROM memory_rating rt
8272
+ WHERE rt.taskId = mr.taskId
8273
+ AND rt.memoryId = mr.memoryId
8274
+ AND rt.source = 'implicit-citation'
8275
+ AND rt.signal > 0
8276
+ ) THEN 1 ELSE 0 END) AS citedRetrievals
8277
+ FROM memory_retrieval mr
8278
+ WHERE mr.retrievedAt > ?
8279
+ AND (mr.eventType IS NULL OR mr.eventType = 'search')
8280
+ GROUP BY mr.retrievalSource
8281
+ ORDER BY retrievals DESC`).all(cutoff);
8282
+ const sourceRows = db.prepare(`SELECT am.source AS source,
8283
+ COUNT(*) AS ratings,
8284
+ SUM(CASE WHEN mr.signal > 0 THEN 1 ELSE 0 END) AS positive,
8285
+ AVG(mr.signal) AS avgSignal
8286
+ FROM memory_rating mr
8287
+ JOIN agent_memory am ON am.id = mr.memoryId
8288
+ WHERE mr.source = 'implicit-citation'
8289
+ AND mr.createdAt > ?
8290
+ GROUP BY am.source
8291
+ ORDER BY ratings DESC`).all(cutoff);
8292
+ const posteriorRow = db.prepare(`SELECT COUNT(*) AS totalMemories,
8293
+ SUM(CASE WHEN alpha <> 1.0 OR beta <> 1.0 THEN 1 ELSE 0 END) AS movedFromPrior,
8294
+ AVG(alpha / (alpha + beta)) AS avgPosteriorMean,
8295
+ AVG(CASE WHEN alpha <> 1.0 OR beta <> 1.0
8296
+ THEN alpha / (alpha + beta) END) AS avgPosteriorMeanMoved,
8297
+ SUM(CASE WHEN alpha / (alpha + beta) > ? THEN 1 ELSE 0 END) AS aboveThreshold
8298
+ FROM agent_memory`).get(threshold);
8299
+ const totalRetrievalRows = db.prepare("SELECT COUNT(*) AS n FROM memory_retrieval").get().n;
8300
+ const ratingsBySource = db.prepare("SELECT source, COUNT(*) AS count FROM memory_rating GROUP BY source ORDER BY count DESC").all();
8301
+ const totalRatingRows = ratingsBySource.reduce((sum, row) => sum + row.count, 0);
8302
+ return {
8303
+ windowDays: days,
8304
+ threshold,
8305
+ cutoff,
8306
+ volume: {
8307
+ retrievals: volumeRow.retrievals,
8308
+ distinctMemories: volumeRow.distinctMemories,
8309
+ retrievalGroups: volumeRow.retrievalGroups,
8310
+ byEventType: {
8311
+ search: volumeRow.searchEvents ?? 0,
8312
+ get: volumeRow.getEvents ?? 0
8313
+ }
8314
+ },
8315
+ byArm: armRows.map((row) => ({
8316
+ retrievalSource: row.retrievalSource,
8317
+ retrievals: row.retrievals,
8318
+ distinctMemories: row.distinctMemories,
8319
+ citedRetrievals: row.citedRetrievals ?? 0,
8320
+ citationRate: row.retrievals > 0 ? (row.citedRetrievals ?? 0) / row.retrievals : 0
8321
+ })),
8322
+ citationBySource: sourceRows.map((row) => ({
8323
+ source: row.source,
8324
+ ratings: row.ratings,
8325
+ positive: row.positive ?? 0,
8326
+ citationRate: row.ratings > 0 ? (row.positive ?? 0) / row.ratings : 0,
8327
+ avgSignal: row.avgSignal ?? 0
8328
+ })),
8329
+ posterior: {
8330
+ totalMemories: posteriorRow.totalMemories,
8331
+ movedFromPrior: posteriorRow.movedFromPrior ?? 0,
8332
+ avgPosteriorMean: posteriorRow.avgPosteriorMean,
8333
+ avgPosteriorMeanMoved: posteriorRow.avgPosteriorMeanMoved,
8334
+ aboveThreshold: posteriorRow.aboveThreshold ?? 0
8335
+ },
8336
+ sanity: {
8337
+ totalRetrievalRows,
8338
+ totalRatingRows,
8339
+ ratingsBySource
8340
+ }
8341
+ };
8342
+ }
8343
+
8187
8344
  // src/http/memory.ts
8188
8345
  init_types();
8189
8346
  var indexMemory = route({
@@ -8300,6 +8457,22 @@ var memoryHealth = route({
8300
8457
  200: { description: "Memory vector index health" }
8301
8458
  }
8302
8459
  });
8460
+ var memoryUsefulness = route({
8461
+ method: "get",
8462
+ path: "/api/memory/usefulness",
8463
+ pattern: ["api", "memory", "usefulness"],
8464
+ summary: "Windowed memory usefulness analytics: retrieval volume, per-arm breakdown, citation rate per source, posterior movement",
8465
+ tags: ["Memory"],
8466
+ auth: { apiKey: true },
8467
+ query: exports_external.object({
8468
+ days: exports_external.coerce.number().int().min(1).max(365).default(30).describe("Analysis window in days (default 30)"),
8469
+ threshold: exports_external.coerce.number().min(0).max(1).default(0.6).describe("Posterior-mean threshold for the aboveThreshold count (default 0.6)")
8470
+ }),
8471
+ responses: {
8472
+ 200: { description: "Usefulness stats for the window" },
8473
+ 400: { description: "Validation error" }
8474
+ }
8475
+ });
8303
8476
  var deleteMemoryById = route({
8304
8477
  method: "delete",
8305
8478
  path: "/api/memory/{id}",
@@ -8325,7 +8498,9 @@ var getMemoryById = route({
8325
8498
  intent: exports_external.string().min(1).optional().describe("Why you are retrieving this memory. Required for agent recall-edge tracking; omit for UI browse calls.")
8326
8499
  }),
8327
8500
  responses: {
8328
- 200: { description: "Memory details" },
8501
+ 200: {
8502
+ description: "Memory details, plus `links` (outgoing memory_link rows; memory-kind targets carry `resolved` + ACL-filtered `target` metadata) and `backlinks` (inbound links from other memories, ACL-filtered)"
8503
+ },
8329
8504
  404: { description: "Memory not found" }
8330
8505
  }
8331
8506
  });
@@ -8453,7 +8628,7 @@ async function handleMemory(req, res, pathSegments, myAgentId) {
8453
8628
  if (embedding)
8454
8629
  store.updateEmbedding(result.memory.id, embedding, provider.name);
8455
8630
  try {
8456
- storeLinks(result.memory.id, memoryAgentId, result.memory.content);
8631
+ refreshLinks(result.memory.id, memoryAgentId, result.memory.content);
8457
8632
  } catch (err) {
8458
8633
  console.error(`[memory] Link resolution failed for ${result.memory.id}:`, err.message);
8459
8634
  }
@@ -8526,7 +8701,12 @@ async function handleMemory(req, res, pathSegments, myAgentId) {
8526
8701
  isLead: false,
8527
8702
  queryText: query
8528
8703
  });
8529
- const ranked = rerank(candidates, { limit: Math.min(limit, 20) });
8704
+ const expanded = expandCandidatesWithGraph(candidates, myAgentId, {
8705
+ scope,
8706
+ source,
8707
+ isLead: false
8708
+ });
8709
+ const ranked = rerank(expanded, { limit: Math.min(limit, 20) });
8530
8710
  const sourceTaskIdHeader = req.headers["x-source-task-id"];
8531
8711
  const sourceTaskId = Array.isArray(sourceTaskIdHeader) ? sourceTaskIdHeader[0] : sourceTaskIdHeader;
8532
8712
  const contextKeyHeader = req.headers["x-context-key"];
@@ -8552,7 +8732,8 @@ async function handleMemory(req, res, pathSegments, myAgentId) {
8552
8732
  compositeScore: r.compositeScore,
8553
8733
  retrievalSource: r.retrievalSource,
8554
8734
  source: r.source,
8555
- scope: r.scope
8735
+ scope: r.scope,
8736
+ tags: r.tags
8556
8737
  }))
8557
8738
  });
8558
8739
  } catch (err) {
@@ -8695,7 +8876,7 @@ async function handleMemory(req, res, pathSegments, myAgentId) {
8695
8876
  if (embedding)
8696
8877
  store.updateEmbedding(result.memory.id, embedding, provider.name);
8697
8878
  try {
8698
- storeLinks(result.memory.id, myAgentId, result.memory.content);
8879
+ refreshLinks(result.memory.id, myAgentId, result.memory.content);
8699
8880
  } catch (err) {
8700
8881
  console.error(`[memory-edit] Link resolution failed for ${result.memory.id}:`, err.message);
8701
8882
  }
@@ -8719,6 +8900,15 @@ async function handleMemory(req, res, pathSegments, myAgentId) {
8719
8900
  json(res, getMemoryStore().getHealth());
8720
8901
  return true;
8721
8902
  }
8903
+ if (memoryUsefulness.match(req.method, pathSegments)) {
8904
+ const queryParams = parseQueryParams(req.url || "");
8905
+ const parsed = await memoryUsefulness.parse(req, res, pathSegments, queryParams);
8906
+ if (!parsed)
8907
+ return true;
8908
+ const { days, threshold } = parsed.query;
8909
+ json(res, getUsefulnessStats({ days, threshold }));
8910
+ return true;
8911
+ }
8722
8912
  if (deleteMemoryById.match(req.method, pathSegments)) {
8723
8913
  const parsed = await deleteMemoryById.parse(req, res, pathSegments, new URLSearchParams);
8724
8914
  if (!parsed)
@@ -8873,7 +9063,13 @@ async function handleMemory(req, res, pathSegments, myAgentId) {
8873
9063
  console.error("[memory-get] recordRetrievals failed:", err.message);
8874
9064
  }
8875
9065
  }
8876
- json(res, { memory });
9066
+ let linkBlocks = { links: [], backlinks: [] };
9067
+ try {
9068
+ linkBlocks = getLinksForMemory(memory.id, { viewerAgentId: myAgentId });
9069
+ } catch (err) {
9070
+ console.error("[memory-get] link traversal failed:", err.message);
9071
+ }
9072
+ json(res, { memory, links: linkBlocks.links, backlinks: linkBlocks.backlinks });
8877
9073
  return true;
8878
9074
  }
8879
9075
  return false;
@@ -18772,6 +18968,7 @@ var httpServer = createHttpServer(async (req, res) => {
18772
18968
  () => handleMcpOAuth(req, res, pathSegments, queryParams),
18773
18969
  () => handleMemory(req, res, pathSegments, myAgentId),
18774
18970
  () => handleOAuthLocks(req, res, pathSegments, queryParams),
18971
+ () => handleCodexOAuthKeepWarm(req, res, pathSegments),
18775
18972
  () => handlePagesPublic(req, res, pathSegments, queryParams),
18776
18973
  () => handlePageProxy(req, res),
18777
18974
  () => handlePages(req, res, pathSegments, queryParams, myAgentId),
@@ -18830,14 +19027,14 @@ async function shutdown() {
18830
19027
  sessionsProcessed: getServerSessionsProcessed()
18831
19028
  });
18832
19029
  if (hasCapability("scheduling")) {
18833
- const { stopScheduler } = await import("./index-zm0x6vmf.js");
19030
+ const { stopScheduler } = await import("./index-zfx5p959.js");
18834
19031
  stopScheduler();
18835
19032
  }
18836
19033
  stopHeartbeat();
18837
19034
  stopScriptRunSupervisor();
18838
19035
  await stopSlackApp();
18839
19036
  if (process.env.OAUTH_KEEPALIVE_DISABLE !== "true") {
18840
- const { stopOAuthKeepalive } = await import("./keepalive-2gxqjgrx.js");
19037
+ const { stopOAuthKeepalive } = await import("./keepalive-rbz05zad.js");
18841
19038
  await stopOAuthKeepalive();
18842
19039
  }
18843
19040
  stopMcpOAuthPendingGc();
@@ -18890,15 +19087,15 @@ try {
18890
19087
  throw err;
18891
19088
  }
18892
19089
  try {
18893
- const { seedPricingFromModelsDev } = await import("./seed-pricing-f23sehzq.js");
19090
+ const { seedPricingFromModelsDev } = await import("./seed-pricing-1szjzfj1.js");
18894
19091
  seedPricingFromModelsDev();
18895
- const { startPricingRefreshLoop } = await import("./pricing-refresh-tqvvrk7a.js");
19092
+ const { startPricingRefreshLoop } = await import("./pricing-refresh-rmtrby6h.js");
18896
19093
  startPricingRefreshLoop();
18897
19094
  } catch (err) {
18898
19095
  console.error("[startup] Failed to seed pricing rows:", err);
18899
19096
  }
18900
19097
  try {
18901
- const { runAllSeeders } = await import("./index-c35g752k.js");
19098
+ const { runAllSeeders } = await import("./index-ha8e9xn2.js");
18902
19099
  await runAllSeeders({ scriptEmbeddingMode: "skip" });
18903
19100
  } catch (err) {
18904
19101
  console.error("[startup] Failed to seed built-in entities:", err);
@@ -18931,31 +19128,31 @@ httpServer.listen(port, async () => {
18931
19128
  initWorkflows();
18932
19129
  startScriptRunSupervisor(getMcpBaseUrl());
18933
19130
  if (hasCapability("scheduling")) {
18934
- const { startScheduler } = await import("./index-zm0x6vmf.js");
18935
- const { getExecutorRegistry: getExecutorRegistry2 } = await import("./index-e01wmtj0.js");
19131
+ const { startScheduler } = await import("./index-zfx5p959.js");
19132
+ const { getExecutorRegistry: getExecutorRegistry2 } = await import("./index-3wr6v2mm.js");
18936
19133
  const intervalMs = Number(process.env.SCHEDULER_INTERVAL_MS) || 1e4;
18937
19134
  startScheduler(getExecutorRegistry2(), intervalMs, {
18938
19135
  runId: globalState.__runId
18939
19136
  });
18940
19137
  }
18941
19138
  if (process.env.HEARTBEAT_DISABLE !== "true") {
18942
- const { startHeartbeat } = await import("./index-464v93y6.js");
19139
+ const { startHeartbeat } = await import("./index-brma88d4.js");
18943
19140
  const heartbeatMs = Number(process.env.HEARTBEAT_INTERVAL_MS) || 90000;
18944
19141
  startHeartbeat(heartbeatMs);
18945
19142
  }
18946
19143
  if (process.env.OAUTH_KEEPALIVE_DISABLE !== "true") {
18947
- const { startOAuthKeepalive } = await import("./keepalive-2gxqjgrx.js");
19144
+ const { startOAuthKeepalive } = await import("./keepalive-rbz05zad.js");
18948
19145
  startOAuthKeepalive();
18949
19146
  }
18950
19147
  startMcpOAuthPendingGc();
18951
19148
  startMemoryGc();
18952
- import("./boot-reembed-8xmfv2pq.js").then(({ runBootReembed }) => runBootReembed()).catch((err) => {
19149
+ import("./boot-reembed-yv7awg4y.js").then(({ runBootReembed }) => runBootReembed()).catch((err) => {
18953
19150
  console.error("[boot-reembed] startup backfill failed (non-fatal):", err);
18954
19151
  });
18955
- import("./boot-reembed-5sd1t9r4.js").then(({ runBootReembedScripts }) => runBootReembedScripts()).catch((err) => {
19152
+ import("./boot-reembed-y1bt3ttn.js").then(({ runBootReembedScripts }) => runBootReembedScripts()).catch((err) => {
18956
19153
  console.error("[boot-reembed-scripts] startup backfill failed (non-fatal):", err);
18957
19154
  });
18958
- import("./boot-scrub-logs-fdw8wbtq.js").then(({ runBootScrubLogs }) => runBootScrubLogs()).catch((err) => {
19155
+ import("./boot-scrub-logs-ddyaeqar.js").then(({ runBootScrubLogs }) => runBootScrubLogs()).catch((err) => {
18959
19156
  console.error("[boot-scrub-logs] startup scrub failed (non-fatal):", err);
18960
19157
  });
18961
19158
  }).on("error", (err) => {
@@ -20,21 +20,21 @@ import {
20
20
  stopWaitPoller,
21
21
  subscribeWaitToBus,
22
22
  validateTemplateVariables
23
- } from "./cli-3t97r3y1.js";
23
+ } from "./cli-tg0f2wmz.js";
24
24
  import"./cli-f14fvzag.js";
25
- import"./cli-2h86bsfe.js";
26
- import"./cli-dy01kwxk.js";
27
- import"./cli-5kav4x1a.js";
25
+ import"./cli-3r5y6ayj.js";
26
+ import"./cli-s9pj3c7z.js";
27
+ import"./cli-709t753c.js";
28
28
  import"./cli-q25ejbyn.js";
29
- import"./cli-8ps5wsk9.js";
29
+ import"./cli-0c3n0eba.js";
30
30
  import"./cli-dh55d5fg.js";
31
31
  import {
32
32
  interpolate
33
- } from "./cli-d8vmtyyr.js";
33
+ } from "./cli-951w7c79.js";
34
34
  import"./cli-z2zcxes1.js";
35
35
  import"./cli-q21d49ac.js";
36
36
  import"./cli-anrj584m.js";
37
- import"./cli-kg9v8h1w.js";
37
+ import"./cli-8f0dwca2.js";
38
38
  import"./cli-4j2mrzag.js";
39
39
  import {
40
40
  workflowEventBus
@@ -4,22 +4,22 @@ import {
4
4
  runRebootSweep,
5
5
  startHeartbeat,
6
6
  stopHeartbeat
7
- } from "./cli-gtt1f14h.js";
8
- import"./cli-k6ssh5dk.js";
9
- import"./cli-3t97r3y1.js";
7
+ } from "./cli-pt7c7qxz.js";
8
+ import"./cli-56s4ehzw.js";
9
+ import"./cli-tg0f2wmz.js";
10
10
  import"./cli-f14fvzag.js";
11
- import"./cli-2h86bsfe.js";
12
- import"./cli-dy01kwxk.js";
13
- import"./cli-5kav4x1a.js";
11
+ import"./cli-3r5y6ayj.js";
12
+ import"./cli-s9pj3c7z.js";
13
+ import"./cli-709t753c.js";
14
14
  import"./cli-q25ejbyn.js";
15
15
  import"./cli-wspgs9bt.js";
16
- import"./cli-8ps5wsk9.js";
16
+ import"./cli-0c3n0eba.js";
17
17
  import"./cli-dh55d5fg.js";
18
- import"./cli-d8vmtyyr.js";
18
+ import"./cli-951w7c79.js";
19
19
  import"./cli-z2zcxes1.js";
20
20
  import"./cli-q21d49ac.js";
21
21
  import"./cli-anrj584m.js";
22
- import"./cli-kg9v8h1w.js";
22
+ import"./cli-8f0dwca2.js";
23
23
  import"./cli-4j2mrzag.js";
24
24
  import"./cli-9aryf9tv.js";
25
25
  import"./cli-p9swy5t3.js";
@@ -3,14 +3,14 @@ import {
3
3
  extractArgsJsonSchema,
4
4
  extractScriptSignature,
5
5
  typecheckScript
6
- } from "./cli-cwety9qq.js";
6
+ } from "./cli-tp7e60s3.js";
7
7
  import {
8
8
  getScript,
9
9
  upsertScriptByName,
10
10
  validateScriptImports
11
- } from "./cli-2h86bsfe.js";
12
- import"./cli-dy01kwxk.js";
13
- import"./cli-5kav4x1a.js";
11
+ } from "./cli-3r5y6ayj.js";
12
+ import"./cli-s9pj3c7z.js";
13
+ import"./cli-709t753c.js";
14
14
  import"./cli-q25ejbyn.js";
15
15
  import {
16
16
  computeContentHash,
@@ -19,11 +19,11 @@ import {
19
19
  getSkillByName,
20
20
  init_db,
21
21
  updateSkill
22
- } from "./cli-d8vmtyyr.js";
22
+ } from "./cli-951w7c79.js";
23
23
  import"./cli-z2zcxes1.js";
24
24
  import"./cli-q21d49ac.js";
25
25
  import"./cli-anrj584m.js";
26
- import"./cli-kg9v8h1w.js";
26
+ import"./cli-8f0dwca2.js";
27
27
  import"./cli-4j2mrzag.js";
28
28
  import"./cli-p9swy5t3.js";
29
29
 
@@ -4071,17 +4071,13 @@ export const argsSchema = z.object({
4071
4071
  .positive()
4072
4072
  .optional()
4073
4073
  .describe("Max results per query (default 10)"),
4074
- dedupThreshold: z
4075
- .number()
4076
- .optional()
4077
- .describe("Similarity threshold for dedup — memories above this are merged (default 0.92)"),
4078
4074
  });
4079
4075
 
4080
4076
  /** Multi-query fan-out memory recall with dedup and composite reranking. */
4081
4077
  export default async function smartRecall(args: any, ctx: any) {
4082
4078
  const parsed = argsSchema.safeParse(args);
4083
4079
  if (!parsed.success) return { error: "invalid args: " + parsed.error.message };
4084
- const { queries, scope = "all", limit = 10, dedupThreshold = 0.92 } = parsed.data;
4080
+ const { queries, scope = "all", limit = 10 } = parsed.data;
4085
4081
 
4086
4082
  const allResults: any[] = [];
4087
4083
  for (const q of queries) {
@@ -4,20 +4,20 @@ import {
4
4
  runScheduleNow,
5
5
  startScheduler,
6
6
  stopScheduler
7
- } from "./cli-zw3cmjh6.js";
8
- import"./cli-3t97r3y1.js";
7
+ } from "./cli-94vzr3nq.js";
8
+ import"./cli-tg0f2wmz.js";
9
9
  import"./cli-f14fvzag.js";
10
- import"./cli-2h86bsfe.js";
11
- import"./cli-dy01kwxk.js";
12
- import"./cli-5kav4x1a.js";
10
+ import"./cli-3r5y6ayj.js";
11
+ import"./cli-s9pj3c7z.js";
12
+ import"./cli-709t753c.js";
13
13
  import"./cli-q25ejbyn.js";
14
- import"./cli-8ps5wsk9.js";
14
+ import"./cli-0c3n0eba.js";
15
15
  import"./cli-dh55d5fg.js";
16
- import"./cli-d8vmtyyr.js";
16
+ import"./cli-951w7c79.js";
17
17
  import"./cli-z2zcxes1.js";
18
18
  import"./cli-q21d49ac.js";
19
19
  import"./cli-anrj584m.js";
20
- import"./cli-kg9v8h1w.js";
20
+ import"./cli-8f0dwca2.js";
21
21
  import"./cli-4j2mrzag.js";
22
22
  import"./cli-9aryf9tv.js";
23
23
  import"./cli-p9swy5t3.js";