@sentry/junior 0.207.0 → 0.209.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 (49) hide show
  1. package/dist/{agent-CmQlX68D.js → agent-B_tHeZp6.js} +17 -17
  2. package/dist/{agent-hooks-BBX9p6aG.js → agent-hooks-DDJGkqlR.js} +129 -7
  3. package/dist/{agent-runner-CQD4HKK2.js → agent-runner-CPBSl1Xv.js} +5 -5
  4. package/dist/api.js +15 -15
  5. package/dist/app.js +29 -29
  6. package/dist/{auth-pause-state-uv8on6cT.js → auth-pause-state-BZqtr-GX.js} +6 -6
  7. package/dist/{briefs-BXEmjD9D.js → briefs-ZLRkWQQn.js} +2 -2
  8. package/dist/{catalog-runtime-1BZEOR8J.js → catalog-runtime-D89PJa84.js} +1 -1
  9. package/dist/{checkpoint-B-JO5F3c.js → checkpoint-DBX1KyOb.js} +6 -6
  10. package/dist/cli/chat.js +13 -13
  11. package/dist/cli/check.js +3 -3
  12. package/dist/cli/main.js +1 -1
  13. package/dist/cli/plugins.js +3 -3
  14. package/dist/cli/snapshot-create.js +3 -3
  15. package/dist/cli/upgrade.js +3 -3
  16. package/dist/{client-Bp297GA0.js → client-7_NmRtoz.js} +54 -6
  17. package/dist/{config-G2gv97R1.js → config-BPGL4uP-.js} +5 -5
  18. package/dist/{conversation-privacy-BUfel19D.js → conversation-privacy-CgtRvwq8.js} +1 -1
  19. package/dist/{credential-sync-D04NWqMR.js → credential-sync-DCYT7j8m.js} +20 -20
  20. package/dist/{execution-stats-Ds4bSvam.js → execution-stats-CyehCrCF.js} +4 -4
  21. package/dist/{executor-BZu1Ta06.js → executor-ctvBB7kO.js} +32 -3
  22. package/dist/instrumentation.js +2 -2
  23. package/dist/{job-queue-rnAPfUhP.js → job-queue-C1lIZ7DE.js} +1 -1
  24. package/dist/{logging-Dx0S5k2z.js → logging-CHzH6JFD.js} +1 -1
  25. package/dist/nitro.js +3 -3
  26. package/dist/{oauth-callback-server-xGpwURIj.js → oauth-callback-server-DQvCkP93.js} +2 -2
  27. package/dist/{pending-auth-DIZ4iZjS.js → pending-auth-D6c_jWmW.js} +2 -2
  28. package/dist/{profile-d-fKypxo.js → profile-DPAFjrER.js} +4 -4
  29. package/dist/{registry-CWKdLCTG.js → registry-vUqDWPNS.js} +1 -1
  30. package/dist/{resolve-BhRB1s2A.js → resolve-CToO52ls.js} +2 -2
  31. package/dist/{runner-DNml3owD.js → runner-D3KdCdDY.js} +9 -9
  32. package/dist/{sandbox-egress-signals-DUIl3-gW.js → sandbox-egress-signals-C_zy8cZG.js} +1 -1
  33. package/dist/{skills-D9WesdJJ.js → skills-BszTHE4F.js} +2 -2
  34. package/dist/{spawn-Eh_3-s0M.js → spawn-v7JJowIu.js} +2 -2
  35. package/dist/{stats-CFlUGqVA.js → stats-t0wuykQW.js} +39 -31
  36. package/dist/{task-queue-D8I1_5wP.js → task-queue-TyHaXCpO.js} +3 -3
  37. package/dist/{task-runner-DO79gdho.js → task-runner-DVDa7fAI.js} +7 -7
  38. package/dist/{thread-state-DD6BA4xz.js → thread-state-DB_913ic.js} +5 -5
  39. package/dist/{turn-execution-BSIHxmQJ.js → turn-execution-BRd4mQlB.js} +3 -3
  40. package/dist/{turn-lifecycle-DSBK4Ars.js → turn-lifecycle-CoNJoE-n.js} +1 -1
  41. package/dist/{usage-WRXkNOHp.js → usage-D5t1yT3R.js} +2 -2
  42. package/dist/{validation-BbHZ4r4S.js → validation-sI1EnNoM.js} +1 -1
  43. package/dist/{version-C71UcRWw.js → version-BrgX_LoI.js} +1 -1
  44. package/dist/version.js +1 -1
  45. package/dist/{web-authorization-C73gJV7l.js → web-authorization-BNCTTM5f.js} +1 -1
  46. package/dist/{web-input-Ce1FcNIM.js → web-input-NEbUfS0Q.js} +5 -107
  47. package/dist/{work-BEzDU_2x.js → work-Dv5SHQ4C.js} +9 -9
  48. package/dist/{worker-MK2ubOv-.js → worker-1GzySfPG.js} +15 -10
  49. package/package.json +6 -6
@@ -1,11 +1,11 @@
1
- import { F as isRecord$1, I as toOptionalNumber, L as toOptionalString } from "./logging-Dx0S5k2z.js";
2
- import { a as getChatConfig } from "./config-G2gv97R1.js";
1
+ import { F as isRecord$1, I as toOptionalNumber, L as toOptionalString } from "./logging-CHzH6JFD.js";
2
+ import { a as getChatConfig } from "./config-BPGL4uP-.js";
3
3
  import { _ as parseSlackMessageTs, d as parseStoredSlackActor, h as parseSlackTeamId, p as parseSlackChannelId } from "./context-Bplcgypl.js";
4
- import { Ft as getConversationStore, It as getDb, J as withSlackRetries, Qt as sameDestination, U as getSlackClient, Xt as parseDestination, pt as JUNIOR_THREAD_STATE_TTL_MS, u as getPlugins } from "./agent-hooks-BBX9p6aG.js";
4
+ import { Gt as getDb, J as withSlackRetries, U as getSlackClient, Wt as getConversationStore, an as parseDestination, pt as JUNIOR_THREAD_STATE_TTL_MS, sn as sameDestination, u as getPlugins } from "./agent-hooks-DDJGkqlR.js";
5
5
  import { n as juniorDestinations } from "./destinations-BeBiJeEM.js";
6
- import { S as juniorAttachments, a as juniorSchedulerRuns, c as juniorStats, l as juniorEventAutomations, o as juniorSchedulerTasks, w as juniorConversations } from "./executor-BZu1Ta06.js";
7
- import { o as ToolInputError } from "./usage-WRXkNOHp.js";
8
- import { C as getDefaultRedisStateAdapterFor, w as getStateAdapter } from "./profile-d-fKypxo.js";
6
+ import { S as juniorAttachments, a as juniorSchedulerRuns, c as juniorStats, l as juniorEventAutomations, o as juniorSchedulerTasks, w as juniorConversations } from "./executor-ctvBB7kO.js";
7
+ import { o as ToolInputError } from "./usage-D5t1yT3R.js";
8
+ import { C as getDefaultRedisStateAdapterFor, w as getStateAdapter } from "./profile-DPAFjrER.js";
9
9
  import "./vercel-queue-DIkVcfK4.js";
