@sentry/junior 0.155.0 → 0.157.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 (94) hide show
  1. package/dist/{agent-hooks-AWVTLAV2.js → agent-hooks-QI5EPOKQ.js} +10 -10
  2. package/dist/api/conversations/attachments.d.ts +32 -0
  3. package/dist/api/conversations/priority.d.ts +21 -0
  4. package/dist/api/conversations/routes.d.ts +4 -1
  5. package/dist/api/locations/detail.d.ts +4 -1
  6. package/dist/api/schema/conversation.d.ts +33 -8
  7. package/dist/api/schema/location.d.ts +4 -1
  8. package/dist/api/schema/person.d.ts +4 -1
  9. package/dist/api/schema/task.d.ts +8 -8
  10. package/dist/api/schema.js +1 -1
  11. package/dist/api.js +182 -48
  12. package/dist/app.js +128 -44
  13. package/dist/{catalog-runtime-V6YD6KH5.js → catalog-runtime-HUGHAFUN.js} +5 -5
  14. package/dist/chat/agent/types.d.ts +2 -0
  15. package/dist/chat/agent-invocations/types.d.ts +12 -12
  16. package/dist/chat/attachments/storage.d.ts +14 -0
  17. package/dist/chat/attachments/store.d.ts +68 -0
  18. package/dist/chat/attachments/vercel.d.ts +3 -0
  19. package/dist/chat/conversations/retention.d.ts +4 -0
  20. package/dist/chat/event-tasks/tool-support.d.ts +1 -1
  21. package/dist/chat/event-tasks/types.d.ts +1 -1
  22. package/dist/chat/ingress/bot-mention.d.ts +13 -0
  23. package/dist/chat/plugins/unfinished-work.d.ts +11 -0
  24. package/dist/chat/runtime/agent-runner.d.ts +2 -0
  25. package/dist/chat/scheduled-tasks/tool-support.d.ts +5 -5
  26. package/dist/chat/scheduled-tasks/tools/create.d.ts +2 -2
  27. package/dist/chat/scheduled-tasks/tools/delete.d.ts +2 -2
  28. package/dist/chat/scheduled-tasks/tools/list.d.ts +2 -2
  29. package/dist/chat/scheduled-tasks/tools/run-now.d.ts +2 -2
  30. package/dist/chat/scheduled-tasks/tools/update.d.ts +2 -2
  31. package/dist/chat/services/conversation-memory.d.ts +1 -1
  32. package/dist/chat/slack/tools/send-files.d.ts +17 -11
  33. package/dist/chat/state/conversation.d.ts +2 -1
  34. package/dist/chat/task-execution/slack-work.d.ts +2 -2
  35. package/dist/chat/tools/types.d.ts +2 -0
  36. package/dist/{chunk-773XC7P4.js → chunk-3GS7O66Z.js} +159 -128
  37. package/dist/{chunk-JFZBGFNX.js → chunk-46ADYIPE.js} +2 -1
  38. package/dist/{chunk-KTVHAHUV.js → chunk-4M25PSFB.js} +1 -1
  39. package/dist/{chunk-4K5N6HTX.js → chunk-5TIH5GOE.js} +5 -5
  40. package/dist/{chunk-TVXAN43I.js → chunk-6MI43QZO.js} +1 -1
  41. package/dist/{chunk-RN3AWYEP.js → chunk-77QB5FNI.js} +1 -1
  42. package/dist/{chunk-Y7ZUBP2K.js → chunk-7J65DOBL.js} +6 -6
  43. package/dist/{chunk-2AHVM3HK.js → chunk-AFQ47JQ7.js} +10 -8
  44. package/dist/{chunk-ELOTIL5F.js → chunk-BLCVTEE7.js} +4 -4
  45. package/dist/{chunk-ZLSFOSDK.js → chunk-CZCMFRUQ.js} +18 -1
  46. package/dist/{chunk-2WLJDM23.js → chunk-D7BNWRYL.js} +1 -1
  47. package/dist/{chunk-EORR34UB.js → chunk-F7VOY4VQ.js} +1 -1
  48. package/dist/{chunk-JJX77MB7.js → chunk-G2FN3I66.js} +3 -3
  49. package/dist/{chunk-J2SYI36O.js → chunk-GEY6IFXH.js} +4 -4
  50. package/dist/{chunk-37G5HJ2X.js → chunk-GO2W3VZY.js} +4 -4
  51. package/dist/{chunk-LQT3SWFA.js → chunk-HJ3EZHIX.js} +351 -5
  52. package/dist/{chunk-SDRJ2LE3.js → chunk-I3OQVVMV.js} +1 -1
  53. package/dist/{chunk-TKJ7277U.js → chunk-MDZQ62PB.js} +2 -2
  54. package/dist/{chunk-V57LZDHN.js → chunk-MGJW3SW4.js} +6 -6
  55. package/dist/{chunk-7NYEB2TM.js → chunk-MKA3T2R6.js} +1 -1
  56. package/dist/{chunk-RQ62VKM7.js → chunk-MXO6VFB3.js} +1 -1
  57. package/dist/{chunk-AENPRXCG.js → chunk-OWASYHHV.js} +68 -39
  58. package/dist/{chunk-UWTXAYBP.js → chunk-PP4UQTH3.js} +9 -9
  59. package/dist/{chunk-JIC33O5L.js → chunk-RQBRGPUF.js} +2 -2
  60. package/dist/{chunk-NWSKFYOH.js → chunk-S4PFOWRA.js} +1 -1
  61. package/dist/{chunk-NKFRRZIT.js → chunk-TA5R6BME.js} +19 -18
  62. package/dist/{chunk-XFZLQANQ.js → chunk-UJYA75N5.js} +2 -2
  63. package/dist/{chunk-Y6MVGU7L.js → chunk-VBKFO65J.js} +35 -10
  64. package/dist/{chunk-KBT2I5ER.js → chunk-VDAEXEBB.js} +6 -6
  65. package/dist/{chunk-J7MWZFFP.js → chunk-VIBHFGQC.js} +4 -4
  66. package/dist/{chunk-APHDJYN7.js → chunk-VYDM7HUF.js} +1 -1
  67. package/dist/{chunk-CPQBTTI6.js → chunk-WNNYOPXX.js} +5 -5
  68. package/dist/{chunk-MLBH7J7J.js → chunk-XRERMHPN.js} +1 -1
  69. package/dist/cli/chat.js +30 -30
  70. package/dist/cli/check.js +6 -6
  71. package/dist/cli/plugins.js +13 -13
  72. package/dist/cli/snapshot-create.js +9 -9
  73. package/dist/cli/upgrade.js +7 -7
  74. package/dist/db/schema/agent-invocations.d.ts +4 -4
  75. package/dist/db/schema/attachments.d.ts +178 -0
  76. package/dist/db/schema.d.ts +183 -5
  77. package/dist/{db-WT7P56AH.js → db-VQAV4PJ3.js} +7 -7
  78. package/dist/handlers/retention.d.ts +4 -1
  79. package/dist/instrumentation.js +4 -4
  80. package/dist/nitro.js +2 -2
  81. package/dist/{oauth-callback-server-R2PK2MCA.js → oauth-callback-server-K5KQAAAX.js} +23 -23
  82. package/dist/{runner-O7YYUIHT.js → runner-U7QI7P4S.js} +14 -15
  83. package/dist/{skills-S6HLQRH7.js → skills-ENKRBZ7K.js} +6 -6
  84. package/dist/spawn-4XGNONLS.js +37 -0
  85. package/dist/{validation-46WD2OAR.js → validation-VKCDVGA6.js} +6 -6
  86. package/dist/version.js +1 -1
  87. package/dist/{work-YT5QUBS3.js → work-IBD6PWP2.js} +17 -17
  88. package/dist/worker-TJFXOZRC.js +24 -0
  89. package/migrations/0027_attachment_storage.sql +16 -0
  90. package/migrations/meta/0027_snapshot.json +2554 -0
  91. package/migrations/meta/_journal.json +8 -1
  92. package/package.json +5 -4
  93. package/dist/spawn-B4SBFFA2.js +0 -37
  94. package/dist/worker-4C5BEDWN.js +0 -24
