@sentry/junior 0.262.0 → 0.263.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 (62) hide show
  1. package/dist/{adapter-t-Y9RHML.js → adapter-BIacI0Bt.js} +1 -1
  2. package/dist/{admin-BCqeFndQ.js → admin-C7vUk7s9.js} +1 -1
  3. package/dist/{agent-hooks-9q2zdKHL.js → agent-hooks-CqnZfuCt.js} +73 -32
  4. package/dist/{agent-runner-Cx6NO5LE.js → agent-runner-BUBas7Yy.js} +123 -733
  5. package/dist/api/schema.d.ts +4 -0
  6. package/dist/api/schema.js +3 -3
  7. package/dist/api.js +28 -27
  8. package/dist/app.js +30 -29
  9. package/dist/{assistant-reply-B2qUBAwL.js → assistant-reply-BFmjgJjD.js} +1 -1
  10. package/dist/{automation-DrpcA-SX.js → automation-CWX0qL8U.js} +1 -1
  11. package/dist/{briefs-DsGH2Vym.js → briefs-h55v5lX9.js} +4 -4
  12. package/dist/{catalog-runtime-CfwKT0sn.js → catalog-runtime-Suf-aLlh.js} +1 -1
  13. package/dist/cli/chat.js +15 -15
  14. package/dist/cli/check.js +3 -3
  15. package/dist/cli/main.js +3 -3
  16. package/dist/cli/plugins.js +4 -4
  17. package/dist/cli/snapshot-create.js +4 -4
  18. package/dist/cli/upgrade.js +3 -3
  19. package/dist/{client-DpfjZgNk.js → client-DZBCBj1M.js} +2 -2
  20. package/dist/{config-BiCtNiu5.js → config-Dnv8KmNs.js} +2 -2
  21. package/dist/{connections-D9IKbfk-.js → connections-Br0_xv27.js} +10 -10
  22. package/dist/{conversation-CvuKJ3tA.js → conversation-B0baEwoA.js} +2 -0
  23. package/dist/{conversation-privacy-CBUI0frD.js → conversation-privacy-FY8yc2q3.js} +1 -1
  24. package/dist/{credential-sync-Bu6ZOuOk.js → credential-sync-BvkiyWF5.js} +14 -14
  25. package/dist/{executor-O8xqLDN6.js → executor-J9k2sp9m.js} +2 -2
  26. package/dist/{images-AM1exvU0.js → images-DV2FlEGL.js} +3 -3
  27. package/dist/instrumentation.js +2 -2
  28. package/dist/{job-queue-DmarAQGI.js → job-queue-B4yTgklN.js} +1 -1
  29. package/dist/{logging-dZN1Bvtu.js → logging-Dk_FpF36.js} +1 -1
  30. package/dist/{message-C_g2S8kv.js → message-BzseAFH1.js} +4 -3
  31. package/dist/nitro.js +3 -3
  32. package/dist/{oauth-callback-server-DvvOvr4q.js → oauth-callback-server-bTspTMCC.js} +2 -2
  33. package/dist/{profile-BP2N5uDY.js → profile-Dq5I7TV1.js} +3 -3
  34. package/dist/{prompt-DeVax2qO.js → prompt-CxatQVaj.js} +1 -1
  35. package/dist/{registry-BUje_knT.js → registry-BFzQFV_y.js} +1 -1
  36. package/dist/{resolve-DftZiYNU.js → resolve-CnRHib0U.js} +3 -3
  37. package/dist/{result-CRMRT9CE.js → result-DczfmNBa.js} +8 -7
  38. package/dist/{runner-4mmL2Pt1.js → runner-CJd9Wec-.js} +11 -11
  39. package/dist/{sandbox-egress-signals-1ysv0z5A.js → sandbox-egress-signals-DUmVkOx4.js} +1 -1
  40. package/dist/{schema-XuTZukI9.js → schema-QidbykYl.js} +2 -2
  41. package/dist/{service-account-B1sH3P7d.js → service-account-BI2kQDrb.js} +3 -3
  42. package/dist/{service-account-Del2I_x3.js → service-account-x2QZXm4X.js} +3 -3
  43. package/dist/{session-stop-ZuyOHxdK.js → session-stop-CtyJsnEj.js} +11 -11
  44. package/dist/{skills-lPeepA2b.js → skills-Dbzx9-rS.js} +2 -2
  45. package/dist/{spawn-DovpdlrW.js → spawn-D8WU99UV.js} +2 -2
  46. package/dist/store-TKg1HVKx.js +697 -0
  47. package/dist/{store-dZynGGFW.js → store-UlOrW6JC.js} +6 -6
  48. package/dist/{task-queue-CmMCtzHO.js → task-queue-BRB49H-J.js} +3 -3
  49. package/dist/{task-runner-BRgJ5e0s.js → task-runner-C575f2Dd.js} +10 -10
  50. package/dist/{tasks-Bh2qYaed.js → tasks-LOItiYgL.js} +42 -53
  51. package/dist/{thread-state-DA37FsAT.js → thread-state-IDHdZA7R.js} +5 -5
  52. package/dist/{turn-failure-response-BLcscQ-f.js → turn-failure-response-h_LSXJ-M.js} +46 -20
  53. package/dist/{turn-lifecycle-D0e887FM.js → turn-lifecycle-Cvi6Sb8Y.js} +1 -1
  54. package/dist/{turn-session-routing-DdbSbJS6.js → turn-session-routing-5Nyv4fso.js} +1 -1
  55. package/dist/{validation-DtcovXqq.js → validation-BeTriWC2.js} +1 -1
  56. package/dist/{version-JcDaJ75p.js → version-BQX_hLDC.js} +1 -1
  57. package/dist/version.js +1 -1
  58. package/dist/{viewer-oMTUVAcR.js → viewer-DmNRM88V.js} +3 -3
  59. package/dist/{web-input-FQ5wgqYn.js → web-input-BHcGXSox.js} +96 -35
  60. package/dist/{work-BiIKfayl.js → work-DLJMV02b.js} +10 -9
  61. package/dist/{worker-BZ7l75NM.js → worker-vfG2ESg1.js} +5 -5
  62. package/package.json +5 -5
@@ -1,10 +1,10 @@
1
- import { B as toOptionalNumber, V as toOptionalString, z as isRecord } from "./logging-dZN1Bvtu.js";
2
- import { i as getChatConfig } from "./config-BiCtNiu5.js";
1
+ import { B as toOptionalNumber, V as toOptionalString, z as isRecord } from "./logging-Dk_FpF36.js";
2
+ import { i as getChatConfig } from "./config-Dnv8KmNs.js";
3
3
  import { s as parseStoredSlackActor } from "./actor-tlxzqaRe.js";
4
- import { B as sameDestination, R as parseDestination, u as getConversationStore } from "./viewer-oMTUVAcR.js";
5
- import { gt as JUNIOR_THREAD_STATE_TTL_MS } from "./agent-hooks-9q2zdKHL.js";
6
- import { n as getDefaultRedisStateAdapterFor, r as getStateAdapter } from "./adapter-t-Y9RHML.js";
7
- import "./job-queue-DmarAQGI.js";
4
+ import { B as sameDestination, R as parseDestination, u as getConversationStore } from "./viewer-DmNRM88V.js";
5
+ import { gt as JUNIOR_THREAD_STATE_TTL_MS } from "./agent-hooks-CqnZfuCt.js";
6
+ import { n as getDefaultRedisStateAdapterFor, r as getStateAdapter } from "./adapter-BIacI0Bt.js";
7
+ import "./job-queue-B4yTgklN.js";
8
8
  import { z } from "zod";
