@sentry/junior 0.270.0 → 0.272.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 (75) hide show
  1. package/dist/{actor-CP9K2Idu.js → actor-B4DYygOB.js} +1 -1
  2. package/dist/{adapter-BQNTKVTF.js → adapter-BDYDi1F9.js} +1 -1
  3. package/dist/{admin-CKVEoXa4.js → admin-Dj7EFycG.js} +1 -1
  4. package/dist/{agent-runner-MSQSMFkq.js → agent-runner-Cl6Usx2Y.js} +336 -280
  5. package/dist/api/schema.d.ts +2 -2
  6. package/dist/api/schema.js +5 -5
  7. package/dist/api.d.ts +1 -1
  8. package/dist/api.js +81 -37
  9. package/dist/{app-Bz8t4P8p.d.ts → app-DjZblE2J.d.ts} +8 -2
  10. package/dist/app.d.ts +1 -1
  11. package/dist/app.js +74 -40
  12. package/dist/{interruption-marker-CdblrIQK.js → assistant-reply-DN2w6JL_.js} +2 -8
  13. package/dist/{automation-Dwh_xcqM.js → automation-CV7g5h3A.js} +1 -1
  14. package/dist/{briefs-DNFzFFVx.js → briefs-PysAqnjV.js} +4 -4
  15. package/dist/{catalog-runtime-Bdym_wKy.js → catalog-runtime-BNeCWIaF.js} +1 -1
  16. package/dist/cli/chat.js +14 -14
  17. package/dist/cli/check.js +3 -3
  18. package/dist/cli/main.js +3 -3
  19. package/dist/cli/plugins.js +4 -4
  20. package/dist/cli/snapshot-create.js +4 -4
  21. package/dist/cli/upgrade.d.ts +1 -1
  22. package/dist/cli/upgrade.js +3 -3
  23. package/dist/{client-B2MjENki.js → client-FRphcDWW.js} +2 -2
  24. package/dist/{config-Dm3pWRqY.js → config-BUP9wjiR.js} +3 -3
  25. package/dist/{connections-0BBhiD-p.js → connections-CesHau9u.js} +10 -10
  26. package/dist/{conversation-AhOVzN_k.js → conversation-BtQzLoK8.js} +12 -1
  27. package/dist/{conversation-privacy-C1pJ89rs.js → conversation-privacy-DiGvA9a3.js} +1 -1
  28. package/dist/{credential-sync-BRiWYs6_.js → credential-sync-D2odJC30.js} +15 -15
  29. package/dist/{credentialed-BeBaJMZ_.js → credentialed-CgTulRDH.js} +33 -26
  30. package/dist/{db-BYOuu6v2.d.ts → db-BPLmOwXf.d.ts} +11 -1
  31. package/dist/{executor-BB6eJkD4.js → executor-DGDpyegI.js} +30 -7
  32. package/dist/instrumentation.js +2 -2
  33. package/dist/{job-queue-DiaXoSDg.js → job-queue-CjB97sii.js} +2 -2
  34. package/dist/{list-BTDRxkOg.js → list-JZUP1yog.js} +37 -53
  35. package/dist/{logging-C6EdT6PP.js → logging-CjkDr-jP.js} +1 -1
  36. package/dist/message-D9y8PKA1.js +186 -0
  37. package/dist/nitro.d.ts +1 -1
  38. package/dist/nitro.js +3 -3
  39. package/dist/{oauth-callback-server-CjFFVGqa.js → oauth-callback-server-02Pej6hj.js} +2 -2
  40. package/dist/{prompt-BPSdXYXV.js → prompt-vfceH0c-.js} +1 -1
  41. package/dist/{registry-CndmkP2P.js → registry-7XgwNgQe.js} +2 -2
  42. package/dist/{reporting-window-DRCi1Ls_.js → reporting-window-DgHgwQB3.js} +6 -1
  43. package/dist/{resolve-BkAA1wH7.js → resolve-CuuxNfWG.js} +3 -3
  44. package/dist/{result-9TJTpuYP.js → result-BRhb6iN1.js} +17 -13
  45. package/dist/{runner-BmKLSyJm.js → runner-DaWCofuS.js} +11 -11
  46. package/dist/{sandbox-egress-signals-CjLaogMo.js → sandbox-egress-signals-Bn6FA1UC.js} +1 -1
  47. package/dist/{schema-WayPSHFu.d.ts → schema-CNjAzYOw.d.ts} +28 -5
  48. package/dist/{schema-DNLJ_MzW.js → schema-D5VLF4NT.js} +13 -9
  49. package/dist/{service-account-DlhYl-Mu.js → service-account-D9vrsi8d.js} +3 -3
  50. package/dist/{service-account-D6e9cVmH.js → service-account-H45LIAG2.js} +3 -3
  51. package/dist/{session-stop-MZRgYqYH.js → session-stop-HKl0ECX0.js} +81 -153
  52. package/dist/{skills-BggTR_ue.js → skills-CsiKu3-g.js} +2 -2
  53. package/dist/{spawn-DmtlcAT_.js → spawn-DqjBxqWh.js} +2 -2
  54. package/dist/{store-BeWGgaMA.js → store-CPF2kzbu.js} +3 -3
  55. package/dist/{store-Byarin7b.js → store-DyVKH0QB.js} +47 -30
  56. package/dist/{task-queue-Dt1_ZoI_.js → task-queue-BbQXCcNX.js} +3 -3
  57. package/dist/{task-runner-DyKqAPpm.js → task-runner-ChzW5E7R.js} +7 -7
  58. package/dist/{thread-state-BHBLMvgb.js → thread-state-Ds8JTsX6.js} +5 -5
  59. package/dist/{turn-failure-response-DWXy_0oJ.js → turn-failure-response-DCMvjsA0.js} +15 -10
  60. package/dist/{turn-lifecycle-AiXkVqCB.js → turn-lifecycle-DM_77q33.js} +1 -1
  61. package/dist/{turn-session-routing-B9KLBhaT.js → turn-session-routing-BV_gX7n3.js} +13 -13
  62. package/dist/{validation-BW60Vtx_.js → validation-DcGelbBi.js} +1 -1
  63. package/dist/{version-CivPYmkH.js → version-C48azPKq.js} +1 -1
  64. package/dist/version.js +1 -1
  65. package/dist/{viewer-BTgAfdUg.js → viewer-BCRuO8Wg.js} +26 -10
  66. package/dist/{work-Bjm52fHo.js → work-zxkmbJAp.js} +27 -11
  67. package/dist/{worker-CMbgtHLu.js → worker-CNNxHF1V.js} +6 -6
  68. package/migrations/0071_review_item_turn.sql +1 -0
  69. package/migrations/0072_conversation_read_positions.sql +10 -0
  70. package/migrations/meta/0071_snapshot.json +4003 -0
  71. package/migrations/meta/0072_snapshot.json +4064 -0
  72. package/migrations/meta/_journal.json +14 -0
  73. package/package.json +4 -4
  74. package/dist/message-DsjiWRVg.js +0 -59
  75. package/migrations/AGENTS.md +0 -17
