@sentry/junior 0.158.0 → 0.160.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 (69) hide show
  1. package/dist/{agent-hooks-BOWFTDE5.js → agent-hooks-U6R3O2V4.js} +10 -10
  2. package/dist/api/conversations/cancel-pending-messages.d.ts +4 -0
  3. package/dist/api/conversations/events.d.ts +1 -1
  4. package/dist/api/schema/conversation.d.ts +45 -0
  5. package/dist/api/schema.d.ts +2 -2
  6. package/dist/api/schema.js +5 -1
  7. package/dist/api.js +96 -23
  8. package/dist/app.js +32 -32
  9. package/dist/{catalog-runtime-7GZ25WTR.js → catalog-runtime-HIDNHGOP.js} +5 -5
  10. package/dist/chat/conversations/history.d.ts +35 -2
  11. package/dist/chat/conversations/projection.d.ts +13 -0
  12. package/dist/chat/slack/mrkdwn.d.ts +2 -1
  13. package/dist/chat/slack/tools/send-files.d.ts +2 -2
  14. package/dist/chat/task-execution/state.d.ts +10 -0
  15. package/dist/chat/task-execution/store.d.ts +11 -0
  16. package/dist/chat/tool-support/action-review.d.ts +5 -4
  17. package/dist/chat/tools/search-conversation-events.d.ts +1 -1
  18. package/dist/{chunk-BNFGY66A.js → chunk-2MK6S2UA.js} +1 -1
  19. package/dist/{chunk-YEZS4TEY.js → chunk-2SFMRMDV.js} +1 -1
  20. package/dist/{chunk-4XJ2WSTI.js → chunk-3AHIB66R.js} +5 -5
  21. package/dist/{chunk-EQ6Y37MD.js → chunk-42E7432W.js} +1 -1
  22. package/dist/{chunk-SSU65ZTZ.js → chunk-472VVYYV.js} +1 -1
  23. package/dist/{chunk-VURJ2NSF.js → chunk-4UO3UAW7.js} +1 -1
  24. package/dist/{chunk-DTVTBZNP.js → chunk-56TFPTZU.js} +1 -1
  25. package/dist/{chunk-FA32YRZ3.js → chunk-756F567I.js} +5 -5
  26. package/dist/{chunk-UJ6N32ZM.js → chunk-BGVQGEKB.js} +4 -4
  27. package/dist/{chunk-UQJO35BP.js → chunk-FJR66CQT.js} +4 -4
  28. package/dist/{chunk-A7EDLNGU.js → chunk-FKMWPA4A.js} +55 -4
  29. package/dist/{chunk-6GJCOUTA.js → chunk-HDPH4CHJ.js} +1 -1
  30. package/dist/{chunk-FAJ6SMEE.js → chunk-J77DLAPE.js} +2 -2
  31. package/dist/{chunk-AF4PHIP6.js → chunk-JQZIUESN.js} +41 -10
  32. package/dist/{chunk-RCIKTZZF.js → chunk-LNUZXEEI.js} +1 -1
  33. package/dist/{chunk-EXITAVHO.js → chunk-M5HCOMDR.js} +90 -35
  34. package/dist/{chunk-KAFYW3O6.js → chunk-MBDWMEO6.js} +10 -10
  35. package/dist/{chunk-ROOTB7J7.js → chunk-OUAZDZTZ.js} +2 -2
  36. package/dist/{chunk-4JAOLUDB.js → chunk-P7W3ZL5J.js} +35 -6
  37. package/dist/{chunk-3A7VXSPJ.js → chunk-PVIM2RWO.js} +8 -8
  38. package/dist/{chunk-SAJPQLTY.js → chunk-PZUJPPON.js} +1 -1
  39. package/dist/{chunk-4Q6QVTKA.js → chunk-RJGRXDA7.js} +5 -5
  40. package/dist/{chunk-C3FYJZSA.js → chunk-RLOXMHLA.js} +40 -4
  41. package/dist/{chunk-UPPU3FQU.js → chunk-TBRJGMTO.js} +1 -1
  42. package/dist/{chunk-JEXQQLEC.js → chunk-TPFOVXRB.js} +18 -18
  43. package/dist/{chunk-NOEERHHR.js → chunk-U26KRMYX.js} +6 -6
  44. package/dist/{chunk-PHQDXC27.js → chunk-UNDTW2PY.js} +1 -1
  45. package/dist/{chunk-IEM3GFXL.js → chunk-URPLKXLG.js} +9 -9
  46. package/dist/{chunk-CZCMFRUQ.js → chunk-UYUS4L6F.js} +22 -0
  47. package/dist/{chunk-X4BLYIMV.js → chunk-WACYTIIK.js} +6 -6
  48. package/dist/{chunk-LUSAAJJA.js → chunk-XPX3DYG7.js} +2 -2
  49. package/dist/{chunk-IXYGGJRA.js → chunk-YPMDNE7R.js} +1 -1
  50. package/dist/{chunk-KSZXVR5G.js → chunk-ZNBGWMVQ.js} +1 -1
  51. package/dist/cli/chat.js +30 -30
  52. package/dist/cli/check.js +6 -6
  53. package/dist/cli/plugins.js +13 -13
  54. package/dist/cli/snapshot-create.js +9 -9
  55. package/dist/cli/upgrade.js +7 -7
  56. package/dist/{db-HFWTPYT7.js → db-2JKT3BB5.js} +7 -7
  57. package/dist/instrumentation.js +4 -4
  58. package/dist/nitro.js +2 -2
  59. package/dist/{oauth-callback-server-J3NW4QL5.js → oauth-callback-server-7MC2UMQC.js} +23 -23
  60. package/dist/{runner-CL6QHML5.js → runner-GUU4G7XO.js} +13 -13
  61. package/dist/{skills-WZWKZIFQ.js → skills-7NW5N3VM.js} +6 -6
  62. package/dist/spawn-WGK4W3XF.js +37 -0
  63. package/dist/{validation-4HVSSLJV.js → validation-AQLI6N2C.js} +6 -6
  64. package/dist/version.js +1 -1
  65. package/dist/{work-UF4KXPVG.js → work-FLFK5XNU.js} +17 -17
  66. package/dist/worker-KSJIRBQJ.js +24 -0
  67. package/package.json +5 -5
  68. package/dist/spawn-TQJWADG4.js +0 -37
  69. package/dist/worker-HI7I2W2U.js +0 -24