9
9
  import { randomUUID } from "node:crypto";
10
10
  import { destinationSchema } from "@sentry/junior-plugin-api";
@@ -1,5 +1,5 @@
1
- import { m as logWarn } from "./logging-dZN1Bvtu.js";
2
- import { c as QUEUE_SIGNATURE_MAX_AGE_MS, d as createVercelQueueClient, l as signQueueMessage, p as runWithTurnRequestDeadline, u as verifyQueueMessage } from "./job-queue-DmarAQGI.js";
1
+ import { m as logWarn } from "./logging-Dk_FpF36.js";
2
+ import { c as QUEUE_SIGNATURE_MAX_AGE_MS, d as createVercelQueueClient, l as signQueueMessage, p as runWithTurnRequestDeadline, u as verifyQueueMessage } from "./job-queue-B4yTgklN.js";
3
3
  import { z } from "zod";
4
4
  import { createHash } from "node:crypto";
5
5
  import { handleCallback, registerDevConsumer } from "@vercel/queue";
@@ -114,7 +114,7 @@ function pluginTaskCallback() {
114
114
  maxDeliveries: PLUGIN_TASK_MAX_DELIVERIES,
115
115
  onRejected: logPluginTaskQueueMessageRejected,
116
116
  run: async (message) => {
117
- const { processPluginTask } = await import("./task-runner-BRgJ5e0s.js").then((n) => n.r);
117
+ const { processPluginTask } = await import("./task-runner-C575f2Dd.js").then((n) => n.r);
118
118
  await processPluginTask(message);
119
119
  },
120
120
  topic: PLUGIN_TASK_QUEUE_TOPIC,
@@ -1,17 +1,17 @@
1
1
  import { t as __exportAll } from "./rolldown-runtime-nwUcYXjP.js";
2
- import { $t as isToolResultError, Gn as openSlackDirectMessage, Kn as postSlackMessage, Kt as getPiMessageRole, Ln as escapeSlackMrkdwnText, Pt as getTurnRecord, Rn as formatSlackLink, Xt as instructionTextForProjection, Z as hydrateConversationMessages, en as isToolResultMessage, i as readScheduledAutomation, l as blockEventAutomation, m as getEventAutomation, rn as stripRuntimeTurnContext, rt as fallbackShortTitle, tn as normalizeToolNameFromResult } from "./tasks-Bh2qYaed.js";
3
- import { g as runBestEffort, m as logWarn } from "./logging-dZN1Bvtu.js";
2
+ import { $t as isToolResultMessage, Gt as getPiMessageRole, Kn as openSlackDirectMessage, Nt as getTurnRecord, Qt as isToolResultError, Rn as escapeSlackMrkdwnText, X as hydrateConversationMessages, Yt as instructionTextForProjection, en as normalizeToolNameFromResult, i as readScheduledAutomation, l as blockEventAutomation, m as getEventAutomation, nn as stripRuntimeTurnContext, nt as fallbackShortTitle, qn as postSlackMessage, zn as formatSlackLink } from "./tasks-LOItiYgL.js";
3
+ import { g as runBestEffort, m as logWarn } from "./logging-Dk_FpF36.js";
4
4
  import { g as parseSlackMessageTs } from "./actor-tlxzqaRe.js";
5
- import { T as agentTurnTotalTokens, d as getDb, r as readActorIdentity, u as getConversationStore, w as agentTurnCostUsd } from "./viewer-oMTUVAcR.js";
5
+ import { T as agentTurnTotalTokens, d as getDb, r as readActorIdentity, u as getConversationStore, w as agentTurnCostUsd } from "./viewer-DmNRM88V.js";
6
6
  import { s as juniorConversations } from "./agent-invocations-CxKldAeB.js";
7
- import { a as juniorAutomationRuns, s as juniorAutomations } from "./executor-O8xqLDN6.js";
7
+ import { a as juniorAutomationRuns, s as juniorAutomations } from "./executor-J9k2sp9m.js";
8
8
  import { m as sameActorIdentity } from "./history-AY8rs-FR.js";
9
- import { h as credentialSubjectSchema } from "./registry-BUje_knT.js";
10
- import { Ct as createPluginModel, Pt as createPluginConversationEvents, St as createPluginEmbedder, Xt as createPluginCache, gt as JUNIOR_THREAD_STATE_TTL_MS, p as coreTaskRegistrations, u as getPlugins, wt as createPluginLogger, xt as createPluginState, yt as getDashboardTaskLink } from "./agent-hooks-9q2zdKHL.js";
11
- import { r as getStateAdapter } from "./adapter-t-Y9RHML.js";
12
- import { r as getPersistedThreadState, s as coerceThreadConversationState } from "./thread-state-DA37FsAT.js";
13
- import { t as resolveConversationRouting } from "./turn-session-routing-DdbSbJS6.js";
14
- import { i as pluginTaskParamsSchema, o as sendVercelPluginTask, r as pluginTaskId } from "./task-queue-CmMCtzHO.js";
9
+ import { h as credentialSubjectSchema } from "./registry-BFzQFV_y.js";
10
+ import { Ct as createPluginState, Et as createPluginLogger, It as createPluginConversationEvents, Qt as createPluginCache, Tt as createPluginModel, gt as JUNIOR_THREAD_STATE_TTL_MS, p as coreTaskRegistrations, u as getPlugins, wt as createPluginEmbedder, yt as getDashboardTaskLink } from "./agent-hooks-CqnZfuCt.js";
11
+ import { r as getStateAdapter } from "./adapter-BIacI0Bt.js";
12
+ import { r as getPersistedThreadState, s as coerceThreadConversationState } from "./thread-state-IDHdZA7R.js";
13
+ import { t as resolveConversationRouting } from "./turn-session-routing-5Nyv4fso.js";
14
+ import { i as pluginTaskParamsSchema, o as sendVercelPluginTask, r as pluginTaskId } from "./task-queue-BRB49H-J.js";
15
15
  import { z } from "zod";
16
16
  import { createHash } from "node:crypto";
17
17
  import { and, asc, count, desc, eq, gte, inArray, isNotNull, lte, max, sql } from "drizzle-orm";
@@ -1,19 +1,19 @@
1
- import { a as completeText, f as unwrapCurrentInstruction, p as escapeXml, s as resolveGatewayModel, y as isProviderRetryError } from "./client-DpfjZgNk.js";
2
- import { V as toOptionalString, f as logException, m as logWarn, o as getActiveTraceId, p as logInfo, s as getLogContextAttributes, t as buildTurnFailureResponse, u as logAudit, y as setSpanAttributes, z as isRecord } from "./logging-dZN1Bvtu.js";
1
+ import { a as completeText, f as unwrapCurrentInstruction, p as escapeXml, s as resolveGatewayModel, y as isProviderRetryError } from "./client-DZBCBj1M.js";
2
+ import { V as toOptionalString, f as logException, m as logWarn, o as getActiveTraceId, p as logInfo, s as getLogContextAttributes, t as buildTurnFailureResponse, u as logAudit, y as setSpanAttributes, z as isRecord } from "./logging-Dk_FpF36.js";
3
3
  import { n as captureMessage } from "./sentry-BBUlHih9.js";
4
- import { n as botConfig, v as normalizeSlackEmojiName } from "./config-BiCtNiu5.js";
4
+ import { n as botConfig, v as normalizeSlackEmojiName } from "./config-Dnv8KmNs.js";
5
5
  import { c as toStoredSlackActor, f as parseSlackUserId, g as parseSlackMessageTs } from "./actor-tlxzqaRe.js";
6
- import { C as addAgentTurnUsage, R as parseDestination, c as getConversationEventStore, d as getDb, f as getSqlExecutor, m as withConversationEventLock, p as createSqlConversationEventStore, u as getConversationStore, x as bindProviderConversation, y as startLocationThread } from "./viewer-oMTUVAcR.js";
6
+ import { C as addAgentTurnUsage, R as parseDestination, c as getConversationEventStore, d as getDb, f as getSqlExecutor, m as withConversationEventLock, p as createSqlConversationEventStore, u as getConversationStore, x as bindProviderConversation, y as startLocationThread } from "./viewer-DmNRM88V.js";
7
7
  import { d as juniorDestinations } from "./agent-invocations-CxKldAeB.js";
8
- import { a as juniorAutomationRuns, l as juniorLocationConfigurations, o as juniorAutomationVersions, s as juniorAutomations } from "./executor-O8xqLDN6.js";
8
+ import { a as juniorAutomationRuns, l as juniorLocationConfigurations, o as juniorAutomationVersions, s as juniorAutomations } from "./executor-J9k2sp9m.js";
9
9
  import { d as contextProvenance, f as instructionActors, n as agentHistoryItemSchema, p as instructionProvenanceFor } from "./history-AY8rs-FR.js";
10
- import { _ as CredentialUnavailableError, a as resolveAuthTokenPlaceholder, f as credentialContextForActor, h as credentialSubjectSchema, o as resolvePluginCommandEnv, p as credentialContextSchema } from "./registry-BUje_knT.js";
11
- import { n as pluginCatalogRuntime } from "./catalog-runtime-CfwKT0sn.js";
12
- import { $t as agentsInstructionsUpdatedEvent, Qt as JUNIOR_NATIVE_EVENT_NAMESPACE, Xt as createPluginCache, ct as getSlackClient, dt as normalizeSlackConversationId, en as authenticationLinkedEvent, it as SlackActionError, n as applyPluginFormatMarkdown, pt as withSlackRetries, tn as authenticationUnlinkedEvent, u as getPlugins, ut as isDmChannel, wt as createPluginLogger } from "./agent-hooks-9q2zdKHL.js";
13
- import { a as acquireActiveLock, i as MUTATION_LOCK_TTL_MS, o as fenceLock, r as getStateAdapter, s as withLock } from "./adapter-t-Y9RHML.js";
14
- import { N as messageCardRef } from "./conversation-CvuKJ3tA.js";
15
- import { y as sleep } from "./profile-BP2N5uDY.js";
16
- import { A as eventAutomationSchema, E as scheduledAutomationSchema, S as automationVersionSchema } from "./automation-DrpcA-SX.js";
10
+ import { _ as CredentialUnavailableError, a as resolveAuthTokenPlaceholder, f as credentialContextForActor, h as credentialSubjectSchema, o as resolvePluginCommandEnv, p as credentialContextSchema } from "./registry-BFzQFV_y.js";
11
+ import { n as pluginCatalogRuntime } from "./catalog-runtime-Suf-aLlh.js";
12
+ import { Et as createPluginLogger, Qt as createPluginCache, ct as getSlackClient, dt as normalizeSlackConversationId, en as JUNIOR_NATIVE_EVENT_NAMESPACE, it as SlackActionError, n as applyPluginFormatMarkdown, nn as authenticationLinkedEvent, pt as withSlackRetries, rn as authenticationUnlinkedEvent, tn as agentsInstructionsUpdatedEvent, u as getPlugins, ut as isDmChannel, xt as ToolInputError } from "./agent-hooks-CqnZfuCt.js";
13
+ import { a as acquireActiveLock, i as MUTATION_LOCK_TTL_MS, o as fenceLock, r as getStateAdapter, s as withLock } from "./adapter-BIacI0Bt.js";
14
+ import { N as messageCardRef } from "./conversation-B0baEwoA.js";
15
+ import { y as sleep } from "./profile-Dq5I7TV1.js";
16
+ import { A as eventAutomationSchema, E as scheduledAutomationSchema, S as automationVersionSchema } from "./automation-CWX0qL8U.js";
17
17
  import { isDeepStrictEqual } from "node:util";
18
18
  import { z } from "zod";
19
19
  import { createHash, createHmac, randomBytes, randomUUID, timingSafeEqual } from "node:crypto";
@@ -1336,12 +1336,10 @@ const sandboxEgressAuthRequiredSignalSchema = z.object({
1336
1336
  });
1337
1337
  const sandboxEgressPermissionDeniedSignalSchema = z.object({
1338
1338
  account: pluginProviderAccountSchema.optional(),
1339
- acceptedPermissions: z.string().optional(),
1340
1339
  grant: sandboxEgressGrantSchema,
1341
1340
  message: z.string().min(1),
1342
1341
  provider: providerNameSchema,
1343
1342
  source: z.literal("upstream"),
1344
- sso: z.string().optional(),
1345
1343
  status: httpStatusSchema,
1346
1344
  upstreamHost: z.string().min(1),
1347
1345
  upstreamPath: z.string().min(1),
@@ -2007,21 +2005,6 @@ function displayedUpstreamPath(upstreamUrl) {
2007
2005
  if (upstreamUrl.hostname.toLowerCase() === "github.com" && (gitService === "git-upload-pack" || gitService === "git-receive-pack")) return `${upstreamUrl.pathname}?service=${gitService}`;
2008
2006
  return upstreamUrl.pathname;
2009
2007
  }
2010
- function upstreamPermissionAttributes(provider, upstream) {
2011
- if (provider !== "github") return {};
2012
- return {
2013
- "app.github.accepted_permissions": upstream.headers.get("x-accepted-github-permissions") ?? void 0,
2014
- "app.github.sso": upstream.headers.get("x-github-sso") ?? void 0
2015
- };
2016
- }
2017
- function githubPermissionHeaders(upstream) {
2018
- const acceptedPermissions = upstream.headers.get("x-accepted-github-permissions");
2019
- const sso = upstream.headers.get("x-github-sso");
2020
- return {
2021
- ...acceptedPermissions ? { acceptedPermissions } : void 0,
2022
- ...sso ? { sso } : void 0
2023
- };
2024
- }
2025
2008
  function permissionDeniedMessage(provider, grant) {
2026
2009
  return `${provider} returned HTTP 403 after the runtime injected the ${grant.name} grant. The request was forwarded; this is not a local runtime block.`;
2027
2010
  }
@@ -2193,8 +2176,7 @@ function leaseLogAttributes(input) {
2193
2176
  provider: input.provider,
2194
2177
  status: input.status
2195
2178
  }),
2196
- ...routingAttributes(input.request, input.upstreamUrl),
2197
- ...input.upstream ? upstreamPermissionAttributes(input.provider, input.upstream) : void 0
2179
+ ...routingAttributes(input.request, input.upstreamUrl)
2198
2180
  };
2199
2181
  }