package/dist/app.js CHANGED
@@ -1,15 +1,15 @@
1
1
  import {
2
2
  processConversationWork
3
- } from "./chunk-J7MWZFFP.js";
3
+ } from "./chunk-VIBHFGQC.js";
4
4
  import {
5
5
  bindSpawnAgent
6
- } from "./chunk-RQ62VKM7.js";
6
+ } from "./chunk-MXO6VFB3.js";
7
7
  import {
8
8
  createAgentInvocationWorker,
9
9
  enqueueAgentInvocation,
10
10
  listPendingAgentInvocationMailboxAppends,
11
11
  routeAgentInvocationWork
12
- } from "./chunk-Y7ZUBP2K.js";
12
+ } from "./chunk-7J65DOBL.js";
13
13
  import {
14
14
  GET as GET2,
15
15
  GET2 as GET3,
@@ -36,22 +36,23 @@ import {
36
36
  startSlackProcessingReaction,
37
37
  stripLeadingBotMention,
38
38
  wakePausedTurn
39
- } from "./chunk-NKFRRZIT.js";
39
+ } from "./chunk-TA5R6BME.js";
40
40
  import "./chunk-FA6POGLH.js";
41
41
  import {
42
42
  getTurnRequestDeadline,
43
43
  runWithTurnRequestDeadline
44
- } from "./chunk-NWSKFYOH.js";
44
+ } from "./chunk-S4PFOWRA.js";
45
45
  import {
46
46
  GET,
47
47
  conversationVisibilityFromSlackChannelType,
48
48
  createApiTurnWorker,
49
+ createVercelAttachmentStorage,
49
50
  lookupSlackUser,
50
51
  resolveSlackChannelTypeFromMessage,
51
52
  resolveSlackConversationContext,
52
53
  routeApiTurnWork
53
- } from "./chunk-Y6MVGU7L.js";
54
- import "./chunk-KTVHAHUV.js";
54
+ } from "./chunk-VBKFO65J.js";
55
+ import "./chunk-4M25PSFB.js";
55
56
  import {
56
57
  CONVERSATION_WORK_STALE_ENQUEUE_MS,
57
58
  appendAndEnqueueInboundMessage,
@@ -62,7 +63,7 @@ import {
62
63
  isInvalidConversationRecordError,
63
64
  listActiveConversationIds,
64
65
  removeActiveConversation
65
- } from "./chunk-ELOTIL5F.js";
66
+ } from "./chunk-BLCVTEE7.js";
66
67
  import {
67
68
  buildDeliveredTurnStatePatch,
68
69
  claimDispatchMailboxAppend,
@@ -93,7 +94,7 @@ import {
93
94
  requireTurnFailureEventId,
94
95
  resolveTurnSessionRouting,
95
96
  scheduleSessionCompletedPluginTasks
96
- } from "./chunk-UWTXAYBP.js";
97
+ } from "./chunk-PP4UQTH3.js";
97
98
  import {
98
99
  ConversationTurnLifecycleService,
99
100
  coerceThreadConversationState,
@@ -103,7 +104,7 @@ import {
103
104
  persistThreadRuntimeState,
104
105
  persistThreadState,
105
106
  persistThreadStateById
106
- } from "./chunk-4K5N6HTX.js";
107
+ } from "./chunk-5TIH5GOE.js";
107
108
  import "./chunk-UTL3MHPC.js";