@@ -7,7 +7,7 @@ import {
7
7
  PluginCredentialFailureError,
8
8
  agentNameSchema,
9
9
  createPluginAuthOrchestration
10
- } from "./chunk-FA32YRZ3.js";
10
+ } from "./chunk-756F567I.js";
11
11
  import {
12
12
  authorizationId
13
13
  } from "./chunk-DIB4GX3G.js";
@@ -32,7 +32,7 @@ import {
32
32
  searchSlackUsers,
33
33
  selectPluginGrant,
34
34
  toMcpProviderError
35
- } from "./chunk-3A7VXSPJ.js";
35
+ } from "./chunk-PVIM2RWO.js";
36
36
  import {
37
37
  RetryableDeliveryError,
38
38
  actorFromRun,
@@ -48,7 +48,7 @@ import {
48
48
  getSlackMessagePermalink,
49
49
  resolveBaseUrl,
50
50
  uploadFilesToConversation
51
- } from "./chunk-4JAOLUDB.js";
51
+ } from "./chunk-P7W3ZL5J.js";
52
52
  import {
53
53
  parseSandboxEgressAuthRequiredSignal,
54
54
  parseSandboxEgressPermissionDeniedSignal,
@@ -74,7 +74,7 @@ import {
74
74
  runNonInteractiveCommand,
75
75
  throwSandboxOperationError,
76
76
  wrapSandboxSetupError
77
- } from "./chunk-UJ6N32ZM.js";
77
+ } from "./chunk-BGVQGEKB.js";
78
78
  import {
79
79
  SCHEDULED_TASK_SYSTEM_ACTOR,
80
80
  compactEventTask,
@@ -107,10 +107,10 @@ import {
107
107
  scheduledTaskAttributes,
108
108
  storeAttachments,
109
109
  writableEventTask
110
- } from "./chunk-4Q6QVTKA.js";
110
+ } from "./chunk-RJGRXDA7.js";
111
111
  import {
112
112
  parseSlackThreadId
113
- } from "./chunk-DTVTBZNP.js";
113
+ } from "./chunk-56TFPTZU.js";
114
114
  import {
115
115
  AGENTS_REMOVAL_NOTICE,
116
116
  AGENTS_REPLACEMENT_NOTICE,
@@ -165,6 +165,7 @@ import {
165
165
  piMessageFromHistoryItem,
166
166
  positiveInteger,
167
167
  recordAgentsInstructionsUpdated,
168
+ recordAttachmentsDelivered,
168
169
  recordAuthorizationRequested,
169
170
  recordGuardianActionReviewed,
170
171
  recordMcpProviderConnected,
@@ -180,7 +181,7 @@ import {
180
181
  stripRuntimeTurnContext,
181
182
  trimTrailingAssistantMessages,
182
183
  truncateText
183
- } from "./chunk-C3FYJZSA.js";
184
+ } from "./chunk-RLOXMHLA.js";
184
185
  import {
185
186
  JUNIOR_THREAD_STATE_TTL_MS
186
187
  } from "./chunk-3Y47VMHV.js";
@@ -196,7 +197,7 @@ import {
196
197
  getSlackToolContext,
197
198
  readActorIdentity,
198
199
  resolveChannelCapabilities
199
- } from "./chunk-NOEERHHR.js";
200
+ } from "./chunk-U26KRMYX.js";
200
201
  import {
201
202
  SlackActionError,
202
203
  downloadPrivateSlackFile,
@@ -205,7 +206,7 @@ import {
205
206
  isConversationScopedChannel,
206
207
  normalizeSlackConversationId,
207
208
  withSlackRetries
208
- } from "./chunk-ROOTB7J7.js";
209
+ } from "./chunk-OUAZDZTZ.js";
209
210
  import {
210
211
  KNOWN_CONVERSATION_EVENT_TYPES,
211
212
  contextProvenance,
@@ -217,10 +218,10 @@ import {
217
218
  instructionActors,
218
219
  instructionProvenanceFor,
219
220
  sameActorIdentity
220
- } from "./chunk-AF4PHIP6.js";
221
+ } from "./chunk-JQZIUESN.js";
221
222
  import {
222
223
  juniorIdentities
223
- } from "./chunk-VURJ2NSF.js";
224
+ } from "./chunk-4UO3UAW7.js";
224
225
  import {
225
226
  SANDBOX_DATA_ROOT,
226
227
  SANDBOX_SKILLS_ROOT,
@@ -232,7 +233,7 @@ import {
232
233
  } from "./chunk-EM225ITJ.js";
233
234
  import {
234
235
  getStateAdapter
235
- } from "./chunk-PHQDXC27.js";
236
+ } from "./chunk-UNDTW2PY.js";
236
237
  import {
237
238
  ACTIVE_TURN_COMPACTION_SUMMARY_PREFIX,
238
239
  COMPACTION_SUMMARY_PREFIX,
@@ -265,7 +266,7 @@ import {
265
266
  resolveGatewayCredential,
266
267
  resolveGatewayModel,
267
268
  unwrapCurrentInstruction
268
- } from "./chunk-FAJ6SMEE.js";
269
+ } from "./chunk-J77DLAPE.js";
269
270
  import {
270
271
  canExposeConversationPayload,
271
272
  resolveConversationPrivacy,
@@ -275,16 +276,16 @@ import {
275
276
  toGenAiMessagesTraceAttributes,
276
277
  toGenAiPayloadMetadata,
277
278
  toGenAiPayloadTraceAttributes
278
- } from "./chunk-UPPU3FQU.js";
279
+ } from "./chunk-TBRJGMTO.js";
279
280
  import {
280
281
  discoverSkills,
281
282
  findSkillByName,
282
283
  loadSkillsByName,
283
284
  parseSkillInvocation
284
- } from "./chunk-LUSAAJJA.js";
285
+ } from "./chunk-XPX3DYG7.js";
285
286
  import {
286
287
  pluginCatalogRuntime
287
- } from "./chunk-YEZS4TEY.js";
288
+ } from "./chunk-2SFMRMDV.js";
288
289
  import {
289
290
  CredentialUnavailableError,
290
291
  OAuthProviderError,
@@ -292,7 +293,7 @@ import {
292
293
  getOAuthProviderErrorAttributes,
293
294
  resolveAuthTokenPlaceholder,
294
295
  resolvePluginCommandEnv
295
- } from "./chunk-EQ6Y37MD.js";
296
+ } from "./chunk-42E7432W.js";
296
297
  import {
297
298
  credentialUserSubjectId
298
299
  } from "./chunk-BDUENQD3.js";