10
10
  import { z } from "zod";
11
11
  import { createHash, randomUUID } from "node:crypto";
@@ -138,6 +138,9 @@ const storedInboundMessageSchema = z.object({
138
138
  function conversationKey(conversationId) {
139
139
  return `${CONVERSATION_PREFIX}:${conversationId}`;
140
140
  }
141
+ function conversationStopKey(conversationId) {
142
+ return `${CONVERSATION_PREFIX}:stop:${conversationId}`;
143
+ }
141
144
  function indexLockKey(indexKey) {
142
145
  return `${indexKey}:lock`;
143
146
  }
@@ -249,8 +252,6 @@ function normalizeExecution(conversationId, value) {
249
252
  const inboundMessageIds = Array.isArray(value.inboundMessageIds) ? uniqueStrings(value.inboundMessageIds.map((id) => typeof id === "string" ? id : void 0).filter((id) => Boolean(id))) : [];
250
253
  const lease = normalizeLease(value.lease);
251
254
  const runId = toOptionalString(value.runId);
252
- const normalizedStop = normalizeStop(value.stop);
253
- const stop = normalizedStop?.runId === runId ? normalizedStop : void 0;
254
255
  return {
255
256
  status: status === "idle" && lease ? "running" : status === "idle" && pendingMessages.length > 0 ? "pending" : status,
256
257
  inboundMessageIds: uniqueStrings([...inboundMessageIds, ...pendingMessages.map((message) => message.inboundMessageId)]),
@@ -262,7 +263,6 @@ function normalizeExecution(conversationId, value) {
262
263
  lastProgressAtMs: toOptionalNumber(value.lastProgressAtMs),
263
264
  retryCount: toOptionalNumber(value.retryCount),
264
265
  runId,
265
- stop,
266
266
  updatedAtMs: toOptionalNumber(value.updatedAtMs)
267
267
  };
268
268
  }
@@ -577,7 +577,7 @@ async function writeConversation(state, lock, conversation) {
577
577
  ...conversation,
578
578
  execution
579
579
  };
580
- if (!await state.extendLock(lock, CONVERSATION_MUTATION_LOCK_TTL_MS)) throw new ConversationMutationFencedError(next.conversationId);
580
+ await fenceConversationMutation(state, lock, next.conversationId);
581
581
  const hasSlackDestination = next.destination?.platform === "slack";
582
582
  const stored = {
583
583
  ...next,
@@ -870,6 +870,16 @@ async function ackMessages$1(args) {
870
870
  function isHumanFacingMessage(message) {
871
871
  return message.source === "web" || message.source === "slack";
872
872
  }
873
+ async function readConversationStop(state, conversationId) {
874
+ return normalizeStop(await state.get(conversationStopKey(conversationId)));
875
+ }
876
+ async function fenceConversationMutation(state, lock, conversationId) {
877
+ if (!await state.extendLock(lock, CONVERSATION_MUTATION_LOCK_TTL_MS)) throw new ConversationMutationFencedError(conversationId);
878
+ }
879
+ /** Return whether one Conversation run has a durable stop request. */
880
+ async function hasConversationStop(args) {
881
+ return (await readConversationStop(await getConnectedState(args.state), args.conversationId))?.runId === args.runId;
882
+ }
873
883
  /** Persist a stop request for the current run without process affinity. */
874
884
  async function stopConversationWork$1(args) {
875
885
  const nowMs = args.nowMs ?? now$1();
@@ -878,14 +888,15 @@ async function stopConversationWork$1(args) {
878
888
  if (!current || !hasRunnableWork(current)) return { status: "no_work" };
879
889
  const runId = current.execution.runId ?? randomUUID();
880
890
  const inboundMessageIds = current.execution.pendingMessages.filter(isHumanFacingMessage).map((message) => message.inboundMessageId);
881
- await writeConversation(state, lock, withExecutionUpdate(current, {
891
+ if (current.execution.runId === void 0) await writeConversation(state, lock, withExecutionUpdate(current, {
882
892
  ...current.execution,
883
- runId,
884
- stop: {
885
- inboundMessageIds,
886
- runId
887
- }
893
+ runId
888
894
  }, nowMs));
895
+ await fenceConversationMutation(state, lock, args.conversationId);
896
+ await state.set(conversationStopKey(args.conversationId), {
897
+ inboundMessageIds,
898
+ runId
899
+ }, JUNIOR_THREAD_STATE_TTL_MS);
889
900
  return {
890
901
  runId,
891
902
  status: "requested"
@@ -901,7 +912,7 @@ async function completeConversationStop$1(args) {
901
912
  status: "lost_lease",
902
913
  removedInboundMessageIds: []
903
914
  };
904
- const stop = current.execution.stop;
915
+ const stop = await readConversationStop(state, args.conversationId);
905
916
  if (!stop || stop.runId !== args.runId) return {
906
917
  status: "none",
907
918
  removedInboundMessageIds: []
@@ -916,9 +927,10 @@ async function completeConversationStop$1(args) {
916
927
  await writeConversation(state, lock, withExecutionUpdate(current, {
917
928
  ...current.execution,
918
929
  lastEnqueuedAtMs: pendingMessages.length === 0 ? void 0 : current.execution.lastEnqueuedAtMs,
919
- pendingMessages,
920
- stop: void 0
930
+ pendingMessages
921
931
  }, nowMs));
932
+ await fenceConversationMutation(state, lock, args.conversationId);
933
+ await state.delete(conversationStopKey(args.conversationId));
922
934
  return {
923
935
  status: "cleared",
924
936
  removedInboundMessageIds
@@ -951,8 +963,7 @@ async function cancelHumanFacingPendingMessages$1(args) {
951
963
  pendingMessages,
952
964
  retryCount: becomesIdle ? 0 : current.execution.retryCount,
953
965
  runId: becomesIdle ? void 0 : current.execution.runId,
954
- status: becomesIdle ? "idle" : current.execution.status,
955
- stop: becomesIdle ? void 0 : current.execution.stop
966
+ status: becomesIdle ? "idle" : current.execution.status
956
967
  }, nowMs));
957
968
  return { cancelledInboundMessageIds };
958
969
  });
@@ -1017,8 +1028,7 @@ async function recordConversationRetry$1(args) {
1017
1028
  retryCount: count,
1018
1029
  pendingMessages: stopped ? [] : current.execution.pendingMessages,
1019
1030
  runId: stopped ? void 0 : current.execution.runId,
1020
- status: stopped ? "failed" : "paused",
1021
- stop: stopped ? void 0 : current.execution.stop
1031
+ status: stopped ? "failed" : "paused"
1022
1032
  }, nowMs));
1023
1033
  return stopped ? "stopped" : "recorded";
1024
1034
  });
@@ -1030,7 +1040,8 @@ async function completeConversationWork$1(args) {
1030
1040
  const current = await readConversation(state, args.conversationId);
1031
1041
  if (!current || current.execution.lease?.token !== args.leaseToken) return "lost_lease";
1032
1042
  const hasPending = pendingMessages(current).length > 0;
1033
- const needsRun = current.execution.status === "paused" || args.resumeIfStopped === true && current.execution.stop !== void 0;
1043
+ const stopped = args.resumeIfStopped === true && (await readConversationStop(state, args.conversationId))?.runId === current.execution.runId;
1044
+ const needsRun = current.execution.status === "paused" || stopped;
1034
1045
  const runnable = needsRun || hasPending;
1035
1046
  await writeConversation(state, lock, withExecutionUpdate(current, {
1036
1047
  ...current.execution,
@@ -1038,8 +1049,7 @@ async function completeConversationWork$1(args) {
1038
1049
  status: needsRun ? "paused" : hasPending ? "pending" : "idle",
1039
1050
  lastProgressAtMs: args.madeProgress === false ? current.execution.lastProgressAtMs : nowMs,
1040
1051
  retryCount: runnable || args.madeProgress === false ? current.execution.retryCount : 0,
1041
- runId: runnable ? current.execution.runId : void 0,
1042
- stop: runnable ? current.execution.stop : void 0
1052
+ runId: runnable ? current.execution.runId : void 0
1043
1053
  }, nowMs));
1044
1054
  return runnable ? "pending" : "completed";
1045
1055
  });
@@ -1116,8 +1126,7 @@ async function deadLetterAttempt$1(args) {
1116
1126
  ...current.execution,
1117
1127
  lease: void 0,
1118
1128
  status: runnable ? "pending" : "failed",
1119
- runId: runnable ? current.execution.runId : void 0,
1120
- stop: runnable ? current.execution.stop : void 0
1129
+ runId: runnable ? current.execution.runId : void 0
1121
1130
  }, nowMs));
1122
1131
  return runnable ? "pending" : "failed";
1123
1132
  });
@@ -1137,8 +1146,7 @@ async function clearExpiredConversationLease$1(args) {
1137
1146
  retryCount,
1138
1147
  pendingMessages: stopped ? [] : current.execution.pendingMessages,
1139
1148
  runId: stopped ? void 0 : current.execution.runId,
1140
- status: stopped ? "failed" : "paused",
1141
- stop: stopped ? void 0 : current.execution.stop
1149
+ status: stopped ? "failed" : "paused"
1142
1150
  }, nowMs));
