@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
@@ -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-aenr2vrd.js";
114
+ } from "./cli-dza5039b.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-pqgd2rd1.js";
140
- import"./cli-rk3snywa.js";
147
+ } from "./cli-3cm8ar1c.js";
148
+ import"./cli-ee3fkebs.js";
141
149
  import {
142
150
  normalizeModelKey
143
- } from "./cli-72vm595k.js";
151
+ } from "./cli-6tfm5fr1.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-ef1wbkhh.js";
159
+ } from "./cli-fdnpymsv.js";
152
160
  import {
153
161
  checkHeartbeatChecklist,
154
162
  runHeartbeatSweep,
155
163
  stopHeartbeat
156
- } from "./cli-3s560caw.js";
164
+ } from "./cli-t8m00q3b.js";
157
165
  import {
158
166
  createResumeFollowUp,
159
167
  createWorkerTaskFollowUp
160
- } from "./cli-wdp73c7w.js";
168
+ } from "./cli-gchg43wt.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-987a9zvn.js";
176
+ } from "./cli-r3y5chyg.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-06p7cfcg.js";
196
+ } from "./cli-1aqc46he.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-4hapc9v6.js";
217
+ } from "./cli-4f6vw5vy.js";
210
218
  import {
211
219
  searchScripts
212
- } from "./cli-7d38eycj.js";
220
+ } from "./cli-h3vhr1gj.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-0wbkrrky.js";
228
+ } from "./cli-0d5xddf1.js";
221
229
  import"./cli-q25ejbyn.js";
222
- import"./cli-wgbsdhjc.js";
230
+ import"./cli-xqzvygxp.js";
223
231
  import {
224
232
  getSlackApp,
225
233
  startSlackApp,
226
234
  stopSlackApp
227
- } from "./cli-rtqc5r54.js";
235
+ } from "./cli-f1f82qgv.js";
228
236
  import"./cli-rkndnn90.js";
229
237
  import"./cli-b0p7rfnd.js";
230
238
  import {
231
239
  recordUnmappedIdentity
232
- } from "./cli-efaejv9v.js";
240
+ } from "./cli-2b0ew5v8.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-dn44vqyb.js";
254
+ } from "./cli-0d404x64.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-wjsj96hh.js";
262
+ } from "./cli-aqr96mny.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-ng2k7kwa.js";
574
+ } from "./cli-4ke1amr9.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-eqq99cyd.js";
589
+ } from "./cli-kavm2cv5.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();
@@ -8184,6 +8247,98 @@ function hasRetrievalForTask(taskId, memoryId) {
8184
8247
  return row != null;
8185
8248
  }
8186
8249
 