@@ -320,7 +321,7 @@ import {
320
321
  summarizeMessageText,
321
322
  withLogContext,
322
323
  withSpan
323
- } from "./chunk-KSZXVR5G.js";
324
+ } from "./chunk-ZNBGWMVQ.js";
324
325
  import {
325
326
  startInactiveSpan,
326
327
  withActiveSpan
@@ -1731,6 +1732,7 @@ function buildOutputSection(platform) {
1731
1732
  `<output format="markdown">`,
1732
1733
  "- Start with the answer or result, not internal process narration.",
1733
1734
  "- Use concise Markdown suitable for terminal output: short paragraphs, bullets, links, and fenced code blocks when helpful.",
1735
+ "- When you mention a pull request, include a direct link. Prefer the full PR URL or a Markdown link; do not leave bare `PR #123` text without a URL or repo.",
1734
1736
  "- End every turn with a final user-facing response.",
1735
1737
  "</output>"
1736
1738
  ].join("\n");
@@ -1740,6 +1742,7 @@ function buildOutputSection(platform) {
1740
1742
  "- Default to the shortest complete reply\u2014usually 1\u20135 sentences and under 800 characters. Include only the outcome, decisive evidence, and any blocker or required next action. If useful detail would exceed that, put it in a Slack canvas and reply with the link. An explicit user request for detail overrides this target.",
1741
1743
  "- Start with the answer or result, not internal process narration.",
1742
1744
  "- Use Slack-flavored Markdown: **bold** section labels, `code`, [text](url) links, bullet lists, and fenced code blocks. No hash-prefixed headings and no tables. When the answer primarily lists several URLs, show each URL bare instead of as a labeled link.",
1745
+ "- When you mention a pull request, include a direct link. Prefer the full PR URL or a Markdown link; `owner/repo#number` is also accepted and is linkified on delivery. Do not leave bare `PR #123` text without a URL or repo.",
1743
1746
  "- End every turn with a final user-facing markdown response unless the Slack action rules allow a no-reply completion.",
1744
1747
  "</output>"
1745
1748
  ].join("\n");
@@ -10543,7 +10546,8 @@ var sendFilesResultSchema = juniorToolOutputSchema.extend({
10543
10546
  attachment_refs: z42.array(
10544
10547
  z42.object({
10545
10548
  id: z42.string().min(1),
10546
- name: z42.string().min(1)
10549
+ // Same noun as storage, delivery events, and the report API.
10550
+ filename: z42.string().min(1)
10547
10551
  })
10548
10552
  )
10549
10553
  });
@@ -10581,7 +10585,7 @@ function createSendFilesTool(context, state, materializeFile, attachments) {
10581
10585
  )
10582
10586
  }),