1143
1151
  return stopped ? "stopped" : "requeued";
1144
1152
  });
@@ -2669,4 +2677,4 @@ async function readStats(start, end) {
2669
2677
  return await getDb().select().from(juniorStats).where(and(gte(juniorStats.date, start), lte(juniorStats.date, end))).orderBy(asc(juniorStats.date), asc(juniorStats.namespace), asc(juniorStats.metric), asc(juniorStats.name));
2670
2678
  }
2671
2679
  //#endregion
2672
- export { workspaceSnapshotFinishedEvent as $, eventAutomationTriggerAvailable as A, recordConversationRetry as At, createEventAutomation as B, isFinalAttempt as Bt, SCHEDULED_AUTOMATION_SYSTEM_ACTOR as C, drainConversationMailbox as Ct, eventAutomationMatchesDestination as D, hasRunnableConversationWork as Dt, eventAutomationListToolResultSchema as E, getConversationWorkState as Et, effectiveTaskOutcomes as F, startConversationWork as Ft, listDeletedEventAutomationsCreatedBy as G, buildDeterministicAssistantMessageId as Gt, eventAutomationBelongsToUser as H, injectContinuationToolName as Ht, moveTaskOutcomes as I, stopConversationWork as It, listPublicEventAutomationsForTeams as J, listEventAutomationsCreatedBy as K, buildDeterministicTurnId as Kt, resolveTaskOutcomes as L, CONVERSATION_WORK_CHECK_IN_INTERVAL_MS as Lt, requireEventAutomationSlackContext as M, removeActiveConversation as Mt, requireSupportedEventAutomationTrigger as N, requestAnotherSlice as Nt, eventAutomationToolResult as O, listActiveConversationIds as Ot, writableEventAutomation as P, requestConversationWork as Pt, WORKSPACE_SNAPSHOT_READY_EVENT as Q, taskOutcomeInputSchema as R, CONVERSATION_WORK_STALE_ENQUEUE_MS as Rt, withScheduledAutomationLock as S, deadLetterAttempt as St, compactEventAutomation as T, getConversation as Tt, findMatchingEventAutomations as U, juniorToolOutputSchema as Ut, deleteEventAutomation as V, isInvalidConversationRecordError as Vt, getEventAutomation as W, makeStructuredToolOutput as Wt, getEventCatalog as X, saveEventAutomation as Y, WORKSPACE_SNAPSHOT_FAILED_EVENT as Z, parseScheduledAutomationRow as _, clearConsumedConversationWake as _t, requestAttachmentDeletion as a, normalizeCatalogEventIdentifier as at, saveScheduledAutomationInLock as b, completeConversationWork as bt, parseSlackThreadId as c, registeredEventTypeSchema as ct, resolveSlackChannelIdFromThreadId as d, ackMessages as dt, workspaceSnapshotWatch as et, createScheduledAutomation as f, appendAndEnqueueExclusiveInboundMessage as ft, listScheduledAutomationsForTeam as g, checkInConversationWork as gt, listScheduledAutomations as h, cancelHumanFacingPendingMessages as ht, readLiveAttachment as i, hasPluginEventCatalogEntries as it, registeredEventAutomationTriggerSchema as j, releaseConversationWork as jt, eventAutomationToolResultSchema as k, recordAttemptFailure as kt, readSlackRawMessageContext as l, registeredResourceTypeSchema as lt, listPublicScheduledAutomationsForTeams as m, beginConversationResume as mt, readStats as n, eventNamespaceSchema as nt, storeAttachment as o, pluginSupportsEvent as ot, isListedScheduledAutomation as p, appendAndEnqueueInboundMessage as pt, listEventAutomationsForTeam as q, collectAttachmentGarbage as r, hasEventCatalogEntries as rt, storeAttachments as s, registeredEventMatchSchema as st, incrementStat as t, eventGuidance as tt, resolveSlackChannelIdFromMessage as u, requireSupportedEventMatch as ut, readScheduledAutomation as v, clearExpiredConversationLease as vt, scheduledRunSchema as w, ensureConversationWake as wt, scheduledRunId as x, countPendingConversationMessages as xt, saveScheduledAutomation as y, completeConversationStop as yt, collectEventAutomationMatchKeys as z, hasRunnableConversationWork$1 as zt };
2680
+ export { workspaceSnapshotFinishedEvent as $, eventAutomationTriggerAvailable as A, recordConversationRetry as At, createEventAutomation as B, hasRunnableConversationWork$1 as Bt, SCHEDULED_AUTOMATION_SYSTEM_ACTOR as C, drainConversationMailbox as Ct, eventAutomationMatchesDestination as D, hasRunnableConversationWork as Dt, eventAutomationListToolResultSchema as E, getConversationWorkState as Et, effectiveTaskOutcomes as F, startConversationWork as Ft, listDeletedEventAutomationsCreatedBy as G, makeStructuredToolOutput as Gt, eventAutomationBelongsToUser as H, isInvalidConversationRecordError as Ht, moveTaskOutcomes as I, stopConversationWork as It, listPublicEventAutomationsForTeams as J, listEventAutomationsCreatedBy as K, buildDeterministicAssistantMessageId as Kt, resolveTaskOutcomes as L, CONVERSATION_WORK_CHECK_IN_INTERVAL_MS as Lt, requireEventAutomationSlackContext as M, removeActiveConversation as Mt, requireSupportedEventAutomationTrigger as N, requestAnotherSlice as Nt, eventAutomationToolResult as O, listActiveConversationIds as Ot, writableEventAutomation as P, requestConversationWork as Pt, WORKSPACE_SNAPSHOT_READY_EVENT as Q, taskOutcomeInputSchema as R, CONVERSATION_WORK_STALE_ENQUEUE_MS as Rt, withScheduledAutomationLock as S, deadLetterAttempt as St, compactEventAutomation as T, getConversation as Tt, findMatchingEventAutomations as U, injectContinuationToolName as Ut, deleteEventAutomation as V, isFinalAttempt as Vt, getEventAutomation as W, juniorToolOutputSchema as Wt, getEventCatalog as X, saveEventAutomation as Y, WORKSPACE_SNAPSHOT_FAILED_EVENT as Z, parseScheduledAutomationRow as _, clearConsumedConversationWake as _t, requestAttachmentDeletion as a, normalizeCatalogEventIdentifier as at, saveScheduledAutomationInLock as b, completeConversationWork as bt, parseSlackThreadId as c, registeredEventTypeSchema as ct, resolveSlackChannelIdFromThreadId as d, ackMessages as dt, workspaceSnapshotWatch as et, createScheduledAutomation as f, appendAndEnqueueExclusiveInboundMessage as ft, listScheduledAutomationsForTeam as g, checkInConversationWork as gt, listScheduledAutomations as h, cancelHumanFacingPendingMessages as ht, readLiveAttachment as i, hasPluginEventCatalogEntries as it, registeredEventAutomationTriggerSchema as j, releaseConversationWork as jt, eventAutomationToolResultSchema as k, recordAttemptFailure as kt, readSlackRawMessageContext as l, registeredResourceTypeSchema as lt, listPublicScheduledAutomationsForTeams as m, beginConversationResume as mt, readStats as n, eventNamespaceSchema as nt, storeAttachment as o, pluginSupportsEvent as ot, isListedScheduledAutomation as p, appendAndEnqueueInboundMessage as pt, listEventAutomationsForTeam as q, buildDeterministicTurnId as qt, collectAttachmentGarbage as r, hasEventCatalogEntries as rt, storeAttachments as s, registeredEventMatchSchema as st, incrementStat as t, eventGuidance as tt, resolveSlackChannelIdFromMessage as u, requireSupportedEventMatch as ut, readScheduledAutomation as v, clearExpiredConversationLease as vt, scheduledRunSchema as w, ensureConversationWake as wt, scheduledRunId as x, countPendingConversationMessages as xt, saveScheduledAutomation as y, completeConversationStop as yt, collectEventAutomationMatchKeys as z, hasConversationStop as zt };
@@ -1,6 +1,6 @@
1
- import { f as logWarn } from "./logging-Dx0S5k2z.js";
1
+ import { f as logWarn } from "./logging-CHzH6JFD.js";
2
2
  import { a as signQueueMessage, i as QUEUE_SIGNATURE_MAX_AGE_MS, o as verifyQueueMessage, s as createVercelQueueClient } from "./vercel-queue-DIkVcfK4.js";