8250
+ // src/be/memory/usefulness-stats.ts
8251
+ init_db();
8252
+ function getUsefulnessStats(options = {}) {
8253
+ const days = options.days ?? 30;
8254
+ const threshold = options.threshold ?? 0.6;
8255
+ const cutoff = new Date(Date.now() - days * 24 * 60 * 60 * 1000).toISOString();
8256
+ const db = getDb();
8257
+ const volumeRow = db.prepare(`SELECT COUNT(*) AS retrievals,
8258
+ COUNT(DISTINCT memoryId) AS distinctMemories,
8259
+ COUNT(DISTINCT retrievalId) AS retrievalGroups,
8260
+ SUM(CASE WHEN eventType = 'search' THEN 1 ELSE 0 END) AS searchEvents,
8261
+ SUM(CASE WHEN eventType = 'get' THEN 1 ELSE 0 END) AS getEvents
8262
+ FROM memory_retrieval
8263
+ WHERE retrievedAt > ?`).get(cutoff);
8264
+ const armRows = db.prepare(`SELECT mr.retrievalSource AS retrievalSource,
8265
+ COUNT(*) AS retrievals,
8266
+ COUNT(DISTINCT mr.memoryId) AS distinctMemories,
8267
+ SUM(CASE WHEN EXISTS (
8268
+ SELECT 1
8269
+ FROM memory_rating rt
8270
+ WHERE rt.taskId = mr.taskId
8271
+ AND rt.memoryId = mr.memoryId
8272
+ AND rt.source = 'implicit-citation'
8273
+ AND rt.signal > 0
8274
+ ) THEN 1 ELSE 0 END) AS citedRetrievals
8275
+ FROM memory_retrieval mr
8276
+ WHERE mr.retrievedAt > ?
8277
+ AND (mr.eventType IS NULL OR mr.eventType = 'search')
8278
+ GROUP BY mr.retrievalSource
8279
+ ORDER BY retrievals DESC`).all(cutoff);
8280
+ const sourceRows = db.prepare(`SELECT am.source AS source,
8281
+ COUNT(*) AS ratings,
8282
+ SUM(CASE WHEN mr.signal > 0 THEN 1 ELSE 0 END) AS positive,
8283
+ AVG(mr.signal) AS avgSignal
8284
+ FROM memory_rating mr
8285
+ JOIN agent_memory am ON am.id = mr.memoryId
8286
+ WHERE mr.source = 'implicit-citation'
8287
+ AND mr.createdAt > ?
8288
+ GROUP BY am.source
8289
+ ORDER BY ratings DESC`).all(cutoff);
8290
+ const posteriorRow = db.prepare(`SELECT COUNT(*) AS totalMemories,
8291
+ SUM(CASE WHEN alpha <> 1.0 OR beta <> 1.0 THEN 1 ELSE 0 END) AS movedFromPrior,
8292
+ AVG(alpha / (alpha + beta)) AS avgPosteriorMean,
8293
+ AVG(CASE WHEN alpha <> 1.0 OR beta <> 1.0
8294
+ THEN alpha / (alpha + beta) END) AS avgPosteriorMeanMoved,
8295
+ SUM(CASE WHEN alpha / (alpha + beta) > ? THEN 1 ELSE 0 END) AS aboveThreshold
8296
+ FROM agent_memory`).get(threshold);
8297
+ const totalRetrievalRows = db.prepare("SELECT COUNT(*) AS n FROM memory_retrieval").get().n;
8298
+ const ratingsBySource = db.prepare("SELECT source, COUNT(*) AS count FROM memory_rating GROUP BY source ORDER BY count DESC").all();
8299
+ const totalRatingRows = ratingsBySource.reduce((sum, row) => sum + row.count, 0);
8300
+ return {
8301
+ windowDays: days,
8302
+ threshold,
8303
+ cutoff,
8304
+ volume: {
8305
+ retrievals: volumeRow.retrievals,
8306
+ distinctMemories: volumeRow.distinctMemories,
8307
+ retrievalGroups: volumeRow.retrievalGroups,
8308
+ byEventType: {
8309
+ search: volumeRow.searchEvents ?? 0,
8310
+ get: volumeRow.getEvents ?? 0
8311
+ }
8312
+ },
8313
+ byArm: armRows.map((row) => ({
8314
+ retrievalSource: row.retrievalSource,
8315
+ retrievals: row.retrievals,
8316
+ distinctMemories: row.distinctMemories,
8317
+ citedRetrievals: row.citedRetrievals ?? 0,
8318
+ citationRate: row.retrievals > 0 ? (row.citedRetrievals ?? 0) / row.retrievals : 0
8319
+ })),
8320
+ citationBySource: sourceRows.map((row) => ({
8321
+ source: row.source,
8322
+ ratings: row.ratings,
8323
+ positive: row.positive ?? 0,
8324
+ citationRate: row.ratings > 0 ? (row.positive ?? 0) / row.ratings : 0,
8325
+ avgSignal: row.avgSignal ?? 0
8326
+ })),
8327
+ posterior: {
8328
+ totalMemories: posteriorRow.totalMemories,
8329
+ movedFromPrior: posteriorRow.movedFromPrior ?? 0,
8330
+ avgPosteriorMean: posteriorRow.avgPosteriorMean,
8331
+ avgPosteriorMeanMoved: posteriorRow.avgPosteriorMeanMoved,
8332
+ aboveThreshold: posteriorRow.aboveThreshold ?? 0
8333
+ },
8334
+ sanity: {
8335
+ totalRetrievalRows,
8336
+ totalRatingRows,
8337
+ ratingsBySource
8338
+ }
8339
+ };
8340
+ }
8341
+
8187
8342
  // src/http/memory.ts
8188
8343
  init_types();
