@sentry/junior 0.144.0 → 0.146.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 (104) hide show
  1. package/dist/{agent-hooks-GCUTGKY3.js → agent-hooks-SLJADYE5.js} +10 -10
  2. package/dist/api/conversations/detail.d.ts +1 -0
  3. package/dist/api/schema/conversation.d.ts +2 -0
  4. package/dist/api/schema.js +1 -1
  5. package/dist/api.js +40 -22
  6. package/dist/app.js +400 -461
  7. package/dist/{catalog-runtime-DWVYKDC6.js → catalog-runtime-RQIMSDPR.js} +5 -5
  8. package/dist/chat/agent/request.d.ts +1 -1
  9. package/dist/chat/agent/resume.d.ts +6 -18
  10. package/dist/chat/agent/skills.d.ts +0 -1
  11. package/dist/chat/agent/tools.d.ts +1 -2
  12. package/dist/chat/agent-dispatch/types.d.ts +1 -1
  13. package/dist/chat/app/conversation-work.d.ts +24 -0
  14. package/dist/chat/conversations/message-search.d.ts +32 -0
  15. package/dist/chat/conversations/projection.d.ts +11 -3
  16. package/dist/chat/conversations/sql/message-search.d.ts +4 -0
  17. package/dist/chat/conversations/store.d.ts +1 -1
  18. package/dist/chat/conversations/tool-source.d.ts +5 -0
  19. package/dist/chat/db.d.ts +2 -2
  20. package/dist/chat/runtime/agent-run-outcome.d.ts +1 -1
  21. package/dist/chat/runtime/reply-executor.d.ts +5 -5
  22. package/dist/chat/runtime/slack-resume.d.ts +12 -4
  23. package/dist/chat/slack/message/attachments.d.ts +2 -0
  24. package/dist/chat/slack/message/blocks.d.ts +2 -0
  25. package/dist/chat/slack/message/content.d.ts +18 -0
  26. package/dist/chat/slack/message/identity.d.ts +7 -0
  27. package/dist/chat/slack/tools/{conversation-search.d.ts → conversation-message-search.d.ts} +21 -14
  28. package/dist/chat/slack/tools/user-lookup.d.ts +2 -1
  29. package/dist/chat/state/locks.d.ts +28 -0
  30. package/dist/chat/task-execution/checkpoint.d.ts +84 -0
  31. package/dist/chat/task-execution/paused-turn.d.ts +29 -0
  32. package/dist/chat/task-execution/queue-signing.d.ts +1 -0
  33. package/dist/chat/task-execution/queue.d.ts +7 -1
  34. package/dist/chat/task-execution/slack-work.d.ts +1 -1
  35. package/dist/chat/task-execution/state.d.ts +4 -4
  36. package/dist/chat/task-execution/store.d.ts +2 -2
  37. package/dist/chat/task-execution/turn-cursor-keys.d.ts +6 -0
  38. package/dist/chat/{state/turn-session.d.ts → task-execution/turn-cursor.d.ts} +52 -51
  39. package/dist/chat/task-execution/turn-wake.d.ts +29 -0
  40. package/dist/chat/tools/{query-conversation-events.d.ts → search-conversation-events.d.ts} +3 -3
  41. package/dist/chat/tools/types.d.ts +1 -1
  42. package/dist/{chunk-SBZP2J5Q.js → chunk-37EVZP66.js} +48 -35
  43. package/dist/{chunk-A67GZN73.js → chunk-37JJDS4H.js} +1 -1
  44. package/dist/{chunk-BBCWYXHB.js → chunk-47OSH2ZO.js} +7 -7
  45. package/dist/{chunk-4X5KM7Z6.js → chunk-AISNSNDV.js} +14 -14
  46. package/dist/{chunk-RIFJUJSI.js → chunk-B63BF443.js} +1 -1
  47. package/dist/{chunk-SSDTQDYQ.js → chunk-BLETMLRX.js} +566 -268
  48. package/dist/{chunk-I44JB7HQ.js → chunk-F7REGDKO.js} +1 -1
  49. package/dist/{chunk-DVO5VKYQ.js → chunk-FEKQHPVA.js} +5 -5
  50. package/dist/{chunk-SUK7NC5A.js → chunk-FGHADGIC.js} +2 -2
  51. package/dist/{chunk-7KAW7UF4.js → chunk-FXDDDSPL.js} +4 -4
  52. package/dist/{chunk-BEGGFVFR.js → chunk-GDQEU4I7.js} +414 -542
  53. package/dist/{chunk-UDQMY6RS.js → chunk-GYEKOX7N.js} +43 -1
  54. package/dist/{chunk-W7JFV5SB.js → chunk-H6U2U3EP.js} +14 -17
  55. package/dist/{chunk-WTX2RFJG.js → chunk-HQE6EJS5.js} +1 -1
  56. package/dist/{chunk-IUFM5JWV.js → chunk-JAL3CH4G.js} +3 -0
  57. package/dist/{chunk-E7HCWOHG.js → chunk-JLMVCNXL.js} +2 -1
  58. package/dist/{chunk-PELZ2ZSY.js → chunk-JUA6VU2Z.js} +33 -63
  59. package/dist/{chunk-SHEEZSLY.js → chunk-LVW7BLLT.js} +2 -2
  60. package/dist/{chunk-GKA74DRA.js → chunk-M6ZWP4RI.js} +1 -1
  61. package/dist/{chunk-HNO2E5WB.js → chunk-MCFIXAV5.js} +1 -1
  62. package/dist/{chunk-3GU4PWA3.js → chunk-MKRIZ4VG.js} +29 -30
  63. package/dist/{chunk-QUZJDAQQ.js → chunk-OFPYOC3M.js} +93 -90
  64. package/dist/{chunk-ZF3N3JD6.js → chunk-PB222GIA.js} +1 -1
  65. package/dist/{chunk-PKH6762I.js → chunk-PH4Q3A6W.js} +1 -1
  66. package/dist/{chunk-STFCL3K4.js → chunk-QG7OOKIN.js} +1 -1
  67. package/dist/{chunk-WSOLZJJS.js → chunk-QSXZ42KX.js} +3 -3
  68. package/dist/{chunk-44RJWAND.js → chunk-SCGVWUZX.js} +6 -6
  69. package/dist/{chunk-CNTWB2SM.js → chunk-T5GXFFLA.js} +1 -1
  70. package/dist/{chunk-LDWNYCZ6.js → chunk-TCEJ7XXM.js} +1 -1
  71. package/dist/{chunk-QE3TICD4.js → chunk-V6SRLKUB.js} +2 -2
  72. package/dist/{chunk-54JMYQYS.js → chunk-W65V465O.js} +2 -2
  73. package/dist/{chunk-KCBZSJRU.js → chunk-WR76IVA5.js} +5 -2
  74. package/dist/{chunk-ZZCTGAIT.js → chunk-X22KCSCO.js} +4 -4
  75. package/dist/{chunk-HD6BHR25.js → chunk-X2WMBTS3.js} +32 -34
  76. package/dist/{chunk-KQBXT5B7.js → chunk-ZDGHGY74.js} +6 -6
  77. package/dist/cli/chat.js +32 -32
  78. package/dist/cli/check.js +6 -6
  79. package/dist/cli/plugins.js +13 -13
  80. package/dist/cli/snapshot-create.js +9 -9
  81. package/dist/cli/upgrade.js +7 -7
  82. package/dist/{db-EFLHTBU6.js → db-WWOMXWTT.js} +9 -9
  83. package/dist/instrumentation.js +4 -4
  84. package/dist/nitro.js +4 -4
  85. package/dist/{oauth-callback-server-RO3IQKWM.js → oauth-callback-server-A6ZZX74U.js} +25 -25
  86. package/dist/{runner-LOWW7JKA.js → runner-KSGB2UAV.js} +19 -20
  87. package/dist/{skills-ZLMUG7AE.js → skills-26QPWKVS.js} +6 -6
  88. package/dist/spawn-5LAJXZ2P.js +39 -0
  89. package/dist/{validation-MAKEZNTS.js → validation-OPSRGFGH.js} +6 -6
  90. package/dist/version.js +1 -1
  91. package/dist/{work-5OAGC3I4.js → work-VMSW7STJ.js} +17 -16
  92. package/dist/worker-2JNFB7C7.js +24 -0
  93. package/package.json +5 -5
  94. package/dist/chat/agent/session.d.ts +0 -19
  95. package/dist/chat/conversations/search.d.ts +0 -24
  96. package/dist/chat/conversations/sql/search.d.ts +0 -4
  97. package/dist/chat/runtime/agent-continue-runner.d.ts +0 -37
  98. package/dist/chat/services/agent-continue.d.ts +0 -29
  99. package/dist/chat/services/turn-session-record.d.ts +0 -164
  100. package/dist/chat/slack/legacy-attachments.d.ts +0 -4
  101. package/dist/chat/slack/message.d.ts +0 -12
  102. package/dist/chat/state/turn-session-keys.d.ts +0 -6
  103. package/dist/spawn-R3LUV6RF.js +0 -38
  104. package/dist/worker-KTGGRTTP.js +0 -24
@@ -7,7 +7,7 @@ import {
7
7
  PluginCredentialFailureError,
8
8
  agentNameSchema,
9
9
  createPluginAuthOrchestration
10
- } from "./chunk-DVO5VKYQ.js";
10
+ } from "./chunk-FEKQHPVA.js";
11
11
  import {
12
12
  authorizationId
13
13
  } from "./chunk-DIB4GX3G.js";