10583
10587
  outputSchema: sendFilesResultSchema,
10584
- execute: async ({ files }) => {
10588
+ execute: async ({ files }, options) => {
10585
10589
  const filesToSend = normalizeFiles(files);
10586
10590
  const activeChannelId = context.sourceChannelId;
10587
10591
  if (!activeChannelId) {
@@ -10603,8 +10607,15 @@ function createSendFilesTool(context, state, materializeFile, attachments) {
10603
10607
  });
10604
10608
  const cached = state.getOperationResult(operationKey);
10605
10609
  if (cached) {
10610
+ if (attachments && cached.delivered.length > 0) {
10611
+ await recordAttachmentsDelivered({
10612
+ attachments: cached.delivered,
10613
+ conversationId: attachments.conversationId,
10614
+ ...cached.toolCallId ? { toolCallId: cached.toolCallId } : {}
10615
+ });
10616
+ }
10606
10617
  return sendFilesResultSchema.parse({
10607
- ...cached,
10618
+ ...cached.result,
10608
10619
  deduplicated: true
10609
10620
  });
10610
10621
  }
@@ -10623,13 +10634,36 @@ function createSendFilesTool(context, state, materializeFile, attachments) {
10623
10634
  files: uploads,
10624
10635
  threadTs
10625
10636
  });
10637
+ const delivered = stored.map(
10638
+ (attachment, index) => {
10639
+ const file = materializedFiles[index];
10640
+ return {
10641
+ id: attachment.id,
10642
+ filename: file.filename,
10643
+ contentType: file.mimeType,
10644
+ bytes: file.bytes
10645
+ };
10646
+ }
10647
+ );
10626
10648
  const response = {
10627
- attachment_refs: stored.map((attachment, index) => ({
10649
+ // Tool result stays minimal; transcript/report carries full metadata.
10650
+ attachment_refs: delivered.map((attachment) => ({
10628
10651
  id: attachment.id,
10629
- name: materializedFiles[index].filename
10652
+ filename: attachment.filename
10630
10653
  }))
10631
10654
  };
10632
- state.setOperationResult(operationKey, response);
10655
+ state.setOperationResult(operationKey, {
10656
+ delivered,
10657
+ result: response,
10658
+ ...options.toolCallId ? { toolCallId: options.toolCallId } : {}
10659
+ });
10660
+ if (attachments && delivered.length > 0) {
10661
+ await recordAttachmentsDelivered({
10662
+ attachments: delivered,
10663
+ conversationId: attachments.conversationId,
10664
+ ...options.toolCallId ? { toolCallId: options.toolCallId } : {}
10665
+ });
10666
+ }
10633
10667
  return response;
10634
10668
  }
10635
10669
  });
@@ -13517,6 +13551,9 @@ function buildSandboxInput(toolName, params) {
13517
13551
  import { PluginToolInputError } from "@sentry/junior-plugin-api";
13518
13552
 
13519
13553
  // src/chat/tool-support/action-review.ts
13554
+ import {
13555
+ missingToolAnnotationKeys as missingToolAnnotationKeys2
13556
+ } from "@sentry/junior-plugin-api";
13520
13557
  var ACTION_CONFIRMATION_INSTRUCTIONS = [
13521
13558
  "The action was not executed because explicit user confirmation is required.",
13522
13559
  "Stop tool use for this turn and respond to the user now with a direct, concise confirmation question that names the exact action, target, and material side effects.",
@@ -13529,6 +13566,13 @@ var ACTION_DENIAL_INSTRUCTIONS = [
13529
13566
  "If the reason is missing or withheld authorization and exact confirmation could make the action allowable, stop tool use for this turn and respond to the user now with a direct, concise confirmation question that names the exact action, target, and material side effects.",
13530
13567
  "Proceed only with a materially safer alternative. Otherwise, stop and explain the specific risk to the user without mentioning Guardian or internal review mechanics."
13531
13568
  ].join("\n");
13569
+ var ACTION_REVIEW_LIMIT_INSTRUCTIONS = [
13570
+ "This action was rejected due to unacceptable risk.",
13571
+ "Action review rejected three consecutive tool execution attempts.",
13572
+ "Do not retry this action or an equivalent write this turn.",
13573
+ "Stop tool use for this turn and respond to the user now with a direct, concise explanation of the risk.",
13574
+ "Do not mention Guardian, the runtime, policy, or internal review mechanics."
13575
+ ].join("\n");
13532
13576
  var ToolActionRejectedError = class extends Error {
13533
13577
  decision;
13534
13578
  reason;
@@ -13536,11 +13580,9 @@ var ToolActionRejectedError = class extends Error {
13536
13580
  riskLevel;
13537
13581
  userAuthorization;
13538
13582
  constructor(decision, reason, assessment = {}) {
13539
- super(
13540
- decision === "ask" ? `${ACTION_CONFIRMATION_INSTRUCTIONS}
13541
- Reason: ${reason}` : `${ACTION_DENIAL_INSTRUCTIONS}
13542
- Reason: ${reason}`
13543
- );
13583
+ const instructions = assessment.instructions ?? (decision === "ask" ? ACTION_CONFIRMATION_INSTRUCTIONS : ACTION_DENIAL_INSTRUCTIONS);
13584
+ super(`${instructions}
13585
+ Reason: ${reason}`);
13544
13586
  this.name = "ToolActionRejectedError";
13545
13587
  this.decision = decision;
13546
13588
  this.reason = reason;
@@ -13563,7 +13605,7 @@ var ToolActionReviewUnavailableError = class extends Error {
13563
13605
  var ToolActionReviewLimitError = class extends Error {
13564
13606
  constructor() {
13565
13607
  super(
13566
- "Action review rejected three consecutive tool execution attempts; the run was interrupted."
13608
+ "Action review rejected three consecutive tool execution attempts."
13567
13609
  );
13568
13610
  this.name = "ToolActionReviewLimitError";
13569
13611
  }
@@ -13580,6 +13622,9 @@ function effectiveApprovalMode(tool, resolved) {
13580
13622
  return "review";
13581
13623
  }
13582
13624
  const annotations = resolved?.annotations ?? tool.annotations;
13625
+ if (missingToolAnnotationKeys2(annotations).length > 0) {
13626
+ return "review";
13627
+ }
13583
13628
  if (annotations?.destructiveHint === true || annotations?.openWorldHint === true || annotations?.readOnlyHint === false) {
13584
13629
  return "review";
13585
13630
  }
@@ -13780,10 +13825,19 @@ function createToolActionReview(options) {
13780
13825
  const reviewedAction = projectedRejection(proposal, decision);
13781
13826
  appendVisibleRejection(priorRejections, reviewedAction);
13782
13827
  consecutiveRejections += 1;
13783
- if (consecutiveRejections >= MAX_CONSECUTIVE_REJECTIONS) {
13784
- const limitError = new ToolActionReviewLimitError();
13785
- options.onFatal(limitError);
13786
- throw limitError;
13828
+ const exhausted = consecutiveRejections >= MAX_CONSECUTIVE_REJECTIONS;
13829
+ if (exhausted) {
13830
+ logException(
13831
+ new ToolActionReviewLimitError(),
13832
+ "guardian.action_review.exhausted",
13833
+ {
13834
+ "app.guardian.decision": decision.decision,
13835
+ "app.guardian.risk_level": decision.riskLevel,
13836
+ "app.guardian.user_authorization": decision.userAuthorization,
13837
+ "gen_ai.tool.name": proposal.tool.name,
13838
+ "gen_ai.tool.call.id": toolCallId
13839
+ }
13840
+ );
13787
13841
  }
13788
13842
  pendingRejections.set(toolCallId, {
13789
13843
  decision: decision.decision,
@@ -13796,7 +13850,8 @@ function createToolActionReview(options) {
13796
13850
  throw new ToolActionRejectedError(decision.decision, decision.reason, {
13797
13851
  riskLevel: decision.riskLevel,
13798
13852
  reviewedAction,
13799
- userAuthorization: decision.userAuthorization
13853
+ userAuthorization: decision.userAuthorization,
13854
+ ...exhausted ? { instructions: ACTION_REVIEW_LIMIT_INSTRUCTIONS } : {}
13800
13855
  });
13801
13856
  },
13802
13857
  projectToolResult(toolCallId, result) {
@@ -1,10 +1,10 @@
1
1
  import {
2
2
  createWebAuthorization,
3
3
  deleteWebAuthorization
4
- } from "./chunk-SSU65ZTZ.js";
4
+ } from "./chunk-472VVYYV.js";
5
5
  import {
6
6
  appendAndEnqueueInboundMessage
7
- } from "./chunk-A7EDLNGU.js";
7
+ } from "./chunk-FKMWPA4A.js";
8
8
  import {
9
9
  buildDeliveredTurnStatePatch,
10
10
  completeAuthPauseTurn,
@@ -12,20 +12,20 @@ import {
12
12
  getTurnUserMessage,
13
13
  processPluginTask,
14
14
  scheduleSessionCompletedPluginTasks
15
- } from "./chunk-IEM3GFXL.js";
15
+ } from "./chunk-URPLKXLG.js";
16
16
  import {
17
17
  ConversationTurnLifecycleService,
18
18
  coerceThreadConversationState,
19
19
  getPersistedSandboxState,
20
20
  getPersistedThreadState,
21
21
  persistThreadStateById
22
- } from "./chunk-4XJ2WSTI.js";
22
+ } from "./chunk-3AHIB66R.js";
23
23
  import {
24
24
  healthReportSchema
25
25
  } from "./chunk-UTL3MHPC.js";
26
26
  import {
27
27
  parseSlackThreadId
28
- } from "./chunk-DTVTBZNP.js";
28
+ } from "./chunk-56TFPTZU.js";
29
29
  import {
30
30
  TurnInputCommitLostError,
31
31
  abandonTurnRecord,
@@ -48,17 +48,17 @@ import {
48
48
  saveTurnCheckpoint,
49
49
  startActiveTurn,
50
50
  upsertConversationMessage
51
- } from "./chunk-C3FYJZSA.js";
51
+ } from "./chunk-RLOXMHLA.js";
52
52
  import {
53
53
  normalizeSlackConversationId
54
- } from "./chunk-ROOTB7J7.js";
54
+ } from "./chunk-OUAZDZTZ.js";
55
55
  import {
56
56
  getConversationEventStore,
57
57
  getConversationStore
58
- } from "./chunk-AF4PHIP6.js";
58
+ } from "./chunk-JQZIUESN.js";
59
59
  import {
60
60
  getSlackBotToken
61
- } from "./chunk-FAJ6SMEE.js";
61
+ } from "./chunk-J77DLAPE.js";
62
62
  import {
63
63
  credentialContextForActor
64
64
  } from "./chunk-BDUENQD3.js";
@@ -67,7 +67,7 @@ import {
67
67
  logWarn,
68
68
  setTags,
69
69
  withLogContext
70
- } from "./chunk-KSZXVR5G.js";
70
+ } from "./chunk-ZNBGWMVQ.js";
71
71
 
72
72
  // src/handlers/health.ts
73
73
  function readHealthReport() {
@@ -3,7 +3,7 @@ import {
3
3
  } from "./chunk-EM225ITJ.js";
4
4
  import {
5
5
  getSlackBotToken
6
- } from "./chunk-FAJ6SMEE.js";
6
+ } from "./chunk-J77DLAPE.js";
7
7
  import {
8
8
  parseSlackChannelReferenceId
9
9
  } from "./chunk-V7YE4WCP.js";
@@ -12,7 +12,7 @@ import {
12
12
  setSpanAttributes,
13
13
  setSpanStatus,
14
14
  withSpan
15
- } from "./chunk-KSZXVR5G.js";
15
+ } from "./chunk-ZNBGWMVQ.js";
16
16
 
17
17
  // src/chat/slack/client.ts
18
18
  import { AsyncLocalStorage as AsyncLocalStorage2 } from "async_hooks";
@@ -4,19 +4,19 @@ import {
4
4
  isDmChannel,
5
5
  normalizeSlackConversationId,
6
6
  withSlackRetries
7
- } from "./chunk-ROOTB7J7.js";
7
+ } from "./chunk-OUAZDZTZ.js";
8
8
  import {
9
9
  parseDestination
10
- } from "./chunk-AF4PHIP6.js";
10
+ } from "./chunk-JQZIUESN.js";
11
11
  import {
12
12
  getStateAdapter
13
- } from "./chunk-PHQDXC27.js";
13
+ } from "./chunk-UNDTW2PY.js";
14
14
  import {
15
15
  normalizeSlackEmojiName
16
- } from "./chunk-FAJ6SMEE.js";
16
+ } from "./chunk-J77DLAPE.js";
17
17
  import {
18
18
  pluginCatalogRuntime
19
- } from "./chunk-YEZS4TEY.js";
19
+ } from "./chunk-2SFMRMDV.js";
20
20
  import {
21
21
  parseSlackMessageTs,
22
22
  parseSlackUserId
@@ -25,7 +25,7 @@ import {
25
25
  isRecord,
26
26
  logInfo,
27
27
  logWarn
28
- } from "./chunk-KSZXVR5G.js";
28
+ } from "./chunk-ZNBGWMVQ.js";
29
29
 