2200
2182
  async function recordSandboxAuthRequired(input) {
@@ -2215,8 +2197,7 @@ async function recordSandboxPermissionDenied(input) {
2215
2197
  source: "upstream",
2216
2198
  status: input.upstream.status,
2217
2199
  upstreamHost: input.upstreamUrl.hostname,
2218
- upstreamPath: displayedUpstreamPath(input.upstreamUrl),
2219
- ...input.provider === "github" ? githubPermissionHeaders(input.upstream) : void 0
2200
+ upstreamPath: displayedUpstreamPath(input.upstreamUrl)
2220
2201
  });
2221
2202
  }
2222
2203
  /**
@@ -2326,13 +2307,12 @@ async function executeCredentialedEgressRequest(input) {
2326
2307
  let leaseOrResponse = await resolveLease();
2327
2308
  if (leaseOrResponse instanceof Response) return leaseOrResponse;
2328
2309
  let lease = leaseOrResponse;
2329
- const attributes = (activeLease, status, upstream) => leaseLogAttributes({
2310
+ const attributes = (activeLease, status) => leaseLogAttributes({
2330
2311
  egressId: activeEgressId,
2331
2312
  lease: activeLease,
2332
2313
  provider,
2333
2314
  request,
2334
2315
  status,
2335
- ...upstream ? { upstream } : void 0,
2336
2316
  upstreamUrl
2337
2317
  });
2338
2318
  if (!hasSandboxEgressLeaseTransformForHost(lease, upstreamUrl.hostname)) {
@@ -2387,7 +2367,7 @@ async function executeCredentialedEgressRequest(input) {
2387
2367
  authorization: error.authorization ?? lease.authorization,
2388
2368
  message: error.message
2389
2369
  });
2390
- logWarn("sandbox.egress.upstream_auth_requirement.classified", { ...attributes(lease, upstream.status, upstream) });
2370
+ logWarn("sandbox.egress.upstream_auth_requirement.classified", { ...attributes(lease, upstream.status) });
2391
2371
  await upstream.body?.cancel().catch(() => void 0);
2392
2372
  return authRequiredResponse({
2393
2373
  provider,
@@ -2406,12 +2386,12 @@ async function executeCredentialedEgressRequest(input) {
2406
2386
  upstreamUrl
2407
2387
  });
2408
2388
  if (upstream.status >= 400) logWarn("sandbox.egress.upstream_response.failed", {
2409
- ...attributes(lease, upstream.status, upstream),
2389
+ ...attributes(lease, upstream.status),
2410
2390
  "error.type": `http_${upstream.status}`
2411
2391
  });
2412
2392
  if (upstream.status === UPSTREAM_TOKEN_REJECTION_STATUS) {
2413
2393
  logWarn("sandbox.egress.upstream_auth.rejected", {
2414
- ...attributes(lease, upstream.status, upstream),
2394
+ ...attributes(lease, upstream.status),
2415
2395
  "app.sandbox.egress.www_authenticate": upstream.headers.get("www-authenticate") ?? void 0
2416
2396
  });
2417
2397
  await clearCredentialLease(provider, lease.grant, credentialContext);
@@ -2430,10 +2410,10 @@ async function executeCredentialedEgressRequest(input) {
2430
2410
  });
2431
2411
  }
2432
2412
  if (upstream.status === UPSTREAM_PERMISSION_REJECTION_STATUS && !retriedAfter403) {
2433
- logWarn("sandbox.egress.upstream_auth.rejected", { ...attributes(lease, upstream.status, upstream) });
2413
+ logWarn("sandbox.egress.upstream_auth.rejected", { ...attributes(lease, upstream.status) });
2434
2414
  await clearCredentialLease(provider, lease.grant, credentialContext);
2435
2415
  await upstream.body?.cancel().catch(() => void 0);
2436
- logWarn("sandbox.egress.upstream_auth.retrying", { ...attributes(lease, upstream.status, upstream) });
2416
+ logWarn("sandbox.egress.upstream_auth.retrying", { ...attributes(lease, upstream.status) });
2437
2417
  leaseOrResponse = await resolveLease();
2438
2418
  if (leaseOrResponse instanceof Response) return leaseOrResponse;
2439
2419
  lease = leaseOrResponse;
@@ -2441,7 +2421,7 @@ async function executeCredentialedEgressRequest(input) {
2441
2421
  continue;
2442
2422
  }
2443
2423
  if (upstream.status === UPSTREAM_PERMISSION_REJECTION_STATUS) {
2444
- logWarn("sandbox.egress.upstream_auth.rejected", { ...attributes(lease, upstream.status, upstream) });
2424
+ logWarn("sandbox.egress.upstream_auth.rejected", { ...attributes(lease, upstream.status) });
2445
2425
  await clearCredentialLease(provider, lease.grant, credentialContext);
2446
2426
  await recordPermissionDenied({
2447
2427
  credentialContext,
@@ -2451,7 +2431,7 @@ async function executeCredentialedEgressRequest(input) {
2451
2431
  upstream,
2452
2432
  upstreamUrl
2453
2433
  });
2454
- if (pluginPermissionDenied) logWarn("sandbox.egress.upstream_permission.classified", { ...attributes(lease, upstream.status, upstream) });
2434
+ if (pluginPermissionDenied) logWarn("sandbox.egress.upstream_permission.classified", { ...attributes(lease, upstream.status) });
2455
2435
  return new Response(upstream.body, {
2456
2436
  status: upstream.status,
2457
2437
  statusText: upstream.statusText,
@@ -2467,7 +2447,7 @@ async function executeCredentialedEgressRequest(input) {
2467
2447
  upstream,
2468
2448
  upstreamUrl
2469
2449
  });
2470
- logWarn("sandbox.egress.upstream_permission.classified", { ...attributes(lease, upstream.status, upstream) });
2450
+ logWarn("sandbox.egress.upstream_permission.classified", { ...attributes(lease, upstream.status) });
2471
2451
  }
2472
2452
  return new Response(upstream.body, {
2473
2453
  status: upstream.status,
@@ -2959,6 +2939,17 @@ function buildDeterministicAssistantMessageId(turnId) {
2959
2939
  * both in sync without requiring the full prompt module.
2960
2940
  */
