@sentry/junior 0.194.0 → 0.195.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 (88) hide show
  1. package/dist/{agent-hooks-IDX764FD.js → agent-hooks-VIBTIP5F.js} +11 -11
  2. package/dist/api/activity.d.ts +9 -1
  3. package/dist/api/code/overview.d.ts +12 -0
  4. package/dist/api/locations/detail.d.ts +8 -0
  5. package/dist/api/locations/list.d.ts +5 -0
  6. package/dist/api/people/code.d.ts +6 -0
  7. package/dist/api/people/shared.d.ts +9 -1
  8. package/dist/api/reporting-window.d.ts +39 -1
  9. package/dist/api/schema/code.d.ts +12 -0
  10. package/dist/api/schema/conversation.d.ts +25 -0
  11. package/dist/api/schema/location.d.ts +13 -0
  12. package/dist/api/schema/person.d.ts +14 -0
  13. package/dist/api/schema/task.d.ts +12 -0
  14. package/dist/api/schema.js +1 -1
  15. package/dist/api.js +242 -63
  16. package/dist/app.js +102 -38
  17. package/dist/{catalog-runtime-MICXEBLK.js → catalog-runtime-6E6SGRZK.js} +4 -4
  18. package/dist/chat/config.d.ts +1 -0
  19. package/dist/chat/event-tasks/store.d.ts +27 -17
  20. package/dist/chat/resource-events/notification.d.ts +2 -1
  21. package/dist/chat/services/automated-turn-limit.d.ts +110 -0
  22. package/dist/chat/slack/automated-turn-limit-notice.d.ts +38 -0
  23. package/dist/chat/tasks/execution-stats.d.ts +2 -1
  24. package/dist/chat/tasks/read.d.ts +5 -2
  25. package/dist/{chunk-KNIAWMBU.js → chunk-3VWIZVK7.js} +1 -1
  26. package/dist/{chunk-XND3J6AT.js → chunk-5HNXLP4W.js} +1 -1
  27. package/dist/{chunk-VOB2DKO6.js → chunk-5NR7N567.js} +24 -13
  28. package/dist/{chunk-CFGBKPWQ.js → chunk-6GGDBXXP.js} +3 -3
  29. package/dist/{chunk-IOGDKPVU.js → chunk-6TRQLG3D.js} +1 -1
  30. package/dist/{chunk-V4HXV5MY.js → chunk-7MYXH5LA.js} +1 -1
  31. package/dist/{chunk-6H2MKVV5.js → chunk-7PQMTME5.js} +1 -1
  32. package/dist/{chunk-INTBMGNX.js → chunk-7UED4D5T.js} +21 -21
  33. package/dist/{chunk-NPO24LAN.js → chunk-BJZML4RT.js} +8 -8
  34. package/dist/{chunk-IME5OW4Y.js → chunk-C4NY6L7S.js} +1 -1
  35. package/dist/{chunk-53IEEFFP.js → chunk-CE2P6TOV.js} +3 -3
  36. package/dist/{chunk-WMJS5DDV.js → chunk-DTYOEHUP.js} +148 -19
  37. package/dist/{chunk-GY5SEFVL.js → chunk-FE3Y4KES.js} +5 -5
  38. package/dist/{chunk-G4RARFNT.js → chunk-FEZIEEOP.js} +957 -567
  39. package/dist/{chunk-XLWZRHX5.js → chunk-FPQPYJEG.js} +23 -29
  40. package/dist/{chunk-73JEAQRT.js → chunk-HE5PZAPS.js} +4 -4
  41. package/dist/{chunk-X76JVHQ4.js → chunk-HUQOXMDG.js} +1 -1
  42. package/dist/{chunk-NWWDFHXP.js → chunk-I4RH3KLJ.js} +1 -1
  43. package/dist/{chunk-QMEF4Z7R.js → chunk-JBSCMOLR.js} +5 -5
  44. package/dist/{chunk-JOI3DHML.js → chunk-KBPWC7NU.js} +1 -1
  45. package/dist/{chunk-ADEACKAH.js → chunk-KQ3GZGBK.js} +10 -3
  46. package/dist/{chunk-2NL3Y47F.js → chunk-KUQRWV53.js} +5 -5
  47. package/dist/{chunk-ELCYG6UU.js → chunk-L62JVQPL.js} +3 -3
  48. package/dist/{chunk-7ANA7PBB.js → chunk-LM7UE523.js} +3 -3
  49. package/dist/{chunk-U76RWMFR.js → chunk-LMYRF6HX.js} +4 -2
  50. package/dist/{chunk-F2KSURTJ.js → chunk-N67T4VY3.js} +9 -9
  51. package/dist/{chunk-AWZS5SVX.js → chunk-OQHO62VA.js} +8 -8
  52. package/dist/{chunk-CCTYK5RH.js → chunk-PFQRZ4IB.js} +9 -6
  53. package/dist/{chunk-H4DCWLTR.js → chunk-PYTRZZ4V.js} +8 -8
  54. package/dist/{chunk-XRDSML3K.js → chunk-QHJZSYKY.js} +2 -2
  55. package/dist/{chunk-E53C73ML.js → chunk-QKHZF2LH.js} +4 -4
  56. package/dist/{chunk-YSLIB7ER.js → chunk-QPZL2IYT.js} +82 -6
  57. package/dist/{chunk-RFE7DCZK.js → chunk-R5BGW4WR.js} +2 -2
  58. package/dist/{chunk-ENWIHU54.js → chunk-R5OHONYU.js} +6 -6
  59. package/dist/{chunk-WWXJUURQ.js → chunk-RKA22BQP.js} +1 -1
  60. package/dist/{chunk-P2P6MUQ4.js → chunk-RQO67SAO.js} +2 -2
  61. package/dist/{chunk-OEQOAONV.js → chunk-RZ3PBNDV.js} +6 -6
  62. package/dist/{chunk-G35QGPO2.js → chunk-VYDIA2UL.js} +1 -1
  63. package/dist/{chunk-S7GX44BU.js → chunk-X3PBQ4BK.js} +1 -1
  64. package/dist/cli/chat.js +33 -33
  65. package/dist/cli/check.js +5 -5
  66. package/dist/cli/plugins.js +12 -12
  67. package/dist/cli/snapshot-create.js +9 -9
  68. package/dist/cli/upgrade.js +6 -6
  69. package/dist/db/schema/event-tasks.d.ts +21 -0
  70. package/dist/db/schema.d.ts +19 -0
  71. package/dist/{db-3IEVINAY.js → db-FVCSDROR.js} +6 -6
  72. package/dist/instrumentation.js +3 -3
  73. package/dist/nitro.js +6 -6
  74. package/dist/{oauth-callback-server-N7L2BB4L.js → oauth-callback-server-Z5PXTDOE.js} +29 -29
  75. package/dist/{runner-PTTZV3WU.js → runner-RHYU7OGV.js} +21 -21
  76. package/dist/{skills-POMWS2RR.js → skills-QTN73DN5.js} +5 -5
  77. package/dist/spawn-R56OWLUH.js +42 -0
  78. package/dist/task-runner-LLJZTLRP.js +36 -0
  79. package/dist/{validation-U6LOMXR7.js → validation-2ZK7GA6N.js} +5 -5
  80. package/dist/version.js +1 -1
  81. package/dist/{work-FHA3BS4L.js → work-7IBKSZRU.js} +21 -21
  82. package/dist/{worker-GR4UNVVP.js → worker-RNVQVCO7.js} +10 -10
  83. package/migrations/0038_event_task_status.sql +5 -0
  84. package/migrations/meta/0038_snapshot.json +3323 -0
  85. package/migrations/meta/_journal.json +8 -1
  86. package/package.json +5 -5
  87. package/dist/spawn-R75MXXKE.js +0 -42
  88. package/dist/task-runner-OQLRHADB.js +0 -36