30
30
  // src/chat/slack/outbound.ts
31
31
  var MAX_SLACK_MESSAGE_TEXT_CHARS = 4e4;
@@ -379,6 +379,29 @@ function hasUnmatchedClosingParen(text) {
379
379
  }
380
380
  return balance < 0;
381
381
  }
382
+ var GITHUB_OWNER_PATTERN = "[A-Za-z0-9](?:[A-Za-z0-9-]*[A-Za-z0-9])?";
383
+ var GITHUB_REPO_PATTERN = "[A-Za-z0-9._-]+";
384
+ var GITHUB_REPO_ISSUE_REF_PATTERN = new RegExp(
385
+ `^(${GITHUB_OWNER_PATTERN})\\/(${GITHUB_REPO_PATTERN})#(\\d+)\\b`
386
+ );
387
+ function isGitHubRefBoundary(char) {
388
+ return char === void 0 || !/[A-Za-z0-9._-]/.test(char);
389
+ }
390
+ function readGitHubRepoIssueRef(line, start) {
391
+ if (!isGitHubRefBoundary(start === 0 ? void 0 : line[start - 1])) {
392
+ return void 0;
393
+ }
394
+ const match = GITHUB_REPO_ISSUE_REF_PATTERN.exec(line.slice(start));
395
+ if (!match) {
396
+ return void 0;
397
+ }
398
+ const [text, owner, repo, number] = match;
399
+ return {
400
+ text,
401
+ end: start + text.length,
402
+ url: `https://github.com/${owner}/${repo}/issues/${number}`
403
+ };
404
+ }
382
405
  function readBareUrl(line, start) {
383
406
  let end = start;
384
407
  while (end < line.length) {
@@ -436,6 +459,12 @@ function wrapBareUrlsOnLine(line) {
436
459
  continue;
437
460
  }
438
461
  }
462
+ const repoIssueRef = readGitHubRepoIssueRef(line, i);
463
+ if (repoIssueRef) {
464
+ result += `[${repoIssueRef.text}](${repoIssueRef.url})`;
465
+ i = repoIssueRef.end;
466
+ continue;
467
+ }
439
468
  result += line[i];
440
469
  i++;
441
470
  }