8189
8344
  var indexMemory = route({
@@ -8300,6 +8455,22 @@ var memoryHealth = route({
8300
8455
  200: { description: "Memory vector index health" }
8301
8456
  }
8302
8457
  });
8458
+ var memoryUsefulness = route({
8459
+ method: "get",
8460
+ path: "/api/memory/usefulness",
8461
+ pattern: ["api", "memory", "usefulness"],
8462
+ summary: "Windowed memory usefulness analytics: retrieval volume, per-arm breakdown, citation rate per source, posterior movement",
8463
+ tags: ["Memory"],
8464
+ auth: { apiKey: true },
8465
+ query: exports_external.object({
8466
+ days: exports_external.coerce.number().int().min(1).max(365).default(30).describe("Analysis window in days (default 30)"),
8467
+ threshold: exports_external.coerce.number().min(0).max(1).default(0.6).describe("Posterior-mean threshold for the aboveThreshold count (default 0.6)")
8468
+ }),
8469
+ responses: {
8470
+ 200: { description: "Usefulness stats for the window" },
8471
+ 400: { description: "Validation error" }
8472
+ }
8473
+ });
8303
8474
  var deleteMemoryById = route({
8304
8475
  method: "delete",
8305
8476
  path: "/api/memory/{id}",
@@ -8325,7 +8496,9 @@ var getMemoryById = route({
8325
8496
  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
8497
  }),
8327
8498
  responses: {
8328
- 200: { description: "Memory details" },
8499
+ 200: {
8500
+ 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)"
8501
+ },
8329
8502
  404: { description: "Memory not found" }
8330
8503
  }
8331
8504
  });
@@ -8453,7 +8626,7 @@ async function handleMemory(req, res, pathSegments, myAgentId) {
8453
8626
  if (embedding)
8454
8627
  store.updateEmbedding(result.memory.id, embedding, provider.name);
8455
8628
  try {
8456
- storeLinks(result.memory.id, memoryAgentId, result.memory.content);
8629
+ refreshLinks(result.memory.id, memoryAgentId, result.memory.content);
8457
8630
  } catch (err) {
8458
8631
  console.error(`[memory] Link resolution failed for ${result.memory.id}:`, err.message);
8459
8632
  }
@@ -8526,7 +8699,12 @@ async function handleMemory(req, res, pathSegments, myAgentId) {
8526
8699
  isLead: false,
8527
8700
  queryText: query
8528
8701
  });
8529
- const ranked = rerank(candidates, { limit: Math.min(limit, 20) });
8702
+ const expanded = expandCandidatesWithGraph(candidates, myAgentId, {
8703
+ scope,
8704
+ source,
8705
+ isLead: false
8706
+ });
8707
+ const ranked = rerank(expanded, { limit: Math.min(limit, 20) });
8530
8708
  const sourceTaskIdHeader = req.headers["x-source-task-id"];
8531
8709
  const sourceTaskId = Array.isArray(sourceTaskIdHeader) ? sourceTaskIdHeader[0] : sourceTaskIdHeader;
8532
8710
  const contextKeyHeader = req.headers["x-context-key"];
@@ -8552,7 +8730,8 @@ async function handleMemory(req, res, pathSegments, myAgentId) {
8552
8730
  compositeScore: r.compositeScore,
8553
8731
  retrievalSource: r.retrievalSource,
8554
8732
  source: r.source,
8555
- scope: r.scope
8733
+ scope: r.scope,
8734
+ tags: r.tags
8556
8735
  }))
8557
8736
  });