@@ -1,8 +1,8 @@
1
1
  import { c as modelProfileSchema, u as TURN_REASONING_LEVELS } from "./model-profile-B998sjVd.js";
2
- import { C as getSqlExecutor, x as getConversationStore } from "./viewer-BTgAfdUg.js";
2
+ import { C as getSqlExecutor, x as getConversationStore } from "./viewer-BCRuO8Wg.js";
3
3
  import { a as juniorAgentInvocations, i as juniorAgentBindings, n as AGENT_INVOCATION_PARENT_MAILBOX_STATUSES, t as AGENT_INVOCATION_MAILBOX_STATUSES } from "./agent-invocations-C1RNOCs8.js";
4
- import "./executor-BB6eJkD4.js";
5
- import { p as credentialContextSchema } from "./registry-CndmkP2P.js";
4
+ import "./executor-DGDpyegI.js";
5
+ import { p as credentialContextSchema } from "./registry-7XgwNgQe.js";
6
6
  import { z } from "zod";
7
7
  import { createHash } from "node:crypto";
8
8
  import { and, asc, count, countDistinct, desc, eq, inArray, lt, ne, or, sql } from "drizzle-orm";
@@ -228,6 +228,28 @@ const CHILD_AGENT_RESULTS = [
228
228
  "blocked",
229
229
  "failed"
230
230
  ];
231
+ // src/chat/agent-invocations/bindings.ts
232
+ function bindingFromRow(row) {
233
+ return agentBindingSchema.parse({
234
+ childConversationId: row.childConversationId,
235
+ name: row.name,
236
+ parentConversationId: row.parentConversationId
237
+ });
238
+ }
239
+ /** Read one named child binding in its parent-agent scope. */
240
+ async function getAgentBinding(args) {
241
+ const rows = await getSqlExecutor().db().select().from(juniorAgentBindings).where(and(eq(juniorAgentBindings.parentConversationId, args.parentConversationId), eq(juniorAgentBindings.name, args.name)));
242
+ return rows[0] ? bindingFromRow(rows[0]) : void 0;
243
+ }
244
+ /** Find a direct child agent of one parent by name or child Conversation id. */
245
+ async function findChildAgentConversationId(args) {
246
+ const binding = await getAgentBinding({
247
+ name: args.target,
248
+ parentConversationId: args.parentConversationId
249
+ });
250
+ if (binding) return binding.childConversationId;
251
+ return (await getSqlExecutor().db().select({ childConversationId: juniorAgentInvocations.childConversationId }).from(juniorAgentInvocations).where(and(eq(juniorAgentInvocations.parentConversationId, args.parentConversationId), eq(juniorAgentInvocations.childConversationId, args.target))).limit(1))[0]?.childConversationId;
252
+ }
231
253
  // src/chat/agent-invocations/errors.ts
232
254
  /** A child agent already uses this name in the parent Conversation. */
233
255
  var AgentNameInUseError = class extends Error {
@@ -250,13 +272,23 @@ var AgentMessageQueueFullError = class extends Error {
250
272
  this.name = "AgentMessageQueueFullError";
251
273
  }
252
274
  };
253
- /** A messageAgent target is not the parent or a child of the sender. */
275
+ /**
276
+ * A messageAgent target is not the parent, a child, or a top-level agent that
277
+ * the sender can message.
278
+ */
254
279
  var AgentMessageTargetError = class extends Error {
255
280
  constructor(message) {
256
281
  super(message);
257
282
  this.name = "AgentMessageTargetError";
258
283
  }
259
284
  };
285
+ /** A top-level agent paused automated Turns, so it takes no agent message. */
286
+ var AgentMessagePausedError = class extends Error {
287
+ constructor(conversationId) {
288
+ super(`${conversationId} paused automated work until a person replies there`);
289
+ this.name = "AgentMessagePausedError";
290
+ }
291
+ };
260
292
  // src/chat/agent-invocations/store.ts
261
293
  const CREATE_LOCK_PREFIX = "junior:agent_invocation:create";
262
294
  /**
@@ -334,13 +366,6 @@ function parseAgentInvocationResultMessageId(messageId) {
334
366
  if (!messageId.startsWith(RESULT_MESSAGE_PREFIX) || !messageId.endsWith(RESULT_MESSAGE_SUFFIX)) return;
335
367
  return messageId.slice(17, -7) || void 0;
336
368
  }
337
- function bindingFromRow(row) {
338
- return agentBindingSchema.parse({
339
- childConversationId: row.childConversationId,
340
- name: row.name,
341
- parentConversationId: row.parentConversationId
342
- });
343
- }
344
369
  /** Parse one agent invocation row. */