2961
2941
  const TURN_CONTEXT_TAG = "runtime-turn-context";
2942
+ /** Turn context section that only session context includes. */
2943
+ const SESSION_CONTEXT_SECTION_TAG = "runtime";
2944
+ /**
2945
+ * Turn context sections that are true only for the Turn that received them.
2946
+ * Context compaction removes them from the context of earlier Turns.
2947
+ */
2948
+ const REQUEST_CONTEXT_SECTION_TAG = {
2949
+ pluginContext: "plugin-context",
2950
+ conversationNotes: "conversation-notes",
2951
+ disabledTools: "disabled-tools"
2952
+ };
2962
2953
  // src/chat/pi/transcript.ts
2963
2954
  const RUNTIME_TURN_CONTEXT_START = `<${TURN_CONTEXT_TAG}>`;
2964
2955
  const AGENTS_INSTRUCTIONS_START = "# AGENTS.md instructions";
@@ -3293,6 +3284,7 @@ const storedTurnRecordSchema = z.object({
3293
3284
  errorMessage: z.string().optional(),
3294
3285
  cumulativeToolCallCount: z.number().int().nonnegative().optional(),
3295
3286
  turnLimitWrappedUp: z.boolean().optional(),
3287
+ lostWorkerResumeCount: z.number().int().nonnegative().optional(),
3296
3288
  turnStartSeq: seqCursorSchema.optional(),
3297
3289
  runtimeContext: z.array(piMessageSchema).optional()
3298
3290
  }).strip();