108
109
  import {
109
110
  getVercelConversationWorkQueue,
@@ -122,7 +123,7 @@ import {
122
123
  import {
123
124
  validatePluginEgressCredentialHooks,
124
125
  validatePluginRegistrations
125
- } from "./chunk-MLBH7J7J.js";
126
+ } from "./chunk-XRERMHPN.js";
126
127
  import {
127
128
  defineJuniorPlugins,
128
129
  pluginCatalogConfigFromEnv,
@@ -154,11 +155,11 @@ import {
154
155
  setConfigDefaults,
155
156
  shouldEmitDevAgentTrace,
156
157
  shouldPropagateSandboxEgressTrace
157
- } from "./chunk-AENPRXCG.js";
158
+ } from "./chunk-OWASYHHV.js";
158
159
  import {
159
160
  AuthorizationFlowDisabledError,
160
161
  PluginCredentialFailureError
161
- } from "./chunk-CPQBTTI6.js";
162
+ } from "./chunk-WNNYOPXX.js";
162
163
  import "./chunk-DIB4GX3G.js";
163
164
  import {
164
165
  createAgentRunner,
@@ -166,7 +167,7 @@ import {
166
167
  deleteMcpAuthSessionsForUserProvider,
167
168
  deleteMcpServerSessionId,
168
169
  deleteMcpStoredOAuthCredentials
169
- } from "./chunk-2AHVM3HK.js";
170
+ } from "./chunk-AFQ47JQ7.js";
170
171
  import {
171
172
  RetryableDeliveryError
172
173
  } from "./chunk-RF6J3DIO.js";
@@ -174,7 +175,7 @@ import {
174
175
  formatProviderLabel,
175
176
  postSlackMessage,
176
177
  startOAuthFlow
177
- } from "./chunk-KBT2I5ER.js";
178
+ } from "./chunk-VDAEXEBB.js";
178
179
  import "./chunk-7MA4HV4W.js";
179
180
  import {
180
181
  getExperimentalFeatures,
@@ -183,16 +184,18 @@ import {
183
184
  import {
184
185
  getSandboxResourceConfig,
185
186
  setSandboxResourceConfig
186
- } from "./chunk-37G5HJ2X.js";
187
+ } from "./chunk-GO2W3VZY.js";
187
188
  import {
189
+ collectAttachmentGarbage,
188
190
  createSchedulerSqlStore,
189
191
  findMatchingEventTasks,
190
192
  logScheduledTaskRunSkipped,
193
+ requestAttachmentDeletion,
191
194
  scheduledTaskRunAttributes
192
- } from "./chunk-LQT3SWFA.js";
195
+ } from "./chunk-HJ3EZHIX.js";
193
196
  import {
194
197
  parseSlackThreadId
195
- } from "./chunk-APHDJYN7.js";
198
+ } from "./chunk-VYDM7HUF.js";
196
199
  import {
197
200
  ConversationTurnBoundaryError,
198
201
  CooperativeTurnYieldError,
@@ -242,7 +245,7 @@ import {
242
245
  trimTrailingAssistantMessages,
243
246
  turnHasReply,
244
247
  upsertConversationMessage
245
- } from "./chunk-J2SYI36O.js";
248
+ } from "./chunk-GEY6IFXH.js";
246
249
  import "./chunk-3Y47VMHV.js";
247
250
  import "./chunk-PDO5BLNM.js";
248
251
  import "./chunk-UIE3R5XU.js";