package/dist/app.js CHANGED
@@ -1,15 +1,15 @@
1
1
  import {
2
2
  processConversationWork
3
- } from "./chunk-73JEAQRT.js";
3
+ } from "./chunk-HE5PZAPS.js";
4
4
  import {
5
5
  bindSpawnAgent
6
- } from "./chunk-XRDSML3K.js";
6
+ } from "./chunk-QHJZSYKY.js";
7
7
  import {
8
8
  createAgentInvocationWorker,
9
9
  enqueueAgentInvocation,
10
10
  listPendingAgentInvocationMailboxAppends,
11
11
  resolveAgentInvocationId
12
- } from "./chunk-F2KSURTJ.js";
12
+ } from "./chunk-N67T4VY3.js";
13
13
  import {
14
14
  GET as GET2,
15
15
  GET2 as GET3,
@@ -37,12 +37,12 @@ import {
37
37
  startProcessingReaction,
38
38
  stripLeadingBotMention,
39
39
  wakePausedTurn
40
- } from "./chunk-INTBMGNX.js";
40
+ } from "./chunk-7UED4D5T.js";
41
41
  import "./chunk-FA6POGLH.js";
42
42
  import {
43
43
  AgentRunError,
44
44
  executeTurn
45
- } from "./chunk-53IEEFFP.js";
45
+ } from "./chunk-CE2P6TOV.js";
46
46
  import {
47
47
  buildDeliveredTurnStatePatch,
48
48
  completeAuthPauseTurn,
@@ -53,7 +53,7 @@ import {
53
53
  getTurnUserSlackMessageTs,
54
54
  persistAuthPauseTurnState,
55
55
  requireTurnFailureEventId
56
- } from "./chunk-2NL3Y47F.js";
56
+ } from "./chunk-KUQRWV53.js";
57
57
  import {
58
58
  claimDispatchMailboxAppend,
59
59
  confirmDispatchMailboxAppend,
@@ -73,11 +73,11 @@ import {
73
73
  processPluginTask,
74
74
  resolveTurnSessionRouting,
75
75
  scheduleSessionCompletedPluginTasks
76
- } from "./chunk-NPO24LAN.js";
76
+ } from "./chunk-BJZML4RT.js";
77
77
  import {
78
78
  ConversationTurnLifecycleService,
79
79
  getTurnLifecycle
80
- } from "./chunk-6H2MKVV5.js";
80
+ } from "./chunk-7PQMTME5.js";
81
81
  import {
82
82
  coerceThreadConversationState,
83
83
  getLocationConfigurationService,
@@ -86,7 +86,7 @@ import {
86
86
  persistThreadRuntimeState,
87
87
  persistThreadState,
88
88
  persistThreadStateById
89
- } from "./chunk-GY5SEFVL.js";
89
+ } from "./chunk-FE3Y4KES.js";
90
90
  import {
91
91
  GET,
92
92
  appendAndEnqueueWebMessage,
@@ -101,24 +101,24 @@ import {
101
101
  resolveSlackChannelTypeFromMessage,
102
102
  resolveSlackConversationContext,
103
103
  webActorFromEmail
104
- } from "./chunk-H4DCWLTR.js";
104
+ } from "./chunk-PYTRZZ4V.js";
105
105
  import {
106
106
  createWebAuthorization,
107
107
  deleteWebAuthorization
108
- } from "./chunk-XND3J6AT.js";
108
+ } from "./chunk-5HNXLP4W.js";
109
109
  import {
110
110
  recordTaskExecution
111
- } from "./chunk-VOB2DKO6.js";
111
+ } from "./chunk-5NR7N567.js";
112
112
  import "./chunk-RC745GGZ.js";