@@ -3,38 +3,38 @@ import {
3
3
  } from "./chunk-RF6J3DIO.js";
4
4
  import {
5
5
  resolveBaseUrl
6
- } from "./chunk-4JAOLUDB.js";
6
+ } from "./chunk-P7W3ZL5J.js";
7
7
  import {
8
8
  isExperimentalFeatureEnabled
9
9
  } from "./chunk-5IDFPCON.js";
10
10
  import {
11
11
  createPluginLogger,
12
12
  getPlugins
13
- } from "./chunk-NOEERHHR.js";
13
+ } from "./chunk-U26KRMYX.js";
14
14
  import {
15
15
  getSlackClient,
16
16
  withSlackRetries
17
- } from "./chunk-ROOTB7J7.js";
17
+ } from "./chunk-OUAZDZTZ.js";
18
18
  import {
19
19
  getDb,
20
20
  parseDestination
21
- } from "./chunk-AF4PHIP6.js";
21
+ } from "./chunk-JQZIUESN.js";
22
22
  import {
23
23
  sleep
24
24
  } from "./chunk-EM225ITJ.js";
25
25
  import {
26
26
  acquireActiveLock,
27
27
  getStateAdapter
28
- } from "./chunk-PHQDXC27.js";
28
+ } from "./chunk-UNDTW2PY.js";
29
29
  import {
30
30
  pluginCatalogRuntime
31
- } from "./chunk-YEZS4TEY.js";
31
+ } from "./chunk-2SFMRMDV.js";
32
32
  import {
33
33
  fetchWithBoundedOAuthErrorBodies
34
- } from "./chunk-EQ6Y37MD.js";
34
+ } from "./chunk-42E7432W.js";
35
35
  import {
36
36
  isRecord
37
- } from "./chunk-KSZXVR5G.js";
37
+ } from "./chunk-ZNBGWMVQ.js";
38
38
 