@@ -28,7 +28,7 @@ import {
28
28
  patchMcpAuthSession,
29
29
  selectPluginGrant,
30
30
  toMcpProviderError
31
- } from "./chunk-BBCWYXHB.js";
31
+ } from "./chunk-47OSH2ZO.js";
32
32
  import {
33
33
  RetryableDeliveryError,
34
34
  actorFromRouting,
@@ -44,12 +44,12 @@ import {
44
44
  getSlackMessagePermalink,
45
45
  resolveBaseUrl,
46
46
  uploadFilesToConversation
47
- } from "./chunk-KQBXT5B7.js";
47
+ } from "./chunk-ZDGHGY74.js";
48
48
  import {
49
49
  estimateTextTokens,
50
50
  getAgentContextCompactionTriggerTokens,
51
51
  getAgentContextInputLimitTokens
52
- } from "./chunk-CNTWB2SM.js";
52
+ } from "./chunk-T5GXFFLA.js";
53
53
  import {
54
54
  AGENTS_REMOVAL_NOTICE,
55
55
  AGENTS_REPLACEMENT_NOTICE,
@@ -66,6 +66,7 @@ import {
66
66
  canReusePendingAuthLink,
67
67
  collectFiles,
68
68
  containsNoReplyMarker,
69
+ continuableMessages,
69
70
  decideReply,
70
71
  extractAssistantText,
71
72
  findSingleRepositoryDirectory,
@@ -86,17 +87,13 @@ import {
86
87
  isTurnInputCommitLostError,
87
88
  loadConnectedMcpProviders,
88
89
  loadConversationProjection,
90
+ loadTurnCheckpoint,
89
91
  loadTurnRoute,
90
- loadTurnSessionRecord,
91
92
  mergeArtifactsState,
92
93
  missingPathSearchResult,
93
94
  normalizeToLf,
94
95
  normalizeToolNameFromResult,
95
96
  openConversationProjection,
96
- persistAuthPauseSessionRecord,
97
- persistContinuationSessionRecord,
98
- persistRunningSessionRecord,
99
- persistYieldSessionRecord,
100
97
  piMessageFromHistoryItem,
101
98
  positiveInteger,
102
99
  recordAgentsInstructionsUpdated,
@@ -110,10 +107,11 @@ import {
110
107
  resolveWorkspacePath,
111
108
  retainRuntimeTurnContext,
112
109
  sanitizeAssistantText,
110
+ saveTurnCheckpoint,
113
111
  stripRuntimeTurnContext,
114
112
  trimTrailingAssistantMessages,
115
113
  truncateText
116
- } from "./chunk-BEGGFVFR.js";
114
+ } from "./chunk-GDQEU4I7.js";
117
115
  import {
118
116
  JUNIOR_THREAD_STATE_TTL_MS
119
117
  } from "./chunk-3Y47VMHV.js";
@@ -145,7 +143,7 @@ import {
145
143
  runNonInteractiveCommand,
146
144
  throwSandboxOperationError,
147
145
  wrapSandboxSetupError
148
- } from "./chunk-7KAW7UF4.js";
146
+ } from "./chunk-FXDDDSPL.js";
149
147
  import {
150
148
  SCHEDULED_TASK_SYSTEM_ACTOR,
151
149
  compactEventTask,
@@ -177,15 +175,15 @@ import {
177
175
  saveEventTask,
178
176
  scheduledTaskAttributes,
179
177
  writableEventTask
180
- } from "./chunk-ZZCTGAIT.js";
178
+ } from "./chunk-X22KCSCO.js";
181
179
  import {
182
180
  parseSlackThreadId
183
- } from "./chunk-PKH6762I.js";
181
+ } from "./chunk-PH4Q3A6W.js";
184
182
  import {
185
183
  SHORT_TITLE_MAX_LENGTH,
186
184
  generateShortTitle,
187
185
  resolveTaskTitle
188
- } from "./chunk-54JMYQYS.js";
186
+ } from "./chunk-W65V465O.js";
189
187
  import {
190
188
  ToolInputError,
191
189
  addAgentTurnUsage,
@@ -203,7 +201,7 @@ import {
203
201
  getSlackToolContext,
204
202
  readActorIdentity,
205
203
  resolveChannelCapabilities
206
- } from "./chunk-44RJWAND.js";
204
+ } from "./chunk-SCGVWUZX.js";
207
205
  import {
208
206
  SlackActionError,
209
207
  downloadPrivateSlackFile,
@@ -212,18 +210,23 @@ import {
212
210
  isConversationScopedChannel,
213
211
  normalizeSlackConversationId,
214
212
  withSlackRetries
215
- } from "./chunk-QE3TICD4.js";
213
+ } from "./chunk-V6SRLKUB.js";
216
214
  import {
217
215
  KNOWN_CONVERSATION_EVENT_TYPES,
218
216
  contextProvenance,
219
217
  getConversationEventStore,
220
- getConversationSearchStore,
218
+ getConversationMessageSearchStore,
221
219
  getConversationStore,
222
220
  getDb,
221
+ getSqlExecutor,
223
222
  instructionActors,
224
223
  instructionProvenanceFor,
225
- sameActorIdentity
226
- } from "./chunk-SBZP2J5Q.js";
224
+ sameActorIdentity,
225
+ upsertIdentity
226
+ } from "./chunk-37EVZP66.js";
227
+ import {
228
+ juniorIdentities
229
+ } from "./chunk-MCFIXAV5.js";
227
230
  import {
228
231
  SANDBOX_DATA_ROOT,
229
232
  SANDBOX_SKILLS_ROOT,
@@ -235,7 +238,7 @@ import {
235
238
  } from "./chunk-EM225ITJ.js";
236
239
  import {
237
240
  getStateAdapter
238
- } from "./chunk-UDQMY6RS.js";
241
+ } from "./chunk-GYEKOX7N.js";
239
242
  import {
240
243
  ACTIVE_TURN_COMPACTION_SUMMARY_PREFIX,
241
244
  COMPACTION_SUMMARY_PREFIX,
@@ -263,13 +266,12 @@ import {
263
266
  modelIdForProfile,
264
267
  modelProfileSchema,
265
268
  normalizeSlackEmojiName,
266
- parseTurnReasoningLevel,
267
269
  profileConfig,
268
270
  renderCurrentInstruction,
269
271
  resolveGatewayCredential,
270
272
  resolveGatewayModel,
271
273
  unwrapCurrentInstruction
272
- } from "./chunk-3GU4PWA3.js";
274
+ } from "./chunk-MKRIZ4VG.js";
273
275
  import {
274
276
  canExposeConversationPayload,
275
277
  resolveConversationPrivacy,
@@ -279,16 +281,16 @@ import {
279
281
  toGenAiMessagesTraceAttributes,
280
282
  toGenAiPayloadMetadata,
281
283
  toGenAiPayloadTraceAttributes
282
- } from "./chunk-STFCL3K4.js";
284
+ } from "./chunk-QG7OOKIN.js";
283
285
  import {
284
286
  discoverSkills,
285
287
  findSkillByName,
286
288
  loadSkillsByName,
287
289
  parseSkillInvocation
288
- } from "./chunk-SUK7NC5A.js";
290
+ } from "./chunk-FGHADGIC.js";
289
291
  import {
290
292
  pluginCatalogRuntime
291
- } from "./chunk-ZF3N3JD6.js";
293
+ } from "./chunk-PB222GIA.js";
292
294
  import {
293
295
  CredentialUnavailableError,
294
296
  OAuthProviderError,
@@ -296,7 +298,7 @@ import {
296
298
  getOAuthProviderErrorAttributes,
297
299
  resolveAuthTokenPlaceholder,
298
300
  resolvePluginCommandEnv
299
- } from "./chunk-A67GZN73.js";
301
+ } from "./chunk-37JJDS4H.js";
300
302
  import {
301
303
  credentialUserSubjectId
302
304
  } from "./chunk-RUIXF3YQ.js";