113
113
  import {
114
114
  createVercelPluginTaskCallback,
115
115
  queueCallback,
116
116
  registerVercelPluginTaskDevConsumer
117
- } from "./chunk-CFGBKPWQ.js";
117
+ } from "./chunk-6GGDBXXP.js";
118
118
  import {
119
119
  validatePluginEgressCredentialHooks,
120
120
  validatePluginRegistrations
121
- } from "./chunk-KNIAWMBU.js";
121
+ } from "./chunk-3VWIZVK7.js";
122
122
  import {
123
123
  defineJuniorPlugins,
124
124
  pluginCatalogConfigFromEnv,
@@ -129,6 +129,7 @@ import {
129
129
  RESOURCE_EVENT_MESSAGE_AUTHOR,
130
130
  RESOURCE_EVENT_SYSTEM_ACTOR,
131
131
  SANDBOX_EGRESS_PROXY_PATH,
132
+ admitAutomatedTurn,
132
133
  buildSteeringPiMessage,
133
134
  clearSandboxEgressSignals,
134
135
  consumeSandboxEgressAuthRequiredSignal,
@@ -144,11 +145,14 @@ import {
144
145
  latestReportedProgress,
145
146
  listThreadReplies,
146
147
  logScheduledTaskRunSkipped,
148
+ maybePostAutomatedTurnLimitNotice,
147
149
  normalizeSandboxEgressTracePropagationDomains,
148
150
  parseSandboxEgressCredentialToken,
151
+ postAutomatedTurnLimitNoticeForDestination,
149
152
  processWorkspaceSnapshotJob,
150
153
  publicArtifactHeaders,
151
154
  readPublicArtifact,
155
+ recordFinishedTurnForAutomatedLimit,
152
156
  renderAttachmentText,
153
157
  renderBlockText,
154
158
  renderTaskInput,
@@ -158,11 +162,11 @@ import {
158
162
  shouldEmitDevAgentTrace,
159
163
  shouldPropagateSandboxEgressTrace,
160
164
  unpublishedArtifactHeaders
161
- } from "./chunk-G4RARFNT.js";
165
+ } from "./chunk-FEZIEEOP.js";
162
166
  import {
163
167
  AuthorizationFlowDisabledError,
164
168
  PluginCredentialFailureError
165
- } from "./chunk-QMEF4Z7R.js";
169
+ } from "./chunk-JBSCMOLR.js";
166
170
  import "./chunk-6Y5B5PEX.js";
167
171
  import "./chunk-DIB4GX3G.js";
168
172
  import {
@@ -170,14 +174,14 @@ import {
170
174
  deleteMcpAuthSessionsForUserProvider,
171
175
  deleteMcpServerSessionId,
172
176
  deleteMcpStoredOAuthCredentials
173
- } from "./chunk-AWZS5SVX.js";
177
+ } from "./chunk-OQHO62VA.js";
174
178
  import {
175
179
  RetryableDeliveryError,
176
180
  createAgentRunner,
177
181
  formatProviderLabel,
178
182
  postSlackMessage,
179
183
  startOAuthFlow
180
- } from "./chunk-ENWIHU54.js";
184
+ } from "./chunk-R5OHONYU.js";
181
185
  import {
182
186
  ConversationTurnBoundaryError,
183
187
  CooperativeTurnYieldError,
@@ -193,7 +197,7 @@ import {
193
197
  markTurnCompleted,
194
198
  markTurnFailed,
195
199
  startActiveTurn
196
- } from "./chunk-G35QGPO2.js";
200
+ } from "./chunk-VYDIA2UL.js";
197
201
  import {
198
202
  abandonTurnRecord,
199
203
  appendThreadContextMessages,
@@ -230,7 +234,7 @@ import {
230
234
  trimTrailingAssistantMessages,
231
235
  turnHasReply,
232
236
  upsertConversationMessage
233
- } from "./chunk-OEQOAONV.js";
237
+ } from "./chunk-RZ3PBNDV.js";
234
238
  import {
235
239
  getExperimentalFeatures,
236
240
  isExperimentalFeatureEnabled,
@@ -250,10 +254,10 @@ import {
250
254
  scheduledRunId,
251
255
  scheduledRunSchema,
252
256
  withScheduledTaskLock
253
- } from "./chunk-WMJS5DDV.js";
257
+ } from "./chunk-DTYOEHUP.js";
254
258
  import {
255
259
  parseSlackThreadId
256
- } from "./chunk-IOGDKPVU.js";
260
+ } from "./chunk-6TRQLG3D.js";
257
261
  import {
258
262
  CONVERSATION_WORK_STALE_ENQUEUE_MS,
259
263
  appendAndEnqueueInboundMessage,
@@ -268,16 +272,16 @@ import {
268
272
  removeActiveConversation,
269
273
  requestConversationWork,
270
274
  stopConversationWork
271
- } from "./chunk-E53C73ML.js";
275
+ } from "./chunk-QKHZF2LH.js";
272
276
  import {
273
277
  buildDeterministicAssistantMessageId,
274
278
  buildDeterministicTurnId
275
279
  } from "./chunk-DA2KGZZI.js";