@@ -262,7 +265,7 @@ import {
262
265
  verifyEventTaskCredentialSubject,
263
266
  verifyScheduledTaskCredentialSubject,
264
267
  verifySlackDirectCredentialSubject
265
- } from "./chunk-V57LZDHN.js";
268
+ } from "./chunk-MGJW3SW4.js";
266
269
  import {
267
270
  SlackActionError,
268
271
  downloadPrivateSlackFile,
@@ -272,7 +275,7 @@ import {
272
275
  normalizeSlackConversationId,
273
276
  runWithSlackInstallationToken,
274
277
  runWithWorkspaceTeamId
275
- } from "./chunk-TKJ7277U.js";
278
+ } from "./chunk-MDZQ62PB.js";
276
279
  import {
277
280
  contextProvenance,
278
281
  createSlackDestination,
@@ -285,19 +288,19 @@ import {
285
288
  requireSlackDestination,
286
289
  withConversationEventLock,
287
290
  withConversationMutationLock
288
- } from "./chunk-JJX77MB7.js";
291
+ } from "./chunk-G2FN3I66.js";
289
292
  import {
290
293
  juniorAgentBindings,
291
294
  juniorAgentInvocations,
292
295
  juniorConversationEvents,
293
296
  juniorConversations
294
- } from "./chunk-773XC7P4.js";
297
+ } from "./chunk-3GS7O66Z.js";
295
298
  import "./chunk-EM225ITJ.js";
296
299
  import {
297
300
  acquireActiveLock,
298
301
  getStateAdapter,
299
302
  withActiveLock
300
- } from "./chunk-SDRJ2LE3.js";
303
+ } from "./chunk-I3OQVVMV.js";
301
304
  import {
302
305
  STANDARD_MODEL_PROFILE,
303
306
  botConfig,
@@ -315,16 +318,16 @@ import {
315
318
  modelIdForProfile,
316
319
  setSlackReactionConfig,
317
320
  standardModelId
318
- } from "./chunk-XFZLQANQ.js";
321
+ } from "./chunk-UJYA75N5.js";
319
322
  import {
320
323
  juniorDestinations
321
324
  } from "./chunk-VFUK3X5B.js";
322
- import "./chunk-2WLJDM23.js";
323
- import "./chunk-JIC33O5L.js";
325
+ import "./chunk-D7BNWRYL.js";
326
+ import "./chunk-RQBRGPUF.js";
324
327
  import {
325
328
  pluginCatalogRuntime
326
- } from "./chunk-TVXAN43I.js";
327
- import "./chunk-RN3AWYEP.js";
329
+ } from "./chunk-6MI43QZO.js";
330
+ import "./chunk-77QB5FNI.js";
328
331
  import {
329
332
  credentialContextForActor
330
333
  } from "./chunk-BDUENQD3.js";
@@ -356,7 +359,7 @@ import {
356
359
  withContext,
357
360
  withLogContext,
358
361
  withSpan
359
- } from "./chunk-7NYEB2TM.js";
362
+ } from "./chunk-MKA3T2R6.js";
360
363
  import {
361
364
  continueTrace
362
365
  } from "./chunk-6GWA276C.js";
@@ -364,10 +367,10 @@ import "./chunk-OOUNJNMR.js";
364
367
  import "./chunk-H4HBKISO.js";
365
368
  import {
366
369
  JUNIOR_PLUGIN_TASK_CALLBACK_ROUTE
367
- } from "./chunk-EORR34UB.js";
370
+ } from "./chunk-F7VOY4VQ.js";
368
371
  import {
369
372
  JUNIOR_VERSION
370
- } from "./chunk-JFZBGFNX.js";
373
+ } from "./chunk-46ADYIPE.js";
371
374
  import "./chunk-MLKGABMK.js";
372
375
 
373
376
  // src/app.ts
@@ -1938,6 +1941,7 @@ async function purgeConversationTree(executor, args) {
1938
1941
  inArray(juniorAgentBindings.childConversationId, ids)
1939
1942
  )
1940
1943
  );
1944
+ await requestAttachmentDeletion(executor, ids, args.nowMs);
1941
1945
  await executor.db().update(juniorConversations).set({
1942
1946
  transcriptPurgedAt: new Date(args.nowMs),
1943
1947
  ...(args.retention ? !isPublic : resolvedScrubMetadata) ? { title: null, channelName: null, actor: null } : {}
@@ -1989,14 +1993,26 @@ async function runRetentionPurge(executor, args) {
1989
1993
  }
1990
1994
  });
1991
1995
  }
1996
+ const attachmentResult = args.attachmentStorage ? await collectAttachmentGarbage({
1997
+ db: executor,
1998
+ nowMs: args.nowMs,
1999
+ storage: args.attachmentStorage
2000
+ }) : { deleted: 0 };
1992
2001
  logInfo("retention.purge.completed", {
2002
+ "app.retention.attachments": attachmentResult.deleted,
1993
2003
  "app.retention.scanned": roots.length,
1994
2004
  "app.retention.purged": purged,
1995
2005
  "app.retention.failed": failed,
1996
2006
  "app.retention.conversations": conversations,
1997
2007
  "app.retention.duration_ms": Date.now() - startedAtMs
1998
2008
  });
1999
- return { scanned: roots.length, purged, failed, conversations };
2009
+ return {
2010
+ scanned: roots.length,
2011
+ purged,
2012
+ failed,
2013
+ conversations,
2014
+ attachments: attachmentResult.deleted
2015
+ };
2000
2016
  }
2001
2017
 
2002
2018
  // src/handlers/retention.ts
@@ -2016,12 +2032,13 @@ function verifyRetentionRequest(request) {
2016
2032
  const expected = Buffer.from(secret);
2017
2033
  return actual.length === expected.length && timingSafeEqual3(actual, expected);
2018
2034
  }