8558
8737
  } catch (err) {
@@ -8695,7 +8874,7 @@ async function handleMemory(req, res, pathSegments, myAgentId) {
8695
8874
  if (embedding)
8696
8875
  store.updateEmbedding(result.memory.id, embedding, provider.name);
8697
8876
  try {
8698
- storeLinks(result.memory.id, myAgentId, result.memory.content);
8877
+ refreshLinks(result.memory.id, myAgentId, result.memory.content);
8699
8878
  } catch (err) {
8700
8879
  console.error(`[memory-edit] Link resolution failed for ${result.memory.id}:`, err.message);
8701
8880
  }
@@ -8719,6 +8898,15 @@ async function handleMemory(req, res, pathSegments, myAgentId) {
8719
8898
  json(res, getMemoryStore().getHealth());
8720
8899
  return true;
8721
8900
  }
8901
+ if (memoryUsefulness.match(req.method, pathSegments)) {
8902
+ const queryParams = parseQueryParams(req.url || "");
8903
+ const parsed = await memoryUsefulness.parse(req, res, pathSegments, queryParams);
8904
+ if (!parsed)
8905
+ return true;
8906
+ const { days, threshold } = parsed.query;
8907
+ json(res, getUsefulnessStats({ days, threshold }));
8908
+ return true;
8909
+ }
8722
8910
  if (deleteMemoryById.match(req.method, pathSegments)) {
8723
8911
  const parsed = await deleteMemoryById.parse(req, res, pathSegments, new URLSearchParams);
8724
8912
  if (!parsed)
@@ -8873,7 +9061,13 @@ async function handleMemory(req, res, pathSegments, myAgentId) {
8873
9061
  console.error("[memory-get] recordRetrievals failed:", err.message);
8874
9062
  }
8875
9063
  }
8876
- json(res, { memory });
9064
+ let linkBlocks = { links: [], backlinks: [] };
9065
+ try {
9066
+ linkBlocks = getLinksForMemory(memory.id, { viewerAgentId: myAgentId });
9067
+ } catch (err) {
9068
+ console.error("[memory-get] link traversal failed:", err.message);
9069
+ }
9070
+ json(res, { memory, links: linkBlocks.links, backlinks: linkBlocks.backlinks });
8877
9071
  return true;
8878
9072
  }
8879
9073
  return false;
@@ -18772,6 +18966,7 @@ var httpServer = createHttpServer(async (req, res) => {
18772
18966
  () => handleMcpOAuth(req, res, pathSegments, queryParams),
18773
18967
  () => handleMemory(req, res, pathSegments, myAgentId),
18774
18968
  () => handleOAuthLocks(req, res, pathSegments, queryParams),
18969
+ () => handleCodexOAuthKeepWarm(req, res, pathSegments),
18775
18970
  () => handlePagesPublic(req, res, pathSegments, queryParams),
18776
18971
  () => handlePageProxy(req, res),
18777
18972
  () => handlePages(req, res, pathSegments, queryParams, myAgentId),
@@ -18830,14 +19025,14 @@ async function shutdown() {
18830
19025
  sessionsProcessed: getServerSessionsProcessed()
18831
19026
  });
18832
19027
  if (hasCapability("scheduling")) {
18833
- const { stopScheduler } = await import("./index-md9ke5yd.js");
19028
+ const { stopScheduler } = await import("./index-20mf9wvc.js");
18834
19029
  stopScheduler();
18835
19030
  }
18836
19031
  stopHeartbeat();
18837
19032
  stopScriptRunSupervisor();
18838
19033
  await stopSlackApp();
18839
19034
  if (process.env.OAUTH_KEEPALIVE_DISABLE !== "true") {
18840
- const { stopOAuthKeepalive } = await import("./keepalive-54awap1s.js");
19035
+ const { stopOAuthKeepalive } = await import("./keepalive-3gvnbxaj.js");
18841
19036
  await stopOAuthKeepalive();
18842
19037
  }
18843
19038
  stopMcpOAuthPendingGc();
@@ -18890,15 +19085,15 @@ try {
18890
19085
  throw err;
18891
19086
  }
18892
19087
  try {
18893
- const { seedPricingFromModelsDev } = await import("./seed-pricing-1af3yh3p.js");
19088
+ const { seedPricingFromModelsDev } = await import("./seed-pricing-7yfaf123.js");
18894
19089
  seedPricingFromModelsDev();
18895
- const { startPricingRefreshLoop } = await import("./pricing-refresh-q3yep8w5.js");
19090
+ const { startPricingRefreshLoop } = await import("./pricing-refresh-rat240yg.js");
18896
19091
  startPricingRefreshLoop();
18897
19092
  } catch (err) {
18898
19093
  console.error("[startup] Failed to seed pricing rows:", err);
18899
19094
  }
18900
19095
  try {
18901
- const { runAllSeeders } = await import("./index-kax7pt3w.js");
19096
+ const { runAllSeeders } = await import("./index-6zpajd9e.js");
18902
19097
  await runAllSeeders({ scriptEmbeddingMode: "skip" });
18903
19098
  } catch (err) {
18904
19099
  console.error("[startup] Failed to seed built-in entities:", err);
@@ -18931,31 +19126,31 @@ httpServer.listen(port, async () => {
18931
19126
  initWorkflows();
18932
19127
  startScriptRunSupervisor(getMcpBaseUrl());
18933
19128
  if (hasCapability("scheduling")) {
18934
- const { startScheduler } = await import("./index-md9ke5yd.js");
18935
- const { getExecutorRegistry: getExecutorRegistry2 } = await import("./index-nbh8s0gd.js");
19129
+ const { startScheduler } = await import("./index-20mf9wvc.js");
19130
+ const { getExecutorRegistry: getExecutorRegistry2 } = await import("./index-w15fk28m.js");
18936
19131
  const intervalMs = Number(process.env.SCHEDULER_INTERVAL_MS) || 1e4;
18937
19132
  startScheduler(getExecutorRegistry2(), intervalMs, {
18938
19133
  runId: globalState.__runId
18939
19134
  });
18940
19135
  }
18941
19136
  if (process.env.HEARTBEAT_DISABLE !== "true") {
18942
- const { startHeartbeat } = await import("./index-jw00ycgg.js");
19137
+ const { startHeartbeat } = await import("./index-744yvc8x.js");
18943
19138
  const heartbeatMs = Number(process.env.HEARTBEAT_INTERVAL_MS) || 90000;
18944
19139
  startHeartbeat(heartbeatMs);
18945
19140
  }
18946
19141
  if (process.env.OAUTH_KEEPALIVE_DISABLE !== "true") {
18947
- const { startOAuthKeepalive } = await import("./keepalive-54awap1s.js");
19142
+ const { startOAuthKeepalive } = await import("./keepalive-3gvnbxaj.js");
18948
19143
  startOAuthKeepalive();
18949
19144
  }
18950
19145
  startMcpOAuthPendingGc();
18951
19146
  startMemoryGc();
18952
- import("./boot-reembed-3af9vms0.js").then(({ runBootReembed }) => runBootReembed()).catch((err) => {
19147
+ import("./boot-reembed-0t815mmm.js").then(({ runBootReembed }) => runBootReembed()).catch((err) => {
18953
19148
  console.error("[boot-reembed] startup backfill failed (non-fatal):", err);
18954
19149
  });
18955
- import("./boot-reembed-jd82hb59.js").then(({ runBootReembedScripts }) => runBootReembedScripts()).catch((err) => {
19150
+ import("./boot-reembed-50zzk97q.js").then(({ runBootReembedScripts }) => runBootReembedScripts()).catch((err) => {
18956
19151
  console.error("[boot-reembed-scripts] startup backfill failed (non-fatal):", err);
18957
19152
  });
18958
- import("./boot-scrub-logs-858c7xqe.js").then(({ runBootScrubLogs }) => runBootScrubLogs()).catch((err) => {
19153
+ import("./boot-scrub-logs-r99nbmxh.js").then(({ runBootScrubLogs }) => runBootScrubLogs()).catch((err) => {
18959
19154
  console.error("[boot-scrub-logs] startup scrub failed (non-fatal):", err);
18960
19155
  });
18961
19156
  }).on("error", (err) => {
@@ -4,20 +4,20 @@ import {
4
4
  runScheduleNow,
5
5
  startScheduler,
6
6
  stopScheduler
7
- } from "./cli-987a9zvn.js";
8
- import"./cli-06p7cfcg.js";
7
+ } from "./cli-r3y5chyg.js";
8
+ import"./cli-1aqc46he.js";
9
9
  import"./cli-f14fvzag.js";
10
- import"./cli-4hapc9v6.js";
11
- import"./cli-7d38eycj.js";
12
- import"./cli-0wbkrrky.js";
10
+ import"./cli-4f6vw5vy.js";
11
+ import"./cli-h3vhr1gj.js";
12
+ import"./cli-0d5xddf1.js";
13
13
  import"./cli-q25ejbyn.js";
14
- import"./cli-wjsj96hh.js";
14
+ import"./cli-aqr96mny.js";
15
15
  import"./cli-dh55d5fg.js";
16
- import"./cli-ng2k7kwa.js";
16
+ import"./cli-4ke1amr9.js";
17
17
  import"./cli-z2zcxes1.js";
18
18
  import"./cli-q21d49ac.js";
19
19
  import"./cli-anrj584m.js";
20
- import"./cli-eqq99cyd.js";
20
+ import"./cli-kavm2cv5.js";
21
21
  import"./cli-4j2mrzag.js";
22
22
  import"./cli-9aryf9tv.js";
23
23
  import"./cli-p9swy5t3.js";
@@ -3,14 +3,14 @@ import {
3
3
  extractArgsJsonSchema,
4
4
  extractScriptSignature,
5
5
  typecheckScript
6
- } from "./cli-ef1wbkhh.js";
6
+ } from "./cli-fdnpymsv.js";
7
7
  import {
8
8
  getScript,
9
9
  upsertScriptByName,
10
10
  validateScriptImports
11
- } from "./cli-4hapc9v6.js";
12
- import"./cli-7d38eycj.js";
13
- import"./cli-0wbkrrky.js";
11
+ } from "./cli-4f6vw5vy.js";
12
+ import"./cli-h3vhr1gj.js";
13
+ import"./cli-0d5xddf1.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-ng2k7kwa.js";
22
+ } from "./cli-4ke1amr9.js";
23
23
  import"./cli-z2zcxes1.js";
24
24
  import"./cli-q21d49ac.js";
25
25
  import"./cli-anrj584m.js";
26
- import"./cli-eqq99cyd.js";
26
+ import"./cli-kavm2cv5.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,22 +4,22 @@ import {
4
4
  runRebootSweep,
5
5
  startHeartbeat,
6
6
  stopHeartbeat
7
- } from "./cli-3s560caw.js";
8
- import"./cli-wdp73c7w.js";
9
- import"./cli-06p7cfcg.js";
7
+ } from "./cli-t8m00q3b.js";
8
+ import"./cli-gchg43wt.js";
9
+ import"./cli-1aqc46he.js";
10
10
  import"./cli-f14fvzag.js";
11
- import"./cli-4hapc9v6.js";
12
- import"./cli-7d38eycj.js";
13
- import"./cli-0wbkrrky.js";
11
+ import"./cli-4f6vw5vy.js";
12
+ import"./cli-h3vhr1gj.js";
13
+ import"./cli-0d5xddf1.js";
14
14
  import"./cli-q25ejbyn.js";
15
15
  import"./cli-wspgs9bt.js";
16
- import"./cli-wjsj96hh.js";
16
+ import"./cli-aqr96mny.js";
17
17
  import"./cli-dh55d5fg.js";
18
- import"./cli-ng2k7kwa.js";
18
+ import"./cli-4ke1amr9.js";
19
19
  import"./cli-z2zcxes1.js";
20
20
  import"./cli-q21d49ac.js";
21
21
  import"./cli-anrj584m.js";
22
- import"./cli-eqq99cyd.js";
22
+ import"./cli-kavm2cv5.js";
23
23
  import"./cli-4j2mrzag.js";
24
24
  import"./cli-9aryf9tv.js";
25
25
  import"./cli-p9swy5t3.js";
@@ -20,21 +20,21 @@ import {
20
20
  stopWaitPoller,
21
21
  subscribeWaitToBus,
22
22
  validateTemplateVariables
23
- } from "./cli-06p7cfcg.js";
23
+ } from "./cli-1aqc46he.js";
24
24
  import"./cli-f14fvzag.js";
25
- import"./cli-4hapc9v6.js";
26
- import"./cli-7d38eycj.js";
27
- import"./cli-0wbkrrky.js";
25
+ import"./cli-4f6vw5vy.js";
26
+ import"./cli-h3vhr1gj.js";
27
+ import"./cli-0d5xddf1.js";
28
28
  import"./cli-q25ejbyn.js";
29
- import"./cli-wjsj96hh.js";
29
+ import"./cli-aqr96mny.js";
30
30
  import"./cli-dh55d5fg.js";
31
31
  import {
32
32
  interpolate
33
- } from "./cli-ng2k7kwa.js";
33
+ } from "./cli-4ke1amr9.js";
34
34
  import"./cli-z2zcxes1.js";
35
35
  import"./cli-q21d49ac.js";
36
36
  import"./cli-anrj584m.js";
37
- import"./cli-eqq99cyd.js";
37
+ import"./cli-kavm2cv5.js";
38
38
  import"./cli-4j2mrzag.js";
39
39
  import {
40
40
  workflowEventBus
@@ -1,11 +1,11 @@
1
1
  import {
2
2
  ensureTokenOrThrow
3
- } from "./cli-pqgd2rd1.js";
4
- import"./cli-ng2k7kwa.js";
3
+ } from "./cli-3cm8ar1c.js";
4
+ import"./cli-4ke1amr9.js";
5
5
  import"./cli-z2zcxes1.js";
6
6
  import"./cli-q21d49ac.js";
7
7
  import"./cli-anrj584m.js";
8
- import"./cli-eqq99cyd.js";
8
+ import"./cli-kavm2cv5.js";
9
9
  import"./cli-4j2mrzag.js";
10
10
  import {
11
11
  __require
@@ -54,7 +54,7 @@ async function notifySlack(text) {
54
54
  return;
55
55
  }
56
56
  try {
57
- const { getSlackApp } = await import("./app-16zmk3px.js");
57
+ const { getSlackApp } = await import("./app-va5mr9yw.js");
58
58
  const app = getSlackApp();
59
59
  if (!app) {
60
60
  console.warn("[OAuth Keepalive] Slack not available, cannot send notification");