276
- import "./chunk-RFE7DCZK.js";
280
+ import "./chunk-R5BGW4WR.js";
277
281
  import {
278
282
  getSandboxResourceConfig,
279
283
  setSandboxResourceConfig
280
- } from "./chunk-ELCYG6UU.js";
284
+ } from "./chunk-L62JVQPL.js";
281
285
  import "./chunk-PDO5BLNM.js";
282
286
  import "./chunk-UIE3R5XU.js";
283
287
  import {
@@ -286,7 +290,7 @@ import {
286
290
  } from "./chunk-X6GDDWQH.js";
287
291
  import {
288
292
  getTurnRequestDeadline
289
- } from "./chunk-NWWDFHXP.js";
293
+ } from "./chunk-I4RH3KLJ.js";
290
294
  import {
291
295
  getVercelConversationWorkQueue,
292
296
  resolveConversationWorkQueueTopic,
@@ -322,7 +326,7 @@ import {
322
326
  verifyEventTaskCredentialSubject,
323
327
  verifyScheduledTaskCredentialSubject,
324
328
  verifySlackDirectCredentialSubject
325
- } from "./chunk-CCTYK5RH.js";
329
+ } from "./chunk-PFQRZ4IB.js";
326
330
  import "./chunk-3Y47VMHV.js";
327
331
  import {
328
332
  createSlackDestination,
@@ -334,7 +338,7 @@ import {
334
338
  requireSlackDestination,
335
339
  withConversationEventLock,
336
340
  withConversationMutationLock
337
- } from "./chunk-ADEACKAH.js";
341
+ } from "./chunk-KQ3GZGBK.js";
338
342
  import {
339
343
  juniorAgentBindings,
340
344
  juniorAgentInvocations,
@@ -342,13 +346,13 @@ import {
342
346
  juniorConversations,
343
347
  juniorSchedulerRuns,
344
348
  juniorSchedulerTasks
345
- } from "./chunk-XLWZRHX5.js";
346
- import "./chunk-7ANA7PBB.js";
349
+ } from "./chunk-FPQPYJEG.js";
350
+ import "./chunk-LM7UE523.js";
347
351
  import {
348
352
  acquireActiveLock,
349
353
  getStateAdapter,
350
354
  withActiveLock
351
- } from "./chunk-V4HXV5MY.js";
355
+ } from "./chunk-7MYXH5LA.js";
352
356
  import {
353
357
  instructionProvenanceFor
354
358
  } from "./chunk-GFBR4S3Q.js";
@@ -370,17 +374,17 @@ import {
370
374
  isProviderRetryError,
371
375
  setProfiles,
372
376
  setSlackReactionConfig
373
- } from "./chunk-U76RWMFR.js";
377
+ } from "./chunk-LMYRF6HX.js";
374
378
  import {
375
379
  defaultModelId,
376
380
  modelIdForProfile
377
381
  } from "./chunk-D4YV5TDV.js";
378
- import "./chunk-JOI3DHML.js";
379
- import "./chunk-P2P6MUQ4.js";
382
+ import "./chunk-KBPWC7NU.js";
383
+ import "./chunk-RQO67SAO.js";
380
384
  import {
381
385
  pluginCatalogRuntime
382
- } from "./chunk-WWXJUURQ.js";
383
- import "./chunk-S7GX44BU.js";
386
+ } from "./chunk-RKA22BQP.js";
387
+ import "./chunk-X3PBQ4BK.js";
384
388
  import {
385
389
  credentialContextForActor
386
390
  } from "./chunk-CEMMLV5L.js";