39
39
  // src/chat/capabilities/router.ts
40
40
  var ProviderCredentialRouter = class {
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  pluginCatalogRuntime
3
- } from "./chunk-YEZS4TEY.js";
3
+ } from "./chunk-2SFMRMDV.js";
4
4
 
5
5
  // src/chat/plugins/validation.ts
6
6
  import { isDeepStrictEqual } from "util";
@@ -1,13 +1,13 @@
1
1
  import {
2
2
  ToolInputError
3
- } from "./chunk-C3FYJZSA.js";
3
+ } from "./chunk-RLOXMHLA.js";
4
4
  import {
5
5
  canRouteResourceEvents,
6
6
  getPlugins
7
- } from "./chunk-NOEERHHR.js";
7
+ } from "./chunk-U26KRMYX.js";
8
8
  import {
9
9
  getDb
10
- } from "./chunk-AF4PHIP6.js";
10
+ } from "./chunk-JQZIUESN.js";
11
11
  import {
12
12
  juniorAttachments,
13
13
  juniorConversations,
@@ -15,13 +15,13 @@ import {
15
15
  juniorSchedulerRuns,
16
16
  juniorSchedulerTasks,
17
17
  juniorStats
18
- } from "./chunk-VURJ2NSF.js";
18
+ } from "./chunk-4UO3UAW7.js";
19
19
  import {
20
20
  juniorDestinations
21
21
  } from "./chunk-VFUK3X5B.js";