2019
- async function GET5(request) {
2035
+ async function GET5(request, options = {}) {
2020
2036
  if (!verifyRetentionRequest(request)) {
2021
2037
  return new Response("Unauthorized", { status: 401 });
2022
2038
  }
2023
2039
  try {
2024
2040
  const result = await runRetentionPurge(getSqlExecutor(), {
2041
+ attachmentStorage: options.attachmentStorage ?? createVercelAttachmentStorage(),
2025
2042
  nowMs: Date.now()
2026
2043
  });
2027
2044
  return Response.json(result, { status: 200 });
@@ -3209,6 +3226,71 @@ function buildSlackInboundMessage(args) {
3209
3226
  };
3210
3227
  }
3211
3228
 
3229
+ // src/chat/ingress/bot-mention.ts
3230
+ function escapeRegExp(value) {
3231
+ return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
3232
+ }
3233
+ function stripInlineCode(line) {
3234
+ return line.replace(/(`+)(?:(?!\1)[^\n])*\1/g, " ");
3235
+ }
3236
+ function fenceMarkerLength(trimmed) {
3237
+ let n = 0;
3238
+ while (trimmed[n] === "`") {
3239
+ n += 1;
3240
+ }
3241
+ return n;
3242
+ }
3243
+ function singleLineFenceSuffix(trimmed) {
3244
+ const openLen = fenceMarkerLength(trimmed);
3245
+ if (openLen < 3) {
3246
+ return void 0;
3247
+ }
3248
+ const afterOpen = trimmed.slice(openLen);
3249
+ const closeRel = afterOpen.indexOf("`".repeat(openLen));
3250
+ if (closeRel === -1) {
3251
+ return void 0;
3252
+ }
3253
+ return afterOpen.slice(closeRel + openLen);
3254
+ }
3255
+ function textOutsideCode(text) {
3256
+ const lines = text.split("\n");
3257
+ const out = [];
3258
+ let inFence = false;
3259
+ for (const line of lines) {
3260
+ const trimmed = line.trimStart();
3261
+ if (trimmed.startsWith("```")) {
3262
+ if (inFence) {
3263
+ inFence = false;
3264
+ const suffix2 = trimmed.slice(fenceMarkerLength(trimmed));
3265
+ if (suffix2.length > 0) {
3266
+ out.push(stripInlineCode(suffix2));
3267
+ }
3268
+ continue;
3269
+ }
3270
+ const suffix = singleLineFenceSuffix(trimmed);
3271
+ if (suffix !== void 0) {
3272
+ out.push(stripInlineCode(suffix));
3273
+ continue;
3274
+ }
3275
+ inFence = true;
3276
+ continue;
3277
+ }
3278
+ if (inFence) {
3279
+ continue;
3280
+ }
3281
+ out.push(stripInlineCode(line));
3282
+ }
3283
+ return out.join("\n");
3284
+ }
3285
+ function textMentionsBot(text, botUserId) {
3286
+ if (!botUserId || !text) {
3287
+ return false;
3288
+ }
3289
+ const outside = textOutsideCode(text);
3290
+ const id = escapeRegExp(botUserId);
3291
+ return new RegExp(`<@${id}(?:\\|[^>]+)?>`).test(outside);
3292
+ }
3293
+
3212
3294
  // src/chat/ingress/message-changed.ts
3213
3295
  import { Message as Message2 } from "chat";
3214
3296
  function getEditedMentionMessageId(messageTs) {
@@ -3222,9 +3304,6 @@ function isMessageChangedEnvelope(value) {
3222
3304
  if (!event || typeof event !== "object") return false;
3223
3305
  return event.type === "message" && event.subtype === "message_changed" && typeof event.channel === "string" && typeof event.message === "object" && event.message !== null && typeof event.previous_message === "object" && event.previous_message !== null;
3224
3306
  }
3225
- function textMentionsBot(text, botUserId) {
3226
- return text.includes(`<@${botUserId}>`);
3227
- }
3228
3307
  function getAttachmentType(mimeType) {
3229
3308
  if (mimeType?.startsWith("image/")) {
3230
3309
  return "image";
@@ -3507,9 +3586,6 @@ function installationFromEnvelope(body) {
3507
3586
  function isDmEvent(event) {
3508
3587
  return event.channel_type === "im" || event.channel?.startsWith("D") === true;
3509
3588
  }
3510
- function textMentionsBot2(event, botUserId) {
3511
- return Boolean(botUserId && event.text?.includes(`<@${botUserId}>`));
3512
- }
3513
3589
  function shouldIgnoreMessageSubtype(event) {
3514
3590
  return Boolean(event.subtype && IGNORED_MESSAGE_SUBTYPES.has(event.subtype));
3515
3591
  }
@@ -3591,7 +3667,10 @@ async function routeParsedMessage(args) {
3591
3667
  conversationStore: args.conversationStore,
3592
3668
  installation: args.installation
3593
3669
  });
3594
- const isMention = args.event.type === "app_mention" || textMentionsBot2(args.event, args.adapter.botUserId);
3670
+ const botUserId = args.adapter.botUserId;
3671
+ const isMention = Boolean(
3672
+ botUserId && textMentionsBot(args.event.text ?? "", botUserId)
3673
+ );
3595
3674
  if (isMention) {
3596
3675
  args.message.isMention = true;
3597
3676
  }
@@ -4281,11 +4360,11 @@ var THREAD_OPTOUT_PATTERNS = [
4281
4360
  var ACKNOWLEDGMENT_ONLY_RE = /^(?:thanks(?: you)?|thank you|thx|ty|got it|sounds good|sgtm|lgtm|ok(?:ay)?|cool|nice|perfect|awesome|great|makes sense|understood|roger|yep|yup|kk|on it|will do)(?:[.!]+)?$/i;
4282
4361
  var DIRECTED_FOLLOW_UP_CUE_RE = /\b(?:you said|you just said|your last response|your last answer|what did you just say|what do you mean|what did you mean|explain(?: that| this| it| more)?|clarify(?: that| this| it)?|expand(?: on)?(?: that| this| it)?|elaborate(?: on)?(?: that| this| it)?|say more)\b/i;
4283
4362
  var TERSE_CLARIFICATION_RE = /^(?:which one|which ones|why|how so|what do you mean|what did you mean|say more|explain that|clarify that|expand on that|elaborate on that)\??$/i;
4284
- function escapeRegExp(value) {
4363
+ function escapeRegExp2(value) {
4285
4364
  return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
4286
4365
  }
4287
4366
  function containsAssistantInvocation(text, botUserName) {
4288
- const escapedUserName = escapeRegExp(botUserName);
4367
+ const escapedUserName = escapeRegExp2(botUserName);
4289
4368
  const plainNameMentionRe = new RegExp(`(^|\\s)@${escapedUserName}\\b`, "i");
4290
4369
  const labeledEntityMentionRe = new RegExp(
4291
4370
  `<@[^>|]+\\|${escapedUserName}>`,
@@ -6529,7 +6608,8 @@ function createReplyToThread(deps) {
6529
6608
  isBot: true
6530
6609
  },
6531
6610
  meta: {
6532
- replied: true
6611
+ replied: true,
6612
+ source: "slack"
6533
6613
  }
6534
6614
  });
6535
6615
  await persistThreadState(thread, {
@@ -6717,6 +6797,7 @@ function createReplyToThread(deps) {
6717
6797
  const recordedMessageId = recordDeliveredAssistantMessage({
6718
6798
  conversation: preparedState.conversation,
6719
6799
  sessionId: turnId,
6800
+ source: "slack",
6720
6801
  text,
6721
6802
  userMessageId: preparedState.userMessageId
6722
6803
  });
@@ -7372,6 +7453,7 @@ function toConversationMessage(args) {
7372
7453
  explicitMention: args.explicitMention,
7373
7454
  imageAttachmentCount: imageAttachmentCount > 0 ? imageAttachmentCount : void 0,
7374
7455
  imagesHydrated: !messageHasPotentialImageAttachment,
7456
+ source: "slack",
7375
7457
  ...slackTs ? { slackTs } : {}
7376
7458
  }
7377
7459
  };
@@ -9060,7 +9142,9 @@ async function createApp(options) {
9060
9142
  const waitUntil = options?.waitUntil ?? await defaultWaitUntil();
9061
9143
  const tracePropagation = { domains: sandboxEgressTracePropagationDomains };
9062
9144
  const conversationWorkQueue = getVercelConversationWorkQueue();
9145
+ const attachmentStorage = createVercelAttachmentStorage();
9063
9146
  const agentRunner = createAgentRunner(executeAgentRun, {
9147
+ attachmentStorage,
9064
9148
  bindSpawnAgent: (request) => bindSpawnAgent(request, { queue: conversationWorkQueue }),
9065
9149
  tracePropagation
9066
9150
  });
@@ -1,15 +1,15 @@
1
1
  import {
2
2
  pluginCatalogRuntime
3
- } from "./chunk-TVXAN43I.js";
4
- import "./chunk-RN3AWYEP.js";
3
+ } from "./chunk-6MI43QZO.js";
4
+ import "./chunk-77QB5FNI.js";
5
5
  import "./chunk-BDUENQD3.js";
6
6
  import "./chunk-V7YE4WCP.js";
7
- import "./chunk-7NYEB2TM.js";
7
+ import "./chunk-MKA3T2R6.js";
8
8
  import "./chunk-6GWA276C.js";
9
9
  import "./chunk-OOUNJNMR.js";
10
10
  import "./chunk-H4HBKISO.js";
11
- import "./chunk-EORR34UB.js";
12
- import "./chunk-JFZBGFNX.js";
11
+ import "./chunk-F7VOY4VQ.js";
12
+ import "./chunk-46ADYIPE.js";
13
13
  import "./chunk-MLKGABMK.js";
14
14
  export {
15
15
  pluginCatalogRuntime
@@ -24,6 +24,7 @@ import type { SlackActionToken } from "@/chat/slack/action-token";
24
24
  import type { TurnReasoningLevel } from "@/chat/reasoning-level";
25
25
  import type { ImageGenerateToolDeps, ViewImageToolDeps, WebFetchToolDeps, WebSearchToolDeps } from "@/chat/tools/types";
26
26
  import type { AssistantMessage } from "@earendil-works/pi-ai";
27
+ import type { AttachmentStorage } from "@/chat/attachments/storage";
27
28
  /** One attachment the model may see for the current instruction. */
28
29
  export type AgentAttachment = {
29
30
  data?: Buffer;
@@ -136,6 +137,7 @@ export type AgentEvent = {
136
137
  };
137
138
  /** Resolved environment and optional per-run tool test overrides. */
138
139
  export type AgentEnvironment = {
140
+ attachmentStorage?: AttachmentStorage;
139
141
  configuration?: Record<string, unknown>;
140
142
  locationConfiguration?: LocationConfigurationService;
141
143
  skillDirs?: string[];
@@ -86,8 +86,8 @@ export declare const agentInvocationSchema: z.ZodDiscriminatedUnion<[z.ZodObject
86
86
  conversationId: z.ZodString;
87
87
  }, z.core.$strict>], "platform">;
88
88
  destinationVisibility: z.ZodOptional<z.ZodEnum<{
89
- public: "public";
90
89
  private: "private";
90
+ public: "public";
91
91
  }>>;
92
92
  input: z.ZodString;
93
93
  invocationId: z.ZodString;
@@ -108,8 +108,8 @@ export declare const agentInvocationSchema: z.ZodDiscriminatedUnion<[z.ZodObject
108
108
  teamId: z.ZodString;
109
109
  channelId: z.ZodString;
110
110
  visibility: z.ZodEnum<{
111
- public: "public";
112
111
  private: "private";
112
+ public: "public";
113
113
  }>;
114
114
  messageTs: z.ZodOptional<z.ZodString>;
115
115
  threadTs: z.ZodOptional<z.ZodString>;
@@ -120,8 +120,8 @@ export declare const agentInvocationSchema: z.ZodDiscriminatedUnion<[z.ZodObject
120
120
  }, z.core.$strict>, z.ZodObject<{
121
121
  platform: z.ZodLiteral<"web">;
122
122
  visibility: z.ZodEnum<{
123
- public: "public";
124
123
  private: "private";
124
+ public: "public";
125
125
  }>;
126
126
  conversationId: z.ZodString;
127
127
  }, z.core.$strict>], "platform">;
@@ -211,8 +211,8 @@ export declare const agentInvocationSchema: z.ZodDiscriminatedUnion<[z.ZodObject
211
211
  conversationId: z.ZodString;
212
212
  }, z.core.$strict>], "platform">;
213
213
  destinationVisibility: z.ZodOptional<z.ZodEnum<{
214
- public: "public";
215
214
  private: "private";
215
+ public: "public";
216
216
  }>>;
217
217
  input: z.ZodString;
218
218
  invocationId: z.ZodString;
@@ -233,8 +233,8 @@ export declare const agentInvocationSchema: z.ZodDiscriminatedUnion<[z.ZodObject
233
233
  teamId: z.ZodString;
234
234
  channelId: z.ZodString;
235
235
  visibility: z.ZodEnum<{
236
- public: "public";
237
236
  private: "private";
237
+ public: "public";
238
238
  }>;
239
239
  messageTs: z.ZodOptional<z.ZodString>;
240
240
  threadTs: z.ZodOptional<z.ZodString>;
@@ -245,8 +245,8 @@ export declare const agentInvocationSchema: z.ZodDiscriminatedUnion<[z.ZodObject
245
245
  }, z.core.$strict>, z.ZodObject<{
246
246
  platform: z.ZodLiteral<"web">;
247
247
  visibility: z.ZodEnum<{
248
- public: "public";
249
248
  private: "private";
249
+ public: "public";
250
250
  }>;
251
251
  conversationId: z.ZodString;
252
252
  }, z.core.$strict>], "platform">;
@@ -334,8 +334,8 @@ export declare const agentInvocationSchema: z.ZodDiscriminatedUnion<[z.ZodObject
334
334
  conversationId: z.ZodString;
335
335
  }, z.core.$strict>], "platform">;
336
336
  destinationVisibility: z.ZodOptional<z.ZodEnum<{
337
- public: "public";
338
337
  private: "private";
338
+ public: "public";
339
339
  }>>;
340
340
  input: z.ZodString;
341
341
  invocationId: z.ZodString;
@@ -356,8 +356,8 @@ export declare const agentInvocationSchema: z.ZodDiscriminatedUnion<[z.ZodObject
356
356
  teamId: z.ZodString;
357
357
  channelId: z.ZodString;
358
358
  visibility: z.ZodEnum<{
359
- public: "public";
360
359
  private: "private";
360
+ public: "public";
361
361
  }>;
362
362
  messageTs: z.ZodOptional<z.ZodString>;
363
363
  threadTs: z.ZodOptional<z.ZodString>;
@@ -368,8 +368,8 @@ export declare const agentInvocationSchema: z.ZodDiscriminatedUnion<[z.ZodObject
368
368
  }, z.core.$strict>, z.ZodObject<{
369
369
  platform: z.ZodLiteral<"web">;
370
370
  visibility: z.ZodEnum<{
371
- public: "public";
372
371
  private: "private";
372
+ public: "public";
373
373
  }>;
374
374
  conversationId: z.ZodString;
375
375
  }, z.core.$strict>], "platform">;
@@ -459,8 +459,8 @@ export declare const createAgentInvocationSchema: z.ZodObject<{
459
459
  conversationId: z.ZodString;
460
460
  }, z.core.$strict>], "platform">;
461
461
  destinationVisibility: z.ZodOptional<z.ZodEnum<{
462
- public: "public";
463
462
  private: "private";
463
+ public: "public";
464
464
  }>>;
465
465
  idempotencyKey: z.ZodString;
466
466
  input: z.ZodString;
@@ -477,8 +477,8 @@ export declare const createAgentInvocationSchema: z.ZodObject<{
477
477
  teamId: z.ZodString;
478
478
  channelId: z.ZodString;
479
479
  visibility: z.ZodEnum<{
480
- public: "public";
481
480
  private: "private";
481
+ public: "public";
482
482
  }>;
483
483
  messageTs: z.ZodOptional<z.ZodString>;
484
484
  threadTs: z.ZodOptional<z.ZodString>;
@@ -489,8 +489,8 @@ export declare const createAgentInvocationSchema: z.ZodObject<{
489
489
  }, z.core.$strict>, z.ZodObject<{
490
490
  platform: z.ZodLiteral<"web">;
491
491
  visibility: z.ZodEnum<{
492
- public: "public";
493
492
  private: "private";
493
+ public: "public";
494
494
  }>;
495
495
  conversationId: z.ZodString;
496
496
  }, z.core.$strict>], "platform">;
@@ -0,0 +1,14 @@
1
+ /** Bytes and metadata written to attachment object storage. */
2
+ export interface AttachmentWrite {
3
+ body: Buffer;
4
+ contentType: string;
5
+ key: string;
6
+ }
7
+ /** Small object-storage capability used by conversation attachments. */
8
+ export interface AttachmentStorage {
9
+ readonly provider: string;
10
+ put(input: AttachmentWrite): Promise<void>;
11
+ /** Return live object bytes, or null when the key is missing. */
12
+ get(key: string): Promise<ReadableStream<Uint8Array> | null>;
13
+ delete(keys: string[]): Promise<void>;
14
+ }
@@ -0,0 +1,68 @@
1
+ import type { JuniorSqlDatabase } from "@/db/db";
2
+ import type { SandboxFileUpload } from "@/chat/tools/sandbox/file-uploads";
3
+ import type { AttachmentStorage } from "./storage";
4
+ export interface StoredAttachment {
5
+ id: string;
6
+ }
7
+ /** Live conversation-owned attachment metadata. */
8
+ export interface AttachmentRecord {
9
+ bytes: number;
10
+ contentType: string;
11
+ conversationId: string;
12
+ filename: string;
13
+ id: string;
14
+ provider: string;
15
+ storageKey: string;
16
+ }
17
+ export interface AttachmentGarbageCollectionResult {
18
+ deleted: number;
19
+ }
20
+ /**
21
+ * Persist one conversation-owned file.
22
+ *
23
+ * Identity is content-stable under the conversation. Object storage is written
24
+ * first under a unique key; the SQL row is created only after that write
25
+ * succeeds. A row means the attachment is durable. Retries reuse an existing
26
+ * live row. A purge-marked row is revived by writing a new object and pointing
27
+ * the row at it, unless the conversation is still purged. If the SQL write
28
+ * fails after object storage accepts the bytes, this path deletes that unique
29
+ * object. A process crash between those steps can leave an unreferenced unique
30
+ * object with no SQL row.
31
+ */
32
+ export declare function storeAttachment(args: {
33
+ conversationId: string;
34
+ db: JuniorSqlDatabase;
35
+ file: SandboxFileUpload;
36
+ nowMs?: number;
37
+ storage: AttachmentStorage;
38
+ }): Promise<StoredAttachment>;
39
+ /** Load one live attachment owned by a conversation. */
40
+ export declare function readLiveAttachment(args: {
41
+ attachmentId: string;
42
+ conversationId: string;
43
+ db: JuniorSqlDatabase;
44
+ }): Promise<AttachmentRecord | null>;
45
+ /** Persist many conversation-owned files. */
46
+ export declare function storeAttachments(args: {
47
+ conversationId: string;
48
+ db: JuniorSqlDatabase;
49
+ files: SandboxFileUpload[];
50
+ nowMs?: number;
51
+ storage: AttachmentStorage;
52
+ }): Promise<StoredAttachment[]>;
53
+ /** Mark attachments unavailable when their conversation content is purged. */
54
+ export declare function requestAttachmentDeletion(db: JuniorSqlDatabase, conversationIds: string[], nowMs: number): Promise<void>;
55
+ /**
56
+ * Delete purged attachments in one bounded batch.
57
+ *
58
+ * Eligible rows are explicitly purge-marked, or owned by a conversation whose
59
+ * transcript is already purged. That second path covers a concurrent store that
60
+ * inserted after purge marked existing rows. Delete object keys first, then
61
+ * remove rows that are still eligible so a failed blob delete remains retryable.
62
+ */
63
+ export declare function collectAttachmentGarbage(args: {
64
+ db: JuniorSqlDatabase;
65
+ nowMs: number;
66
+ storage: AttachmentStorage;
67
+ limit?: number;
68
+ }): Promise<AttachmentGarbageCollectionResult>;
@@ -0,0 +1,3 @@
1
+ import type { AttachmentStorage } from "./storage";
2
+ /** Store private conversation attachments in Vercel Blob. */
3
+ export declare function createVercelAttachmentStorage(): AttachmentStorage;