@@ -416,13 +420,13 @@ import {
416
420
  withContext,
417
421
  withLogContext,
418
422
  withSpan
419
- } from "./chunk-X76JVHQ4.js";
423
+ } from "./chunk-HUQOXMDG.js";
420
424
  import {
421
425
  continueTrace
422
426
  } from "./chunk-PEQXYSSE.js";
423
427
  import {
424
428
  JUNIOR_VERSION
425
- } from "./chunk-IME5OW4Y.js";
429
+ } from "./chunk-C4NY6L7S.js";
426
430
 
427
431
  // src/app.ts
428
432
  import { createRequire } from "module";
@@ -7251,6 +7255,21 @@ function createSlackTurn(deps) {
7251
7255
  })
7252
7256
  );
7253
7257
  await persistThreadRuntimeStateWithRetry(thread, completedState);
7258
+ const automatedTurnLimit = await recordFinishedTurnForAutomatedLimit(
7259
+ {
7260
+ conversationId,
7261
+ destination,
7262
+ maxTurns: botConfig.maxConsecutiveAutomatedTurns,
7263
+ source
7264
+ }
7265
+ );
7266
+ await maybePostAutomatedTurnLimitNotice({
7267
+ conversationId,
7268
+ destination,
7269
+ maxTurns: botConfig.maxConsecutiveAutomatedTurns,
7270
+ threadTs,
7271
+ update: automatedTurnLimit
7272
+ });
7254
7273
  } catch (saveError) {
7255
7274
  saveFailed = true;
7256
7275
  saveFailureEventId = logException(
@@ -9141,6 +9160,19 @@ function createConversationTurnWorker(agentRunner, deliverMessage) {
9141
9160
  surface
9142
9161
  });
9143
9162
  }
9163
+ const automatedTurnLimit = await recordFinishedTurnForAutomatedLimit({
9164
+ conversationId: context.conversationId,
9165
+ destination,
9166
+ maxTurns: botConfig.maxConsecutiveAutomatedTurns,
9167
+ source
9168
+ });
9169
+ await maybePostAutomatedTurnLimitNotice({
9170
+ conversationId: context.conversationId,
9171
+ destination,
9172
+ maxTurns: botConfig.maxConsecutiveAutomatedTurns,
9173
+ threadTs: conversationLocation?.provider === "slack" ? conversationLocation.threadTs : void 0,
9174
+ update: automatedTurnLimit
9175
+ });
9144
9176
  completedSuccessfully = reply.diagnostics.outcome === "success";