@@ -318,6 +320,7 @@ import {
318
320
  logInfo,
319
321
  logWarn,
320
322
  normalizeGenAiFinishReason,
323
+ normalizeIdentityEmail,
321
324
  serializeGenAiAttribute,
322
325
  setSpanAttributes,
323
326
  setSpanStatus,
@@ -325,7 +328,7 @@ import {
325
328
  summarizeMessageText,
326
329
  withLogContext,
327
330
  withSpan
328
- } from "./chunk-RIFJUJSI.js";
331
+ } from "./chunk-B63BF443.js";
329
332
  import {
330
333
  startInactiveSpan,
331
334
  withActiveSpan
@@ -1404,21 +1407,6 @@ function actionConfirmationRetryMessages(messages) {
1404
1407
  return retryMessages;
1405
1408
  }
1406
1409
 
1407
- // src/chat/agent/session.ts
1408
- async function restoreSessionRecord(args) {
1409
- const sessionRecordState = await loadTurnSessionRecord({
1410
- conversationId: args.conversationId,
1411
- sessionId: args.turnId
1412
- });
1413
- const { resumedFromSessionRecord, currentSliceId, existingSessionRecord } = sessionRecordState;
1414
- return {
1415
- currentSliceId,
1416
- existingSessionRecord,
1417
- resumedFromSessionRecord,
1418
- sessionRecordState
1419
- };
1420
- }
1421
-
1422
1410
  // src/chat/mcp/tool-name.ts
1423
1411
  function parseMcpProviderFromToolName(toolName) {
1424
1412
  if (!toolName.startsWith("mcp__")) return void 0;
@@ -1590,7 +1578,6 @@ async function restoreSkillRuntime(args) {
1590
1578
  const restoredSkill = await args.skillSandbox.loadSkill(skillName);
1591
1579
  if (restoredSkill) {
1592
1580
  upsertActiveSkill(args.activeSkills, restoredSkill);
1593
- args.syncLoadedSkillNamesForResume();
1594
1581
  }
1595
1582
  }
1596
1583
  if (args.invokedSkill) {
@@ -1599,7 +1586,6 @@ async function restoreSkillRuntime(args) {
1599
1586
  );
1600
1587
  if (restoredSkill) {
1601
1588
  upsertActiveSkill(args.activeSkills, restoredSkill);
1602
- args.syncLoadedSkillNamesForResume();
1603
1589
  }
1604
1590
  }
1605
1591
  }
@@ -8149,7 +8135,7 @@ function createSearchResourceEventTypesTool(catalog) {
8149
8135
  outputSchema: outputSchema2,
8150
8136
  async execute({ query, namespace, maxResults }) {
8151
8137
  const normalizedQuery = normalizeSearchText(query ?? "");
8152
- const terms = normalizedQuery.split(/\s+/).filter(Boolean);
8138
+ const terms2 = normalizedQuery.split(/\s+/).filter(Boolean);
8153
8139
  const matches = searchableResourceTypes(catalog).filter(
8154
8140
  (resourceType) => {
8155
8141
  if (namespace && resourceType.namespace !== namespace) return false;
@@ -8161,7 +8147,7 @@ function createSearchResourceEventTypesTool(catalog) {
8161
8147
  ...resourceType.suggestedEvents ?? []
8162
8148
  ].join(" ")
8163
8149
  );
8164
- return terms.every((term) => text.includes(term));
8150
+ return terms2.every((term) => text.includes(term));
8165
8151
  }
8166
8152
  );
8167
8153
  const resourceTypes = matches.slice(
@@ -9833,32 +9819,63 @@ function createSlackChannelListMessagesTool(context) {
9833
9819
  });
9834
9820
  }
9835
9821
 
9836
- // src/chat/slack/tools/conversation-search.ts
9822
+ // src/chat/slack/tools/conversation-message-search.ts
9837
9823
  import { z as z37 } from "zod";
9824
+
9825
+ // src/chat/conversations/tool-source.ts
9826
+ var CONVERSATIONS_TOOL_SOURCE = {
9827
+ id: "conversations",
9828
+ description: "Search messages and events in retained Junior conversations."
9829
+ };
9830
+
9831
+ // src/chat/slack/tools/conversation-message-search.ts
9838
9832
  var DEFAULT_LIMIT = 5;
9839
- var conversationSearchOutputSchema = juniorToolOutputSchema.extend({
9840
- query: z37.string(),
9833
+ var conversationMessageSearchOutputSchema = juniorToolOutputSchema.extend({
9834
+ channel_id: z37.string().min(1).optional(),
9841
9835
  count: z37.number().int().nonnegative(),
9842
- threads: z37.array(
9836
+ query: z37.string().optional(),
9837
+ matches: z37.array(
9843
9838
  z37.object({
9839
+ channel_id: z37.string().min(1),
9840
+ channel_name: z37.string().min(1).optional(),
9844
9841
  conversation_id: z37.string().min(1),
9845
- thread_ts: z37.string().min(1),
9842
+ excerpt: z37.string(),
9846
9843
  message_id: z37.string().min(1),
9847
9844
  message_role: z37.enum(["assistant", "user"]),
9848
9845
  message_timestamp: z37.string().datetime(),
9849
- excerpt: z37.string(),
9850
- permalink: z37.string().url().optional()
9846
+ permalink: z37.string().url().optional(),
9847
+ thread_ts: z37.string().min(1)
9851
9848
  }).strict()
9852
9849
  )
9853
9850
  });
9854
- function createSlackConversationSearchTool(scope, currentConversationId, deps = {}) {
9851
+ function resolveSearchFilters(input) {
9852
+ const query = input.query?.trim() || void 0;
9853
+ let channelId;
9854
+ if (input.channel_id != null) {
9855
+ const parsed = parseRequiredSlackChannelIdParam(
9856
+ "channel_id",
9857
+ input.channel_id
9858
+ );
9859
+ if (!parsed.ok) {
9860
+ throw new ToolInputError(parsed.error);
9861
+ }
9862
+ channelId = parsed.value;
9863
+ }
9864
+ if (!query && !channelId) {
9865
+ throw new ToolInputError(
9866
+ "Provide at least one of `query` or `channel_id`."
9867
+ );
9868
+ }
9869
+ return {
9870
+ ...channelId ? { channelId } : {},
9871
+ ...query ? { query } : {}
9872
+ };
9873
+ }
9874
+ function createSlackConversationMessageSearchTool(scope, currentConversationId, deps = {}) {
9855
9875
  return zodTool({
9856
- description: "Search prior public Junior conversation threads across the current Slack workspace. Use when the user refers to an earlier public discussion, decision, or answer that is not in the current thread. Searches retained visible user and assistant messages only.",
9876
+ description: "Search retained user and assistant messages in public Junior conversations across the current Slack workspace. Excludes the current conversation.",
9857
9877
  exposure: "deferred",
9858
- source: {
9859
- id: "conversation-history",
9860
- description: "Search retained public Junior conversation threads in the current Slack workspace."
9861
- },
9878
+ source: CONVERSATIONS_TOOL_SOURCE,
9862
9879
  annotations: {
9863
9880
  destructiveHint: false,
9864
9881
  idempotentHint: true,
@@ -9866,20 +9883,24 @@ function createSlackConversationSearchTool(scope, currentConversationId, deps =
9866
9883
  readOnlyHint: true
9867
9884
  },
9868
9885
  inputSchema: z37.object({
9869
- query: z37.string().trim().min(1).max(200).describe("Words or a short phrase to find in prior conversations."),
9870
- limit: z37.number().int().min(1).max(10).describe("Maximum number of prior conversation threads to return.").nullable().optional()
9871
- }),
9872
- outputSchema: conversationSearchOutputSchema,
9873
- execute: async ({ query, limit }) => {
9874
- const store = deps.store ?? getConversationSearchStore();
9886
+ channel_id: slackChannelIdParam(
9887
+ "Destination Slack channel ID; no active-channel default."
9888
+ ).nullable().optional(),
9889
+ query: z37.string().trim().min(1).max(200).nullable().describe("Words or phrase to match in message text.").optional(),
9890
+ limit: z37.number().int().min(1).max(10).describe(`Maximum matches. Default ${DEFAULT_LIMIT}; max 10.`).nullable().optional()
9891
+ }).strict(),
9892
+ outputSchema: conversationMessageSearchOutputSchema,
9893
+ execute: async (input) => {
9894
+ const filters = resolveSearchFilters(input);
9895
+ const store = deps.store ?? getConversationMessageSearchStore();
9875
9896
  const matches = await store.search({
9876
9897
  currentConversationId,
9877
- limit: limit ?? DEFAULT_LIMIT,
9878
- query,
9898
+ filters,
9899
+ limit: input.limit ?? DEFAULT_LIMIT,
9879
9900
  scope
9880
9901
  });
9881
9902
  const getPermalink = deps.getPermalink ?? getSlackMessagePermalink;
9882
- const threads = await Promise.all(
9903
+ const matchesOutput = await Promise.all(
9883
9904
  matches.map(async (match) => {
9884
9905
  const reference = parseSlackThreadId(match.conversationId);
9885
9906
  if (!reference || reference.channelId !== match.providerDestinationId) {
@@ -9898,14 +9919,17 @@ function createSlackConversationSearchTool(scope, currentConversationId, deps =
9898
9919
  message_role: match.role,
9899
9920
  message_timestamp: new Date(match.messageCreatedAtMs).toISOString(),
9900
9921
  excerpt: match.excerpt,
9922
+ channel_id: match.providerDestinationId,
9923
+ ...match.channelName ? { channel_name: match.channelName } : {},
9901
9924
  ...permalink ? { permalink } : {}
9902
9925
  };
9903
9926
  })
9904
9927
  );
9905
9928
  return {
9906
- query,
9907
- count: threads.length,
9908
- threads
9929
+ ...filters.query ? { query: filters.query } : {},
9930
+ ...filters.channelId ? { channel_id: filters.channelId } : {},
9931
+ count: matchesOutput.length,
9932
+ matches: matchesOutput
9909
9933
  };
9910
9934
  }
9911
9935
  });
@@ -11311,7 +11335,100 @@ function parseSlackMessageReference(input) {
11311
11335
  };
11312
11336
  }
11313
11337
 
11314
- // src/chat/slack/legacy-attachments.ts
11338
+ // src/chat/slack/message/blocks.ts
11339
+ var MAX_BLOCKS = 50;
11340
+ var MAX_CHILDREN = 50;
11341
+ var MAX_DEPTH = 16;
11342
+ var MAX_NODES = 5e3;
11343
+ var CHILD_KEYS = [
11344
+ "blocks",
11345
+ "elements",
11346
+ "fields",
11347
+ "accessory",
11348
+ "element",
11349
+ "rows",
11350
+ "cells"
11351
+ ];
11352
+ function toText(value) {
11353
+ return typeof value === "string" && value.length > 0 ? value : void 0;
11354
+ }
11355
+ function readText(value) {
11356
+ if (typeof value === "string") return toText(value);
11357
+ if (!value || typeof value !== "object") return void 0;
11358
+ return toText(value.text);
11359
+ }
11360
+ function parseChildren(value, budget, depth) {
11361
+ if (Array.isArray(value)) {
11362
+ return value.slice(0, MAX_CHILDREN).flatMap((child) => parseChildren(child, budget, depth));
11363
+ }
11364
+ return parseElement(value, budget, depth);
11365
+ }
11366
+ function parseElement(value, budget, depth) {
11367
+ if (!value || typeof value !== "object" || depth > MAX_DEPTH || budget.remainingNodes <= 0) {
11368
+ return [];
11369
+ }
11370
+ budget.remainingNodes -= 1;
11371
+ const element = value;
11372
+ const type = toText(element.type);
11373
+ const text = readText(element.text);
11374
+ if (type === "link") {
11375
+ const url = toText(element.url);
11376
+ return [
11377
+ text && url && text !== url ? `${text} (${url})` : text || url
11378
+ ].filter((part) => Boolean(part));
11379
+ }
11380
+ if (type === "button") {
11381
+ const url = toText(element.url);
11382
+ return [text && url ? `${text} (${url})` : text].filter(
11383
+ (part) => Boolean(part)
11384
+ );
11385
+ }
11386
+ if (type === "emoji") {
11387
+ const name = toText(element.name);
11388
+ return name ? [`:${name}:`] : [];
11389
+ }
11390
+ if (type === "user") {
11391
+ const userId = toText(element.user_id);
11392
+ return userId ? [`<@${userId}>`] : [];
11393
+ }
11394
+ if (type === "channel") {
11395
+ const channelId = toText(element.channel_id);
11396
+ return channelId ? [`<#${channelId}>`] : [];
11397
+ }
11398
+ if (type === "usergroup") {
11399
+ const usergroupId = toText(element.usergroup_id);
11400
+ return usergroupId ? [`<!subteam^${usergroupId}>`] : [];
11401
+ }
11402
+ if (type === "broadcast") {
11403
+ const range = toText(element.range);
11404
+ return range ? [`<!${range}>`] : [];
11405
+ }
11406
+ const parts = [
11407
+ text,
11408
+ readText(element.title),
11409
+ readText(element.description),
11410
+ readText(element.label),
11411
+ readText(element.hint),
11412
+ readText(element.placeholder),
11413
+ toText(element.alt_text),
11414
+ toText(element.provider_name),
11415
+ toText(element.fallback)
11416
+ ].filter((part) => Boolean(part));
11417
+ for (const key of CHILD_KEYS) {
11418
+ parts.push(...parseChildren(element[key], budget, depth + 1));
11419
+ }
11420
+ if (type === "checkboxes" || type === "radio_buttons") {
11421
+ parts.push(...parseChildren(element.options, budget, depth + 1));
11422
+ }
11423
+ return parts;
11424
+ }
11425
+ function renderBlockText(value) {
11426
+ if (!Array.isArray(value)) return "";
11427
+ const budget = { remainingNodes: MAX_NODES };
11428
+ return value.slice(0, MAX_BLOCKS).flatMap((block) => parseElement(block, budget, 0)).join("\n");
11429
+ }
11430
+
11431
+ // src/chat/slack/message/attachments.ts
11315
11432
  var MAX_ATTACHMENTS = 10;
11316
11433
  var MAX_FIELDS_PER_ATTACHMENT = 20;
11317
11434
  var MAX_FIELD_CHARS = 1e3;
@@ -11349,6 +11466,7 @@ function renderAttachment(raw) {
11349
11466
  const text = toStr(obj.text);
11350
11467
  const footer = toStr(obj.footer);
11351
11468
  const fields = Array.isArray(obj.fields) ? obj.fields : [];
11469
+ const blockText = renderBlockText(obj.blocks);
11352
11470
  const add = (value) => {
11353
11471
  if (!value) return;
11354
11472
  const normalized = normalizeAttachmentText(value);
@@ -11356,7 +11474,7 @@ function renderAttachment(raw) {
11356
11474
  seen.add(normalized);
11357
11475
  parts.push(normalized);
11358
11476
  };
11359
- const hasRichContent = pretext || title || text;
11477
+ const hasRichContent = pretext || title || text || blockText;
11360
11478
  if (!hasRichContent) {
11361
11479
  add(fallback);
11362
11480
  }
@@ -11372,28 +11490,19 @@ function renderAttachment(raw) {
11372
11490
  for (const field of fields.slice(0, MAX_FIELDS_PER_ATTACHMENT)) {
11373
11491
  add(renderField(field));
11374
11492
  }
11493
+ add(blockText);
11375
11494
  add(footer);
11376
11495
  return parts.join("\n");
11377
11496
  }
11378
- function renderSlackLegacyAttachmentText(input) {
11497
+ function renderAttachmentText(input) {
11379
11498
  const rendered = getAttachmentPayload(input).slice(0, MAX_ATTACHMENTS).map(renderAttachment).filter((line) => line.length > 0).map((line) => `[attachment] ${line}`).join("\n");
11380
11499
  return rendered.slice(0, MAX_ATTACHMENT_TEXT_CHARS);
11381
11500
  }
11382
- function appendSlackLegacyAttachmentText(baseText, rawMessageOrAttachments) {
11383
- const base = baseText?.trim() ?? "";
11384
- const attachmentText = renderSlackLegacyAttachmentText(
11385
- rawMessageOrAttachments
11386
- );
11387
- if (!attachmentText) return base;
11388
- if (!base) return attachmentText;
11389
- return `${base}
11390
- ${attachmentText}`;
11391
- }
11392
11501
 
11393
11502
  // src/chat/slack/tools/thread-read.ts
11394
11503
  var MAX_THREAD_READ_CHARS = 4e4;
11395
11504
  function sanitizeMessage(msg) {
11396
- const attachmentText = renderSlackLegacyAttachmentText(msg.attachments);
11505
+ const attachmentText = renderAttachmentText(msg.attachments);
11397
11506
  return {
11398
11507
  ts: msg.ts,
11399
11508
  user: msg.user,
@@ -11534,6 +11643,10 @@ function createSlackThreadReadTool(context, deps = {}) {
11534
11643
  });
11535
11644
  }
11536
11645
 
11646
+ // src/chat/slack/tools/user-lookup.ts
11647
+ import { and, eq } from "drizzle-orm";
11648
+ import { z as z50 } from "zod";
11649
+
11537
11650
  // src/chat/slack/users.ts
11538
11651
  function normalizeUser(raw) {
11539
11652
  const rawFields = raw.profile?.fields;
@@ -11674,7 +11787,6 @@ async function searchSlackUsers(options) {
11674
11787
  }
11675
11788
 
11676
11789
  // src/chat/slack/tools/user-lookup.ts
11677
- import { z as z50 } from "zod";
11678
11790
  function explicitUserLookupError(error) {
11679
11791
  if (error.apiError === "user_not_found") {
11680
11792
  return "No Slack user found for the supplied user ID.";
@@ -11693,9 +11805,52 @@ function explicitUserLookupError(error) {
11693
11805
  }
11694
11806
  return void 0;
11695
11807
  }
11696
- function createSlackUserLookupTool() {
11808
+ function slackMention(userId) {
11809
+ return `<@${userId}>`;
11810
+ }
11811
+ async function storeProfile(teamId, profile) {
11812
+ await upsertIdentity(getSqlExecutor(), {
11813
+ kind: profile.is_bot ? "service" : "user",
11814
+ provider: "slack",
11815
+ providerTenantId: teamId,
11816
+ providerSubjectId: profile.id,
11817
+ ...profile.real_name || profile.display_name ? { displayName: profile.real_name || profile.display_name } : {},
11818
+ ...profile.name ? { handle: profile.name } : {},
11819
+ ...profile.email ? { email: profile.email, emailVerified: true } : {}
11820
+ });
11821
+ }
11822
+ async function storedUserByEmail(teamId, email) {
11823
+ const emailNormalized = normalizeIdentityEmail(email);
11824
+ if (!emailNormalized) return void 0;
11825
+ const identities = await getSqlExecutor().db().select().from(juniorIdentities).where(
11826
+ and(
11827
+ eq(juniorIdentities.provider, "slack"),
11828
+ eq(juniorIdentities.providerTenantId, teamId),
11829
+ eq(juniorIdentities.kind, "user"),
11830
+ eq(juniorIdentities.emailVerified, true),
11831
+ eq(juniorIdentities.emailNormalized, emailNormalized)
11832
+ )
11833
+ ).limit(2);
11834
+ if (identities.length > 1) {
11835
+ throw new Error(
11836
+ `Multiple Slack users share verified email ${emailNormalized} in workspace ${teamId}`
11837
+ );
11838
+ }
11839
+ const identity = identities[0];
11840
+ if (!identity) return void 0;
11841
+ return {
11842
+ id: identity.providerSubjectId,
11843
+ ...identity.handle ? { name: identity.handle } : {},
11844
+ ...identity.displayName ? { real_name: identity.displayName } : {},
11845
+ ...identity.displayName ? { display_name: identity.displayName } : {},
11846
+ ...identity.email ? { email: identity.email } : {},
11847
+ is_bot: false,
11848
+ is_deleted: false
11849
+ };
11850
+ }
11851
+ function createSlackUserLookupTool(teamId) {
11697
11852
  return zodTool({
11698
- description: "Look up Slack user profiles by user ID, email, or name search. Set mode to match the identifier in value. Returns profile fields including title, status, and custom fields.",
11853
+ description: "Look up Slack user profiles by user ID, email, or name search. Returns Slack `mention` values (`<@U\u2026>`). Use a mention only when one person clearly matches; otherwise ask which person the user means.",
11699
11854
  annotations: {
11700
11855
  destructiveHint: false,
11701
11856
  idempotentHint: true,
@@ -11718,20 +11873,33 @@ function createSlackUserLookupTool() {
11718
11873
  if (!parsedUserId.ok) {
11719
11874
  throw new ToolInputError(parsedUserId.error);
11720
11875
  }
11876
+ const user = await lookupSlackUserProfile(parsedUserId.value);
11877
+ await storeProfile(teamId, user);
11721
11878
  return {
11722
11879
  mode: "user_id",
11723
- user: await lookupSlackUserProfile(parsedUserId.value)
11880
+ mention: slackMention(user.id),
11881
+ user
11724
11882
  };
11725
11883
  }
11726
11884
  if (mode === "email") {
11885
+ const stored = await storedUserByEmail(teamId, value);
11886
+ if (stored) {
11887
+ return {
11888
+ mode: "email",
11889
+ mention: slackMention(stored.id),
11890
+ user: stored
11891
+ };
11892
+ }
11727
11893
  const profile = await lookupSlackUserByEmail(value);
11728
11894
  if (!profile) {
11729
11895
  throw new ToolInputError(
11730
11896
  `No Slack user found with email address ${value}.`
11731
11897
  );
11732
11898
  }
11899
+ await storeProfile(teamId, profile);
11733
11900
  return {
11734
11901
  mode: "email",
11902
+ mention: slackMention(profile.id),
11735
11903
  user: profile
11736
11904
  };
11737
11905
  }
@@ -11741,6 +11909,9 @@ function createSlackUserLookupTool() {
11741
11909
  maxPages: 3,
11742
11910
  includeBots: false
11743
11911
  });
11912
+ if (result.users.length === 1) {
11913
+ await storeProfile(teamId, result.users[0]);
11914
+ }
11744
11915
  return {
11745
11916
  mode: "query",
11746
11917
  query: value,
@@ -11748,7 +11919,10 @@ function createSlackUserLookupTool() {
11748
11919
  searched_pages: result.searched_pages,
11749
11920
  searched_user_count: result.searched_user_count,
11750
11921
  truncated: result.truncated,
11751
- users: result.users
11922
+ users: result.users.map((user) => ({
11923
+ ...user,
11924
+ mention: slackMention(user.id)
11925
+ }))
11752
11926
  };
11753
11927
  } catch (error) {
11754
11928
  if (error instanceof SlackActionError) {
@@ -11854,7 +12028,7 @@ function getTimeZoneOffsetMinutes(timestampMs, timezone) {
11854
12028
  return Math.round((timestampMs - asUtcMs) / 6e4);
11855
12029
  }
11856
12030
 
11857
- // src/chat/tools/query-conversation-events.ts
12031
+ // src/chat/tools/search-conversation-events.ts
11858
12032
  import { z as z52 } from "zod";
11859
12033
  var DEFAULT_LIMIT3 = 25;
11860
12034
  var MAX_LIMIT = 100;
@@ -11862,40 +12036,26 @@ var MAX_EVENT_DATA_BYTES = 4e3;
11862
12036
  var MAX_EVENTS_JSON_BYTES = 2e4;
11863
12037
  var MAX_IDENTITY_CHARS = 256;
11864
12038
  var textEncoder = new TextEncoder();
11865
- var CONVERSATION_EVENTS_TOOL_SOURCE = {
11866
- id: "conversation-events",
11867
- description: "Inspect Junior's durable conversation event log for debugging runtime behavior."
11868
- };
11869
12039
  var knownEventTypeSchema = z52.enum(KNOWN_CONVERSATION_EVENT_TYPES);
11870
12040
  var projectedEventSchema = z52.object({
11871
- seq: z52.number().int().nonnegative().describe("Stable event position; use it for pagination bounds."),
11872
- history_version: z52.number().int().nonnegative().describe(
11873
- "Model-history generation. It increments when handoff or compaction replaces active model context."
11874
- ),
12041
+ seq: z52.number().int().nonnegative().describe("Stable event position for pagination."),
12042
+ history_version: z52.number().int().nonnegative().describe("Agent history generation after replacement."),
11875
12043
  created_at: z52.iso.datetime().describe("When the event was recorded."),
11876
- idempotency_key: z52.string().min(1).optional().describe("Retry-stable event identity, when one was assigned."),
11877
- data: z52.record(z52.string(), z52.unknown()).describe(
11878
- "Event data. Oversized payloads are replaced by identifying fields, payload_omitted, and payload_json_bytes."
11879
- )
12044
+ idempotency_key: z52.string().min(1).optional().describe("Retry-stable event identity, when assigned."),
12045
+ data: z52.record(z52.string(), z52.unknown()).describe("Bounded event data.")
11880
12046
  }).strict();
11881
- var queryConversationEventsOutputSchema = juniorToolOutputSchema.extend({
12047
+ var searchConversationEventsOutputSchema = juniorToolOutputSchema.extend({
11882
12048
  conversation_id: z52.string().min(1),
11883
12049
  events: z52.array(projectedEventSchema),
11884
- has_older: z52.boolean().describe(
11885
- "Whether matching events exist before this page; request them with before_seq set to the first returned seq."
11886
- ),
11887
- has_newer: z52.boolean().describe(
11888
- "Whether matching events exist after this page; request them with after_seq set to the last returned seq."
11889
- ),
11890
- omitted_event_count: z52.number().int().nonnegative().optional().describe(
11891
- "Fetched events omitted to keep this response bounded. Continue with the pagination cursor for the omitted direction."
11892
- )
12050
+ has_older: z52.boolean().describe("Whether matching older events exist."),
12051
+ has_newer: z52.boolean().describe("Whether matching newer events exist."),
12052
+ omitted_event_count: z52.number().int().nonnegative().optional().describe("Events omitted by the response byte limit.")
11893
12053
  });
11894
- function createQueryConversationEventsTool(context) {
12054
+ function createSearchConversationEventsTool(context) {
11895
12055
  return zodTool({
11896
- description: "Inspect Junior's stored turns, tool calls, handoffs, and compaction events when debugging its behavior. Returns events from the current conversation tree or another retained public conversation in the same Slack workspace, newest first by default.",
12056
+ description: "Search the durable event log for one conversation, including messages, agent history, tool results, handoffs, and compactions. Defaults to the current conversation. Outside the current conversation tree, only retained public conversations in the current Slack workspace are accessible.",
11897
12057
  exposure: "deferred",
11898
- source: CONVERSATION_EVENTS_TOOL_SOURCE,
12058
+ source: CONVERSATIONS_TOOL_SOURCE,
11899
12059
  annotations: {
11900
12060
  destructiveHint: false,
11901
12061
  idempotentHint: true,
@@ -11903,31 +12063,25 @@ function createQueryConversationEventsTool(context) {
11903
12063
  readOnlyHint: true
11904
12064
  },
11905
12065
  inputSchema: z52.object({
11906
- conversation_id: z52.string().trim().min(1).describe(
11907
- "Conversation ID to inspect, such as slack:{channelId}:{threadTs} or a child conversation id."
11908
- ),
11909
- after_seq: z52.number().int().nonnegative().nullable().describe(
11910
- "Exclusive lower bound on event seq. When set, returns the next newer page in ascending order."
11911
- ).optional(),
11912
- before_seq: z52.number().int().nonnegative().nullable().describe(
11913
- "Exclusive upper bound on event seq. Combine with defaults or after_seq to page older or bounded ranges."
12066
+ conversation_id: z52.string().trim().min(1).nullable().describe(
12067
+ "Conversation ID to search. Omit or null for the current conversation."
11914
12068
  ).optional(),
12069
+ after_seq: z52.number().int().nonnegative().nullable().describe("Exclusive event sequence lower bound; returns ascending.").optional(),
12070
+ before_seq: z52.number().int().nonnegative().nullable().describe("Exclusive event sequence upper bound.").optional(),
11915
12071
  limit: z52.number().int().min(1).max(MAX_LIMIT).nullable().describe(
11916
- `Maximum events to return. Defaults to ${DEFAULT_LIMIT3}; max ${MAX_LIMIT}.`
12072
+ `Maximum events. Default ${DEFAULT_LIMIT3}; max ${MAX_LIMIT}.`
11917
12073
  ).optional(),
11918
- types: z52.array(knownEventTypeSchema).min(1).nullable().describe(
11919
- "Optional event-type filter. Omit to return every durable event type."
11920
- ).optional()
12074
+ types: z52.array(knownEventTypeSchema).min(1).nullable().describe("Event types to include; omit for all types.").optional()
11921
12075
  }).strict(),
11922
- outputSchema: queryConversationEventsOutputSchema,
12076
+ outputSchema: searchConversationEventsOutputSchema,
11923
12077
  execute: async (input) => {
11924
12078
  const currentConversationId = context.conversationId?.trim();
11925
12079
  if (!currentConversationId) {
11926
12080
  throw new ToolInputError(
11927
- "queryConversationEvents requires an active conversation"
12081
+ "searchConversationEvents requires an active conversation"
11928
12082
  );
11929
12083
  }
11930
- const conversationId = input.conversation_id;
12084
+ const conversationId = input.conversation_id?.trim() || currentConversationId;
11931
12085
  const afterSeq = input.after_seq ?? void 0;
11932
12086
  const beforeSeq = input.before_seq ?? void 0;
11933
12087
  const limit = input.limit ?? DEFAULT_LIMIT3;
@@ -11960,7 +12114,7 @@ function createQueryConversationEventsTool(context) {
11960
12114
  const targetRoot = targetRootConversationId === conversationId ? target : await conversationStore.get({
11961
12115
  conversationId: targetRootConversationId
11962
12116
  });
11963
- assertCanQueryConversationEvents({
12117
+ assertCanSearchConversationEvents({
11964
12118
  accessScope,
11965
12119
  targetConversationId: conversationId,
11966
12120
  targetRootConversationId,
@@ -12038,7 +12192,7 @@ async function resolveRootConversationId(conversationStore, conversationId, pare
12038
12192
  }
12039
12193
  return conversationId;
12040
12194
  }
12041
- function assertCanQueryConversationEvents(args) {
12195
+ function assertCanSearchConversationEvents(args) {
12042
12196
  const {
12043
12197
  accessScope,
12044
12198
  targetConversationId,
@@ -12865,7 +13019,7 @@ function createTools(availableSkills, hooks = {}, context, options = {}) {
12865
13019
  ...createScheduledTaskTools(context)
12866
13020
  };
12867
13021
  if (context.conversationId) {
12868
- tools.queryConversationEvents = createQueryConversationEventsTool(context);
13022
+ tools.searchConversationEvents = createSearchConversationEventsTool(context);
12869
13023
  }
12870
13024
  if (context.supportsImageInput) {
12871
13025
  tools.viewImage = createViewImageTool(
@@ -12902,7 +13056,7 @@ function createTools(availableSkills, hooks = {}, context, options = {}) {
12902
13056
  tools.slackCanvasWrite = createSlackCanvasWriteTool(state);
12903
13057
  tools.slackThreadRead = createSlackThreadReadTool(slackContext);
12904
13058
  if (context.conversationId && slackContext.source.visibility === "public") {
12905
- tools.searchConversationHistory = createSlackConversationSearchTool(
13059
+ tools.searchConversationMessages = createSlackConversationMessageSearchTool(
12906
13060
  {
12907
13061
  kind: "public_provider_tenant",
12908
13062
  provider: "slack",
@@ -12916,7 +13070,7 @@ function createTools(availableSkills, hooks = {}, context, options = {}) {
12916
13070
  context.slackActionToken
12917
13071
  );
12918
13072
  }
12919
- tools.slackUserLookup = createSlackUserLookupTool();
13073
+ tools.slackUserLookup = createSlackUserLookupTool(slackContext.teamId);
12920
13074
  tools.slackListCreate = createSlackListCreateTool(state);
12921
13075
  tools.slackListAddItems = createSlackListAddItemsTool(state);
12922
13076
  tools.slackListGetItems = createSlackListGetItemsTool(state);
@@ -13561,6 +13715,46 @@ var SEARCH_TOOLS_NAME = "searchTools";
13561
13715
  var DEFAULT_MAX_RESULTS2 = 5;
13562
13716
  var MAX_RESULTS3 = 20;
13563
13717
  var MODEL_VISIBLE_DESCRIPTION_CAP = 180;
13718
+ var SEARCH_FIELD_WEIGHTS = [8, 4, 1];
13719
+ var BM25_K1 = 1.2;
13720
+ var BM25_B = 0.75;
13721
+ var SEARCH_STOP_WORDS = /* @__PURE__ */ new Set([
13722
+ "a",
13723
+ "an",
13724
+ "and",
13725
+ "are",
13726
+ "as",
13727
+ "at",
13728
+ "be",
13729
+ "by",
13730
+ "do",
13731
+ "for",
13732
+ "from",
13733
+ "how",
13734
+ "i",
13735
+ "in",
13736
+ "is",
13737
+ "it",
13738
+ "me",
13739
+ "my",
13740
+ "of",
13741
+ "on",
13742
+ "or",
13743
+ "please",
13744
+ "that",
13745
+ "the",
13746
+ "this",
13747
+ "to",
13748
+ "use",
13749
+ "we",
13750
+ "what",
13751
+ "when",
13752
+ "where",
13753
+ "which",
13754
+ "with",
13755
+ "you",
13756
+ "your"
13757
+ ]);
13564
13758
  var searchToolsSourceSchema = z58.object({
13565
13759
  id: z58.string(),
13566
13760
  description: z58.string()
@@ -13585,8 +13779,26 @@ var searchToolsOutputSchema = juniorToolOutputSchema.extend({
13585
13779
  execution_tool: z58.literal("executeTool"),
13586
13780
  tools: z58.array(searchToolsToolSchema)
13587
13781
  }).strict();
13588
- function normalize2(value) {
13589
- return value.toLowerCase().replace(/[^a-z0-9_]+/g, " ").trim();
13782
+ function terms(value) {
13783
+ const chunks = value.match(/[\p{L}\p{N}]+/gu) ?? [];
13784
+ const result = [];
13785
+ for (const chunk of chunks) {
13786
+ result.push(chunk.toLowerCase());
13787
+ const expanded = chunk.replace(/([a-z\d])([A-Z])/g, "$1 $2").replace(/([A-Z]+)([A-Z][a-z])/g, "$1 $2").toLowerCase().split(/\s+/);
13788
+ if (expanded.length > 1) {
13789
+ result.push(...expanded);
13790
+ }
13791
+ }
13792
+ return result;
13793
+ }
13794
+ function queryTerms(query) {
13795
+ return [
13796
+ ...new Set(
13797
+ terms(query).filter(
13798
+ (term) => term.length >= 2 && !SEARCH_STOP_WORDS.has(term)
13799
+ )
13800
+ )
13801
+ ];
13590
13802
  }
13591
13803
  function summarizeModelVisibleDescription(description) {
13592
13804
  const paragraph = description.split(/\n\s*\n/).map((part) => part.trim()).find(Boolean) ?? "";
@@ -13603,36 +13815,114 @@ function schemaText(schema) {
13603
13815
  return "";
13604
13816
  }
13605
13817
  }
13606
- function searchableToolText2(name, definition) {
13607
- return normalize2(
13608
- [
13609
- name,
13610
- definition.identity?.id,
13611
- definition.identity?.name,
13612
- definition.identity?.plugin,
13613
- definition.source?.id,
13614
- definition.source?.description,
13615
- definition.description,
13616
- definition.promptSnippet,
13617
- ...definition.promptGuidelines ?? [],
13618
- schemaText(definition.inputSchema),
13619
- JSON.stringify(definition.annotations ?? {})
13620
- ].filter(Boolean).join(" ")
13818
+ function searchableToolFields(name, definition) {
13819
+ return [
13820
+ terms(
13821
+ [
13822
+ name,
13823
+ definition.identity?.id,
13824
+ definition.identity?.name,
13825
+ definition.identity?.plugin
13826
+ ].filter(Boolean).join(" ")
13827
+ ),
13828
+ terms(
13829
+ [
13830
+ definition.description,
13831
+ definition.promptSnippet,
13832
+ ...definition.promptGuidelines ?? []
13833
+ ].filter(Boolean).join(" ")
13834
+ ),
13835
+ terms(
13836
+ [
13837
+ definition.source?.id,
13838
+ definition.source?.description,
13839
+ schemaText(definition.inputSchema),
13840
+ schemaText(definition.annotations ?? {})
13841
+ ].filter(Boolean).join(" ")
13842
+ )
13843
+ ];
13844
+ }
13845
+ function prepareSearchDocuments(tools, source) {
13846
+ return Object.entries(tools).filter(
13847
+ ([, definition]) => source ? definition.source?.id === source : true
13848
+ ).map(([name, definition]) => ({
13849
+ name,
13850
+ fields: searchableToolFields(name, definition)
13851
+ }));
13852
+ }
13853
+ function averageFieldLengths(documents) {
13854
+ if (documents.length === 0) {
13855
+ return SEARCH_FIELD_WEIGHTS.map(() => 0);
13856
+ }
13857
+ return SEARCH_FIELD_WEIGHTS.map(
13858
+ (_, fieldIndex) => documents.reduce(
13859
+ (total, document) => total + document.fields[fieldIndex].length,
13860
+ 0
13861
+ ) / documents.length
13621
13862
  );
13622
13863
  }
13864
+ function documentFrequencies(documents) {
13865
+ const frequencies = /* @__PURE__ */ new Map();
13866
+ for (const document of documents) {
13867
+ const uniqueTerms = new Set(document.fields.flat());
13868
+ for (const term of uniqueTerms) {
13869
+ frequencies.set(term, (frequencies.get(term) ?? 0) + 1);
13870
+ }
13871
+ }
13872
+ return frequencies;
13873
+ }
13874
+ function scoreSearchDocument(document, query, frequencies, documentCount, averageLengths) {
13875
+ return query.reduce((score, term) => {
13876
+ const documentFrequency = frequencies.get(term) ?? 0;
13877
+ if (documentFrequency === 0) {
13878
+ return score;
13879
+ }
13880
+ const weightedTermFrequency = document.fields.reduce(
13881
+ (weighted, field, fieldIndex) => {
13882
+ const termFrequency = field.filter(
13883
+ (candidate) => candidate === term
13884
+ ).length;
13885
+ if (termFrequency === 0) {
13886
+ return weighted;
13887
+ }
13888
+ const averageLength = averageLengths[fieldIndex] ?? 0;
13889
+ const lengthRatio = averageLength === 0 ? 1 : field.length / averageLength;
13890
+ return weighted + SEARCH_FIELD_WEIGHTS[fieldIndex] * (termFrequency / (1 - BM25_B + BM25_B * lengthRatio));
13891
+ },
13892
+ 0
13893
+ );
13894
+ if (weightedTermFrequency === 0) {
13895
+ return score;
13896
+ }
13897
+ const inverseDocumentFrequency = Math.log(
13898
+ 1 + (documentCount - documentFrequency + 0.5) / (documentFrequency + 0.5)
13899
+ );
13900
+ return score + inverseDocumentFrequency * weightedTermFrequency * (BM25_K1 + 1) / (weightedTermFrequency + BM25_K1);
13901
+ }, 0);
13902
+ }
13623
13903
  function searchCatalogTools(tools, query, source) {
13624
- const entries = Object.entries(tools).sort(
13625
- ([left], [right]) => left.localeCompare(right)
13626
- );
13627
- const sourceEntries = source ? entries.filter(([, definition]) => definition.source?.id === source) : entries;
13628
- if (!normalize2(query)) {
13629
- return sourceEntries.map(([name]) => name);
13904
+ const documents = prepareSearchDocuments(tools, source);
13905
+ if (!query.trim()) {
13906
+ return documents.map(({ name }) => name).sort((left, right) => left.localeCompare(right));
13907
+ }
13908
+ const searchTerms = queryTerms(query);
13909
+ if (searchTerms.length === 0) {
13910
+ return [];
13630
13911
  }
13631
- const terms = normalize2(query).split(/\s+/).filter(Boolean);
13632
- return sourceEntries.filter(([name, definition]) => {
13633
- const text = searchableToolText2(name, definition);
13634
- return terms.every((term) => text.includes(term));
13635
- }).map(([name]) => name);
13912
+ const averageLengths = averageFieldLengths(documents);
13913
+ const frequencies = documentFrequencies(documents);
13914
+ return documents.map((document) => ({
13915
+ name: document.name,
13916
+ score: scoreSearchDocument(
13917
+ document,
13918
+ searchTerms,
13919
+ frequencies,
13920
+ documents.length,
13921
+ averageLengths
13922
+ )
13923
+ })).filter(({ score }) => score > 0).sort(
13924
+ (left, right) => right.score - left.score || left.name.localeCompare(right.name)
13925
+ ).map(({ name }) => name);
13636
13926
  }
13637
13927
  function callNotes(definition) {
13638
13928
  return [
@@ -15468,7 +15758,6 @@ async function wireAgentTools(args) {
15468
15758
  );
15469
15759
  const effective = resolvedSkill ?? loadedSkill;
15470
15760
  upsertActiveSkill(args.activeSkills, effective);
15471
- args.syncLoadedSkillNamesForResume();
15472
15761
  if (await mcpToolManager.activateForSkill(effective)) {
15473
15762
  await args.recordConnectedMcpProvider(effective.pluginProvider);
15474
15763
  }
@@ -15599,6 +15888,18 @@ function extractSliceUsage(messages, beforeMessageCount) {
15599
15888
  );
15600
15889
  return hasAgentTurnUsage(usage) ? usage : void 0;
15601
15890
  }
15891
+ function boundaryKey(messages) {
15892
+ return messages.map((message) => {
15893
+ const record2 = message;
15894
+ const content = typeof record2.content === "string" ? record2.content : JSON.stringify(record2.content ?? null);
15895
+ return [
15896
+ String(record2.role ?? ""),
15897
+ String(record2.timestamp ?? ""),
15898
+ String(record2.toolCallId ?? ""),
15899
+ content
15900
+ ].join("");
15901
+ }).join("");
15902
+ }
15602
15903
  function createResumeState(args) {
15603
15904
  let beforeMessageCount = 0;
15604
15905
  let inputCommitted = false;
@@ -15607,19 +15908,26 @@ function createResumeState(args) {
15607
15908
  let resumeMessages = [];
15608
15909
  let turnContexts = [];
15609
15910
  let turnStartMessageIndex;
15610
- const currentSliceId = args.sessionRecordState.currentSliceId;
15611
- const currentDurationMs = () => Date.now() - args.startedAtMs;
15612
- const sessionRecordBase = () => ({
15613
- channelName: args.channelName,
15911
+ let advancedPastResume = !args.checkpoint.resumed;
15912
+ let resumedBoundaryKey = "";
15913
+ if (args.checkpoint.resumed && args.checkpoint.record.piMessages.length) {
15914
+ const prior = args.checkpoint.record;
15915
+ latestSafeBoundaryMessages = [...prior.piMessages];
15916
+ resumeMessages = [...prior.piMessages];
15917
+ resumedBoundaryKey = boundaryKey(
15918
+ continuableMessages(prior.piMessages, prior.piMessages)
15919
+ );
15920
+ }
15921
+ const currentSliceId = args.checkpoint.sliceId;
15922
+ const durationMs = () => Date.now() - args.startedAtMs;
15923
+ const writeBase = () => ({
15614
15924
  conversationId: args.conversationId,
15925
+ turnId: args.turnId,
15926
+ channelName: args.channelName,
15615
15927
  destination: args.destination,
15616
- ...args.destinationVisibility ? { destinationVisibility: args.destinationVisibility } : {},
15617
- ...args.dispatchId ? { dispatchId: args.dispatchId } : {},
15928
+ destinationVisibility: args.destinationVisibility,
15929
+ dispatchId: args.dispatchId,
15618
15930
  source: args.runSource,
15619
- sessionId: args.turnId,
15620
- loadedSkillNames: args.getLoadedSkillNames(),
15621
- modelId: args.getModelId(),
15622
- ...args.getReasoningLevel() ? { reasoningLevel: args.getReasoningLevel() } : {},
15623
15931
  actor: args.actor,
15624
15932
  surface: args.surface
15625
15933
  });
@@ -15642,7 +15950,7 @@ function createResumeState(args) {
15642
15950
  setTurnContexts(contexts) {
15643
15951
  turnContexts = contexts;
15644
15952
  },
15645
- /** Adopt an already committed epoch replacement as every resume baseline. */
15953
+ /** Use an already committed boundary as the resume baseline. */
15646
15954
  adoptCommittedBoundary(messages) {
15647
15955
  latestSafeBoundaryMessages = [...messages];
15648
15956
  resumeMessages = [...messages];
@@ -15664,18 +15972,23 @@ function createResumeState(args) {
15664
15972
  inputCommitted = true;
15665
15973
  },
15666
15974
  async persistSafeBoundary(messages, trailingMessageProvenance) {
15667
- const persisted = await persistRunningSessionRecord({
15668
- ...sessionRecordBase(),
15975
+ const saved = await saveTurnCheckpoint({
15976
+ mode: "running",
15977
+ ...writeBase(),
15669
15978
  sliceId: currentSliceId,
15670
15979
  messages,
15671
- ...trailingMessageProvenance ? { trailingMessageProvenance } : {},
15672
- ...turnContexts.length > 0 ? { turnContexts } : {},
15673
- ...turnStartMessageIndex !== void 0 ? { turnStartMessageIndex } : {}
15980
+ trailingMessageProvenance,
15981
+ turnContexts: turnContexts.length > 0 ? turnContexts : void 0,
15982
+ turnStartMessageIndex
15674
15983
  });
15675
- if (!persisted) {
15984
+ if (!saved) {
15676
15985
  return false;
15677
15986
  }
15678
15987
  latestSafeBoundaryMessages = [...messages];
15988
+ const persistedKey = boundaryKey(continuableMessages(messages, messages));
15989
+ if (resumedBoundaryKey.length === 0 || persistedKey !== resumedBoundaryKey) {
15990
+ advancedPastResume = true;
15991
+ }
15679
15992
  return true;
15680
15993
  },
15681
15994
  async requireDurableInputCheckpoint(messages, trailingMessageProvenance) {
@@ -15690,34 +16003,34 @@ function createResumeState(args) {
15690
16003
  }
15691
16004
  return persisted;
15692
16005
  },
15693
- /** Prepare a cooperative yield at the current durable boundary. */
15694
16006
  prepareYieldIfDue(currentMessages) {
15695
16007
  if (!args.durability.shouldYield?.()) {
15696
16008
  return void 0;
15697
16009
  }
15698
- const nextResumeMessages = this.getResumeSnapshot(currentMessages);
15699
- if (!isContinuablePiBoundary(nextResumeMessages)) {
16010
+ const next = this.getResumeSnapshot(currentMessages);
16011
+ if (!isContinuablePiBoundary(next)) {
15700
16012
  return void 0;
15701
16013
  }
15702
- resumeMessages = nextResumeMessages;
16014
+ resumeMessages = next;
15703
16015
  return new CooperativeTurnYieldError(
15704
- `Agent turn yielded at a safe boundary after ${currentDurationMs()}ms`
16016
+ `Agent turn yielded at a safe boundary after ${durationMs()}ms`
15705
16017
  );
15706
16018
  },
15707
- /** Persist an auth pause; only a durable pause may return `awaiting_auth`. */
15708
16019
  async parkForAuth(pause, currentUsage) {
15709
16020
  const usage = currentUsage ?? (resumeMessages.length > 0 ? extractSliceUsage(resumeMessages, beforeMessageCount) : void 0);
15710
16021
  try {
15711
16022
  await args.recordActiveMcpProviders();
15712
- const sessionRecord = await persistAuthPauseSessionRecord({
15713
- ...sessionRecordBase(),
15714
- currentSliceId,
15715
- currentDurationMs: currentDurationMs(),
15716
- currentUsage: usage,
16023
+ const record2 = await saveTurnCheckpoint({
16024
+ mode: "paused",
16025
+ reason: "auth",
16026
+ ...writeBase(),
16027
+ sliceId: currentSliceId,
16028
+ durationMs: durationMs(),
16029
+ usage,
15717
16030
  messages: resumeMessages,
15718
16031
  errorMessage: pause.message
15719
16032
  });
15720
- if (!sessionRecord) {
16033
+ if (!record2) {
15721
16034
  throw new AuthPausePersistenceError(args.conversationId, args.turnId);
15722
16035
  }
15723
16036
  return {
@@ -15727,7 +16040,7 @@ function createResumeState(args) {
15727
16040
  ...usage ? { usage } : {}
15728
16041
  };
15729
16042
  } catch (error) {
15730
- if (error instanceof AuthPausePersistenceError) {
16043
+ if (error instanceof AuthPausePersistenceError || error instanceof TurnSliceLimitExceededError) {
15731
16044
  throw error;
15732
16045
  }
15733
16046
  throw new AuthPausePersistenceError(
@@ -15737,62 +16050,61 @@ function createResumeState(args) {
15737
16050
  );
15738
16051
  }
15739
16052
  },
15740
- /** Persist a yield, retry, or timeout as a suspended run. */
15741
16053
  async translateSuspension(ending) {
15742
16054
  const { error } = ending;
15743
- if (error instanceof CooperativeTurnYieldError) {
15744
- const usage = ending.currentUsage ?? extractSliceUsage(resumeMessages, beforeMessageCount);
15745
- await args.recordActiveMcpProviders();
15746
- const sessionRecord = await persistYieldSessionRecord({
15747
- ...sessionRecordBase(),
15748
- currentSliceId,
15749
- currentDurationMs: currentDurationMs(),
15750
- currentUsage: usage,
15751
- messages: resumeMessages,
15752
- errorMessage: error.message
16055
+ const reason = error instanceof CooperativeTurnYieldError ? "yield" : error instanceof RetryableDeliveryError ? "retry" : timedOut ? "timeout" : void 0;
16056
+ if (!reason) {
16057
+ return void 0;
16058
+ }
16059
+ if (reason === "retry") {
16060
+ resumeMessages = [...latestSafeBoundaryMessages];
16061
+ }
16062
+ const parkMessages = reason === "yield" ? [...resumeMessages] : continuableMessages(resumeMessages, latestSafeBoundaryMessages);
16063
+ const parkKey = boundaryKey(parkMessages);
16064
+ if (!advancedPastResume && resumedBoundaryKey.length > 0 && parkKey === resumedBoundaryKey) {
16065
+ logWarn("agent.turn.no_progress_fail", {
16066
+ "app.ai.resume_conversation_id": args.conversationId,
16067
+ "app.ai.resume_session_id": args.turnId,
16068
+ "app.ai.resume_slice_id": currentSliceId,
16069
+ "app.ai.resume_reason": reason
15753
16070
  });
15754
- if (!sessionRecord) {
15755
- throw new Error(
15756
- `Failed to persist cooperative yield continuation for conversation=${args.conversationId} turn=${args.turnId}`
15757
- );
15758
- }
16071
+ await saveTurnCheckpoint({
16072
+ mode: "failed",
16073
+ ...writeBase(),
16074
+ sliceId: currentSliceId,
16075
+ durationMs: durationMs(),
16076
+ messages: parkMessages,
16077
+ errorMessage: "Turn made no progress: continue parked at the same boundary"
16078
+ });
16079
+ throw new Error(
16080
+ `Turn made no progress for conversation=${args.conversationId} turn=${args.turnId}`
16081
+ );
16082
+ }
16083
+ const usage = ending.currentUsage ?? extractSliceUsage(parkMessages, beforeMessageCount);
16084
+ await args.recordActiveMcpProviders();
16085
+ const record2 = await saveTurnCheckpoint({
16086
+ mode: "paused",
16087
+ reason,
16088
+ ...writeBase(),
16089
+ sliceId: currentSliceId,
16090
+ durationMs: durationMs(),
16091
+ usage,
16092
+ messages: parkMessages,
16093
+ errorMessage: error instanceof Error ? error.message : String(error)
16094
+ });
16095
+ if (!record2) {
16096
+ throw new Error(
16097
+ `Failed to persist continuation for conversation=${args.conversationId} turn=${args.turnId}`
16098
+ );
16099
+ }
16100
+ if (record2.state === "paused") {
15759
16101
  return {
15760
16102
  status: "suspended",
15761
- resumeVersion: sessionRecord.version,
16103
+ resumeVersion: record2.version,
15762
16104
  ...usage ? { usage } : {}
15763
16105
  };
15764
16106
  }
15765
- const resumeReason = error instanceof RetryableDeliveryError ? "retry" : timedOut ? "timeout" : void 0;
15766
- if (resumeReason) {
15767
- if (resumeReason === "retry") {
15768
- resumeMessages = [...latestSafeBoundaryMessages];
15769
- }
15770
- const usage = ending.currentUsage ?? extractSliceUsage(resumeMessages, beforeMessageCount);
15771
- await args.recordActiveMcpProviders();
15772
- const sessionRecord = await persistContinuationSessionRecord({
15773
- ...sessionRecordBase(),
15774
- currentSliceId,
15775
- currentDurationMs: currentDurationMs(),
15776
- currentUsage: usage,
15777
- messages: resumeMessages,
15778
- errorMessage: error instanceof Error ? error.message : String(error),
15779
- resumeReason
15780
- });
15781
- if (!sessionRecord) {
15782
- throw new Error(
15783
- `Failed to persist continuation for conversation=${args.conversationId} turn=${args.turnId}`
15784
- );
15785
- }
15786
- if (sessionRecord.state === "awaiting_resume") {
15787
- return {
15788
- status: "suspended",
15789
- resumeVersion: sessionRecord.version,
15790
- ...usage ? { usage } : {}
15791
- };
15792
- }
15793
- throw new TurnSliceLimitExceededError(botConfig.maxSlicesPerTurn);
15794
- }
15795
- return void 0;
16107
+ throw new TurnSliceLimitExceededError(botConfig.maxSlicesPerTurn);
15796
16108
  }
15797
16109
  };
15798
16110
  }
@@ -16482,20 +16794,11 @@ async function executeAgentRunInPrivacyContext(request, conversationPrivacy, run
16482
16794
  const skillInvocation = parseSkillInvocation(userInput, availableSkills);
16483
16795
  const invokedSkill = skillInvocation ? findSkillByName(skillInvocation.skillName, availableSkills) : null;
16484
16796
  const activeSkills = [];
16485
- let loadedSkillNamesForResume = [];
16486
- const syncLoadedSkillNamesForResume = () => {
16487
- loadedSkillNamesForResume = activeSkills.map((skill) => skill.name);
16488
- };
16489
16797
  const skillSandbox = new SkillSandbox(availableSkills, activeSkills);
16490
- const {
16491
- sessionRecordState,
16492
- resumedFromSessionRecord,
16493
- currentSliceId,
16494
- existingSessionRecord
16495
- } = await restoreSessionRecord({
16496
- conversationId,
16497
- turnId
16498
- });
16798
+ const checkpoint = await loadTurnCheckpoint({ conversationId, turnId });
16799
+ const resumedFromSessionRecord = checkpoint.resumed;
16800
+ const currentSliceId = checkpoint.sliceId;
16801
+ const existingSessionRecord = checkpoint.record;
16499
16802
  const committedInstructionProvenance = [
16500
16803
  ...existingSessionRecord?.piMessageProvenance ?? [],
16501
16804
  ...(existingSessionRecord?.actors ?? []).map(instructionProvenanceFor),
@@ -16525,15 +16828,12 @@ async function executeAgentRunInPrivacyContext(request, conversationPrivacy, run
16525
16828
  ...routing.destinationVisibility ? { destinationVisibility: routing.destinationVisibility } : {},
16526
16829
  ...routing.dispatch?.id ? { dispatchId: routing.dispatch.id } : {},
16527
16830
  durability,
16528
- getLoadedSkillNames: () => loadedSkillNamesForResume,
16529
- getReasoningLevel: () => turnRoute?.reasoningLevel,
16530
- getModelId: () => activeModelId,
16531
16831
  recordActiveMcpProviders,
16532
16832
  actor,
16533
16833
  runSource,
16534
16834
  conversationId,
16535
16835
  turnId,
16536
- sessionRecordState,
16836
+ checkpoint,
16537
16837
  startedAtMs: replyStartedAtMs,
16538
16838
  surface
16539
16839
  });
@@ -16565,8 +16865,7 @@ async function executeAgentRunInPrivacyContext(request, conversationPrivacy, run
16565
16865
  activeSkills,
16566
16866
  invokedSkill,
16567
16867
  priorPiMessages,
16568
- skillSandbox,
16569
- syncLoadedSkillNamesForResume
16868
+ skillSandbox
16570
16869
  });
16571
16870
  const explicitSkill = invokedSkill ? activeSkills.find((skill) => skill.name === invokedSkill.name) ?? null : null;
16572
16871
  const { contextContentParts, routerBlocks, userContentParts } = buildPromptInput(input);
@@ -16580,10 +16879,9 @@ async function executeAgentRunInPrivacyContext(request, conversationPrivacy, run
16580
16879
  botConfig,
16581
16880
  activeModelProfile
16582
16881
  );
16583
- const resumedReasoningLevel = existingSessionRecord?.reasoningLevel ? parseTurnReasoningLevel(existingSessionRecord.reasoningLevel) : void 0;
16584
16882
  turnRoute = {
16585
16883
  profile: activeModelProfile,
16586
- reasoningLevel: activeProfileConfig.reasoningLevel ?? resumedReasoningLevel ?? storedTurnRoute.reasoningLevel,
16884
+ reasoningLevel: activeProfileConfig.reasoningLevel ?? storedTurnRoute.reasoningLevel,
16587
16885
  reason: `resumed_handoff:${storedTurnRoute.modelProfile}:${activeModelProfile}`
16588
16886
  };
16589
16887
  } else {
@@ -16793,7 +17091,6 @@ async function executeAgentRunInPrivacyContext(request, conversationPrivacy, run
16793
17091
  state,
16794
17092
  supportsImageInput: () => resolveGatewayModel(activeModelId).input.includes("image"),
16795
17093
  surface,
16796
- syncLoadedSkillNamesForResume,
16797
17094
  toolCalls,
16798
17095
  userInput
16799
17096
  });
@@ -17134,6 +17431,7 @@ async function executeAgentRunInPrivacyContext(request, conversationPrivacy, run
17134
17431
  runResume.setTurnStartMessageIndex(
17135
17432
  existingSessionRecord.turnStartMessageIndex
17136
17433
  );
17434
+ runResume.adoptCommittedBoundary([...agent.state.messages]);
17137
17435
  } else if (promptHistoryMessages.length > 0) {
17138
17436
  agent.state.messages = [...promptHistoryMessages];
17139
17437
  }
@@ -17458,7 +17756,7 @@ async function executeAgentRunInPrivacyContext(request, conversationPrivacy, run
17458
17756
  throw error.originalError;
17459
17757
  }
17460
17758
  const runError = error instanceof AssistantMessageDeliveryError ? error.originalError : error;
17461
- if (runError instanceof AuthPausePersistenceError) {
17759
+ if (runError instanceof AuthPausePersistenceError || runError instanceof TurnSliceLimitExceededError) {
17462
17760
  throw runError;
17463
17761
  }
17464
17762
  if (resume && runError instanceof AuthorizationPauseError) {
@@ -17572,8 +17870,8 @@ export {
17572
17870
  deliverResourceEventSubscription,
17573
17871
  sanitizeScheduledTaskPrincipal,
17574
17872
  listThreadReplies,
17575
- renderSlackLegacyAttachmentText,
17576
- appendSlackLegacyAttachmentText,
17873
+ renderBlockText,
17874
+ renderAttachmentText,
17577
17875
  latestReportedProgress,
17578
17876
  executeCredentialedEgressRequest,
17579
17877
  createContextCompactor,