22
22
  import {
23
23
  logInfo
24
- } from "./chunk-KSZXVR5G.js";
24
+ } from "./chunk-ZNBGWMVQ.js";
25
25
 
26
26
  // src/chat/event-tasks/store.ts
27
27
  import { and, asc, desc, eq, inArray, or, sql } from "drizzle-orm";
@@ -13,7 +13,7 @@ import {
13
13
  instructionProvenanceFor,
14
14
  sanitizePostgresJson,
15
15
  withConversationEventLock
16
- } from "./chunk-AF4PHIP6.js";
16
+ } from "./chunk-JQZIUESN.js";
17
17
  import {
18
18
  SANDBOX_WORKSPACE_ROOT,
19
19
  sleep
@@ -23,14 +23,14 @@ import {
23
23
  fenceLock,
24
24
  getStateAdapter,
25
25
  withLock
26
- } from "./chunk-PHQDXC27.js";
26
+ } from "./chunk-UNDTW2PY.js";
27
27
  import {
28
28
  botConfig,
29
29
  completeText,
30
30
  escapeXml,
31
31
  resolveGatewayModel,
32
32
  unwrapCurrentInstruction
33
- } from "./chunk-FAJ6SMEE.js";
33
+ } from "./chunk-J77DLAPE.js";
34
34
  import {
35
35
  parseSlackMessageTs,
36
36
  toStoredSlackActor
@@ -40,7 +40,7 @@ import {
40
40
  logException,
41
41
  logWarn,
42
42
  setSpanAttributes
43
- } from "./chunk-KSZXVR5G.js";
43
+ } from "./chunk-ZNBGWMVQ.js";
44
44
 
45
45
  // src/chat/turn-context-tag.ts
46
46
  var TURN_CONTEXT_TAG = "runtime-turn-context";
@@ -1615,6 +1615,41 @@ async function recordToolExecutionStarted(args) {
1615
1615
  }
1616
1616
  ]);
1617
1617
  }
1618
+ function attachmentsDeliveredIdempotencyKey(args) {
1619
+ if (args.toolCallId) {
1620
+ return `attachments_delivered:tool:${args.toolCallId}`;
1621
+ }
1622
+ if (args.turnId) {
1623
+ return `attachments_delivered:turn:${args.turnId}:` + args.attachments.map((attachment) => attachment.id).sort().join(",");
1624
+ }
1625
+ return `attachments_delivered:${args.conversationId}:` + args.attachments.map((attachment) => attachment.id).sort().join(",");
1626
+ }
1627
+ async function recordAttachmentsDelivered(args) {
1628
+ if (args.attachments.length === 0) return;
1629
+ await getConversationEventStore().append(args.conversationId, [
1630
+ {
1631
+ // Retries after a successful Slack upload must not create duplicate rows.
1632
+ idempotencyKey: attachmentsDeliveredIdempotencyKey({
1633
+ attachments: args.attachments,
1634
+ conversationId: args.conversationId,
1635
+ ...args.toolCallId ? { toolCallId: args.toolCallId } : {},
1636
+ ...args.turnId ? { turnId: args.turnId } : {}
1637
+ }),
1638
+ data: {
1639
+ type: "attachments_delivered",
1640
+ attachments: args.attachments.map((attachment) => ({
1641
+ id: attachment.id,
1642
+ filename: attachment.filename,
1643
+ contentType: attachment.contentType,
1644
+ bytes: attachment.bytes
1645
+ })),
1646
+ ...args.toolCallId ? { toolCallId: args.toolCallId } : {},
1647
+ ...args.turnId ? { turnId: args.turnId } : {}
1648
+ },
1649
+ createdAtMs: args.createdAtMs ?? Date.now()
1650
+ }
1651
+ ]);
1652
+ }
1618
1653
  async function recordGuardianActionReviewed(args) {
1619
1654
  await getConversationEventStore().append(args.conversationId, [
1620
1655
  {
@@ -3175,6 +3210,7 @@ export {
3175
3210
  loadTurnRoute,
3176
3211
  recordTurnRoute,
3177
3212
  recordToolExecutionStarted,
3213
+ recordAttachmentsDelivered,
3178
3214
  recordGuardianActionReviewed,
3179
3215
  ToolInputError,
3180
3216
  MAX_TEXT_CHARS,
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  logWarn
3
- } from "./chunk-KSZXVR5G.js";
3
+ } from "./chunk-ZNBGWMVQ.js";
4
4
 
5
5
  // src/chat/conversation-privacy.ts
6
6
  import { AsyncLocalStorage } from "async_hooks";