345
370
  function invocationFromRow(row) {
346
371
  return agentInvocationSchema.parse({
@@ -376,21 +401,20 @@ function invocationFromRow(row) {
376
401
  function sameCreateInput(invocation, input) {
377
402
  return invocation.parentConversationId === input.parentConversationId && invocation.agentName === input.agentName && invocation.input === input.input && invocation.agentType === input.agentType && invocation.modelProfile === input.modelProfile && invocation.reasoningLevel === input.reasoningLevel && JSON.stringify(invocation.actor) === JSON.stringify(input.actor) && JSON.stringify(invocation.credentialContext) === JSON.stringify(input.credentialContext) && JSON.stringify(invocation.destination) === JSON.stringify(input.destination);
378
403
  }
379
- /** Read one named child binding in its parent-agent scope. */
380
- async function getAgentBinding(args) {
381
- const rows = await getSqlExecutor().db().select().from(juniorAgentBindings).where(and(eq(juniorAgentBindings.parentConversationId, args.parentConversationId), eq(juniorAgentBindings.name, args.name)));
382
- return rows[0] ? bindingFromRow(rows[0]) : void 0;
383
- }
384
404
  /** Read one durable agent invocation. */
385
405
  async function getAgentInvocation(invocationId) {
386
406
  const rows = await getSqlExecutor().db().select().from(juniorAgentInvocations).where(eq(juniorAgentInvocations.invocationId, invocationId));
387
407
  return rows[0] ? invocationFromRow(rows[0]) : void 0;
388
408
  }
409
+ /** List the running and paused agent invocations of one child Conversation. */
410
+ async function listActiveAgentInvocationsForConversation(childConversationId) {
411
+ return (await getSqlExecutor().db().select().from(juniorAgentInvocations).where(and(eq(juniorAgentInvocations.childConversationId, childConversationId), inArray(juniorAgentInvocations.status, ["running", "paused"]))).orderBy(asc(juniorAgentInvocations.createdAt))).map(invocationFromRow);
412
+ }
389
413
  /** Resolve the single invocation that may resume for one child conversation. */
390
414
  async function getActiveAgentInvocationForConversation(childConversationId) {
391
- const rows = await getSqlExecutor().db().select().from(juniorAgentInvocations).where(and(eq(juniorAgentInvocations.childConversationId, childConversationId), inArray(juniorAgentInvocations.status, ["running", "paused"]))).orderBy(asc(juniorAgentInvocations.createdAt)).limit(2);
392
- if (rows.length > 1) throw new Error(`Child conversation ${childConversationId} has multiple active agent invocations`);
393
- return rows[0] ? invocationFromRow(rows[0]) : void 0;
415
+ const active = await listActiveAgentInvocationsForConversation(childConversationId);
416
+ if (active.length > 1) throw new Error(`Child conversation ${childConversationId} has multiple active agent invocations`);
417
+ return active[0];
394
418
  }
395
419
  /** Read the newest agent invocation of one child Conversation. */
396
420
  async function getLatestAgentInvocationForConversation(childConversationId) {
@@ -524,15 +548,6 @@ async function createAgentInvocationFromLatest(args, nowMs = Date.now()) {
524
548
  if (!invocation || invocation.childConversationId !== args.latest.childConversationId) throw new Error(`Agent invocation creation raced for ${invocationId}`);
525
549
  return invocation;
526
550
  }
527
- /** Find a direct child agent of one parent by name or child Conversation id. */
528
- async function findChildAgentConversationId(args) {
529
- const binding = await getAgentBinding({
530
- name: args.target,
531
- parentConversationId: args.parentConversationId
532
- });
533
- if (binding) return binding.childConversationId;
534
- return (await getSqlExecutor().db().select({ childConversationId: juniorAgentInvocations.childConversationId }).from(juniorAgentInvocations).where(and(eq(juniorAgentInvocations.parentConversationId, args.parentConversationId), eq(juniorAgentInvocations.childConversationId, args.target))).limit(1))[0]?.childConversationId;
535
- }
536
551
  /**
537
552
  * Return whether a pending agent invocation still waits for older open work
538
553
  * on its child.
@@ -659,12 +674,14 @@ async function markAgentInvocationPaused(invocationId, nowMs = Date.now()) {
659
674
  * result. The same write marks the result for the parent mailbox. If the
660
675
  * child still has open work, the result is `replaced`: the parent gets one
661
676
  * report, from the agent invocation that finishes the child's work.
677
+ * `reportNow` sends the result even then, when that open work does not
678
+ * continue this task.
662
679
  */
663
680
  async function completeAgentInvocation(args) {
664
681
  const nowMs = args.nowMs ?? Date.now();
665
682
  const current = await getAgentInvocation(args.invocationId);
666
683
  if (!current || isTerminalAgentInvocation(current)) return current;
667
- const parentMailboxStatus = args.status !== "stopped" && await hasOpenChildWork(current) ? "replaced" : "pending";
684
+ const parentMailboxStatus = !args.reportNow && args.status !== "stopped" && await hasOpenChildWork(current) ? "replaced" : "pending";
668
685
  await getSqlExecutor().db().update(juniorAgentInvocations).set({
669
686
  status: args.status,
670
687
  result: args.status === "completed" ? args.result : null,
@@ -694,4 +711,4 @@ async function markAgentInvocationSteered(invocationId, nowMs = Date.now()) {
694
711
  function isTerminalAgentInvocation(invocation) {
695
712
  return TERMINAL_AGENT_INVOCATION_STATUSES.includes(invocation.status);
696
713
  }
697
- export { AgentMessageQueueFullError as A, ConversationTurnBoundaryError as B, markAgentInvocationParentMailboxAppended as C, parseAgentInvocationResultMessageId as D, markAgentInvocationSteered as E, agentNameSchema as F, isCooperativeTurnYieldError as G, TurnInputCommitLostError as H, AGENT_TYPES as I, markTurnClosed as J, isTurnInputCommitLostError as K, agentTypeInstructions as L, AgentNameInUseError as M, CHILD_AGENT_RESULTS as N, reportReplacedAgentInvocation as O, PARENT_AGENT_TARGET as P, agentTypeStartsWithParentHistory as R, markAgentInvocationMailboxAppended as S, markAgentInvocationRunning as T, TurnInputDeferredError as U, CooperativeTurnYieldError as V, getConversationTurnBoundaryError as W, markTurnFailed as X, markTurnCompleted as Y, startActiveTurn as Z, getLatestAgentInvocationForConversation as _, createAgentInvocationFromLatest as a, listPendingAgentInvocationMailboxAppends as b, getAgentInvocation as c, getAgentInvocationIdForResult as d, getAgentInvocationMessageId as f, getChildAgentLockName as g, getChildAgentLabel as h, createAgentInvocationForMessage as i, AgentMessageTargetError as j, AgentInvocationLimitError as k, getAgentInvocationIdForEvents as l, getAgentInvocationTurnId as m, completeAgentInvocation as n, findChildAgentConversationId as o, getAgentInvocationResultMessageId as p, isTurnInputDeferredError as q, createAgentInvocation as r, getActiveAgentInvocationForConversation as s, NON_TERMINAL_AGENT_INVOCATION_STATUSES as t, getAgentInvocationIdForMessage as u, invocationFromRow as v, markAgentInvocationPaused as w, listPendingAgentInvocationResults as x, isTerminalAgentInvocation as y, formatAgentTypes as z };
714
+ export { startActiveTurn as $, AgentMessagePausedError as A, agentTypeStartsWithParentHistory as B, markAgentInvocationParentMailboxAppended as C, parseAgentInvocationResultMessageId as D, markAgentInvocationSteered as E, CHILD_AGENT_RESULTS as F, TurnInputDeferredError as G, ConversationTurnBoundaryError as H, PARENT_AGENT_TARGET as I, isTurnInputCommitLostError as J, getConversationTurnBoundaryError as K, agentNameSchema as L, AgentMessageTargetError as M, AgentNameInUseError as N, reportReplacedAgentInvocation as O, findChildAgentConversationId as P, markTurnFailed as Q, AGENT_TYPES as R, markAgentInvocationMailboxAppended as S, markAgentInvocationRunning as T, CooperativeTurnYieldError as U, formatAgentTypes as V, TurnInputCommitLostError as W, markTurnClosed as X, isTurnInputDeferredError as Y, markTurnCompleted as Z, invocationFromRow as _, createAgentInvocationFromLatest as a, listPendingAgentInvocationMailboxAppends as b, getAgentInvocationIdForEvents as c, getAgentInvocationMessageId as d, getAgentInvocationResultMessageId as f, getLatestAgentInvocationForConversation as g, getChildAgentLockName as h, createAgentInvocationForMessage as i, AgentMessageQueueFullError as j, AgentInvocationLimitError as k, getAgentInvocationIdForMessage as l, getChildAgentLabel as m, completeAgentInvocation as n, getActiveAgentInvocationForConversation as o, getAgentInvocationTurnId as p, isCooperativeTurnYieldError as q, createAgentInvocation as r, getAgentInvocation as s, NON_TERMINAL_AGENT_INVOCATION_STATUSES as t, getAgentInvocationIdForResult as u, isTerminalAgentInvocation as v, markAgentInvocationPaused as w, listPendingAgentInvocationResults as x, listActiveAgentInvocationsForConversation as y, agentTypeInstructions as z };
@@ -1,5 +1,5 @@
1
- import { h as logWarn } from "./logging-C6EdT6PP.js";
2
- import { c as QUEUE_SIGNATURE_MAX_AGE_MS, d as getQueueProvider, l as signQueueMessage, p as runWithTurnRequestDeadline, u as verifyQueueMessage } from "./job-queue-DiaXoSDg.js";
1
+ import { h as logWarn } from "./logging-CjkDr-jP.js";
2
+ import { c as QUEUE_SIGNATURE_MAX_AGE_MS, d as getQueueProvider, l as signQueueMessage, p as runWithTurnRequestDeadline, u as verifyQueueMessage } from "./job-queue-CjB97sii.js";
3
3
  import { z } from "zod";
4
4
  import { createHash } from "node:crypto";
5
5
  // src/chat/queue/callback.ts
@@ -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-DyKqAPpm.js").then((n) => n.r);
113
+ const { processPluginTask } = await import("./task-runner-ChzW5E7R.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-nwUcYXjP.js";
2
- import { Dr as normalizeToolNameFromResult, Er as isToolResultMessage, Gt as hydrateConversationMessages, On as getTurnRecord, Sr as instructionTextForProjection, Tr as isToolResultError, kr as stripRuntimeTurnContext, t as resolveConversationRouting, u as getDispatchRecord, vr as getPiMessageRole } from "./turn-session-routing-B9KLBhaT.js";
3
- import { m as parseSlackMessageTs } from "./actor-CP9K2Idu.js";
4
- import { S as getDb, i as readActorIdentity, x as getConversationStore } from "./viewer-BTgAfdUg.js";
2
+ import { Dr as normalizeToolNameFromResult, Er as isToolResultMessage, Gt as hydrateConversationMessages, On as getTurnRecord, Sr as instructionTextForProjection, Tr as isToolResultError, kr as stripRuntimeTurnContext, t as resolveConversationRouting, u as getDispatchRecord, vr as getPiMessageRole } from "./turn-session-routing-BV_gX7n3.js";
3
+ import { h as parseSlackMessageTs } from "./actor-B4DYygOB.js";
4
+ import { S as getDb, i as readActorIdentity, x as getConversationStore } from "./viewer-BCRuO8Wg.js";
5
5
  import { _ as sameActorIdentity } from "./media-U6Tuz6Mi.js";
6
- import { ar as createPluginLogger, g as coreTaskRegistrations, hr as createPluginConversationEvents, ir as createPluginModel, jr as createPluginCache, nr as createPluginState, p as getPlugins, rr as createPluginEmbedder } from "./credentialed-BeBaJMZ_.js";
7
- import { r as getStateAdapter } from "./adapter-BQNTKVTF.js";
8
- import { o as coerceThreadConversationState, r as getPersistedThreadState } from "./thread-state-BHBLMvgb.js";
9
- import { i as pluginTaskParamsSchema, r as pluginTaskId, s as sendVercelPluginTask } from "./task-queue-Dt1_ZoI_.js";
6
+ import { ar as createPluginLogger, g as coreTaskRegistrations, hr as createPluginConversationEvents, ir as createPluginModel, jr as createPluginCache, nr as createPluginState, p as getPlugins, rr as createPluginEmbedder } from "./credentialed-CgTulRDH.js";
7
+ import { r as getStateAdapter } from "./adapter-BDYDi1F9.js";
8
+ import { o as coerceThreadConversationState, r as getPersistedThreadState } from "./thread-state-Ds8JTsX6.js";
9
+ import { i as pluginTaskParamsSchema, r as pluginTaskId, s as sendVercelPluginTask } from "./task-queue-BbQXCcNX.js";
10
10
  import { pluginRunContextSchema } from "@sentry/junior-plugin-api";
11
11
  // src/chat/plugins/task-runner.ts
12
12
  /**
@@ -1,8 +1,8 @@
1
- import { Kr as createDurableLocationConfigurationService, Kt as persistConversationMessages } from "./turn-session-routing-B9KLBhaT.js";
2
- import { B as isRecord, H as toOptionalString, V as toOptionalNumber } from "./logging-C6EdT6PP.js";
3
- import { S as getDb } from "./viewer-BTgAfdUg.js";
4
- import { In as JUNIOR_THREAD_STATE_TTL_MS } from "./credentialed-BeBaJMZ_.js";
5
- import { r as getStateAdapter } from "./adapter-BQNTKVTF.js";
1
+ import { Kr as createDurableLocationConfigurationService, Kt as persistConversationMessages } from "./turn-session-routing-BV_gX7n3.js";
2
+ import { B as isRecord, H as toOptionalString, V as toOptionalNumber } from "./logging-CjkDr-jP.js";
3
+ import { S as getDb } from "./viewer-BCRuO8Wg.js";
4
+ import { In as JUNIOR_THREAD_STATE_TTL_MS } from "./credentialed-CgTulRDH.js";
5
+ import { r as getStateAdapter } from "./adapter-BDYDi1F9.js";
6
6
  // src/chat/state/conversation.ts
7
7
  function defaultConversationState() {
8
8
  return {
@@ -1,13 +1,12 @@
1
- import { Fr as buildDeterministicTurnId, Gt as hydrateConversationMessages, an as markConversationMessage, yn as clearPendingAuth } from "./turn-session-routing-B9KLBhaT.js";
2
- import { _ as getProviderErrorAttributes, g as findProviderError, m as ProviderError, v as getProviderErrorUserMessage } from "./client-B2MjENki.js";
3
- import { B as isRecord, t as buildTurnFailureResponse } from "./logging-C6EdT6PP.js";
4
- import { m as parseSlackMessageTs } from "./actor-CP9K2Idu.js";
5
- import { S as getDb, y as getConversationEventStore } from "./viewer-BTgAfdUg.js";
6
- import { Er as listConversationAnnotations } from "./credentialed-BeBaJMZ_.js";
7
- import { B as removedCardSchema, V as resolveMessageCards, z as readMessageCardRefs } from "./conversation-AhOVzN_k.js";
8
- import { D as parseAgentInvocationResultMessageId, J as markTurnClosed, Y as markTurnCompleted, c as getAgentInvocation, m as getAgentInvocationTurnId } from "./store-Byarin7b.js";
9
- import { t as getInterruptionMarker } from "./interruption-marker-CdblrIQK.js";
10
- import { a as persistThreadStateById, o as coerceThreadConversationState, r as getPersistedThreadState } from "./thread-state-BHBLMvgb.js";
1
+ import { Fr as buildDeterministicTurnId, Gt as hydrateConversationMessages, an as markConversationMessage, yn as clearPendingAuth } from "./turn-session-routing-BV_gX7n3.js";
2
+ import { _ as getProviderErrorAttributes, g as findProviderError, m as ProviderError, v as getProviderErrorUserMessage } from "./client-FRphcDWW.js";
3
+ import { B as isRecord, t as buildTurnFailureResponse } from "./logging-CjkDr-jP.js";
4
+ import { h as parseSlackMessageTs } from "./actor-B4DYygOB.js";
5
+ import { S as getDb, y as getConversationEventStore } from "./viewer-BCRuO8Wg.js";
6
+ import { Er as listConversationAnnotations } from "./credentialed-CgTulRDH.js";
7
+ import { B as readMessageCardRefs, H as resolveMessageCards, V as removedCardSchema } from "./conversation-BtQzLoK8.js";
8
+ import { D as parseAgentInvocationResultMessageId, X as markTurnClosed, Z as markTurnCompleted, p as getAgentInvocationTurnId, s as getAgentInvocation } from "./store-DyVKH0QB.js";
9
+ import { a as persistThreadStateById, o as coerceThreadConversationState, r as getPersistedThreadState } from "./thread-state-Ds8JTsX6.js";
11
10
  // src/chat/conversations/pending-cards.ts
12
11
  /**
13
12
  * Add the cards that tool results selected since the last visible assistant
@@ -140,6 +139,12 @@ async function persistAuthPauseTurnState(args) {
140
139
  });
141
140
  await persistThreadStateById(args.threadStateId, { conversation });
142
141
  }
142
+ // src/chat/interruption-marker.ts
143
+ const INTERRUPTED_MARKER = "\n\n[Response interrupted before completion]";
144
+ /** Return the marker added when a visible reply ended mid-execution. */
145
+ function getInterruptionMarker() {
146
+ return INTERRUPTED_MARKER;
147
+ }
143
148
  // src/chat/services/turn-failure-response.ts
144
149
  /** Require captured turn failures to carry a real Sentry event reference. */
145
150
  function requireTurnFailureEventId(eventId, eventName) {
@@ -1,4 +1,4 @@
1
- import { y as getConversationEventStore } from "./viewer-BTgAfdUg.js";
1
+ import { y as getConversationEventStore } from "./viewer-BCRuO8Wg.js";
2
2
  // src/chat/conversations/turn-lifecycle.ts
3
3
  /** Persist correlated turn lifecycle facts with retry-safe terminal exclusion. */
4
4
  var ConversationTurnLifecycleService = class {
@@ -1,18 +1,18 @@
1
- import { a as completeText, f as unwrapCurrentInstruction, p as escapeXml, s as resolveGatewayModel, y as isProviderRetryError } from "./client-B2MjENki.js";
2
- import { i as getChatConfig, n as botConfig } from "./config-Dm3pWRqY.js";
3
- import { B as isRecord, E as withSpan, H as toOptionalString, V as toOptionalNumber, _ as runBestEffort, b as setSpanAttributes, h as logWarn, o as getActiveTraceContext, p as logException, t as buildTurnFailureResponse } from "./logging-C6EdT6PP.js";
4
- import { c as parseStoredSlackActor, l as toStoredSlackActor, m as parseSlackMessageTs } from "./actor-CP9K2Idu.js";
5
- import { A as startLocationThread, C as getSqlExecutor, G as agentTurnTotalTokens, M as resolveActorIdentityId, Q as sameDestination, S as getDb, T as withConversationEventLock, U as addAgentTurnUsage, V as bindProviderConversation, W as agentTurnCostUsd, X as parseDestination, w as createSqlConversationEventStore, x as getConversationStore, y as getConversationEventStore } from "./viewer-BTgAfdUg.js";
1
+ import { a as completeText, f as unwrapCurrentInstruction, p as escapeXml, s as resolveGatewayModel, y as isProviderRetryError } from "./client-FRphcDWW.js";
2
+ import { i as getChatConfig, n as botConfig } from "./config-BUP9wjiR.js";
3
+ import { B as isRecord, E as withSpan, H as toOptionalString, V as toOptionalNumber, _ as runBestEffort, b as setSpanAttributes, h as logWarn, o as getActiveTraceContext, p as logException, t as buildTurnFailureResponse } from "./logging-CjkDr-jP.js";
4
+ import { c as parseStoredSlackActor, h as parseSlackMessageTs, l as toStoredSlackActor } from "./actor-B4DYygOB.js";
5
+ import { A as startLocationThread, C as getSqlExecutor, G as agentTurnTotalTokens, M as resolveActorIdentityId, Q as sameDestination, S as getDb, T as withConversationEventLock, U as addAgentTurnUsage, V as bindProviderConversation, W as agentTurnCostUsd, X as parseDestination, w as createSqlConversationEventStore, x as getConversationStore, y as getConversationEventStore } from "./viewer-BCRuO8Wg.js";
6
6
  import { d as juniorDestinations, s as juniorConversations } from "./agent-invocations-C1RNOCs8.js";
7
- import { d as juniorAutomations, l as juniorAutomationRuns, p as juniorLocationConfigurations, u as juniorAutomationVersions } from "./executor-BB6eJkD4.js";
7
+ import { d as juniorAutomations, l as juniorAutomationRuns, p as juniorLocationConfigurations, u as juniorAutomationVersions } from "./executor-DGDpyegI.js";
8
8
  import { a as agentHistoryItemSchema, g as instructionProvenanceFor, h as instructionActors, m as contextProvenance } from "./media-U6Tuz6Mi.js";
9
- import { f as credentialContextForActor, h as credentialSubjectSchema } from "./registry-CndmkP2P.js";
10
- import { n as pluginCatalogRuntime } from "./catalog-runtime-Bdym_wKy.js";
11
- import { Bn as getDashboardTaskLink, Ct as openSlackDirectMessage, Et as postSlackMessage, Fr as authenticationUnlinkedEvent, Gt as parseSandboxEgressAuthRequiredSignal, Hn as ToolInputError, In as JUNIOR_THREAD_STATE_TTL_MS, Mr as JUNIOR_NATIVE_EVENT_NAMESPACE, Nn as sleep$1, Nr as agentsInstructionsUpdatedEvent, Pr as authenticationLinkedEvent, Yt as resolveSandboxEgressProviderForHost, ar as createPluginLogger, ht as formatSlackLink, jr as createPluginCache, mt as escapeSlackMrkdwnText, p as getPlugins, pt as startOAuthFlow, t as executeCredentialedEgressRequest, ut as formatProviderLabel } from "./credentialed-BeBaJMZ_.js";
9
+ import { f as credentialContextForActor, h as credentialSubjectSchema } from "./registry-7XgwNgQe.js";
10
+ import { n as pluginCatalogRuntime } from "./catalog-runtime-BNeCWIaF.js";
11
+ import { Bn as getDashboardTaskLink, Ct as openSlackDirectMessage, Et as postSlackMessage, Fr as authenticationUnlinkedEvent, Gt as parseSandboxEgressAuthRequiredSignal, Hn as ToolInputError, In as JUNIOR_THREAD_STATE_TTL_MS, Mr as JUNIOR_NATIVE_EVENT_NAMESPACE, Nn as sleep$1, Nr as agentsInstructionsUpdatedEvent, Pr as authenticationLinkedEvent, Yt as resolveSandboxEgressProviderForHost, ar as createPluginLogger, ht as formatSlackLink, jr as createPluginCache, mt as escapeSlackMrkdwnText, p as getPlugins, pt as startOAuthFlow, t as executeCredentialedEgressRequest, ut as formatProviderLabel } from "./credentialed-CgTulRDH.js";
12
12
  import { a as withLock, i as fenceLock, n as MUTATION_LOCK_TTL_MS } from "./locks-D-0h111u.js";
13
- import { n as getDefaultRedisStateAdapterFor, r as getStateAdapter } from "./adapter-BQNTKVTF.js";
14
- import { L as messageCardRef } from "./conversation-AhOVzN_k.js";
15
- import { O as eventAutomationSchema, S as automationVersionSchema, j as scheduledAutomationSchema } from "./automation-Dwh_xcqM.js";
13
+ import { n as getDefaultRedisStateAdapterFor, r as getStateAdapter } from "./adapter-BDYDi1F9.js";
14
+ import { R as messageCardRef } from "./conversation-BtQzLoK8.js";
15
+ import { O as eventAutomationSchema, S as automationVersionSchema, j as scheduledAutomationSchema } from "./automation-CV7g5h3A.js";
16
16
  import { isDeepStrictEqual } from "node:util";
17
17
  import { z } from "zod";
18
18
  import { createHash, randomUUID } from "node:crypto";
@@ -6030,7 +6030,7 @@ function slackSourceForDestination(args) {
6030
6030
  * Reads parent Conversations when this Conversation has no Destination.
6031
6031
  */
6032
6032
  async function resolveConversationRouting(args) {
6033
- const conversationStore = args.conversationStore ?? (await import("./viewer-BTgAfdUg.js").then((n) => n.v)).getConversationStore();
6033
+ const conversationStore = args.conversationStore ?? (await import("./viewer-BCRuO8Wg.js").then((n) => n.v)).getConversationStore();
6034
6034
  const chain = await loadConversationChain(args.conversationId, conversationStore);
6035
6035
  let destination;
6036
6036
  let source;
@@ -1,5 +1,5 @@
1
1
  import { t as __exportAll } from "./rolldown-runtime-nwUcYXjP.js";
2
- import { n as pluginCatalogRuntime } from "./catalog-runtime-Bdym_wKy.js";
2
+ import { n as pluginCatalogRuntime } from "./catalog-runtime-BNeCWIaF.js";
3
3
  import { isDeepStrictEqual } from "node:util";
4
4
  // src/chat/plugins/validation.ts
5
5
  var validation_exports = /* @__PURE__ */ __exportAll({
@@ -1,5 +1,5 @@
1
1
  // package.json
2
- var version = "0.270.0";
2
+ var version = "0.272.0";
3
3
  // src/version.ts
4
4
  /** Installed Junior package version, or `unknown` when package metadata is unavailable. */
5
5
  const JUNIOR_VERSION = typeof version === "string" && version.trim() ? version : "unknown";
package/dist/version.js CHANGED
@@ -1 +1 @@
1
- export { t as JUNIOR_VERSION } from "./version-CivPYmkH.js";
1
+ export { t as JUNIOR_VERSION } from "./version-C48azPKq.js";
@@ -1,9 +1,9 @@
1
1
  import { t as __exportAll } from "./rolldown-runtime-nwUcYXjP.js";
2
- import { i as getChatConfig } from "./config-Dm3pWRqY.js";
3
- import { L as GOOGLE_IDENTITY_PROVIDER, h as logWarn, z as normalizeIdentityEmail } from "./logging-C6EdT6PP.js";
4
- import { a as isSlackUserId, d as parseSlackChannelReferenceId, f as parseSlackTeamId, s as parseActorUserId } from "./actor-CP9K2Idu.js";
2
+ import { i as getChatConfig } from "./config-BUP9wjiR.js";
3
+ import { L as GOOGLE_IDENTITY_PROVIDER, h as logWarn, z as normalizeIdentityEmail } from "./logging-CjkDr-jP.js";
4
+ import { a as isSlackUserId, d as parseSlackChannelReferenceId, f as parseSlackTeamId, s as parseActorUserId } from "./actor-B4DYygOB.js";
5
5
  import { c as juniorIdentities, d as juniorDestinations, l as juniorUsers, o as conversationReadColumns, s as juniorConversations } from "./agent-invocations-C1RNOCs8.js";
6
- import { _ as CONVERSATION_METRICS, h as juniorConversationBindings, m as juniorConversationParticipants, t as createJuniorSqlExecutor, v as juniorConversationMetrics, x as juniorConversationAnnotations, y as juniorConversationEvents } from "./executor-BB6eJkD4.js";
6
+ import { S as juniorConversationAnnotations, b as juniorConversationEvents, g as juniorConversationBindings, h as juniorConversationParticipants, t as createJuniorSqlExecutor, v as CONVERSATION_METRICS, y as juniorConversationMetrics } from "./executor-DGDpyegI.js";
7
7
  import { d as newConversationEventSchema, f as encodeHistoryPayload, l as decodeStoredConversationEvent, n as detectImageMediaType, o as conversationEventDataSchema, u as historyReplacementSchema, v as usageSchema } from "./media-U6Tuz6Mi.js";
8
8
  import { a as withLock } from "./locks-D-0h111u.js";
9
9
  import { createHash, randomUUID } from "node:crypto";
@@ -995,6 +995,9 @@ var SqlStore = class {
995
995
  if (!row) return;
996
996
  if (row.visibility === "public" || row.visibility === "private") return row.visibility;
997
997
  }
998
+ async recordDestinationVisibility(args) {
999
+ await this.upsertDestination(destinationUpsertFromDestination(args), args.nowMs ?? Date.now());
1000
+ }
998
1001
  async findSlackDestinationByName(args) {
999
1002
  const normalized = args.channelName.trim().replace(/^#/, "").toLowerCase();
1000
1003
  if (!normalized) return;
@@ -1406,20 +1409,33 @@ var SqlConversationEventStore = class {
1406
1409
  nowMs: event.createdAtMs
1407
1410
  });
1408
1411
  rows.push(insertFromEvent(conversationId, seq++, historyVersion, event, actorIdentityId));
1409
- if (actorIdentityId) await recordConversationParticipant(this.executor, {
1410
- actorIdentityId,
1411
- conversationId,
1412
- atMs: event.createdAtMs,
1413
- restoreArchive: eventUnarchivesConversation(event.data)
1414
- });
1415
1412
  }
1416
1413
  await this.executor.db().insert(juniorConversationEvents).values(rows);
1414
+ for (const event of pending) if (event.data.type === "turn_started") await this.recordTurnInputParticipants(conversationId, event.data.inputMessageIds);
1417
1415
  return rows.map((row) => ({
1418
1416
  seq: row.seq,
1419
1417
  historyVersion: row.historyVersion
1420
1418
  }));
1421
1419
  });
1422
1420
  }
1421
+ /**
1422
+ * Add the authors of Turn input messages to the conversation.
1423
+ * Only people who start a Turn join it. Thread context, such as backfilled
1424
+ * or skipped messages, keeps its author without membership.
1425
+ */
1426
+ async recordTurnInputParticipants(conversationId, inputMessageIds) {
1427
+ const rows = await this.executor.db().select().from(juniorConversationEvents).where(and(eq(juniorConversationEvents.conversationId, conversationId), eq(juniorConversationEvents.type, "message"), inArray(sql`${juniorConversationEvents.payload}->>'messageId'`, [...inputMessageIds])));
1428
+ for (const row of rows) {
1429
+ const { data } = eventFromRow(row);
1430
+ if (!row.actorIdentityId || data.type !== "message") continue;
1431
+ await recordConversationParticipant(this.executor, {
1432
+ actorIdentityId: row.actorIdentityId,
1433
+ conversationId,
1434
+ atMs: row.createdAt.getTime(),
1435
+ restoreArchive: eventUnarchivesConversation(data)
1436
+ });
1437
+ }
1438
+ }
1423
1439
  async replaceHistory(conversationId, replacement) {
1424
1440
  const parsed = historyReplacementSchema.parse(replacement);
1425
1441
  await withConversationEventLock(this.executor, conversationId, async () => {
@@ -1,14 +1,14 @@
1
- import { Dn as failTurnRecord, Nt as openConversationProjection, On as getTurnRecord, Tn as abandonTurnRecord, dn as PluginCredentialFailureError, hn as AuthorizationFlowDisabledError, mr as isTurnExecutionLimitExceededError, wn as saveTurnCheckpoint, yr as getTerminalAssistantMessages } from "./turn-session-routing-B9KLBhaT.js";
2
- import { n as botConfig } from "./config-Dm3pWRqY.js";
3
- import { j as SYSTEM_IDENTITY_ID, x as getConversationStore, y as getConversationEventStore } from "./viewer-BTgAfdUg.js";
1
+ import { Dn as failTurnRecord, Nt as openConversationProjection, On as getTurnRecord, Tn as abandonTurnRecord, dn as PluginCredentialFailureError, hn as AuthorizationFlowDisabledError, mr as isTurnExecutionLimitExceededError, wn as saveTurnCheckpoint, yr as getTerminalAssistantMessages } from "./turn-session-routing-BV_gX7n3.js";
2
+ import { n as botConfig } from "./config-BUP9wjiR.js";
3
+ import { j as SYSTEM_IDENTITY_ID, x as getConversationStore, y as getConversationEventStore } from "./viewer-BCRuO8Wg.js";
4
4
  import { _ as sameActorIdentity, p as agentInstructionProvenance } from "./media-U6Tuz6Mi.js";
5
- import { Et as withoutSavedSteeringMessages, Mt as readBlockedReport, Tt as buildSteeringPiMessage, _t as recordSubagentEnded, ht as stopChildAgentsOf, vt as recordSubagentStarted } from "./agent-runner-MSQSMFkq.js";
6
- import { E as markAgentInvocationSteered, H as TurnInputCommitLostError, K as isTurnInputCommitLostError, L as agentTypeInstructions, O as reportReplacedAgentInvocation, R as agentTypeStartsWithParentHistory, S as markAgentInvocationMailboxAppended, T as markAgentInvocationRunning, W as getConversationTurnBoundaryError, _ as getLatestAgentInvocationForConversation, c as getAgentInvocation, f as getAgentInvocationMessageId, m as getAgentInvocationTurnId, n as completeAgentInvocation, r as createAgentInvocation, s as getActiveAgentInvocationForConversation, w as markAgentInvocationPaused, y as isTerminalAgentInvocation } from "./store-Byarin7b.js";
7
- import { r as getAssistantReplyText } from "./interruption-marker-CdblrIQK.js";
8
- import { C as maybePostAutomatedTurnLimitNotice, D as recordFinishedTurnForAutomatedLimit, O as resetAutomatedTurnLimit } from "./session-stop-MZRgYqYH.js";
9
- import { r as appendAndEnqueueInboundMessage } from "./store-BeWGgaMA.js";
10
- import { t as ConversationTurnLifecycleService } from "./turn-lifecycle-AiXkVqCB.js";
11
- import { a as persistThreadStateById, n as getPersistedSandboxState, r as getPersistedThreadState } from "./thread-state-BHBLMvgb.js";
5
+ import { Dt as buildSteeringPiMessage, Ot as withoutSavedSteeringMessages, Pt as readBlockedReport, _t as stopChildAgentsOf, bt as recordSubagentStarted, yt as recordSubagentEnded } from "./agent-runner-Cl6Usx2Y.js";
6
+ import { B as agentTypeStartsWithParentHistory, E as markAgentInvocationSteered, J as isTurnInputCommitLostError, K as getConversationTurnBoundaryError, O as reportReplacedAgentInvocation, S as markAgentInvocationMailboxAppended, T as markAgentInvocationRunning, W as TurnInputCommitLostError, d as getAgentInvocationMessageId, g as getLatestAgentInvocationForConversation, n as completeAgentInvocation, o as getActiveAgentInvocationForConversation, p as getAgentInvocationTurnId, r as createAgentInvocation, s as getAgentInvocation, v as isTerminalAgentInvocation, w as markAgentInvocationPaused, y as listActiveAgentInvocationsForConversation, z as agentTypeInstructions } from "./store-DyVKH0QB.js";
7
+ import { n as getAssistantReplyText } from "./assistant-reply-DN2w6JL_.js";
8
+ import { A as recordFinishedTurnForAutomatedLimit, j as resetAutomatedTurnLimit, w as maybePostAutomatedTurnLimitNotice } from "./session-stop-HKl0ECX0.js";
9
+ import { r as appendAndEnqueueInboundMessage } from "./store-CPF2kzbu.js";
10
+ import { t as ConversationTurnLifecycleService } from "./turn-lifecycle-DM_77q33.js";
11
+ import { a as persistThreadStateById, n as getPersistedSandboxState, r as getPersistedThreadState } from "./thread-state-Ds8JTsX6.js";
12
12
  import { isDeepStrictEqual } from "node:util";
13
13
  import { z } from "zod";
14
14
  // src/chat/runtime/turn-execution.ts
@@ -264,7 +264,7 @@ async function persistTerminalLifecycle(terminal) {
264
264
  await finishTurn(terminal.childConversationId, turnId, agentInvocationTurnEnd(terminal));
265
265
  }
266
266
  /** Stop an invocation whose worker died, or project its terminal turn result. */
267
- async function projectTerminalTurn(invocation) {
267
+ async function projectTerminalTurn(invocation, options = {}) {
268
268
  let turn = await getTurnRecord(invocation.childConversationId, getAgentInvocationTurnId(invocation.invocationId));
269
269
  if (!turn) return;
270
270
  if (turn.state === "running") {
@@ -281,6 +281,7 @@ async function projectTerminalTurn(invocation) {
281
281
  const failed = turn.state !== "completed" || Boolean(turn.errorMessage);
282
282
  const blocked = turn.turnStartMessageIndex === void 0 ? void 0 : readBlockedReport(turn.piMessages.slice(turn.turnStartMessageIndex));
283
283
  return await completeAgentInvocation({
284
+ ...options,
284
285
  invocationId: invocation.invocationId,
285
286
  ...failed ? {
286
287
  errorMessage: turn.errorMessage ?? "Agent invocation failed",
@@ -294,6 +295,20 @@ async function projectTerminalTurn(invocation) {
294
295
  }
295
296
  });
296
297
  }
298
+ /**
299
+ * End an agent invocation that is still running or paused while other work
300
+ * of its child starts. A saved finished Turn gives its result. Otherwise it
301
+ * fails. The newer work does not continue this task, so the result goes to
302
+ * the parent on its own.
303
+ */
304
+ async function endOtherActiveAgentInvocation(invocation) {
305
+ return await projectTerminalTurn(invocation, { reportNow: true }) ?? await completeAgentInvocation({
306
+ invocationId: invocation.invocationId,
307
+ errorMessage: "This task was not resumed. Newer work for this child agent started, so this task ended without a result.",
308
+ reportNow: true,
309
+ status: "failed"
310
+ });
311
+ }
297
312
  /** Classify authorization failures that terminally block background work. */
298
313
  function blockingInvocationError(error) {
299
314
  const cause = getConversationTurnBoundaryError(error)?.cause ?? error;
@@ -428,6 +443,7 @@ function createAgentInvocationWorker(agentRunner, options = {}) {
428
443
  await acknowledge();
429
444
  return { status: "completed" };
430
445
  }
446
+ for (const active of await listActiveAgentInvocationsForConversation(invocation.childConversationId)) if (active.invocationId !== invocation.invocationId) await finish(await endOtherActiveAgentInvocation(active));
431
447
  invocation = await markAgentInvocationRunning(invocation.invocationId) ?? invocation;
432
448
  if (isTerminalAgentInvocation(invocation)) {
433
449
  await finish(invocation);
@@ -1,10 +1,10 @@
1
1
  import { t as __exportAll } from "./rolldown-runtime-nwUcYXjP.js";
2
- import { Xn as isInvalidConversationRecordError, Yn as isFinalAttempt, qn as hasConversationStop } from "./turn-session-routing-B9KLBhaT.js";
3
- import { y as isProviderRetryError } from "./client-B2MjENki.js";
4
- import { i as getChatConfig } from "./config-Dm3pWRqY.js";
5
- import { T as withLogContext, b as setSpanAttributes, h as logWarn, m as logInfo, p as logException } from "./logging-C6EdT6PP.js";
6
- import { f as getTurnRequestDeadline, m as ConversationQueueMessageRejectedError } from "./job-queue-DiaXoSDg.js";
7
- import { C as requestAnotherSlice, T as startConversationWork, b as recordConversationRetry, d as countPendingConversationMessages, f as deadLetterAttempt, g as getConversationWorkState, i as beginConversationResume, l as completeConversationStop, m as ensureConversationWake, o as checkInConversationWork, p as drainConversationMailbox, s as clearConsumedConversationWake, t as ackMessages, u as completeConversationWork, x as releaseConversationWork, y as recordAttemptFailure } from "./store-BeWGgaMA.js";
2
+ import { Xn as isInvalidConversationRecordError, Yn as isFinalAttempt, qn as hasConversationStop } from "./turn-session-routing-BV_gX7n3.js";
3
+ import { y as isProviderRetryError } from "./client-FRphcDWW.js";
4
+ import { i as getChatConfig } from "./config-BUP9wjiR.js";
5
+ import { T as withLogContext, b as setSpanAttributes, h as logWarn, m as logInfo, p as logException } from "./logging-CjkDr-jP.js";
6
+ import { f as getTurnRequestDeadline, m as ConversationQueueMessageRejectedError } from "./job-queue-CjB97sii.js";
7
+ import { C as requestAnotherSlice, T as startConversationWork, b as recordConversationRetry, d as countPendingConversationMessages, f as deadLetterAttempt, g as getConversationWorkState, i as beginConversationResume, l as completeConversationStop, m as ensureConversationWake, o as checkInConversationWork, p as drainConversationMailbox, s as clearConsumedConversationWake, t as ackMessages, u as completeConversationWork, x as releaseConversationWork, y as recordAttemptFailure } from "./store-CPF2kzbu.js";
8
8
  // src/chat/task-execution/attempt-selection.ts
9
9
  function selectContiguousTurnBatch(messages) {
10
10
  const first = messages[0];
@@ -0,0 +1 @@
1
+ ALTER TABLE "junior_review_items" ADD COLUMN "added_by_turn_id" text;
@@ -0,0 +1,10 @@
1
+ CREATE TABLE "junior_conversation_read_positions" (
2
+ "user_id" text NOT NULL,
3
+ "conversation_id" text NOT NULL,
4
+ "last_read_seq" integer NOT NULL,
5
+ "updated_at" timestamp with time zone NOT NULL,
6
+ CONSTRAINT "junior_conversation_read_positions_user_conversation_pk" PRIMARY KEY("user_id","conversation_id")
7
+ );
8
+ --> statement-breakpoint
9
+ ALTER TABLE "junior_conversation_read_positions" ADD CONSTRAINT "junior_conversation_read_positions_user_id_junior_users_id_fk" FOREIGN KEY ("user_id") REFERENCES "public"."junior_users"("id") ON DELETE no action ON UPDATE no action;--> statement-breakpoint
10
+ ALTER TABLE "junior_conversation_read_positions" ADD CONSTRAINT "junior_conversation_read_positions_conversation_id_junior_conversations_conversation_id_fk" FOREIGN KEY ("conversation_id") REFERENCES "public"."junior_conversations"("conversation_id") ON DELETE no action ON UPDATE no action;