@@ -3390,6 +3382,7 @@ function materializeTurnRecord(stored, piProjection, turnStartMessageIndex, runt
3390
3382
  credentialSubject: stored.credentialSubject,
3391
3383
  cumulativeToolCallCount: stored.cumulativeToolCallCount,
3392
3384
  turnLimitWrappedUp: stored.turnLimitWrappedUp,
3385
+ lostWorkerResumeCount: stored.lostWorkerResumeCount,
3393
3386
  cumulativeUsage: runtimeMetrics?.cumulativeUsage,
3394
3387
  dispatchId: stored.dispatchId,
3395
3388
  dispatchOutcome: stored.dispatchOutcome,
@@ -3461,6 +3454,7 @@ function buildStoredRecord(args) {
3461
3454
  credentialSubject: args.credentialSubject,
3462
3455
  cumulativeToolCallCount: args.cumulativeToolCallCount,
3463
3456
  turnLimitWrappedUp: args.turnLimitWrappedUp,
3457
+ lostWorkerResumeCount: args.lostWorkerResumeCount,
3464
3458
  dispatchId: args.dispatchId,
3465
3459
  dispatchOutcome: args.dispatchOutcome,
3466
3460
  errorMessage: args.errorMessage,
@@ -3538,6 +3532,7 @@ async function updateTurnState(args) {
3538
3532
  credentialSubject: args.existing.credentialSubject,
3539
3533
  cumulativeToolCallCount: args.existing.cumulativeToolCallCount,
3540
3534
  turnLimitWrappedUp: args.existing.turnLimitWrappedUp,
3535
+ lostWorkerResumeCount: args.existing.lostWorkerResumeCount,
3541
3536
  dispatchId: args.existing.dispatchId,
3542
3537
  dispatchOutcome: args.existing.dispatchOutcome,
3543
3538
  errorMessage: args.errorMessage ?? args.existing.errorMessage,
@@ -3613,6 +3608,7 @@ async function upsertTurnRecordLocked(args, fence) {
3613
3608
  credentialSubject: existingRecord?.credentialSubject ?? args.credentialSubject,
3614
3609
  cumulativeToolCallCount: args.cumulativeToolCallCount ?? existingRecord?.cumulativeToolCallCount,
3615
3610
  turnLimitWrappedUp: args.turnLimitWrappedUp ?? existingRecord?.turnLimitWrappedUp,
3611
+ lostWorkerResumeCount: args.lostWorkerResumeCount ?? existingRecord?.lostWorkerResumeCount,
3616
3612
  dispatchId,
3617
3613
  dispatchOutcome: args.dispatchOutcome ?? existingRecord?.dispatchOutcome,
3618
3614
  errorMessage: args.errorMessage,
@@ -3796,7 +3792,8 @@ function sharedWrite(args, latest) {
3796
3792
  traceId: getActiveTraceId() ?? latest?.traceId,
3797
3793
  turnStartMessageIndex: args.turnStartMessageIndex ?? latest?.turnStartMessageIndex,
3798
3794
  cumulativeToolCallCount: args.cumulativeToolCallCount ?? latest?.cumulativeToolCallCount,
3799
- turnLimitWrappedUp: args.turnLimitWrappedUp ?? latest?.turnLimitWrappedUp
3795
+ turnLimitWrappedUp: args.turnLimitWrappedUp ?? latest?.turnLimitWrappedUp,
3796
+ lostWorkerResumeCount: args.lostWorkerResumeCount ?? latest?.lostWorkerResumeCount
3800
3797
  })
3801
3798
  };
3802
3799
  }
@@ -5329,14 +5326,6 @@ async function recordGuardianActionReviewed(args) {
5329
5326
  createdAtMs: Date.now()
5330
5327
  }]);
5331
5328
  }
5332
- // src/chat/tools/execution/tool-input-error.ts
5333
- /** Thrown when a tool fails due to invalid model/user input, not a system error. */
5334
- var ToolInputError = class extends Error {
5335
- constructor(message, options) {
5336
- super(message, options);
5337
- this.name = "ToolInputError";
5338
- }
5339
- };
5340
5329
  // src/chat/automations/revision.ts
5341
5330
  /** Storage revisions prevent stale edits from replacing newer values. */