3
- import { o as runWithTurnRequestDeadline } from "./job-queue-rnAPfUhP.js";
3
+ import { o as runWithTurnRequestDeadline } from "./job-queue-C1lIZ7DE.js";
4
4
  import { z } from "zod";
5
5
  import { createHash } from "node:crypto";
6
6
  import { handleCallback, registerDevConsumer } from "@vercel/queue";
@@ -110,7 +110,7 @@ function pluginTaskCallback() {
110
110
  maxDeliveries: PLUGIN_TASK_MAX_DELIVERIES,
111
111
  onRejected: logPluginTaskQueueMessageRejected,
112
112
  run: async (message) => {
113
- const { processPluginTask } = await import("./task-runner-DO79gdho.js").then((n) => n.r);
113
+ const { processPluginTask } = await import("./task-runner-DVDa7fAI.js").then((n) => n.r);
114
114
  await processPluginTask(message);
115
115
  },
116
116
  topic: PLUGIN_TASK_QUEUE_TOPIC,
@@ -1,12 +1,12 @@
1
1
  import { t as __exportAll } from "./rolldown-runtime-B4FMCO8f.js";
2
2
  import { _ as parseSlackMessageTs, r as credentialSubjectSchema } from "./context-Bplcgypl.js";
3
- import { Ft as getConversationStore, It as getDb, Q as readActorIdentity, _t as createPluginState, bt as createPluginLogger, p as coreTaskRegistrations, pt as JUNIOR_THREAD_STATE_TTL_MS, u as getPlugins, vt as createPluginEmbedder, xt as createPluginConversationEvents, yt as createPluginModel } from "./agent-hooks-BBX9p6aG.js";
3
+ import { At as createPluginConversationEvents, Gt as getDb, Q as readActorIdentity, Wt as getConversationStore, _t as createPluginState, bt as createPluginLogger, p as coreTaskRegistrations, pt as JUNIOR_THREAD_STATE_TTL_MS, u as getPlugins, vt as createPluginEmbedder, yt as createPluginModel } from "./agent-hooks-DDJGkqlR.js";
4
4
  import { K as sameActorIdentity } from "./conversation-AA4R1VUn.js";
5
- import { Dt as isToolResultError, Ot as isToolResultMessage, Q as hydrateConversationMessages, bt as getPiMessageRole, jt as stripRuntimeTurnContext, kt as normalizeToolNameFromResult, s as getTurnRecord, wt as instructionTextForProjection } from "./checkpoint-B-JO5F3c.js";
6
- import { w as getStateAdapter } from "./profile-d-fKypxo.js";
7
- import { u as recordAutomationExecution } from "./execution-stats-Ds4bSvam.js";
8
- import { r as getPersistedThreadState, s as coerceThreadConversationState } from "./thread-state-DD6BA4xz.js";
9
- import { i as pluginTaskParamsSchema, o as sendVercelPluginTask, r as pluginTaskId } from "./task-queue-D8I1_5wP.js";
5
+ import { Dt as isToolResultError, Ot as isToolResultMessage, Q as hydrateConversationMessages, bt as getPiMessageRole, jt as stripRuntimeTurnContext, kt as normalizeToolNameFromResult, s as getTurnRecord, wt as instructionTextForProjection } from "./checkpoint-DBX1KyOb.js";
6
+ import { w as getStateAdapter } from "./profile-DPAFjrER.js";
7
+ import { u as recordAutomationExecution } from "./execution-stats-CyehCrCF.js";
8
+ import { r as getPersistedThreadState, s as coerceThreadConversationState } from "./thread-state-DB_913ic.js";
9
+ import { i as pluginTaskParamsSchema, o as sendVercelPluginTask, r as pluginTaskId } from "./task-queue-TyHaXCpO.js";
10
10
  import { z } from "zod";
11
11
  import { createHash } from "node:crypto";
12
12
  import { destinationSchema, destinationVisibilitySchema, isSlackDestination, pluginRunContextSchema, replyAttributionSchema, sourceSchema, taskOutcomeSchema } from "@sentry/junior-plugin-api";
@@ -345,7 +345,7 @@ function slackSourceForDestination(args) {
345
345
  * Reads parent Conversations when this Conversation has no Destination.
346
346
  */
347
347
  async function resolveConversationRouting(args) {
348
- const conversationStore = args.conversationStore ?? (await import("./agent-hooks-BBX9p6aG.js").then((n) => n.Mt)).getConversationStore();
348
+ const conversationStore = args.conversationStore ?? (await import("./agent-hooks-DDJGkqlR.js").then((n) => n.Vt)).getConversationStore();
349
349
  const chain = await loadConversationChain(args.conversationId, conversationStore);
350
350
  let destination;
351
351
  let source;
@@ -1,9 +1,9 @@
1
- import { F as isRecord, I as toOptionalNumber, L as toOptionalString } from "./logging-Dx0S5k2z.js";
2
- import { It as getDb, pt as JUNIOR_THREAD_STATE_TTL_MS } from "./agent-hooks-BBX9p6aG.js";
1
+ import { F as isRecord, I as toOptionalNumber, L as toOptionalString } from "./logging-CHzH6JFD.js";
2
+ import { Gt as getDb, pt as JUNIOR_THREAD_STATE_TTL_MS } from "./agent-hooks-DDJGkqlR.js";
3
3
  import { n as juniorDestinations } from "./destinations-BeBiJeEM.js";
4
- import { u as juniorLocationConfigurations } from "./executor-BZu1Ta06.js";
5
- import { $ as persistConversationMessages } from "./checkpoint-B-JO5F3c.js";
6
- import { w as getStateAdapter } from "./profile-d-fKypxo.js";
4
+ import { u as juniorLocationConfigurations } from "./executor-ctvBB7kO.js";
5
+ import { $ as persistConversationMessages } from "./checkpoint-DBX1KyOb.js";
6
+ import { w as getStateAdapter } from "./profile-DPAFjrER.js";
7
7
  import { z } from "zod";
8
8
  import { randomUUID } from "node:crypto";
9
9
  import { and, eq, sql } from "drizzle-orm";
@@ -1,6 +1,6 @@
1
- import { Nt as getConversationEventStore } from "./agent-hooks-BBX9p6aG.js";
2
- import { n as runAgentWithTimeout } from "./agent-runner-CQD4HKK2.js";
3
- import { t as ConversationTurnLifecycleService } from "./turn-lifecycle-DSBK4Ars.js";
1
+ import { Ht as getConversationEventStore } from "./agent-hooks-DDJGkqlR.js";
2
+ import { n as runAgentWithTimeout } from "./agent-runner-CPBSl1Xv.js";
3
+ import { t as ConversationTurnLifecycleService } from "./turn-lifecycle-CoNJoE-n.js";
4
4
  //#region src/chat/runtime/turn-execution.ts
5
5
  /** An error thrown while the agent advances a Run. */
6
6
  var AgentRunError = class extends Error {
@@ -1,4 +1,4 @@
1
- import { Nt as getConversationEventStore } from "./agent-hooks-BBX9p6aG.js";
1
+ import { Ht as getConversationEventStore } from "./agent-hooks-DDJGkqlR.js";
2
2
  //#region src/chat/conversations/turn-lifecycle.ts
3
3
  /** Persist correlated turn lifecycle facts with retry-safe terminal exclusion. */
4
4
  var ConversationTurnLifecycleService = class {
@@ -1,5 +1,5 @@
1
- import { f as logWarn } from "./logging-Dx0S5k2z.js";
2
- import { n as botConfig } from "./config-G2gv97R1.js";
1
+ import { f as logWarn } from "./logging-CHzH6JFD.js";
2
+ import { n as botConfig } from "./config-BPGL4uP-.js";
3
3
  import { P as usageSchema } from "./conversation-AA4R1VUn.js";
4
4
  const TITLE_PROMPTS = {
5
5
  conversation: [
@@ -1,5 +1,5 @@
1
1
  import { t as __exportAll } from "./rolldown-runtime-B4FMCO8f.js";
2
- import { n as pluginCatalogRuntime } from "./catalog-runtime-1BZEOR8J.js";
2
+ import { n as pluginCatalogRuntime } from "./catalog-runtime-D89PJa84.js";
3
3
  import { isDeepStrictEqual } from "node:util";
4
4
  //#region src/chat/plugins/validation.ts
5
5
  var validation_exports = /* @__PURE__ */ __exportAll({
@@ -1,5 +1,5 @@
1
1
  //#region package.json
2
- var version = "0.207.0";
2
+ var version = "0.209.0";
3
3
  //#endregion
4
4
  //#region src/version.ts
5
5
  /** Installed Junior package version, or `unknown` when package metadata is unavailable. */
package/dist/version.js CHANGED
@@ -1,2 +1,2 @@
1
- import { t as JUNIOR_VERSION } from "./version-C71UcRWw.js";
1
+ import { t as JUNIOR_VERSION } from "./version-BrgX_LoI.js";
2
2
  export { JUNIOR_VERSION };
@@ -1,4 +1,4 @@
1
- import { w as getStateAdapter } from "./profile-d-fKypxo.js";
1
+ import { w as getStateAdapter } from "./profile-DPAFjrER.js";
2
2
  import { randomUUID } from "node:crypto";
3
3
  //#region src/chat/conversations/web-authorization.ts
4
4
  const WEB_AUTHORIZATION_PREFIX = "junior:web_authorization:v1";
@@ -1,17 +1,12 @@
1
- import { f as logWarn } from "./logging-Dx0S5k2z.js";
2
- import { t as canExposeConversationPayload } from "./conversation-privacy-BUfel19D.js";
3
- import { s as getSlackBotToken } from "./config-G2gv97R1.js";
1
+ import { f as logWarn } from "./logging-CHzH6JFD.js";
2
+ import { s as getSlackBotToken } from "./config-BPGL4uP-.js";
4
3
  import "./context-Bplcgypl.js";
5
- import { Ft as getConversationStore, It as getDb, K as normalizeSlackConversationId } from "./agent-hooks-BBX9p6aG.js";
6
- import { n as juniorDestinations } from "./destinations-BeBiJeEM.js";
7
- import { E as juniorUsers, T as juniorIdentities, m as juniorConversationParticipants, w as juniorConversations } from "./executor-BZu1Ta06.js";
8
- import { Kt as buildDeterministicTurnId, c as parseSlackThreadId, ft as appendAndEnqueueExclusiveInboundMessage, pt as appendAndEnqueueInboundMessage } from "./stats-CFlUGqVA.js";
4
+ import { K as normalizeSlackConversationId, Wt as getConversationStore } from "./agent-hooks-DDJGkqlR.js";
5
+ import { c as parseSlackThreadId, ft as appendAndEnqueueExclusiveInboundMessage, pt as appendAndEnqueueInboundMessage, qt as buildDeterministicTurnId } from "./stats-t0wuykQW.js";
9
6
  import { t as healthReportSchema } from "./reporting-schema-DosTN__Q.js";
10
7
  import { z } from "zod";
11
8
  import { createHash } from "node:crypto";
12
- import { and, eq, exists, gte, inArray, isNotNull, notExists, or } from "drizzle-orm";
13
9
  import { createWebSource, localDestinationSchema } from "@sentry/junior-plugin-api";
14
- import { alias } from "drizzle-orm/pg-core";
15
10
  import { del, get, put } from "@vercel/blob";
16
11
  //#region src/handlers/health.ts
17
12
  /** Build Junior's process health value for HTTP and reporting consumers. */
@@ -234,103 +229,6 @@ function resolveConversationDestination(args) {
234
229
  return args.existing ?? requireLocalDestination(args.conversationId);
235
230
  }
236
231
  //#endregion
237
- //#region src/api/conversations/membership.ts
238
- /** True when the viewer is a materialized participant on this root conversation. */
239
- function conversationHasParticipantUser(userId) {
240
- const participant = getDb().select({ rootConversationId: juniorConversationParticipants.rootConversationId }).from(juniorConversationParticipants).where(and(eq(juniorConversationParticipants.rootConversationId, juniorConversations.conversationId), eq(juniorConversationParticipants.userId, userId)));
241
- return exists(participant);
242
- }
243
- /**
244
- * True when a verified primary-email user participates on this root
245
- * conversation. Used only for the actorEmail feed fallback.
246
- */
247
- function conversationHasParticipantEmail(email) {
248
- const participant = getDb().select({ rootConversationId: juniorConversationParticipants.rootConversationId }).from(juniorConversationParticipants).innerJoin(juniorUsers, eq(juniorUsers.id, juniorConversationParticipants.userId)).where(and(eq(juniorConversationParticipants.rootConversationId, juniorConversations.conversationId), eq(juniorUsers.primaryEmailNormalized, email)));
249
- return exists(participant);
250
- }
251
- /** True when one user's personal feed has archived this root after the cutoff. */
252
- function conversationArchivedForUser(userId, archivedAfter) {
253
- const archive = getDb().select({ rootConversationId: juniorConversationParticipants.rootConversationId }).from(juniorConversationParticipants).where(and(eq(juniorConversationParticipants.rootConversationId, juniorConversations.conversationId), eq(juniorConversationParticipants.userId, userId), isNotNull(juniorConversationParticipants.archivedAt), archivedAfter ? gte(juniorConversationParticipants.archivedAt, archivedAfter) : void 0));
254
- return exists(archive);
255
- }
256
- /** True when one user's personal feed has not archived this root. */
257
- function conversationNotArchivedForUser(userId) {
258
- const archive = getDb().select({ rootConversationId: juniorConversationParticipants.rootConversationId }).from(juniorConversationParticipants).where(and(eq(juniorConversationParticipants.rootConversationId, juniorConversations.conversationId), eq(juniorConversationParticipants.userId, userId), isNotNull(juniorConversationParticipants.archivedAt)));
259
- return notExists(archive);
260
- }
261
- /** True when one primary-email user's feed archived this root after the cutoff. */
262
- function conversationArchivedForEmail(email, archivedAfter) {
263
- const archive = getDb().select({ rootConversationId: juniorConversationParticipants.rootConversationId }).from(juniorConversationParticipants).innerJoin(juniorUsers, eq(juniorUsers.id, juniorConversationParticipants.userId)).where(and(eq(juniorConversationParticipants.rootConversationId, juniorConversations.conversationId), eq(juniorUsers.primaryEmailNormalized, email), isNotNull(juniorConversationParticipants.archivedAt), archivedAfter ? gte(juniorConversationParticipants.archivedAt, archivedAfter) : void 0));
264
- return exists(archive);
265
- }
266
- /** True when one primary-email user's personal feed has not archived this root. */
267
- function conversationNotArchivedForEmail(email) {
268
- const archive = getDb().select({ rootConversationId: juniorConversationParticipants.rootConversationId }).from(juniorConversationParticipants).innerJoin(juniorUsers, eq(juniorUsers.id, juniorConversationParticipants.userId)).where(and(eq(juniorConversationParticipants.rootConversationId, juniorConversations.conversationId), eq(juniorUsers.primaryEmailNormalized, email), isNotNull(juniorConversationParticipants.archivedAt)));
269
- return notExists(archive);
270
- }
271
- /** Root-actor ownership or a materialized participant row for the same person. */
272
- function viewerConversationMembership(args) {
273
- if (args.actorMatch && args.participantMatch) return or(args.actorMatch, args.participantMatch);
274
- return args.actorMatch ?? args.participantMatch;
275
- }
276
- /** Read personal archive timestamps for a bounded set of conversation roots. */
277
- async function conversationArchiveTimes(db, conversationIds, subject) {
278
- if (!subject || conversationIds.length === 0) return /* @__PURE__ */ new Map();
279
- const query = db.select({
280
- archivedAt: juniorConversationParticipants.archivedAt,
281
- rootConversationId: juniorConversationParticipants.rootConversationId
282
- }).from(juniorConversationParticipants);
283
- const rows = "userId" in subject ? await query.where(and(eq(juniorConversationParticipants.userId, subject.userId), inArray(juniorConversationParticipants.rootConversationId, [...conversationIds]), isNotNull(juniorConversationParticipants.archivedAt))) : await query.innerJoin(juniorUsers, eq(juniorUsers.id, juniorConversationParticipants.userId)).where(and(eq(juniorUsers.primaryEmailNormalized, subject.email), inArray(juniorConversationParticipants.rootConversationId, [...conversationIds]), isNotNull(juniorConversationParticipants.archivedAt)));
284
- return new Map(rows.flatMap((row) => row.archivedAt ? [[row.rootConversationId, row.archivedAt.getTime()]] : []));
285
- }
286
- /** Find which of the supplied roots include the linked viewer as a participant. */
287
- async function conversationIdsWithParticipantUser(db, conversationIds, userId) {
288
- if (conversationIds.length === 0) return /* @__PURE__ */ new Set();
289
- const rows = await db.select({ rootConversationId: juniorConversationParticipants.rootConversationId }).from(juniorConversationParticipants).where(and(eq(juniorConversationParticipants.userId, userId), inArray(juniorConversationParticipants.rootConversationId, [...conversationIds])));
290
- return new Set(rows.map((row) => row.rootConversationId));
291
- }
292
- //#endregion
293
- //#region src/api/conversations/access.ts
294
- const rootConversation = alias(juniorConversations, "access_root_conversation");
295
- const rootDestination = alias(juniorDestinations, "access_root_destination");
296
- const rootIdentity = alias(juniorIdentities, "access_root_identity");
297
- /** Resolve viewer access for a bounded set of persisted conversations. */
298
- async function readConversationAccessFromSql(db, conversationIds, viewer) {
299
- if (conversationIds.length === 0) return /* @__PURE__ */ new Map();
300
- const normalizedViewerEmail = viewer?.email.trim().toLowerCase() || void 0;
301
- const rows = await db.select({
302
- conversationId: juniorConversations.conversationId,
303
- parentConversationId: juniorConversations.parentConversationId,
304
- storedRootConversationId: juniorConversations.rootConversationId,
305
- rootConversationId: rootConversation.conversationId,
306
- rootParentConversationId: rootConversation.parentConversationId,
307
- rootRootConversationId: rootConversation.rootConversationId,
308
- visibility: rootDestination.visibility,
309
- rootEmailNormalized: rootIdentity.emailNormalized,
310
- rootEmailVerified: rootIdentity.emailVerified,
311
- rootUserId: rootIdentity.userId
312
- }).from(juniorConversations).leftJoin(rootConversation, eq(rootConversation.conversationId, juniorConversations.rootConversationId)).leftJoin(rootDestination, eq(rootDestination.id, rootConversation.destinationId)).leftJoin(rootIdentity, eq(rootIdentity.id, rootConversation.actorIdentityId)).where(inArray(juniorConversations.conversationId, [...conversationIds]));
313
- const membershipConversationIds = /* @__PURE__ */ new Set();
314
- for (const row of rows) {
315
- membershipConversationIds.add(row.conversationId);
316
- if (row.storedRootConversationId) membershipConversationIds.add(row.storedRootConversationId);
317
- }
318
- const participantRootIds = viewer !== void 0 ? await conversationIdsWithParticipantUser(db, [...membershipConversationIds], viewer.id) : /* @__PURE__ */ new Set();
319
- return new Map(rows.map((row) => {
320
- const validRootConversationId = row.rootConversationId !== null && row.rootConversationId === row.storedRootConversationId && row.rootRootConversationId === row.rootConversationId && row.rootParentConversationId === null && (row.parentConversationId !== null || row.storedRootConversationId === row.conversationId) ? row.rootConversationId ?? void 0 : void 0;
321
- const visibility = validRootConversationId === void 0 ? null : row.visibility;
322
- const isRootActor = validRootConversationId !== void 0 && viewer !== void 0 && (row.rootUserId === viewer.id || normalizedViewerEmail !== void 0 && row.rootEmailVerified === true && row.rootEmailNormalized === normalizedViewerEmail);
323
- const isMaterializedParticipant = participantRootIds.has(row.conversationId) || validRootConversationId !== void 0 && participantRootIds.has(validRootConversationId);
324
- const isParticipant = isRootActor || isMaterializedParticipant;
325
- const canViewPrivateContent = isParticipant || validRootConversationId !== void 0 && canExposeConversationPayload({ visibility: visibility ?? void 0 });
326
- return [row.conversationId, {
327
- canViewPrivateContent,
328
- isParticipant,
329
- visibility
330
- }];
331
- }));
332
- }
333
- //#endregion
334
232
  //#region src/chat/conversations/web-input.ts
335
233
  /** Store web input in a Conversation mailbox. */
336
234
  function normalizeEmail(email) {
@@ -491,4 +389,4 @@ async function appendAndEnqueueWebMessage(input, options) {
491
389
  };
492
390
  }
493
391
  //#endregion
494
- export { createVercelAttachmentStorage as C, legacyWebMailboxMetadataSchema as S, readHealthReport as T, formatSlackConversationRedactedLabel as _, webActorFromEmail as a, resolveSlackConversationContextFromThreadId as b, conversationArchivedForEmail as c, conversationHasParticipantUser as d, conversationNotArchivedForEmail as f, conversationVisibilityFromSlackChannelType as g, resolveConversationDestination as h, recordWebConversationActivity as i, conversationArchivedForUser as l, viewerConversationMembership as m, conversationTurnIdForMessage as n, readConversationAccessFromSql as o, conversationNotArchivedForUser as p, createAndEnqueueConversation as r, conversationArchiveTimes as s, appendAndEnqueueWebMessage as t, conversationHasParticipantEmail as u, resolveSlackChannelTypeFromMessage as v, GET as w, lookupSlackUser as x, resolveSlackConversationContext as y };
392
+ export { webActorFromEmail as a, formatSlackConversationRedactedLabel as c, resolveSlackConversationContextFromThreadId as d, lookupSlackUser as f, readHealthReport as g, GET as h, recordWebConversationActivity as i, resolveSlackChannelTypeFromMessage as l, createVercelAttachmentStorage as m, conversationTurnIdForMessage as n, resolveConversationDestination as o, legacyWebMailboxMetadataSchema as p, createAndEnqueueConversation as r, conversationVisibilityFromSlackChannelType as s, appendAndEnqueueWebMessage as t, resolveSlackConversationContext as u };
@@ -1,13 +1,13 @@
1
1
  import { t as __exportAll } from "./rolldown-runtime-B4FMCO8f.js";
2
- import { A as createAgentInvocationSchema, M as AgentInvocationLimitError, O as agentBindingSchema, Q as AuthorizationFlowDisabledError, f as PluginCredentialFailureError, j as AgentInvocationBusyError, k as agentInvocationSchema } from "./agent-CmQlX68D.js";
3
- import { Ft as getConversationStore, Lt as getSqlExecutor, Nt as getConversationEventStore } from "./agent-hooks-BBX9p6aG.js";
4
- import { f as juniorAgentBindings, p as juniorAgentInvocations } from "./executor-BZu1Ta06.js";
5
- import { B as openConversationProjection, o as failTurnRecord, r as saveTurnCheckpoint, s as getTurnRecord, xt as getTerminalAssistantMessages } from "./checkpoint-B-JO5F3c.js";
6
- import { pt as appendAndEnqueueInboundMessage } from "./stats-CFlUGqVA.js";
7
- import { _ as isTurnInputCommitLostError, h as getConversationTurnBoundaryError, p as TurnInputCommitLostError, s as getAssistantReplyText } from "./pending-auth-DIZ4iZjS.js";
8
- import { t as ConversationTurnLifecycleService } from "./turn-lifecycle-DSBK4Ars.js";
9
- import { n as executeTurn, t as AgentRunError } from "./turn-execution-BSIHxmQJ.js";
10
- import { n as getPersistedSandboxState, o as persistThreadStateById, r as getPersistedThreadState } from "./thread-state-DD6BA4xz.js";
2
+ import { A as createAgentInvocationSchema, M as AgentInvocationLimitError, O as agentBindingSchema, Q as AuthorizationFlowDisabledError, f as PluginCredentialFailureError, j as AgentInvocationBusyError, k as agentInvocationSchema } from "./agent-B_tHeZp6.js";
3
+ import { Ht as getConversationEventStore, Kt as getSqlExecutor, Wt as getConversationStore } from "./agent-hooks-DDJGkqlR.js";
4
+ import { f as juniorAgentBindings, p as juniorAgentInvocations } from "./executor-ctvBB7kO.js";
5
+ import { B as openConversationProjection, o as failTurnRecord, r as saveTurnCheckpoint, s as getTurnRecord, xt as getTerminalAssistantMessages } from "./checkpoint-DBX1KyOb.js";
6
+ import { pt as appendAndEnqueueInboundMessage } from "./stats-t0wuykQW.js";
7
+ import { _ as isTurnInputCommitLostError, h as getConversationTurnBoundaryError, p as TurnInputCommitLostError, s as getAssistantReplyText } from "./pending-auth-D6c_jWmW.js";
8
+ import { t as ConversationTurnLifecycleService } from "./turn-lifecycle-CoNJoE-n.js";
9
+ import { n as executeTurn, t as AgentRunError } from "./turn-execution-BRd4mQlB.js";
10
+ import { n as getPersistedSandboxState, o as persistThreadStateById, r as getPersistedThreadState } from "./thread-state-DB_913ic.js";
11
11
  import { z } from "zod";
12
12
  import { createHash } from "node:crypto";
13
13
  import { and, asc, count, eq, inArray } from "drizzle-orm";
@@ -1,10 +1,10 @@
1
1
  import { t as __exportAll } from "./rolldown-runtime-B4FMCO8f.js";
2
- import { b as isProviderRetryError } from "./client-Bp297GA0.js";
3
- import { S as withLogContext, d as logInfo, f as logWarn, u as logException } from "./logging-Dx0S5k2z.js";
4
- import { a as getChatConfig } from "./config-G2gv97R1.js";
5
- import { At as recordConversationRetry, Bt as isFinalAttempt, Ct as drainConversationMailbox, Et as getConversationWorkState, Ft as startConversationWork, Nt as requestAnotherSlice, St as deadLetterAttempt, Vt as isInvalidConversationRecordError, _t as clearConsumedConversationWake, bt as completeConversationWork, dt as ackMessages, gt as checkInConversationWork, jt as releaseConversationWork, kt as recordAttemptFailure, mt as beginConversationResume, wt as ensureConversationWake, xt as countPendingConversationMessages, yt as completeConversationStop } from "./stats-CFlUGqVA.js";
2
+ import { b as isProviderRetryError } from "./client-7_NmRtoz.js";
3
+ import { S as withLogContext, d as logInfo, f as logWarn, u as logException } from "./logging-CHzH6JFD.js";
4
+ import { a as getChatConfig } from "./config-BPGL4uP-.js";
5
+ import { At as recordConversationRetry, Ct as drainConversationMailbox, Et as getConversationWorkState, Ft as startConversationWork, Ht as isInvalidConversationRecordError, Nt as requestAnotherSlice, St as deadLetterAttempt, Vt as isFinalAttempt, _t as clearConsumedConversationWake, bt as completeConversationWork, dt as ackMessages, gt as checkInConversationWork, jt as releaseConversationWork, kt as recordAttemptFailure, mt as beginConversationResume, wt as ensureConversationWake, xt as countPendingConversationMessages, yt as completeConversationStop, zt as hasConversationStop } from "./stats-t0wuykQW.js";
6
6
  import { c as ConversationQueueMessageRejectedError } from "./vercel-queue-DIkVcfK4.js";
7
- import { a as getTurnRequestDeadline } from "./job-queue-rnAPfUhP.js";
7
+ import { a as getTurnRequestDeadline } from "./job-queue-C1lIZ7DE.js";
8
8
  //#region src/chat/task-execution/worker.ts
9
9
  var worker_exports = /* @__PURE__ */ __exportAll({
10
10
  CONVERSATION_WORK_DEFER_DELAY_MS: () => CONVERSATION_WORK_DEFER_DELAY_MS,
@@ -132,7 +132,7 @@ function startLeaseCheckIn(args) {
132
132
  timer.unref?.();
133
133
  return timer;
134
134
  }
135
- /** Poll shared state only when a worker adapter asks to observe remote stops. */
135
+ /** Poll the run-scoped stop marker only when an adapter observes remote stops. */
136
136
  function createConversationStopSignal(args) {
137
137
  const controller = new AbortController();
138
138
  let checking = false;
@@ -142,15 +142,16 @@ function createConversationStopSignal(args) {
142
142
  const requestStop = () => {
143
143
  if (!controller.signal.aborted) controller.abort(/* @__PURE__ */ new Error("Conversation work stopped"));
144
144
  };
145
- if (args.initialStopRunId === args.runId) requestStop();
145
+ if (args.initiallyStopped) requestStop();
146
146
  const check = async () => {
147
147
  if (checking || controller.signal.aborted) return;
148
148
  checking = true;
149
149
  try {
150
- if ((await getConversationWorkState({
150
+ if (await hasConversationStop({
151
151
  conversationId: args.conversationId,
152
+ runId: args.runId,
152
153
  state: args.options.state
153
- }))?.execution.stop?.runId === args.runId) requestStop();
154
+ })) requestStop();
154
155
  } catch (error) {
155
156
  if (!failureCaptured) {
156
157
  failureCaptured = true;
@@ -374,7 +375,11 @@ async function processConversationWorkInContext(message, options) {
374
375
  };
375
376
  const stop = createConversationStopSignal({
376
377
  conversationId,
377
- initialStopRunId: leasedWork.execution.stop?.runId,
378
+ initiallyStopped: await hasConversationStop({
379
+ conversationId,
380
+ runId,
381
+ state: options.state
382
+ }),
378
383
  options,
379
384
  runId
380
385
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sentry/junior",
3
- "version": "0.207.0",
3
+ "version": "0.209.0",
4
4
  "private": false,
5
5
  "publishConfig": {
6
6
  "access": "public"
@@ -58,7 +58,7 @@
58
58
  "@chat-adapter/state-memory": "4.29.0",
59
59
  "@chat-adapter/state-redis": "4.29.0",
60
60
  "@earendil-works/pi-agent-core": "0.84.1",
61
- "@earendil-works/pi-ai": "0.84.1",
61
+ "@earendil-works/pi-ai": "0.85.1",
62
62
  "@hono/zod-validator": "^0.9.0",
63
63
  "@logtape/logtape": "^2.1.1",
64
64
  "@modelcontextprotocol/sdk": "1.29.0",
@@ -85,7 +85,7 @@
85
85
  "pg": "^8.16.3",
86
86
  "yaml": "^2.9.0",
87
87
  "zod": "^4.5.4",
88
- "@sentry/junior-plugin-api": "0.207.0"
88
+ "@sentry/junior-plugin-api": "0.209.0"
89
89
  },
90
90
  "devDependencies": {
91
91
  "@emnapi/core": "^1.10.0",
@@ -104,9 +104,9 @@
104
104
  "typescript": "^6.0.3",
105
105
  "vercel": "^54.4.0",
106
106
  "vitest": "^4.1.7",
107
- "@sentry/junior-testing": "0.0.0",
108
- "@sentry/junior-github": "0.207.0",
109
- "@sentry/junior-memory": "0.207.0"
107
+ "@sentry/junior-memory": "0.209.0",
108
+ "@sentry/junior-github": "0.209.0",
109
+ "@sentry/junior-testing": "0.0.0"
110
110
  },
111
111
  "scripts": {
112
112
  "build": "tsdown",