9145
9177
  return completedSuccessfully ? {
9146
9178
  outcome: assistantMessageDelivered ? "success" : "no_reply"
@@ -9523,8 +9555,40 @@ async function ingestEventTasks(input, options) {
9523
9555
  const tasks = await findMatchingEventTasks(db, event, options.teamId);
9524
9556
  let dispatched = 0;
9525
9557
  const errors = [];
9558
+ const maxTurns = botConfig.maxConsecutiveAutomatedTurns;
9559
+ const noticedDestinations = /* @__PURE__ */ new Set();
9526
9560
  for (const task of tasks) {
9527
9561
  try {
9562
+ const decision = await admitAutomatedTurn({
9563
+ maxTurns,
9564
+ nowMs,
9565
+ scope: { kind: "destination", destination: task.destination }
9566
+ });
9567
+ if (decision.status === "paused") {
9568
+ const destinationId = `${task.destination.teamId}:${task.destination.channelId}`;
9569
+ logInfo("event_tasks.automated_turn_limit.paused", {
9570
+ "app.automated_turn_limit.consecutive": decision.consecutiveAutomatedTurns,
9571
+ "app.automated_turn_limit.max": maxTurns,
9572
+ "app.event_task.id": task.id,
9573
+ "app.resource_event.event_type": event.eventType,
9574
+ "app.resource_event.namespace": event.namespace,
9575
+ "app.slack.channel_id": task.destination.channelId,
9576
+ "app.slack.team_id": task.destination.teamId
9577
+ });
9578
+ if (decision.shouldPostNotice && !noticedDestinations.has(destinationId)) {
9579
+ const posted = await postAutomatedTurnLimitNoticeForDestination({
9580
+ destination: task.destination,
9581
+ maxTurns,
9582
+ nowMs,
9583
+ resumeIn: "channel",
9584
+ scope: { kind: "destination", destination: task.destination }
9585
+ });
9586
+ if (posted) {
9587
+ noticedDestinations.add(destinationId);
9588
+ }
9589
+ }
9590
+ continue;
9591
+ }
9528
9592
  const idempotencyKey = eventTaskDispatchKey(
9529
9593
  task.id,
9530
9594
  event.namespace,
@@ -1,14 +1,14 @@
1
1
  import {
2
2
  pluginCatalogRuntime
3
- } from "./chunk-WWXJUURQ.js";
4
- import "./chunk-S7GX44BU.js";
3
+ } from "./chunk-RKA22BQP.js";
4
+ import "./chunk-X3PBQ4BK.js";
5
5
  import "./chunk-CEMMLV5L.js";
6
6
  import "./chunk-N7TMSOZH.js";
7
7
  import "./chunk-DWPN6SCH.js";
8
8
  import "./chunk-TXKUKMVO.js";
9
- import "./chunk-X76JVHQ4.js";
9
+ import "./chunk-HUQOXMDG.js";
10
10
  import "./chunk-PEQXYSSE.js";
11
- import "./chunk-IME5OW4Y.js";
11
+ import "./chunk-C4NY6L7S.js";
12
12
  export {
13
13
  pluginCatalogRuntime
14
14
  };
@@ -22,6 +22,7 @@ export interface BotConfig {
22
22
  visionModelId?: string;
23
23
  maxSlicesPerTurn: number;
24
24
  maxToolCallsPerTurn: number;
25
+ maxConsecutiveAutomatedTurns: number;
25
26
  turnTimeoutMs: number;
26
27
  userName: string;
27
28
  webSearchModelId: string;
@@ -1,24 +1,34 @@
1
1
  import { type ResourceEvent, type User } from "@sentry/junior-plugin-api";
2
2
  import type { JuniorDatabase } from "@/db/db";
3
+ import { type EventTaskStatus } from "@/db/schema/event-tasks";
3
4
  import { type EventTask } from "./types";
4
- /** Read one event task by id. */
5
- export declare function getEventTask(db: JuniorDatabase, id: string): Promise<EventTask | undefined>;
6
- /** Create one retry-stable event task or return its existing record. */
7
- export declare function createEventTask(db: JuniorDatabase, task: EventTask): Promise<EventTask>;
8
- /** Replace an existing event task. */
9
- export declare function saveEventTask(db: JuniorDatabase, task: EventTask): Promise<EventTask | undefined>;
10
- /** Delete one existing event task. */
11
- export declare function deleteEventTask(db: JuniorDatabase, id: string): Promise<EventTask | undefined>;
12
- /** List event tasks in one Slack workspace. */
13
- export declare function listEventTasksForTeam(db: JuniorDatabase, teamId: string): Promise<EventTask[]>;
5
+ /** Live event task plus retained SQL status for history after delete. */
6
+ export type StoredEventTask = EventTask & {
7
+ status: EventTaskStatus;
8
+ };
9
+ /** Read one event task by id, including deleted rows when present. */
10
+ export declare function getEventTask(db: JuniorDatabase, id: string): Promise<StoredEventTask | undefined>;
11
+ /** Create one retry-stable event task, or revive a deleted row with the new payload. */
12
+ export declare function createEventTask(db: JuniorDatabase, task: EventTask): Promise<StoredEventTask>;
13
+ /** Replace an existing non-deleted event task. */
14
+ export declare function saveEventTask(db: JuniorDatabase, task: EventTask): Promise<StoredEventTask | undefined>;
15
+ /** Mark one existing event task deleted while retaining the row for history. */
16
+ export declare function deleteEventTask(db: JuniorDatabase, id: string): Promise<StoredEventTask | undefined>;
17
+ /** List live event tasks in one Slack workspace. */
18
+ export declare function listEventTasksForTeam(db: JuniorDatabase, teamId: string): Promise<StoredEventTask[]>;
14
19
  /** Return whether one event task was created by a viewer-linked Slack identity. */
15
20
  export declare function eventTaskBelongsToUser(task: EventTask, user: User): boolean;
16
- /** List a bounded newest-first page of event tasks created by one user. */
17
- export declare function listEventTasksCreatedBy(db: JuniorDatabase, user: User, limit: number): Promise<EventTask[]>;
18
- /** List event tasks whose current Slack destination is public. */
19
- export declare function listPublicEventTasksForTeams(db: JuniorDatabase, teamIds: string[], limit: number): Promise<EventTask[]>;
21
+ /** List a bounded newest-first page of live event tasks created by one user. */
22
+ export declare function listEventTasksCreatedBy(db: JuniorDatabase, user: User, limit: number): Promise<StoredEventTask[]>;
20
23
  /**
21
- * Collect match keys from event tasks for these identifiers and event types.
24
+ * List deleted event tasks created by one user, newest first.
25
+ * Used only to keep historical runs after the live task list drops the row.
26
+ */
27
+ export declare function listDeletedEventTasksCreatedBy(db: JuniorDatabase, user: User, limit: number): Promise<StoredEventTask[]>;
28
+ /** List live event tasks whose current Slack destination is public. */
29
+ export declare function listPublicEventTasksForTeams(db: JuniorDatabase, teamIds: string[], limit: number): Promise<StoredEventTask[]>;
30
+ /**
31
+ * Collect match keys from live event tasks for these identifiers and event types.
22
32
  * Does not evaluate match values — only reports keys that filters use.
23
33
  */
24
34
  export declare function collectEventTaskMatchKeys(db: JuniorDatabase, input: {
@@ -27,5 +37,5 @@ export declare function collectEventTaskMatchKeys(db: JuniorDatabase, input: {
27
37
  namespace: string;
28
38
  teamId: string;
29
39
  }): Promise<string[]>;
30
- /** Find every task matching one normalized resource event. */
31
- export declare function findMatchingEventTasks(db: JuniorDatabase, event: ResourceEvent, teamId: string): Promise<EventTask[]>;
40
+ /** Find every live task matching one normalized resource event. */
41
+ export declare function findMatchingEventTasks(db: JuniorDatabase, event: ResourceEvent, teamId: string): Promise<StoredEventTask[]>;
@@ -43,7 +43,8 @@ export declare function createResourceEventInboundMessage(input: {
43
43
  * Enqueue a resource event as normal conversation mailbox input.
44
44
  *
45
45
  * The watch only names the conversation. Destination stays on the conversation
46
- * and is applied when the worker runs.
46
+ * and is applied when the worker runs. After too many automated Turns with no
47
+ * user Turn, later wakes stay quiet until a user message clears the pause.
47
48
  */
48
49
  export declare function enqueueResourceEventNotification(args: {
49
50
  event: ResourceEventNotification;
@@ -0,0 +1,110 @@
1
+ /**
2
+ * Stops event wakes after too many automated Turns with no user Turn.
3
+ *
4
+ * Resource-event watches count on the Conversation. Event tasks and other
5
+ * agent dispatches count on the Slack Destination. A finished user Turn clears
6
+ * every scope that Turn can name.
7
+ */
8
+ import type { Destination, Source } from "@sentry/junior-plugin-api";
9
+ import type { StateAdapter } from "chat";
10
+ import { z } from "zod";
11
+ /** Stored consecutive-turn limit for one Conversation or Destination. */
12
+ declare const automatedTurnLimitStateSchema: z.ZodObject<{
13
+ consecutiveAutomatedTurns: z.ZodNumber;
14
+ noticePostedAtMs: z.ZodOptional<z.ZodNumber>;
15
+ paused: z.ZodBoolean;
16
+ updatedAtMs: z.ZodNumber;
17
+ }, z.core.$strict>;
18
+ export type AutomatedTurnLimitState = z.output<typeof automatedTurnLimitStateSchema>;
19
+ export type AutomatedTurnLimitScope = {
20
+ kind: "conversation";
21
+ conversationId: string;
22
+ } | {
23
+ kind: "destination";
24
+ destination: Destination;
25
+ };
26
+ export type AutomatedTurnLimitDecision = {
27
+ status: "allow";
28
+ consecutiveAutomatedTurns: number;
29
+ } | {
30
+ status: "paused";
31
+ consecutiveAutomatedTurns: number;
32
+ shouldPostNotice: boolean;
33
+ };
34
+ export type AutomatedTurnLimitUpdate = {
35
+ consecutiveAutomatedTurns: number;
36
+ paused: boolean;
37
+ shouldPostNotice: boolean;
38
+ /** Where the pause notice should tell the user to reply. */
39
+ resumeIn: "thread" | "channel";
40
+ };
41
+ /** True when this Source starts an automated Turn rather than a user Turn. */
42
+ export declare function isAutomatedTurnSource(source: Source | undefined): boolean;
43
+ /**
44
+ * Scope that counts automated Turns for this Source.
45
+ * Resource-event watches stay on the Conversation. Dispatches use Destination.
46
+ */
47
+ export declare function automatedTurnLimitScopeForSource(args: {
48
+ conversationId: string;
49
+ destination?: Destination;
50
+ source?: Source;
51
+ }): AutomatedTurnLimitScope | undefined;
52
+ /** Plain notice when automatic updates stop until the user replies. */
53
+ export declare function buildAutomatedTurnLimitResponse(args: {
54
+ maxTurns: number;
55
+ resumeIn?: "thread" | "channel";
56
+ }): string;
57
+ /** Read the current consecutive-turn limit for one scope. */
58
+ export declare function getAutomatedTurnLimitState(args: {
59
+ nowMs?: number;
60
+ scope: AutomatedTurnLimitScope;
61
+ state?: StateAdapter;
62
+ }): Promise<AutomatedTurnLimitState>;
63
+ /**
64
+ * Allow one automated wake, or refuse once the consecutive-turn limit is full.
65
+ * If a prior pause never posted its notice, claim the notice slot so one caller
66
+ * posts it. Clear the claim if that post fails or is skipped.
67
+ */
68
+ export declare function admitAutomatedTurn(args: {
69
+ maxTurns: number;
70
+ nowMs?: number;
71
+ scope: AutomatedTurnLimitScope;
72
+ state?: StateAdapter;
73
+ }): Promise<AutomatedTurnLimitDecision>;
74
+ /** Count one finished automated Turn toward the consecutive-turn limit. */
75
+ export declare function countAutomatedTurn(args: {
76
+ maxTurns: number;
77
+ nowMs?: number;
78
+ scope: AutomatedTurnLimitScope;
79
+ state?: StateAdapter;
80
+ }): Promise<AutomatedTurnLimitUpdate>;
81
+ /**
82
+ * Drop a failed notice claim so a later paused wake can post the notice.
83
+ * Keeps the pause and consecutive count.
84
+ */
85
+ export declare function clearAutomatedTurnLimitNoticeClaim(args: {
86
+ nowMs?: number;
87
+ scope: AutomatedTurnLimitScope;
88
+ state?: StateAdapter;
89
+ }): Promise<void>;
90
+ /** Clear the consecutive automated-turn count after a user-owned Turn. */
91
+ export declare function resetAutomatedTurnLimit(args: {
92
+ nowMs?: number;
93
+ scope: AutomatedTurnLimitScope;
94
+ state?: StateAdapter;
95
+ }): Promise<void>;
96
+ /**
97
+ * Update consecutive automated-turn limits after one finished Turn.
98
+ *
99
+ * Automated Turns count one matching scope. User Turns clear Conversation and
100
+ * Destination scopes so later event wakes can run again.
101
+ */
102
+ export declare function recordFinishedTurnForAutomatedLimit(args: {
103
+ conversationId: string;
104
+ destination?: Destination;
105
+ maxTurns: number;
106
+ nowMs?: number;
107
+ source?: Source;
108
+ state?: StateAdapter;
109
+ }): Promise<AutomatedTurnLimitUpdate | undefined>;
110
+ export {};
@@ -0,0 +1,38 @@
1
+ /**
2
+ * Destination-visible pause notice for the consecutive automated-turn limit.
3
+ *
4
+ * Best-effort: a failed post must not fail the Turn or re-enable event wakes.
5
+ * The consecutive-turn limit claims the notice slot before this post. Clear that
6
+ * claim when the post fails or is skipped so a later paused wake can try again.
7
+ */
8
+ import type { Destination } from "@sentry/junior-plugin-api";
9
+ import { type AutomatedTurnLimitScope, type AutomatedTurnLimitUpdate } from "@/chat/services/automated-turn-limit";
10
+ /** Post the pause notice for one Conversation Location when known. */
11
+ export declare function postAutomatedTurnLimitNoticeForConversation(args: {
12
+ conversationId: string;
13
+ maxTurns: number;
14
+ nowMs?: number;
15
+ resumeIn?: "thread" | "channel";
16
+ scope?: AutomatedTurnLimitScope;
17
+ }): Promise<boolean>;
18
+ /** Post the pause notice for one Slack Destination. */
19
+ export declare function postAutomatedTurnLimitNoticeForDestination(args: {
20
+ destination: Destination;
21
+ maxTurns: number;
22
+ nowMs?: number;
23
+ resumeIn?: "thread" | "channel";
24
+ scope?: AutomatedTurnLimitScope;
25
+ threadTs?: string;
26
+ }): Promise<boolean>;
27
+ /**
28
+ * Post the pause notice after a finished Turn hits the limit.
29
+ * Prefer the Conversation Location so thread watches stay in-thread.
30
+ */
31
+ export declare function maybePostAutomatedTurnLimitNotice(args: {
32
+ conversationId: string;
33
+ destination?: Destination;
34
+ maxTurns: number;
35
+ nowMs?: number;
36
+ threadTs?: string;
37
+ update: AutomatedTurnLimitUpdate | undefined;
38
+ }): Promise<void>;
@@ -79,9 +79,10 @@ export declare function readTaskExecutions(args: {
79
79
  }): Promise<TaskExecutionRecord[]>;
80
80
  /** Load newest-first executions for the supplied viewer-visible tasks. */
81
81
  export declare function readTaskRuns(args: {
82
+ conversationIds?: string[];
82
83
  limit: number;
83
84
  namespace?: string;
84
- tasks: Array<{
85
+ tasks?: Array<{
85
86
  kind: TaskExecutionType;
86
87
  taskId: string;
87
88
  }>;
@@ -1,9 +1,12 @@
1
1
  import type { User } from "@sentry/junior-plugin-api";
2
2
  import type { ConversationSourceTask } from "@/api/schema/conversation";
3
3
  import type { TaskExecutionList, TaskList, TaskRunList } from "@/api/schema/task";
4
- /** Read viewer-owned and public-workspace tasks as one bounded newest-first projection. */
5
4
  export declare function readViewerTasks(user: User): Promise<TaskList>;
6
- /** Read newest runs across the viewer-visible scheduled and event tasks. */
5
+ /**
6
+ * Read newest runs across live viewer-visible tasks and deleted tasks the
7
+ * viewer owns. Deleted task rows stay available so history does not depend on
8
+ * conversation actor membership.
9
+ */
7
10
  export declare function readViewerTaskRuns(user: User): Promise<TaskRunList>;
8
11
  export declare class ViewerTaskNotFoundError extends Error {
9
12
  constructor();
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  pluginCatalogRuntime
3
- } from "./chunk-WWXJUURQ.js";
3
+ } from "./chunk-RKA22BQP.js";
4
4
 
5
5
  // src/chat/plugins/validation.ts
6
6
  import { isDeepStrictEqual } from "util";
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  getStateAdapter
3
- } from "./chunk-V4HXV5MY.js";
3
+ } from "./chunk-7MYXH5LA.js";
4
4
  import {
5
5
  getClient
6
6
  } from "./chunk-PEQXYSSE.js";