5342
5331
  var AutomationConflictError = class extends ToolInputError {
@@ -5825,4 +5814,4 @@ async function saveScheduledAutomation(db, task, expectedRevision, editedBy) {
5825
5814
  async function saveScheduledAutomationInLock(db, task, current) {
5826
5815
  await writeScheduledAutomation(db, requireStoredTask(task), current);
5827
5816
  }
5828
- export { projectConversationMessages as $, createDurableLocationConfigurationService as $n, isToolResultError as $t, ToolInputError as A, parseSandboxEgressCredentialToken as An, saveTurnCheckpoint as At, recordAgentsInstructionsUpdated as B, normalizeSlackStatusText as Bn, TurnToolCallLimitExceededError as Bt, automationVersionOf as C, normalizeSandboxEgressTracePropagationDomains as Cn, abandonReplacedPendingAuth as Ct, AutomationConflictError as D, consumeSandboxEgressAuthRequiredSignal as Dn, wasPendingAuthStopped as Dt, sameDefinitionValue as E, clearSandboxEgressSignals as En, getConversationPendingAuth as Et, loadLastModelProfile as F, resolveBaseUrl as Fn, listTurnSummaries as Ft, recordGuardianActionReviewed as G, openSlackDirectMessage as Gn, extractAssistantText as Gt, recordAuthenticationLinked as H, truncateStatusText as Hn, createTurnLimitGate as Ht, loadProjection as I, startOAuthFlow as In, recordTurnSummary as It, recordToolExecutionStarted as J, uploadFilesToConversation as Jn, getUserMessageInstructionText as Jt, recordMcpProviderConnected as K, postSlackMessage as Kn, getPiMessageRole as Kt, loadTurnProjection as L, escapeSlackMrkdwnText as Ln, TURN_LIMIT_DISABLED_REASON as Lt, commitMessages as M, deliverOAuthAuthorization as Mn, completeTurnRecord as Mt, loadConnectedMcpProviders as N, formatProviderLabel as Nn, failTurnRecord as Nt, automationRevision as O, consumeSandboxEgressPermissionDeniedSignal as On, continuableMessages as Ot, loadConversationProjection as P, parseOAuthStatePayload as Pn, getTurnRecord as Pt, persistConversationMessages as Q, resolvePluginOAuthAccount as Qn, isContinuablePiBoundary as Qt, loadTurnRoute as R, formatSlackLink as Rn, TurnBudgetExceededError as Rt, automationDefinition as S, resolveSandboxEgressProviderForHost as Sn, AuthorizationPauseError as St, readAutomationVersion as T, SANDBOX_EGRESS_PROXY_PATH as Tn, clearPendingAuth as Tt, recordAuthorizationCompleted as U, addReactionToMessage as Un, isTurnExecutionLimitExceededError as Ut, recordAttachmentsDelivered as V, slackMention as Vn, buildTurnErrorResponse as Vt, recordAuthorizationRequested as W, getSlackMessagePermalink as Wn, persistWithRetry as Wt, appendConversationMessages as X, slackExternalRefIdSchema as Xn, instructionTextForProjection as Xt, recordTurnRoute as Y, slackEntitySchema as Yn, hasRuntimeTurnContext as Yt, hydrateConversationMessages as Z, getOAuthAccountProviders as Zn, isAssistantMessage as Zt, parseEventAutomationRow as _, setExperimentalFeatures as _n, PluginCredentialFailureError as _t, saveScheduledAutomation as a, TURN_CONTEXT_TAG as an, appendThreadContextMessages as at, admitEventAutomationRun as b, buildSandboxEgressNetworkPolicy as bn, AuthPausePersistenceError as bt, withScheduledAutomationLock as c, SubscribedReplyReason as cn, estimateConversationContextTokens as ct, createEventAutomation as d, getThreadStopDecision as dn, markConversationMessage as dt, isToolResultMessage as en, configValueSchema as er, persistConversationMessageSummaries as et, deleteEventAutomation as f, estimateTextTokens as fn, normalizeConversationText as ft, listEventAutomationsForTeam as g, isExperimentalFeatureEnabled as gn, createPluginEgress as gt, listDeletedEventAutomationsCreatedBy as h, getExperimentalFeatures as hn, upsertConversationMessage as ht, readScheduledAutomation as i, trimTrailingAssistantMessages as in, setConfigDefaults as ir, resolveTaskTitle as it, commitAcceptedReply as j, sandboxEgressSignalsResponseSchema as jn, abandonTurnRecord as jt, requireAutomationRevision as k, createSandboxEgressCredentialToken as kn, loadTurnCheckpoint as kt, blockEventAutomation as l, decideSubscribedThreadReply as ln, getConversationMessageSlackTs as lt, getEventAutomation as m, getAgentContextInputLimitTokens as mn, turnHasReply as mt, listScheduledAutomationsForTeam as n, retainRuntimeTurnContext as nn, piMessageFromHistoryItem as nr, settleConversationTitleWork as nt, saveScheduledAutomationInLock as o, buildDeterministicAssistantMessageId as on, buildConversationContext as ot, findMatchingEventAutomations as p, getAgentContextCompactionTriggerTokens as pn, recordDeliveredAssistantMessage as pt, recordSubscribedReplyRoute as q, removeReactionFromMessage as qn, getTerminalAssistantMessages as qt, parseScheduledAutomationRow as r, stripRuntimeTurnContext as rn, getConfigDefaults as rr, fallbackShortTitle as rt, scheduledRunId as s, buildDeterministicTurnId as sn, createConversationMemoryService as st, createScheduledAutomation as t, normalizeToolNameFromResult as tn, historyItemFromPiMessage as tr, resolveConversationTitle as tt, collectEventAutomationMatchKeys as u, getSubscribedReplyPreflightDecision as un, isHumanConversationMessage as ut, saveEventAutomation as v, executeCredentialedEgressRequest as vn, createPluginAuthOrchestration as vt, listAutomationVersions as w, shouldPropagateSandboxEgressTrace as wn, canReusePendingAuthLink as wt, eventAutomationRunLimitReason as x, resolveSandboxCommandEnvironment as xn, AuthorizationFlowDisabledError as xt, setEventAutomationStatus as y, createUserTokenStore as yn, authorizationId as yt, openConversationProjection as z, normalizeSlackReplyMarkdown as zn, TurnSliceLimitExceededError as zt };
5817
+ export { persistConversationMessageSummaries as $, resolvePluginOAuthAccount as $n, isToolResultMessage as $t, commitAcceptedReply as A, createSandboxEgressCredentialToken as An, abandonTurnRecord as At, recordAttachmentsDelivered as B, normalizeSlackReplyMarkdown as Bn, buildTurnErrorResponse as Bt, automationVersionOf as C, resolveSandboxEgressProviderForHost as Cn, canReusePendingAuthLink as Ct, AutomationConflictError as D, clearSandboxEgressSignals as Dn, continuableMessages as Dt, sameDefinitionValue as E, SANDBOX_EGRESS_PROXY_PATH as En, wasPendingAuthStopped as Et, loadProjection as F, parseOAuthStatePayload as Fn, recordTurnSummary as Ft, recordMcpProviderConnected as G, getSlackMessagePermalink as Gn, getPiMessageRole as Gt, recordAuthorizationCompleted as H, slackMention as Hn, isTurnExecutionLimitExceededError as Ht, loadTurnProjection as I, resolveBaseUrl as In, TURN_LIMIT_DISABLED_REASON as It, recordTurnRoute as J, removeReactionFromMessage as Jn, hasRuntimeTurnContext as Jt, recordSubscribedReplyRoute as K, openSlackDirectMessage as Kn, getTerminalAssistantMessages as Kt, loadTurnRoute as L, startOAuthFlow as Ln, TurnBudgetExceededError as Lt, loadConnectedMcpProviders as M, sandboxEgressSignalsResponseSchema as Mn, failTurnRecord as Mt, loadConversationProjection as N, deliverOAuthAuthorization as Nn, getTurnRecord as Nt, automationRevision as O, consumeSandboxEgressAuthRequiredSignal as On, loadTurnCheckpoint as Ot, loadLastModelProfile as P, formatProviderLabel as Pn, listTurnSummaries as Pt, projectConversationMessages as Q, getOAuthAccountProviders as Qn, isToolResultError as Qt, openConversationProjection as R, escapeSlackMrkdwnText as Rn, TurnSliceLimitExceededError as Rt, automationDefinition as S, resolveSandboxCommandEnvironment as Sn, abandonReplacedPendingAuth as St, readAutomationVersion as T, shouldPropagateSandboxEgressTrace as Tn, getConversationPendingAuth as Tt, recordAuthorizationRequested as U, truncateStatusText as Un, persistWithRetry as Ut, recordAuthenticationLinked as V, normalizeSlackStatusText as Vn, createTurnLimitGate as Vt, recordGuardianActionReviewed as W, addReactionToMessage as Wn, extractAssistantText as Wt, hydrateConversationMessages as X, slackEntitySchema as Xn, isAssistantMessage as Xt, appendConversationMessages as Y, uploadFilesToConversation as Yn, instructionTextForProjection as Yt, persistConversationMessages as Z, slackExternalRefIdSchema as Zn, isContinuablePiBoundary as Zt, parseEventAutomationRow as _, isExperimentalFeatureEnabled as _n, createPluginAuthOrchestration as _t, saveScheduledAutomation as a, SESSION_CONTEXT_SECTION_TAG as an, setConfigDefaults as ar, buildConversationContext as at, admitEventAutomationRun as b, createUserTokenStore as bn, AuthorizationFlowDisabledError as bt, withScheduledAutomationLock as c, buildDeterministicTurnId as cn, getConversationMessageSlackTs as ct, createEventAutomation as d, getSubscribedReplyPreflightDecision as dn, normalizeConversationText as dt, normalizeToolNameFromResult as en, createDurableLocationConfigurationService as er, resolveConversationTitle as et, deleteEventAutomation as f, getThreadStopDecision as fn, recordDeliveredAssistantMessage as ft, listEventAutomationsForTeam as g, getExperimentalFeatures as gn, PluginCredentialFailureError as gt, listDeletedEventAutomationsCreatedBy as h, getAgentContextInputLimitTokens as hn, createPluginEgress as ht, readScheduledAutomation as i, REQUEST_CONTEXT_SECTION_TAG as in, getConfigDefaults as ir, appendThreadContextMessages as it, commitMessages as j, parseSandboxEgressCredentialToken as jn, completeTurnRecord as jt, requireAutomationRevision as k, consumeSandboxEgressPermissionDeniedSignal as kn, saveTurnCheckpoint as kt, blockEventAutomation as l, SubscribedReplyReason as ln, isHumanConversationMessage as lt, getEventAutomation as m, getAgentContextCompactionTriggerTokens as mn, upsertConversationMessage as mt, listScheduledAutomationsForTeam as n, stripRuntimeTurnContext as nn, historyItemFromPiMessage as nr, fallbackShortTitle as nt, saveScheduledAutomationInLock as o, TURN_CONTEXT_TAG as on, createConversationMemoryService as ot, findMatchingEventAutomations as p, estimateTextTokens as pn, turnHasReply as pt, recordToolExecutionStarted as q, postSlackMessage as qn, getUserMessageInstructionText as qt, parseScheduledAutomationRow as r, trimTrailingAssistantMessages as rn, piMessageFromHistoryItem as rr, resolveTaskTitle as rt, scheduledRunId as s, buildDeterministicAssistantMessageId as sn, estimateConversationContextTokens as st, createScheduledAutomation as t, retainRuntimeTurnContext as tn, configValueSchema as tr, settleConversationTitleWork as tt, collectEventAutomationMatchKeys as u, decideSubscribedThreadReply as un, markConversationMessage as ut, saveEventAutomation as v, setExperimentalFeatures as vn, authorizationId as vt, listAutomationVersions as w, normalizeSandboxEgressTracePropagationDomains as wn, clearPendingAuth as wt, eventAutomationRunLimitReason as x, buildSandboxEgressNetworkPolicy as xn, AuthorizationPauseError as xt, setEventAutomationStatus as y, executeCredentialedEgressRequest as yn, AuthPausePersistenceError as yt, recordAgentsInstructionsUpdated as z, formatSlackLink as zn, TurnToolCallLimitExceededError as zt };
@@ -1,8 +1,8 @@
1
- import { $n as createDurableLocationConfigurationService, Q as persistConversationMessages } from "./tasks-Bh2qYaed.js";
2
- import { B as toOptionalNumber, V as toOptionalString, z as isRecord } from "./logging-dZN1Bvtu.js";
3
- import { d as getDb } from "./viewer-oMTUVAcR.js";
4
- import { gt as JUNIOR_THREAD_STATE_TTL_MS } from "./agent-hooks-9q2zdKHL.js";
5
- import { r as getStateAdapter } from "./adapter-t-Y9RHML.js";
1
+ import { Z as persistConversationMessages, er as createDurableLocationConfigurationService } from "./tasks-LOItiYgL.js";
2
+ import { B as toOptionalNumber, V as toOptionalString, z as isRecord } from "./logging-Dk_FpF36.js";
3
+ import { d as getDb } from "./viewer-DmNRM88V.js";
4
+ import { gt as JUNIOR_THREAD_STATE_TTL_MS } from "./agent-hooks-CqnZfuCt.js";
5
+ import { r as getStateAdapter } from "./adapter-BIacI0Bt.js";
6
6
  // src/chat/state/conversation.ts
7
7
  function defaultConversationState() {
8
8
  return {
@@ -1,19 +1,20 @@
1
- import { Tt as clearPendingAuth, Z as hydrateConversationMessages, dt as markConversationMessage, sn as buildDeterministicTurnId } from "./tasks-Bh2qYaed.js";
2
- import { _ as getProviderErrorAttributes, g as findProviderError, m as ProviderError, v as getProviderErrorUserMessage } from "./client-DpfjZgNk.js";
3
- import { t as buildTurnFailureResponse, z as isRecord } from "./logging-dZN1Bvtu.js";
1
+ import { X as hydrateConversationMessages, cn as buildDeterministicTurnId, ut as markConversationMessage, wt as clearPendingAuth } from "./tasks-LOItiYgL.js";
2
+ import { _ as getProviderErrorAttributes, g as findProviderError, m as ProviderError, v as getProviderErrorUserMessage } from "./client-DZBCBj1M.js";
3
+ import { t as buildTurnFailureResponse, z as isRecord } from "./logging-Dk_FpF36.js";
4
4
  import { g as parseSlackMessageTs } from "./actor-tlxzqaRe.js";
5
- import { c as getConversationEventStore, d as getDb } from "./viewer-oMTUVAcR.js";
6
- import { Lt as markTurnClosed, Rt as markTurnCompleted } from "./agent-runner-Cx6NO5LE.js";
7
- import { Gt as listConversationAnnotations } from "./agent-hooks-9q2zdKHL.js";
8
- import { F as readMessageCardRefs, I as removedCardSchema, L as resolveMessageCards } from "./conversation-CvuKJ3tA.js";
9
- import { o as persistThreadStateById, r as getPersistedThreadState, s as coerceThreadConversationState } from "./thread-state-DA37FsAT.js";
5
+ import { c as getConversationEventStore, d as getDb } from "./viewer-DmNRM88V.js";
6
+ import { qt as listConversationAnnotations } from "./agent-hooks-CqnZfuCt.js";
7
+ import { F as readMessageCardRefs, I as removedCardSchema, L as resolveMessageCards } from "./conversation-B0baEwoA.js";
8
+ import { D as parseAgentInvocationResultMessageId, J as markTurnClosed, Y as markTurnCompleted, c as getAgentInvocation, m as getAgentInvocationTurnId } from "./store-TKg1HVKx.js";
9
+ import { o as persistThreadStateById, r as getPersistedThreadState, s as coerceThreadConversationState } from "./thread-state-IDHdZA7R.js";
10
10
  // src/chat/conversations/pending-cards.ts
11
- /** Select undelivered cards and load their latest saved facts. */
12
- async function loadPendingMessageCards(conversationId) {
13
- const cards = /* @__PURE__ */ new Map();
14
- const deleted = /* @__PURE__ */ new Set();
15
- let beforeSeq;
16
- selection: while (true) {
11
+ /**
12
+ * Add the cards that tool results selected since the last visible assistant
13
+ * Message or Turn start, scanning back from `beforeSeq`. Returns the input
14
+ * message ids of the Turn start that ended the scan.
15
+ */
16
+ async function selectTurnCards(conversationId, selection, beforeSeq) {
17
+ while (true) {
17
18
  const page = await getConversationEventStore().query(conversationId, {
18
19
  beforeSeq,
19
20
  limit: 100,
@@ -25,20 +26,45 @@ async function loadPendingMessageCards(conversationId) {
25
26
  });
26
27
  for (const event of [...page.events].reverse()) {
27
28
  const data = event.data;
28
- if (data.type === "turn_started" || data.type === "message" && data.role === "assistant") break selection;
29
+ if (data.type === "turn_started") return data.inputMessageIds;
30
+ if (data.type === "message" && data.role === "assistant") return [];
29
31
  if (data.type !== "tool_result" || data.isError || typeof data.toolName !== "string" || !isRecord(data.details)) continue;
30
32
  if (data.details.timed_out === true) continue;
31
- if (Array.isArray(data.details.removedCards)) for (const ref of removedCardSchema.array().parse(data.details.removedCards)) deleted.add(JSON.stringify([ref.plugin, ref.key]));
33
+ if (Array.isArray(data.details.removedCards)) for (const ref of removedCardSchema.array().parse(data.details.removedCards)) selection.deleted.add(JSON.stringify([ref.plugin, ref.key]));
32
34
  for (const card of readMessageCardRefs(data.details)) {
33
35
  const key = JSON.stringify([card.plugin, card.key]);
34
- if (!deleted.has(key) && !cards.has(key)) cards.set(key, card);
36
+ if (!selection.deleted.has(key) && !selection.cards.has(key)) selection.cards.set(key, card);
35
37
  }
36
38
  }
37
- if (!page.hasOlder || page.events.length === 0) break;
39
+ if (!page.hasOlder || page.events.length === 0) return [];
38
40
  beforeSeq = page.events[0].seq;
39
41
  }
40
- if (cards.size === 0) return [];
41
- return resolveMessageCards([...cards.values()].reverse(), await listConversationAnnotations(getDb(), conversationId));
42
+ }
43
+ /**
44
+ * Add the cards of child agents whose results started this Turn. A child
45
+ * cannot reply to people, so its parent's reply delivers its cards.
46
+ */
47
+ async function selectChildResultCards(inputMessageIds, selection) {
48
+ const events = getConversationEventStore();
49
+ for (const messageId of [...inputMessageIds].reverse()) {
50
+ const invocationId = parseAgentInvocationResultMessageId(messageId);
51
+ const invocation = invocationId ? await getAgentInvocation(invocationId) : void 0;
52
+ if (!invocation) continue;
53
+ const turnId = getAgentInvocationTurnId(invocation.invocationId);
54
+ const terminal = await events.loadByIdempotencyKey(invocation.childConversationId, `turn:${turnId}:terminal`);
55
+ if (!terminal) continue;
56
+ await selectTurnCards(invocation.childConversationId, selection, terminal.seq);
57
+ }
58
+ }
59
+ /** Select undelivered cards and load their latest saved facts. */
60
+ async function loadPendingMessageCards(conversationId) {
61
+ const selection = {
62
+ cards: /* @__PURE__ */ new Map(),
63
+ deleted: /* @__PURE__ */ new Set()
64
+ };
65
+ await selectChildResultCards(await selectTurnCards(conversationId, selection), selection);
66
+ if (selection.cards.size === 0) return [];
67
+ return resolveMessageCards([...selection.cards.values()].reverse(), await listConversationAnnotations(getDb(), conversationId));
42
68
  }
43
69
  // src/chat/interruption-marker.ts
44
70
  const INTERRUPTED_MARKER = "\n\n[Response interrupted before completion]";
@@ -1,4 +1,4 @@
1
- import { c as getConversationEventStore } from "./viewer-oMTUVAcR.js";
1
+ import { c as getConversationEventStore } from "./viewer-DmNRM88V.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 {
@@ -34,7 +34,7 @@ function slackSourceForDestination(args) {
34
34
  * Reads parent Conversations when this Conversation has no Destination.
35
35
  */
36
36
  async function resolveConversationRouting(args) {
37
- const conversationStore = args.conversationStore ?? (await import("./viewer-oMTUVAcR.js").then((n) => n.s)).getConversationStore();
37
+ const conversationStore = args.conversationStore ?? (await import("./viewer-DmNRM88V.js").then((n) => n.s)).getConversationStore();
38
38
  const chain = await loadConversationChain(args.conversationId, conversationStore);
39
39
  let destination;
40
40
  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-CfwKT0sn.js";
2
+ import { n as pluginCatalogRuntime } from "./catalog-runtime-Suf-aLlh.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.262.0";
2
+ var version = "0.263.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-JcDaJ75p.js";
1
+ export { t as JUNIOR_VERSION } from "./version-BQX_hLDC.js";
@@ -1,9 +1,9 @@
1
1
  import { t as __exportAll } from "./rolldown-runtime-nwUcYXjP.js";
2
- import { I as GOOGLE_IDENTITY_PROVIDER, R as normalizeIdentityEmail } from "./logging-dZN1Bvtu.js";
3
- import { i as getChatConfig } from "./config-BiCtNiu5.js";
2
+ import { I as GOOGLE_IDENTITY_PROVIDER, R as normalizeIdentityEmail } from "./logging-Dk_FpF36.js";
3
+ import { i as getChatConfig } from "./config-Dnv8KmNs.js";
4
4
  import { d as parseSlackTeamId, o as parseActorUserId, u as parseSlackChannelReferenceId } from "./actor-tlxzqaRe.js";
5
5
  import { c as juniorIdentities, d as juniorDestinations, l as juniorUsers, o as conversationReadColumns, s as juniorConversations } from "./agent-invocations-CxKldAeB.js";
6
- import { _ as juniorConversationAnnotations, d as juniorConversationBindings, h as juniorConversationEvents, m as juniorConversationMetrics, p as CONVERSATION_METRICS, t as createJuniorSqlExecutor, u as juniorConversationParticipants } from "./executor-O8xqLDN6.js";
6
+ import { _ as juniorConversationAnnotations, d as juniorConversationBindings, h as juniorConversationEvents, m as juniorConversationMetrics, p as CONVERSATION_METRICS, t as createJuniorSqlExecutor, u as juniorConversationParticipants } from "./executor-J9k2sp9m.js";
7
7
  import { c as newConversationEventSchema, h as usageSchema, l as encodeHistoryPayload, o as decodeStoredConversationEvent, r as conversationEventDataSchema, s as historyReplacementSchema } from "./history-AY8rs-FR.js";
8
8
  import { randomUUID } from "node:crypto";
9
9
  import { and, asc, desc, eq, gt, gte, inArray, isNull, lt, lte, ne, or, sql } from "drizzle-orm";