@sentry/junior 0.194.0 → 0.195.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (88) hide show
  1. package/dist/{agent-hooks-IDX764FD.js → agent-hooks-VIBTIP5F.js} +11 -11
  2. package/dist/api/activity.d.ts +9 -1
  3. package/dist/api/code/overview.d.ts +12 -0
  4. package/dist/api/locations/detail.d.ts +8 -0
  5. package/dist/api/locations/list.d.ts +5 -0
  6. package/dist/api/people/code.d.ts +6 -0
  7. package/dist/api/people/shared.d.ts +9 -1
  8. package/dist/api/reporting-window.d.ts +39 -1
  9. package/dist/api/schema/code.d.ts +12 -0
  10. package/dist/api/schema/conversation.d.ts +25 -0
  11. package/dist/api/schema/location.d.ts +13 -0
  12. package/dist/api/schema/person.d.ts +14 -0
  13. package/dist/api/schema/task.d.ts +12 -0
  14. package/dist/api/schema.js +1 -1
  15. package/dist/api.js +242 -63
  16. package/dist/app.js +102 -38
  17. package/dist/{catalog-runtime-MICXEBLK.js → catalog-runtime-6E6SGRZK.js} +4 -4
  18. package/dist/chat/config.d.ts +1 -0
  19. package/dist/chat/event-tasks/store.d.ts +27 -17
  20. package/dist/chat/resource-events/notification.d.ts +2 -1
  21. package/dist/chat/services/automated-turn-limit.d.ts +110 -0
  22. package/dist/chat/slack/automated-turn-limit-notice.d.ts +38 -0
  23. package/dist/chat/tasks/execution-stats.d.ts +2 -1
  24. package/dist/chat/tasks/read.d.ts +5 -2
  25. package/dist/{chunk-KNIAWMBU.js → chunk-3VWIZVK7.js} +1 -1
  26. package/dist/{chunk-XND3J6AT.js → chunk-5HNXLP4W.js} +1 -1
  27. package/dist/{chunk-VOB2DKO6.js → chunk-5NR7N567.js} +24 -13
  28. package/dist/{chunk-CFGBKPWQ.js → chunk-6GGDBXXP.js} +3 -3
  29. package/dist/{chunk-IOGDKPVU.js → chunk-6TRQLG3D.js} +1 -1
  30. package/dist/{chunk-V4HXV5MY.js → chunk-7MYXH5LA.js} +1 -1
  31. package/dist/{chunk-6H2MKVV5.js → chunk-7PQMTME5.js} +1 -1
  32. package/dist/{chunk-INTBMGNX.js → chunk-7UED4D5T.js} +21 -21
  33. package/dist/{chunk-NPO24LAN.js → chunk-BJZML4RT.js} +8 -8
  34. package/dist/{chunk-IME5OW4Y.js → chunk-C4NY6L7S.js} +1 -1
  35. package/dist/{chunk-53IEEFFP.js → chunk-CE2P6TOV.js} +3 -3
  36. package/dist/{chunk-WMJS5DDV.js → chunk-DTYOEHUP.js} +148 -19
  37. package/dist/{chunk-GY5SEFVL.js → chunk-FE3Y4KES.js} +5 -5
  38. package/dist/{chunk-G4RARFNT.js → chunk-FEZIEEOP.js} +957 -567
  39. package/dist/{chunk-XLWZRHX5.js → chunk-FPQPYJEG.js} +23 -29
  40. package/dist/{chunk-73JEAQRT.js → chunk-HE5PZAPS.js} +4 -4
  41. package/dist/{chunk-X76JVHQ4.js → chunk-HUQOXMDG.js} +1 -1
  42. package/dist/{chunk-NWWDFHXP.js → chunk-I4RH3KLJ.js} +1 -1
  43. package/dist/{chunk-QMEF4Z7R.js → chunk-JBSCMOLR.js} +5 -5
  44. package/dist/{chunk-JOI3DHML.js → chunk-KBPWC7NU.js} +1 -1
  45. package/dist/{chunk-ADEACKAH.js → chunk-KQ3GZGBK.js} +10 -3
  46. package/dist/{chunk-2NL3Y47F.js → chunk-KUQRWV53.js} +5 -5
  47. package/dist/{chunk-ELCYG6UU.js → chunk-L62JVQPL.js} +3 -3
  48. package/dist/{chunk-7ANA7PBB.js → chunk-LM7UE523.js} +3 -3
  49. package/dist/{chunk-U76RWMFR.js → chunk-LMYRF6HX.js} +4 -2
  50. package/dist/{chunk-F2KSURTJ.js → chunk-N67T4VY3.js} +9 -9
  51. package/dist/{chunk-AWZS5SVX.js → chunk-OQHO62VA.js} +8 -8
  52. package/dist/{chunk-CCTYK5RH.js → chunk-PFQRZ4IB.js} +9 -6
  53. package/dist/{chunk-H4DCWLTR.js → chunk-PYTRZZ4V.js} +8 -8
  54. package/dist/{chunk-XRDSML3K.js → chunk-QHJZSYKY.js} +2 -2
  55. package/dist/{chunk-E53C73ML.js → chunk-QKHZF2LH.js} +4 -4
  56. package/dist/{chunk-YSLIB7ER.js → chunk-QPZL2IYT.js} +82 -6
  57. package/dist/{chunk-RFE7DCZK.js → chunk-R5BGW4WR.js} +2 -2
  58. package/dist/{chunk-ENWIHU54.js → chunk-R5OHONYU.js} +6 -6
  59. package/dist/{chunk-WWXJUURQ.js → chunk-RKA22BQP.js} +1 -1
  60. package/dist/{chunk-P2P6MUQ4.js → chunk-RQO67SAO.js} +2 -2
  61. package/dist/{chunk-OEQOAONV.js → chunk-RZ3PBNDV.js} +6 -6
  62. package/dist/{chunk-G35QGPO2.js → chunk-VYDIA2UL.js} +1 -1
  63. package/dist/{chunk-S7GX44BU.js → chunk-X3PBQ4BK.js} +1 -1
  64. package/dist/cli/chat.js +33 -33
  65. package/dist/cli/check.js +5 -5
  66. package/dist/cli/plugins.js +12 -12
  67. package/dist/cli/snapshot-create.js +9 -9
  68. package/dist/cli/upgrade.js +6 -6
  69. package/dist/db/schema/event-tasks.d.ts +21 -0
  70. package/dist/db/schema.d.ts +19 -0
  71. package/dist/{db-3IEVINAY.js → db-FVCSDROR.js} +6 -6
  72. package/dist/instrumentation.js +3 -3
  73. package/dist/nitro.js +6 -6
  74. package/dist/{oauth-callback-server-N7L2BB4L.js → oauth-callback-server-Z5PXTDOE.js} +29 -29
  75. package/dist/{runner-PTTZV3WU.js → runner-RHYU7OGV.js} +21 -21
  76. package/dist/{skills-POMWS2RR.js → skills-QTN73DN5.js} +5 -5
  77. package/dist/spawn-R56OWLUH.js +42 -0
  78. package/dist/task-runner-LLJZTLRP.js +36 -0
  79. package/dist/{validation-U6LOMXR7.js → validation-2ZK7GA6N.js} +5 -5
  80. package/dist/version.js +1 -1
  81. package/dist/{work-FHA3BS4L.js → work-7IBKSZRU.js} +21 -21
  82. package/dist/{worker-GR4UNVVP.js → worker-RNVQVCO7.js} +10 -10
  83. package/migrations/0038_event_task_status.sql +5 -0
  84. package/migrations/meta/0038_snapshot.json +3323 -0
  85. package/migrations/meta/_journal.json +8 -1
  86. package/package.json +5 -5
  87. package/dist/spawn-R75MXXKE.js +0 -42
  88. package/dist/task-runner-OQLRHADB.js +0 -36
@@ -7,7 +7,7 @@ import {
7
7
  PluginCredentialFailureError,
8
8
  agentNameSchema,
9
9
  createPluginAuthOrchestration
10
- } from "./chunk-QMEF4Z7R.js";
10
+ } from "./chunk-JBSCMOLR.js";
11
11
  import {
12
12
  parseSandboxEgressAuthRequiredSignal,
13
13
  parseSandboxEgressPermissionDeniedSignal,
@@ -38,7 +38,7 @@ import {
38
38
  searchSlackUsers,
39
39
  selectPluginGrant,
40
40
  toMcpProviderError
41
- } from "./chunk-AWZS5SVX.js";
41
+ } from "./chunk-OQHO62VA.js";
42
42
  import {
43
43
  RetryableDeliveryError,
44
44
  actorFromRun,
@@ -48,11 +48,12 @@ import {
48
48
  formatProviderLabel,
49
49
  getSlackMessagePermalink,
50
50
  isAgentRunFeatureDisabled,
51
+ postSlackMessage,
51
52
  resolveBaseUrl,
52
53
  surfaceFromRun,
53
54
  toolInvocationDestination,
54
55
  uploadFilesToConversation
55
- } from "./chunk-ENWIHU54.js";
56
+ } from "./chunk-R5OHONYU.js";
56
57
  import {
57
58
  CooperativeTurnYieldError,
58
59
  NO_REPLY_MARKER,
@@ -65,7 +66,7 @@ import {
65
66
  isNoReplyMarker,
66
67
  isTurnInputCommitLostError,
67
68
  sanitizeAssistantText
68
- } from "./chunk-G35QGPO2.js";
69
+ } from "./chunk-VYDIA2UL.js";
69
70
  import {
70
71
  AGENTS_REMOVAL_NOTICE,
71
72
  AGENTS_REPLACEMENT_NOTICE,
@@ -121,7 +122,7 @@ import {
121
122
  stripRuntimeTurnContext,
122
123
  trimTrailingAssistantMessages,
123
124
  truncateText
124
- } from "./chunk-OEQOAONV.js";
125
+ } from "./chunk-RZ3PBNDV.js";
125
126
  import {
126
127
  SCHEDULED_TASK_SYSTEM_ACTOR,
127
128
  WORKSPACE_SNAPSHOT_FAILED_EVENT,
@@ -162,13 +163,13 @@ import {
162
163
  workspaceSnapshotFinishedEvent,
163
164
  workspaceSnapshotWatch,
164
165
  writableEventTask
165
- } from "./chunk-WMJS5DDV.js";
166
+ } from "./chunk-DTYOEHUP.js";
166
167
  import {
167
168
  parseSlackThreadId
168
- } from "./chunk-IOGDKPVU.js";
169
+ } from "./chunk-6TRQLG3D.js";
169
170
  import {
170
171
  appendAndEnqueueInboundMessage
171
- } from "./chunk-E53C73ML.js";
172
+ } from "./chunk-QKHZF2LH.js";
172
173
  import {
173
174
  SHORT_TITLE_MAX_LENGTH,
174
175
  ToolInputError,
@@ -176,7 +177,7 @@ import {
176
177
  generateShortTitle,
177
178
  hasAgentTurnUsage,
178
179
  resolveTaskTitle
179
- } from "./chunk-RFE7DCZK.js";
180
+ } from "./chunk-R5BGW4WR.js";
180
181
  import {
181
182
  bindSandboxFileSystem,
182
183
  createSandboxSession,
@@ -187,7 +188,7 @@ import {
187
188
  resolve,
188
189
  setSnapshotSpanAttributes,
189
190
  stopSession
190
- } from "./chunk-ELCYG6UU.js";
191
+ } from "./chunk-L62JVQPL.js";
191
192
  import {
192
193
  privateTraceResultAttributes
193
194
  } from "./chunk-UIE3R5XU.js";
@@ -197,7 +198,7 @@ import {
197
198
  } from "./chunk-X6GDDWQH.js";
198
199
  import {
199
200
  getTurnRequestDeadline
200
- } from "./chunk-NWWDFHXP.js";
201
+ } from "./chunk-I4RH3KLJ.js";
201
202
  import {
202
203
  getVercelConversationWorkQueue
203
204
  } from "./chunk-DKIJ2RP5.js";
@@ -244,19 +245,23 @@ import {
244
245
  updateWorkspace,
245
246
  withSlackRetries,
246
247
  workspaceRepoCheckoutPath
247
- } from "./chunk-CCTYK5RH.js";
248
+ } from "./chunk-PFQRZ4IB.js";
248
249
  import {
250
+ JUNIOR_THREAD_STATE_TTL_MS
251
+ } from "./chunk-3Y47VMHV.js";
252
+ import {
253
+ destinationKey,
249
254
  getConversationEventStore,
250
255
  getConversationMessageSearchStore,
251
256
  getConversationStore,
252
257
  getDb,
253
258
  getSqlExecutor
254
- } from "./chunk-ADEACKAH.js";
259
+ } from "./chunk-KQ3GZGBK.js";
255
260
  import {
256
261
  juniorArtifacts,
257
262
  juniorIdentities,
258
263
  juniorSchedulerRuns
259
- } from "./chunk-XLWZRHX5.js";
264
+ } from "./chunk-FPQPYJEG.js";
260
265
  import {
261
266
  SANDBOX_DATA_ROOT,
262
267
  SANDBOX_REPOS_ROOT,
@@ -287,12 +292,12 @@ import {
287
292
  throwSandboxOperationError,
288
293
  workspaceSnapshotNotReadyUserMessage,
289
294
  wrapSandboxSetupError
290
- } from "./chunk-7ANA7PBB.js";
295
+ } from "./chunk-LM7UE523.js";
291
296
  import {
292
297
  fenceLock,
293
298
  getStateAdapter,
294
299
  withLock
295
- } from "./chunk-V4HXV5MY.js";
300
+ } from "./chunk-7MYXH5LA.js";
296
301
  import {
297
302
  KNOWN_CONVERSATION_EVENT_TYPES,
298
303
  contextProvenance,
@@ -325,7 +330,7 @@ import {
325
330
  resolveGatewayCredential,
326
331
  resolveGatewayModel,
327
332
  unwrapCurrentInstruction
328
- } from "./chunk-U76RWMFR.js";
333
+ } from "./chunk-LMYRF6HX.js";
329
334
  import {
330
335
  ModelProfileNotConfiguredError,
331
336
  TURN_REASONING_LEVELS,
@@ -342,16 +347,16 @@ import {
342
347
  toGenAiMessagesTraceAttributes,
343
348
  toGenAiPayloadMetadata,
344
349
  toGenAiPayloadTraceAttributes
345
- } from "./chunk-JOI3DHML.js";
350
+ } from "./chunk-KBPWC7NU.js";
346
351
  import {
347
352
  discoverSkills,
348
353
  findSkillByName,
349
354
  loadSkillsByName,
350
355
  parseSkillInvocation
351
- } from "./chunk-P2P6MUQ4.js";
356
+ } from "./chunk-RQO67SAO.js";
352
357
  import {
353
358
  pluginCatalogRuntime
354
- } from "./chunk-WWXJUURQ.js";
359
+ } from "./chunk-RKA22BQP.js";
355
360
  import {
356
361
  CredentialUnavailableError,
357
362
  OAuthProviderError,
@@ -359,7 +364,7 @@ import {
359
364
  getOAuthProviderErrorAttributes,
360
365
  resolveAuthTokenPlaceholder,
361
366
  resolvePluginCommandEnv
362
- } from "./chunk-S7GX44BU.js";
367
+ } from "./chunk-X3PBQ4BK.js";
363
368
  import {
364
369
  credentialContextForActor,
365
370
  credentialUserSubjectId
@@ -395,7 +400,7 @@ import {
395
400
  summarizeMessageText,
396
401
  withLogContext,
397
402
  withSpan
398
- } from "./chunk-X76JVHQ4.js";
403
+ } from "./chunk-HUQOXMDG.js";
399
404
  import {
400
405
  startInactiveSpan,
401
406
  withActiveSpan
@@ -3096,6 +3101,353 @@ async function prepareWorkspaceSnapshot(params) {
3096
3101
  // src/chat/resource-events/ingest.ts
3097
3102
  import { resourceEventSchema } from "@sentry/junior-plugin-api";
3098
3103
 
3104
+ // src/chat/services/automated-turn-limit.ts
3105
+ import { z as z3 } from "zod";
3106
+ var AUTOMATED_TURN_LIMIT_PREFIX = "junior:automated_turn_limit:v1";
3107
+ var AUTOMATED_TURN_LIMIT_LOCK_TTL_MS = 5e3;
3108
+ var AUTOMATED_TURN_LIMIT_LOCK_WAIT_MS = 2e3;
3109
+ var AUTOMATED_TURN_LIMIT_LOCK_RETRY_MS = 25;
3110
+ var automatedTurnLimitStateSchema = z3.object({
3111
+ consecutiveAutomatedTurns: z3.number().int().nonnegative(),
3112
+ noticePostedAtMs: z3.number().finite().nonnegative().optional(),
3113
+ paused: z3.boolean(),
3114
+ updatedAtMs: z3.number().finite().nonnegative()
3115
+ }).strict();
3116
+ function sleep2(ms) {
3117
+ return new Promise((resolve2) => {
3118
+ const timer = setTimeout(resolve2, ms);
3119
+ timer.unref?.();
3120
+ });
3121
+ }
3122
+ function scopeKey(scope) {
3123
+ if (scope.kind === "conversation") {
3124
+ return `${AUTOMATED_TURN_LIMIT_PREFIX}:conversation:${scope.conversationId}`;
3125
+ }
3126
+ return `${AUTOMATED_TURN_LIMIT_PREFIX}:destination:${destinationKey(scope.destination)}`;
3127
+ }
3128
+ function lockKey(key) {
3129
+ return `${key}:lock`;
3130
+ }
3131
+ function parseState(value) {
3132
+ const parsed = automatedTurnLimitStateSchema.safeParse(value);
3133
+ return parsed.success ? parsed.data : void 0;
3134
+ }
3135
+ async function acquireScopeLock(state, key, waitDeadlineMs = Date.now() + AUTOMATED_TURN_LIMIT_LOCK_WAIT_MS) {
3136
+ while (true) {
3137
+ const lock = await state.acquireLock(
3138
+ lockKey(key),
3139
+ AUTOMATED_TURN_LIMIT_LOCK_TTL_MS
3140
+ );
3141
+ if (lock) {
3142
+ return lock;
3143
+ }
3144
+ if (Date.now() >= waitDeadlineMs) {
3145
+ throw new Error(`Could not acquire automated turn limit lock for ${key}`);
3146
+ }
3147
+ await sleep2(AUTOMATED_TURN_LIMIT_LOCK_RETRY_MS);
3148
+ }
3149
+ }
3150
+ async function withScopeLock(state, key, callback) {
3151
+ const lock = await acquireScopeLock(state, key);
3152
+ try {
3153
+ return await callback();
3154
+ } finally {
3155
+ await state.releaseLock(lock);
3156
+ }
3157
+ }
3158
+ function emptyState(nowMs) {
3159
+ return {
3160
+ consecutiveAutomatedTurns: 0,
3161
+ paused: false,
3162
+ updatedAtMs: nowMs
3163
+ };
3164
+ }
3165
+ function resumeInForScope(scope) {
3166
+ return scope.kind === "conversation" ? "thread" : "channel";
3167
+ }
3168
+ function isAutomatedTurnSource(source) {
3169
+ if (!source) {
3170
+ return false;
3171
+ }
3172
+ return source.kind === "resource_event" || source.kind === "event_task" || source.kind === "scheduled_task" || source.kind === "plugin_dispatch" || source.kind === "agent_invocation";
3173
+ }
3174
+ function automatedTurnLimitScopeForSource(args) {
3175
+ if (!isAutomatedTurnSource(args.source)) {
3176
+ return void 0;
3177
+ }
3178
+ if (args.source?.kind === "resource_event") {
3179
+ return {
3180
+ kind: "conversation",
3181
+ conversationId: args.conversationId
3182
+ };
3183
+ }
3184
+ if (args.destination) {
3185
+ return { kind: "destination", destination: args.destination };
3186
+ }
3187
+ return {
3188
+ kind: "conversation",
3189
+ conversationId: args.conversationId
3190
+ };
3191
+ }
3192
+ function buildAutomatedTurnLimitResponse(args) {
3193
+ const place = args.resumeIn === "channel" ? "channel" : "thread";
3194
+ return `I stopped automatic updates after ${args.maxTurns} replies without a new message from you. Send a message or @mention me in this ${place} to continue.`;
3195
+ }
3196
+ async function admitAutomatedTurn(args) {
3197
+ if (args.maxTurns < 1) {
3198
+ throw new Error("Automated turn limit must be at least 1");
3199
+ }
3200
+ const state = args.state ?? getStateAdapter();
3201
+ await state.connect();
3202
+ const nowMs = args.nowMs ?? Date.now();
3203
+ const key = scopeKey(args.scope);
3204
+ return await withScopeLock(state, key, async () => {
3205
+ const current = parseState(await state.get(key)) ?? emptyState(nowMs);
3206
+ if (current.paused || current.consecutiveAutomatedTurns >= args.maxTurns) {
3207
+ const shouldPostNotice = current.noticePostedAtMs === void 0;
3208
+ const next = {
3209
+ consecutiveAutomatedTurns: Math.max(
3210
+ current.consecutiveAutomatedTurns,
3211
+ args.maxTurns
3212
+ ),
3213
+ paused: true,
3214
+ updatedAtMs: nowMs,
3215
+ // Claim the notice slot so concurrent paused wakes do not all post.
3216
+ // Callers must mark success or clear the claim if the post fails.
3217
+ ...shouldPostNotice ? { noticePostedAtMs: nowMs } : current.noticePostedAtMs !== void 0 ? { noticePostedAtMs: current.noticePostedAtMs } : void 0
3218
+ };
3219
+ await state.set(key, next, JUNIOR_THREAD_STATE_TTL_MS);
3220
+ return {
3221
+ status: "paused",
3222
+ consecutiveAutomatedTurns: next.consecutiveAutomatedTurns,
3223
+ shouldPostNotice
3224
+ };
3225
+ }
3226
+ return {
3227
+ status: "allow",
3228
+ consecutiveAutomatedTurns: current.consecutiveAutomatedTurns
3229
+ };
3230
+ });
3231
+ }
3232
+ async function countAutomatedTurn(args) {
3233
+ if (args.maxTurns < 1) {
3234
+ throw new Error("Automated turn limit must be at least 1");
3235
+ }
3236
+ const state = args.state ?? getStateAdapter();
3237
+ await state.connect();
3238
+ const nowMs = args.nowMs ?? Date.now();
3239
+ const key = scopeKey(args.scope);
3240
+ const resumeIn = resumeInForScope(args.scope);
3241
+ return await withScopeLock(state, key, async () => {
3242
+ const current = parseState(await state.get(key)) ?? emptyState(nowMs);
3243
+ const consecutiveAutomatedTurns = current.consecutiveAutomatedTurns + 1;
3244
+ const paused = consecutiveAutomatedTurns >= args.maxTurns;
3245
+ const shouldPostNotice = paused && current.noticePostedAtMs === void 0;
3246
+ const next = {
3247
+ consecutiveAutomatedTurns,
3248
+ paused,
3249
+ updatedAtMs: nowMs,
3250
+ // Claim the notice slot before the destination post. Mark success after
3251
+ // the post lands; clear the claim if the post fails or is skipped.
3252
+ ...shouldPostNotice ? { noticePostedAtMs: nowMs } : current.noticePostedAtMs !== void 0 ? { noticePostedAtMs: current.noticePostedAtMs } : void 0
3253
+ };
3254
+ await state.set(key, next, JUNIOR_THREAD_STATE_TTL_MS);
3255
+ return {
3256
+ consecutiveAutomatedTurns,
3257
+ paused,
3258
+ shouldPostNotice,
3259
+ resumeIn
3260
+ };
3261
+ });
3262
+ }
3263
+ async function clearAutomatedTurnLimitNoticeClaim(args) {
3264
+ const state = args.state ?? getStateAdapter();
3265
+ await state.connect();
3266
+ const nowMs = args.nowMs ?? Date.now();
3267
+ const key = scopeKey(args.scope);
3268
+ await withScopeLock(state, key, async () => {
3269
+ const current = parseState(await state.get(key));
3270
+ if (!current || current.noticePostedAtMs === void 0) {
3271
+ return;
3272
+ }
3273
+ const { noticePostedAtMs: _noticePostedAtMs, ...rest } = current;
3274
+ await state.set(
3275
+ key,
3276
+ {
3277
+ ...rest,
3278
+ updatedAtMs: nowMs
3279
+ },
3280
+ JUNIOR_THREAD_STATE_TTL_MS
3281
+ );
3282
+ });
3283
+ }
3284
+ async function resetAutomatedTurnLimit(args) {
3285
+ const state = args.state ?? getStateAdapter();
3286
+ await state.connect();
3287
+ const key = scopeKey(args.scope);
3288
+ await withScopeLock(state, key, async () => {
3289
+ await state.delete(key);
3290
+ });
3291
+ }
3292
+ async function recordFinishedTurnForAutomatedLimit(args) {
3293
+ const nowMs = args.nowMs ?? Date.now();
3294
+ const automatedScope = automatedTurnLimitScopeForSource({
3295
+ conversationId: args.conversationId,
3296
+ destination: args.destination,
3297
+ source: args.source
3298
+ });
3299
+ if (automatedScope) {
3300
+ return await countAutomatedTurn({
3301
+ maxTurns: args.maxTurns,
3302
+ nowMs,
3303
+ scope: automatedScope,
3304
+ state: args.state
3305
+ });
3306
+ }
3307
+ await resetAutomatedTurnLimit({
3308
+ nowMs,
3309
+ scope: {
3310
+ kind: "conversation",
3311
+ conversationId: args.conversationId
3312
+ },
3313
+ state: args.state
3314
+ });
3315
+ if (args.destination) {
3316
+ await resetAutomatedTurnLimit({
3317
+ nowMs,
3318
+ scope: { kind: "destination", destination: args.destination },
3319
+ state: args.state
3320
+ });
3321
+ }
3322
+ return void 0;
3323
+ }
3324
+
3325
+ // src/chat/slack/automated-turn-limit-notice.ts
3326
+ async function releaseFailedNoticeClaim(args) {
3327
+ try {
3328
+ await clearAutomatedTurnLimitNoticeClaim(args);
3329
+ } catch (error) {
3330
+ logException(error, "automated_turn_limit.notice_claim_clear_failed");
3331
+ }
3332
+ }
3333
+ async function postAutomatedTurnLimitNoticeForConversation(args) {
3334
+ const scope = args.scope ?? {
3335
+ kind: "conversation",
3336
+ conversationId: args.conversationId
3337
+ };
3338
+ try {
3339
+ const conversation = await getConversationStore().get({
3340
+ conversationId: args.conversationId
3341
+ });
3342
+ const location = conversation?.location;
3343
+ if (!location || location.provider !== "slack") {
3344
+ logWarn("automated_turn_limit.notice_skipped", {
3345
+ conversationId: args.conversationId,
3346
+ "app.automated_turn_limit.reason": location ? "unsupported_location" : "missing_location"
3347
+ });
3348
+ await releaseFailedNoticeClaim({
3349
+ nowMs: args.nowMs,
3350
+ scope
3351
+ });
3352
+ return false;
3353
+ }
3354
+ await postSlackMessage({
3355
+ channelId: location.channelId,
3356
+ text: buildAutomatedTurnLimitResponse({
3357
+ maxTurns: args.maxTurns,
3358
+ resumeIn: args.resumeIn ?? "thread"
3359
+ }),
3360
+ ...location.threadTs ? { threadTs: location.threadTs } : void 0
3361
+ });
3362
+ return true;
3363
+ } catch (error) {
3364
+ logException(error, "automated_turn_limit.notice_failed", {
3365
+ conversationId: args.conversationId
3366
+ });
3367
+ await releaseFailedNoticeClaim({
3368
+ nowMs: args.nowMs,
3369
+ scope
3370
+ });
3371
+ return false;
3372
+ }
3373
+ }
3374
+ async function postAutomatedTurnLimitNoticeForDestination(args) {
3375
+ const scope = args.scope ?? {
3376
+ kind: "destination",
3377
+ destination: args.destination
3378
+ };
3379
+ if (args.destination.platform !== "slack") {
3380
+ logWarn("automated_turn_limit.notice_skipped", {
3381
+ "app.automated_turn_limit.reason": "unsupported_destination"
3382
+ });
3383
+ await releaseFailedNoticeClaim({
3384
+ nowMs: args.nowMs,
3385
+ scope
3386
+ });
3387
+ return false;
3388
+ }
3389
+ try {
3390
+ await postSlackMessage({
3391
+ channelId: args.destination.channelId,
3392
+ text: buildAutomatedTurnLimitResponse({
3393
+ maxTurns: args.maxTurns,
3394
+ resumeIn: args.resumeIn ?? "channel"
3395
+ }),
3396
+ ...args.threadTs ? { threadTs: args.threadTs } : void 0
3397
+ });
3398
+ return true;
3399
+ } catch (error) {
3400
+ logException(error, "automated_turn_limit.notice_failed", {
3401
+ "app.slack.channel_id": args.destination.channelId,
3402
+ "app.slack.team_id": args.destination.teamId
3403
+ });
3404
+ await releaseFailedNoticeClaim({
3405
+ nowMs: args.nowMs,
3406
+ scope
3407
+ });
3408
+ return false;
3409
+ }
3410
+ }
3411
+ async function maybePostAutomatedTurnLimitNotice(args) {
3412
+ if (!args.update?.shouldPostNotice) {
3413
+ return;
3414
+ }
3415
+ if (args.update.resumeIn === "thread") {
3416
+ await postAutomatedTurnLimitNoticeForConversation({
3417
+ conversationId: args.conversationId,
3418
+ maxTurns: args.maxTurns,
3419
+ nowMs: args.nowMs,
3420
+ resumeIn: "thread",
3421
+ scope: {
3422
+ kind: "conversation",
3423
+ conversationId: args.conversationId
3424
+ }
3425
+ });
3426
+ return;
3427
+ }
3428
+ if (args.destination) {
3429
+ await postAutomatedTurnLimitNoticeForDestination({
3430
+ destination: args.destination,
3431
+ maxTurns: args.maxTurns,
3432
+ nowMs: args.nowMs,
3433
+ resumeIn: "channel",
3434
+ scope: { kind: "destination", destination: args.destination },
3435
+ threadTs: args.threadTs
3436
+ });
3437
+ return;
3438
+ }
3439
+ await postAutomatedTurnLimitNoticeForConversation({
3440
+ conversationId: args.conversationId,
3441
+ maxTurns: args.maxTurns,
3442
+ nowMs: args.nowMs,
3443
+ resumeIn: args.update.resumeIn,
3444
+ scope: {
3445
+ kind: "conversation",
3446
+ conversationId: args.conversationId
3447
+ }
3448
+ });
3449
+ }
3450
+
3099
3451
  // src/chat/task-input.ts
3100
3452
  function replyContractLines() {
3101
3453
  return [
@@ -3235,6 +3587,38 @@ function createResourceEventInboundMessage(input) {
3235
3587
  };
3236
3588
  }
3237
3589
  async function enqueueResourceEventNotification(args) {
3590
+ const maxTurns = botConfig.maxConsecutiveAutomatedTurns;
3591
+ const decision = await admitAutomatedTurn({
3592
+ maxTurns,
3593
+ nowMs: args.event.occurredAtMs,
3594
+ scope: {
3595
+ kind: "conversation",
3596
+ conversationId: args.subscription.conversationId
3597
+ },
3598
+ state: args.state
3599
+ });
3600
+ if (decision.status === "paused") {
3601
+ logInfo("resource_events.automated_turn_limit.paused", {
3602
+ conversationId: args.subscription.conversationId,
3603
+ "app.automated_turn_limit.consecutive": decision.consecutiveAutomatedTurns,
3604
+ "app.automated_turn_limit.max": maxTurns,
3605
+ "app.resource_event.event_type": args.event.eventType,
3606
+ "app.resource_event.namespace": args.event.namespace
3607
+ });
3608
+ if (decision.shouldPostNotice) {
3609
+ await postAutomatedTurnLimitNoticeForConversation({
3610
+ conversationId: args.subscription.conversationId,
3611
+ maxTurns,
3612
+ nowMs: args.event.occurredAtMs,
3613
+ resumeIn: "thread",
3614
+ scope: {
3615
+ kind: "conversation",
3616
+ conversationId: args.subscription.conversationId
3617
+ }
3618
+ });
3619
+ }
3620
+ return { status: "duplicate" };
3621
+ }
3238
3622
  const text = renderResourceEventNotificationText(
3239
3623
  args.subscription,
3240
3624
  args.event
@@ -5008,10 +5392,10 @@ function validateAndApplyTextEdits(content, edits, targetName) {
5008
5392
  }
5009
5393
 
5010
5394
  // src/chat/tools/sandbox/edit-file.ts
5011
- import { z as z4 } from "zod";
5395
+ import { z as z5 } from "zod";
5012
5396
 
5013
5397
  // src/chat/tool-support/zod-tool.ts
5014
- import { z as z3 } from "zod";
5398
+ import { z as z4 } from "zod";
5015
5399
  function isContentOnlyToolResult(value) {
5016
5400
  return value !== null && typeof value === "object" && Array.isArray(value.content) && !("details" in value);
5017
5401
  }
@@ -5048,7 +5432,7 @@ function zodTool(definition) {
5048
5432
  const { inputSchema: inputSchema2, outputSchema: outputSchema7, prepareArguments, execute, ...toolDef } = definition;
5049
5433
  let modelInputSchema;
5050
5434
  try {
5051
- modelInputSchema = z3.toJSONSchema(inputSchema2);
5435
+ modelInputSchema = z4.toJSONSchema(inputSchema2);
5052
5436
  } catch (error) {
5053
5437
  throw new TypeError(
5054
5438
  "zodTool() inputSchema must be representable as JSON Schema.",
@@ -5058,7 +5442,7 @@ function zodTool(definition) {
5058
5442
  let modelOutputSchema;
5059
5443
  if (outputSchema7) {
5060
5444
  try {
5061
- modelOutputSchema = z3.toJSONSchema(outputSchema7);
5445
+ modelOutputSchema = z4.toJSONSchema(outputSchema7);
5062
5446
  } catch (error) {
5063
5447
  throw new TypeError(
5064
5448
  "zodTool() outputSchema must be representable as JSON Schema.",
@@ -5143,11 +5527,11 @@ async function editFile(params) {
5143
5527
  truncated: diff.truncated
5144
5528
  });
5145
5529
  }
5146
- var editReplacementSchema = z4.object({
5147
- oldText: z4.string().min(1).describe(
5530
+ var editReplacementSchema = z5.object({
5531
+ oldText: z5.string().min(1).describe(
5148
5532
  "Exact text to replace. It must be unique in the original file and must not overlap another edit."
5149
5533
  ),
5150
- newText: z4.string().describe("Replacement text for this edit.")
5534
+ newText: z5.string().describe("Replacement text for this edit.")
5151
5535
  });
5152
5536
  function createEditFileTool() {
5153
5537
  return zodTool({
@@ -5160,9 +5544,9 @@ function createEditFileTool() {
5160
5544
  description: "Edit one sandbox workspace file with exact text replacements. Use for precise changes to existing files; prefer this over writeFile for targeted changes. Each oldText must match exactly, be unique, and not overlap another edit. Returns a diff. Multiple changes to the same file: use one edits[] call.",
5161
5545
  prepareArguments: prepareEditFileArguments,
5162
5546
  executionMode: "sequential",
5163
- inputSchema: z4.object({
5164
- path: z4.string().min(1).describe("Path to edit in the sandbox workspace."),
5165
- edits: z4.array(editReplacementSchema).min(1).describe(
5547
+ inputSchema: z5.object({
5548
+ path: z5.string().min(1).describe("Path to edit in the sandbox workspace."),
5549
+ edits: z5.array(editReplacementSchema).min(1).describe(
5166
5550
  "Exact replacements matched against the original file, not incrementally."
5167
5551
  )
5168
5552
  }),
@@ -5177,7 +5561,7 @@ function createEditFileTool() {
5177
5561
 
5178
5562
  // src/chat/tools/sandbox/find-files.ts
5179
5563
  import path4 from "path";
5180
- import { z as z5 } from "zod";
5564
+ import { z as z6 } from "zod";
5181
5565
  var DEFAULT_FIND_LIMIT = 100;
5182
5566
  async function findFiles(params) {
5183
5567
  if (!params.pattern.trim()) {
@@ -5350,14 +5734,14 @@ function createFindFilesTool() {
5350
5734
  openWorldHint: false,
5351
5735
  readOnlyHint: true
5352
5736
  },
5353
- inputSchema: z5.object({
5354
- pattern: z5.string().min(1).describe(
5737
+ inputSchema: z6.object({
5738
+ pattern: z6.string().min(1).describe(
5355
5739
  "Glob pattern to match, for example '*.ts', '**/*.json', or 'src/**/*.test.ts'."
5356
5740
  ),
5357
- path: z5.string().min(1).describe(
5741
+ path: z6.string().min(1).describe(
5358
5742
  "Directory or file path in the sandbox workspace. Defaults to the workspace root."
5359
5743
  ).optional(),
5360
- limit: z5.coerce.number().int().min(1).describe("Maximum number of file paths to return. Defaults to 100.").optional()
5744
+ limit: z6.coerce.number().int().min(1).describe("Maximum number of file paths to return. Defaults to 100.").optional()
5361
5745
  }),
5362
5746
  outputSchema: juniorToolOutputSchema,
5363
5747
  execute: async () => {
@@ -5370,12 +5754,12 @@ function createFindFilesTool() {
5370
5754
 
5371
5755
  // src/chat/tools/sandbox/grep.ts
5372
5756
  import path5 from "path";
5373
- import { z as z6 } from "zod";
5757
+ import { z as z7 } from "zod";
5374
5758
  var DEFAULT_GREP_LIMIT = 100;
5375
5759
  var MAX_GREP_LINE_CHARS = 500;
5376
- var booleanInput = (description) => z6.preprocess(
5760
+ var booleanInput = (description) => z7.preprocess(
5377
5761
  (value) => value === "true" ? true : value === "false" ? false : value,
5378
- z6.boolean()
5762
+ z7.boolean()
5379
5763
  ).describe(description);
5380
5764
  function truncateGrepLine(value) {
5381
5765
  if (value.length <= MAX_GREP_LINE_CHARS) {
@@ -5729,20 +6113,20 @@ function createGrepTool() {
5729
6113
  openWorldHint: false,
5730
6114
  readOnlyHint: true
5731
6115
  },
5732
- inputSchema: z6.object({
5733
- pattern: z6.string().min(1).describe("Regex pattern or literal text to search for."),
5734
- path: z6.string().min(1).describe(
6116
+ inputSchema: z7.object({
6117
+ pattern: z7.string().min(1).describe("Regex pattern or literal text to search for."),
6118
+ path: z7.string().min(1).describe(
5735
6119
  "Directory or file path in the sandbox workspace. Defaults to the workspace root."
5736
6120
  ).optional(),
5737
- glob: z6.string().min(1).describe("Optional glob filter such as '*.ts' or '**/*.test.ts'.").optional(),
6121
+ glob: z7.string().min(1).describe("Optional glob filter such as '*.ts' or '**/*.test.ts'.").optional(),
5738
6122
  ignoreCase: booleanInput(
5739
6123
  "Whether matching should ignore case."
5740
6124
  ).optional(),
5741
6125
  literal: booleanInput(
5742
6126
  "Treat pattern as literal text instead of regex."
5743
6127
  ).optional(),
5744
- context: z6.coerce.number().int().min(0).describe("Number of surrounding context lines to include.").optional(),
5745
- limit: z6.coerce.number().int().min(1).describe("Maximum matches to return. Defaults to 100.").optional()
6128
+ context: z7.coerce.number().int().min(0).describe("Number of surrounding context lines to include.").optional(),
6129
+ limit: z7.coerce.number().int().min(1).describe("Maximum matches to return. Defaults to 100.").optional()
5746
6130
  }),
5747
6131
  outputSchema: juniorToolOutputSchema,
5748
6132
  execute: async () => {
@@ -5753,7 +6137,7 @@ function createGrepTool() {
5753
6137
 
5754
6138
  // src/chat/tools/sandbox/list-dir.ts
5755
6139
  import path6 from "path";
5756
- import { z as z7 } from "zod";
6140
+ import { z as z8 } from "zod";
5757
6141
  var DEFAULT_LIST_LIMIT = 500;
5758
6142
  async function listDir(params) {
5759
6143
  const dirPath = resolveWorkspacePath(params.path);
@@ -5834,11 +6218,11 @@ function createListDirTool() {
5834
6218
  openWorldHint: false,
5835
6219
  readOnlyHint: true
5836
6220
  },
5837
- inputSchema: z7.object({
5838
- path: z7.string().min(1).describe(
6221
+ inputSchema: z8.object({
6222
+ path: z8.string().min(1).describe(
5839
6223
  "Directory path in the sandbox workspace. Defaults to the workspace root."
5840
6224
  ).optional(),
5841
- limit: z7.coerce.number().int().min(1).describe("Maximum entries to return. Defaults to 500.").optional()
6225
+ limit: z8.coerce.number().int().min(1).describe("Maximum entries to return. Defaults to 500.").optional()
5842
6226
  }),
5843
6227
  outputSchema: juniorToolOutputSchema,
5844
6228
  execute: async () => {
@@ -5850,7 +6234,7 @@ function createListDirTool() {
5850
6234
  }
5851
6235
 
5852
6236
  // src/chat/tools/sandbox/read-file.ts
5853
- import { z as z8 } from "zod";
6237
+ import { z as z9 } from "zod";
5854
6238
 
5855
6239
  // src/chat/tool-support/text-range-result.ts
5856
6240
  var DEFAULT_READ_LIMIT = 1e3;
@@ -5944,10 +6328,10 @@ function createReadFileTool() {
5944
6328
  openWorldHint: false,
5945
6329
  readOnlyHint: true
5946
6330
  },
5947
- inputSchema: z8.object({
5948
- path: z8.string().min(1).describe("Path to the file in the sandbox workspace."),
5949
- offset: z8.coerce.number().int().min(1).describe("1-indexed line number to start reading from.").optional(),
5950
- limit: z8.coerce.number().int().min(1).describe("Maximum number of lines to read. Defaults to 1000.").optional()
6331
+ inputSchema: z9.object({
6332
+ path: z9.string().min(1).describe("Path to the file in the sandbox workspace."),
6333
+ offset: z9.coerce.number().int().min(1).describe("1-indexed line number to start reading from.").optional(),
6334
+ limit: z9.coerce.number().int().min(1).describe("Maximum number of lines to read. Defaults to 1000.").optional()
5951
6335
  }),
5952
6336
  outputSchema: juniorToolOutputSchema,
5953
6337
  execute: async () => {
@@ -6547,25 +6931,25 @@ function createSandbox(options) {
6547
6931
 
6548
6932
  // src/chat/tools/sandbox/file-uploads.ts
6549
6933
  import path7 from "path";
6550
- import { z as z9 } from "zod";
6934
+ import { z as z10 } from "zod";
6551
6935
  var MAX_SANDBOX_FILE_UPLOAD_BYTES = 10 * 1024 * 1024;
6552
6936
  var SANDBOX_ARTIFACTS_DIR = "/tmp/junior/artifacts";
6553
- var sandboxFileReferenceSchema = z9.object({
6554
- path: z9.string().min(1).describe(
6937
+ var sandboxFileReferenceSchema = z10.object({
6938
+ path: z10.string().min(1).describe(
6555
6939
  "Exact source path of an existing sandbox file. Preserve paths returned by other tools unchanged; do not move or rewrite them before sending."
6556
6940
  ),
6557
- filename: z9.string().min(1).nullable().optional().describe(
6941
+ filename: z10.string().min(1).nullable().optional().describe(
6558
6942
  "Optional filename override shown to the recipient. Null is treated as omitted."
6559
6943
  ),
6560
- mimeType: z9.string().min(1).nullable().optional().describe("Optional MIME type override. Null is treated as omitted."),
6561
- bytes: z9.number().int().nonnegative().nullable().optional().describe(
6944
+ mimeType: z10.string().min(1).nullable().optional().describe("Optional MIME type override. Null is treated as omitted."),
6945
+ bytes: z10.number().int().nonnegative().nullable().optional().describe(
6562
6946
  "Optional known file size returned by a producing tool. Null is treated as omitted; sending tools validate the file contents directly."
6563
6947
  )
6564
6948
  });
6565
6949
  var generatedArtifactFileRefSchema = sandboxFileReferenceSchema.extend({
6566
- filename: z9.string().min(1),
6567
- mimeType: z9.string().min(1).optional(),
6568
- bytes: z9.number().int().nonnegative()
6950
+ filename: z10.string().min(1),
6951
+ mimeType: z10.string().min(1).optional(),
6952
+ bytes: z10.number().int().nonnegative()
6569
6953
  }).strict();
6570
6954
  var MIME_BY_EXTENSION = {
6571
6955
  ".png": "image/png",
@@ -7816,7 +8200,7 @@ function serializeMcpPayload(payload, privacy, options = {}) {
7816
8200
  }
7817
8201
 
7818
8202
  // src/chat/tools/sandbox/bash.ts
7819
- import { z as z10 } from "zod";
8203
+ import { z as z11 } from "zod";
7820
8204
  function createBashTool() {
7821
8205
  return zodTool({
7822
8206
  annotations: {
@@ -7826,10 +8210,10 @@ function createBashTool() {
7826
8210
  readOnlyHint: false
7827
8211
  },
7828
8212
  description: "Run a bash command inside the isolated sandbox workspace. Use this for repository inspection/execution tasks that need shell access. Do not use for network-sensitive or destructive actions unless explicitly required.",
7829
- inputSchema: z10.object({
7830
- command: z10.string().min(1).describe("Bash command to run inside the sandbox."),
7831
- cwd: z10.string().min(1).describe("Optional working directory for this command only.").optional(),
7832
- timeoutMs: z10.coerce.number().int().min(1e3).describe(
8213
+ inputSchema: z11.object({
8214
+ command: z11.string().min(1).describe("Bash command to run inside the sandbox."),
8215
+ cwd: z11.string().min(1).describe("Optional working directory for this command only.").optional(),
8216
+ timeoutMs: z11.coerce.number().int().min(1e3).describe(
7833
8217
  "Optional command timeout in milliseconds. Use for commands that may hang."
7834
8218
  ).optional()
7835
8219
  }),
@@ -7843,14 +8227,14 @@ function createBashTool() {
7843
8227
  }
7844
8228
 
7845
8229
  // src/chat/tools/web/image-generate.ts
7846
- import { z as z11 } from "zod";
8230
+ import { z as z12 } from "zod";
7847
8231
  var imageGenerateOutputSchema = juniorToolOutputSchema.extend({
7848
- model: z11.string(),
7849
- prompt: z11.string(),
7850
- enrichedPrompt: z11.string(),
7851
- image_count: z11.number().int().nonnegative(),
7852
- images: z11.array(generatedArtifactFileRefSchema),
7853
- delivery: z11.string()
8232
+ model: z12.string(),
8233
+ prompt: z12.string(),
8234
+ enrichedPrompt: z12.string(),
8235
+ image_count: z12.number().int().nonnegative(),
8236
+ images: z12.array(generatedArtifactFileRefSchema),
8237
+ delivery: z12.string()
7854
8238
  }).strict();
7855
8239
  var ENRICHMENT_SYSTEM_PROMPT = `You are an image prompt enrichment agent. Your job is to rewrite image generation requests to reflect a specific visual identity and mood.
7856
8240
 
@@ -7912,8 +8296,8 @@ function createImageGenerateTool(hooks, options, deps = {}) {
7912
8296
  readOnlyHint: false
7913
8297
  },
7914
8298
  description: "Generate images from a prompt. Use when the user wants to visually show or represent something \u2014 feelings, concepts, art, humor, or any visual idea. Also use for explicit image creation requests.",
7915
- inputSchema: z11.object({
7916
- prompt: z11.string().min(1).max(4e3).describe("Image generation prompt.")
8299
+ inputSchema: z12.object({
8300
+ prompt: z12.string().min(1).max(4e3).describe("Image generation prompt.")
7917
8301
  }),
7918
8302
  outputSchema: imageGenerateOutputSchema,
7919
8303
  execute: async ({ prompt }) => {
@@ -8003,7 +8387,7 @@ function parseMcpProviderFromToolName(toolName) {
8003
8387
  }
8004
8388
 
8005
8389
  // src/chat/tools/skill/call-mcp-tool.ts
8006
- import { z as z12 } from "zod";
8390
+ import { z as z13 } from "zod";
8007
8391
  function resolveMcpArguments(input) {
8008
8392
  const extraKeys = Object.keys(input).filter(
8009
8393
  (key) => key !== "tool_name" && key !== "arguments"
@@ -8046,9 +8430,9 @@ function createCallMcpToolTool(mcpToolManager) {
8046
8430
  readOnlyHint: false
8047
8431
  },
8048
8432
  description: "Call an active MCP tool by exact tool_name. Use searchMcpTools to discover tool names and schemas; copy required provider fields into arguments. Do not call with only tool_name unless the discovered tool has no arguments. Authorization is handled by the runtime when required.",
8049
- inputSchema: z12.object({
8050
- tool_name: z12.string().min(1).describe("Exact MCP tool_name from searchMcpTools."),
8051
- arguments: z12.record(z12.string(), z12.unknown()).describe(
8433
+ inputSchema: z13.object({
8434
+ tool_name: z13.string().min(1).describe("Exact MCP tool_name from searchMcpTools."),
8435
+ arguments: z13.record(z13.string(), z13.unknown()).describe(
8052
8436
  'Arguments matching the disclosed MCP tool schema, for example { "query": "..." } when searchMcpTools shows query is required.'
8053
8437
  ).optional()
8054
8438
  }).passthrough(),
@@ -8101,7 +8485,7 @@ function createCallMcpToolTool(mcpToolManager) {
8101
8485
  }
8102
8486
 
8103
8487
  // src/chat/tools/skill/load-skill.ts
8104
- import { z as z13 } from "zod";
8488
+ import { z as z14 } from "zod";
8105
8489
  function toLoadedSkill(result, availableSkills) {
8106
8490
  if (typeof result.skill_name !== "string" || typeof result.description !== "string" || typeof result.skill_dir !== "string" || typeof result.instructions !== "string") {
8107
8491
  return null;
@@ -8151,8 +8535,8 @@ function createLoadSkillTool(availableSkills, options) {
8151
8535
  readOnlyHint: false
8152
8536
  },
8153
8537
  description: "Load a skill by name for this turn. The result includes working_directory; resolve skill paths there and run skill-owned bash commands from there or with absolute paths. When the skill instructions name an MCP provider, use searchMcpTools before callMcpTool. Use when a request clearly matches a known skill.",
8154
- inputSchema: z13.object({
8155
- skill_name: z13.string().min(1).describe("Skill name to load, without the leading slash.")
8538
+ inputSchema: z14.object({
8539
+ skill_name: z14.string().min(1).describe("Skill name to load, without the leading slash.")
8156
8540
  }),
8157
8541
  outputSchema: juniorToolOutputSchema,
8158
8542
  execute: async ({ skill_name }) => {
@@ -8167,7 +8551,7 @@ function createLoadSkillTool(availableSkills, options) {
8167
8551
  }
8168
8552
 
8169
8553
  // src/chat/tools/skill/search-mcp-tools.ts
8170
- import { z as z14 } from "zod";
8554
+ import { z as z15 } from "zod";
8171
8555
 
8172
8556
  // src/chat/tool-support/skill/mcp-tool-summary.ts
8173
8557
  function toExposedToolSummary(toolDef) {
@@ -8199,29 +8583,29 @@ function toActiveMcpCatalogSummaries(toolDefs) {
8199
8583
  // src/chat/tools/skill/search-mcp-tools.ts
8200
8584
  var DEFAULT_MAX_RESULTS = 5;
8201
8585
  var MAX_RESULTS = 20;
8202
- var providerSummarySchema = z14.object({
8203
- provider: z14.string(),
8204
- description: z14.string(),
8205
- active: z14.boolean()
8586
+ var providerSummarySchema = z15.object({
8587
+ provider: z15.string(),
8588
+ description: z15.string(),
8589
+ active: z15.boolean()
8206
8590
  }).strict();
8207
- var exposedToolSummarySchema = z14.object({
8208
- tool_name: z14.string(),
8209
- mcp_tool_name: z14.string(),
8210
- provider: z14.string(),
8211
- title: z14.string().optional(),
8212
- description: z14.string(),
8213
- input_schema: z14.record(z14.string(), z14.unknown()),
8214
- output_schema: z14.record(z14.string(), z14.unknown()).optional(),
8215
- annotations: z14.record(z14.string(), z14.unknown()).optional()
8591
+ var exposedToolSummarySchema = z15.object({
8592
+ tool_name: z15.string(),
8593
+ mcp_tool_name: z15.string(),
8594
+ provider: z15.string(),
8595
+ title: z15.string().optional(),
8596
+ description: z15.string(),
8597
+ input_schema: z15.record(z15.string(), z15.unknown()),
8598
+ output_schema: z15.record(z15.string(), z15.unknown()).optional(),
8599
+ annotations: z15.record(z15.string(), z15.unknown()).optional()
8216
8600
  }).strict();
8217
8601
  var searchMcpToolsOutputSchema = juniorToolOutputSchema.extend({
8218
- query: z14.string().nullable(),
8219
- provider: z14.string().nullable(),
8220
- total_active_tools: z14.number().int().nonnegative(),
8221
- returned_tools: z14.number().int().nonnegative(),
8222
- execution_tool: z14.literal("callMcpTool"),
8223
- available_providers: z14.array(providerSummarySchema),
8224
- tools: z14.array(exposedToolSummarySchema)
8602
+ query: z15.string().nullable(),
8603
+ provider: z15.string().nullable(),
8604
+ total_active_tools: z15.number().int().nonnegative(),
8605
+ returned_tools: z15.number().int().nonnegative(),
8606
+ execution_tool: z15.literal("callMcpTool"),
8607
+ available_providers: z15.array(providerSummarySchema),
8608
+ tools: z15.array(exposedToolSummarySchema)
8225
8609
  }).strict();
8226
8610
  function normalize(value) {
8227
8611
  return value.toLowerCase().replace(/[^a-z0-9_]+/g, " ").trim();
@@ -8347,14 +8731,14 @@ function createSearchMcpToolsTool(mcpToolManager) {
8347
8731
  readOnlyHint: true
8348
8732
  },
8349
8733
  description: "List or search MCP providers and active MCP tools. When provider is supplied and not yet active, Junior connects to it on demand and returns tool descriptors including schemas. Without provider, returns active tools plus matching configured providers without connecting. Use when choosing a provider tool or when callMcpTool arguments are unclear.",
8350
- inputSchema: z14.object({
8351
- query: z14.string().min(1).describe(
8734
+ inputSchema: z15.object({
8735
+ query: z15.string().min(1).describe(
8352
8736
  "Optional search terms describing the MCP tool or arguments needed."
8353
8737
  ).optional(),
8354
- provider: z14.string().min(1).describe(
8738
+ provider: z15.string().min(1).describe(
8355
8739
  "Optional provider name to list or search within. If configured but not yet connected, Junior activates it on demand."
8356
8740
  ).optional(),
8357
- max_results: z14.number().int().min(1).max(MAX_RESULTS).describe("Maximum matching tool descriptors to return.").optional()
8741
+ max_results: z15.number().int().min(1).max(MAX_RESULTS).describe("Maximum matching tool descriptors to return.").optional()
8358
8742
  }).strict(),
8359
8743
  outputSchema: searchMcpToolsOutputSchema,
8360
8744
  privateTraceResult: (result) => ({
@@ -8394,10 +8778,10 @@ function createSearchMcpToolsTool(mcpToolManager) {
8394
8778
  }
8395
8779
 
8396
8780
  // src/chat/tools/sandbox/view-image.ts
8397
- import { z as z15 } from "zod";
8781
+ import { z as z16 } from "zod";
8398
8782
  var MAX_VIEW_IMAGE_BYTES = 5 * 1024 * 1024;
8399
- var viewImageInputSchema = z15.object({
8400
- path: z15.string().min(1).describe("Path to an image file in the sandbox workspace.")
8783
+ var viewImageInputSchema = z16.object({
8784
+ path: z16.string().min(1).describe("Path to an image file in the sandbox workspace.")
8401
8785
  }).strict();
8402
8786
  function detectImageMimeType(data) {
8403
8787
  if (data.length >= 8 && data.subarray(0, 8).equals(Buffer.from([137, 80, 78, 71, 13, 10, 26, 10]))) {
@@ -8464,7 +8848,7 @@ function createViewImageTool(sandbox, supportsImageInput, deps = {}) {
8464
8848
  }
8465
8849
 
8466
8850
  // src/chat/tools/runtime/report-progress.ts
8467
- import { z as z16 } from "zod";
8851
+ import { z as z17 } from "zod";
8468
8852
  function createReportProgressTool() {
8469
8853
  return zodTool({
8470
8854
  annotations: {
@@ -8474,8 +8858,8 @@ function createReportProgressTool() {
8474
8858
  readOnlyHint: false
8475
8859
  },
8476
8860
  description: "Update the user-visible assistant loading message with a short progress phase. Use this only for work with multiple substantive phases or a materially long wait. Skip short lookups, routine commands, generic filler, and minor substeps. After an initial update, call it again only when the major phase meaningfully changes. Messages must be written in sentence case with a present-participle verb (e.g. 'Searching docs', 'Reviewing results', 'Running checks').",
8477
- inputSchema: z16.object({
8478
- message: z16.string().min(1).describe("Short user-facing progress message.")
8861
+ inputSchema: z17.object({
8862
+ message: z17.string().min(1).describe("Short user-facing progress message.")
8479
8863
  }),
8480
8864
  outputSchema: juniorToolOutputSchema,
8481
8865
  execute: async () => ({})
@@ -8483,9 +8867,9 @@ function createReportProgressTool() {
8483
8867
  }
8484
8868
 
8485
8869
  // src/chat/tools/runtime/spawn-agent.ts
8486
- import { z as z17 } from "zod";
8870
+ import { z as z18 } from "zod";
8487
8871
  var spawnAgentOutputSchema = juniorToolOutputSchema.extend({
8488
- invocation_id: z17.string().min(1)
8872
+ invocation_id: z18.string().min(1)
8489
8873
  });
8490
8874
  function createSpawnAgentTool(spawnAgent) {
8491
8875
  return zodTool({
@@ -8496,10 +8880,10 @@ function createSpawnAgentTool(spawnAgent) {
8496
8880
  openWorldHint: false,
8497
8881
  readOnlyHint: false
8498
8882
  },
8499
- inputSchema: z17.object({
8500
- task: z17.string().trim().min(1).describe("Task for the child agent"),
8883
+ inputSchema: z18.object({
8884
+ task: z18.string().trim().min(1).describe("Task for the child agent"),
8501
8885
  name: agentNameSchema.nullable().optional().describe("Stable child-agent name, or omit for a one-off agent"),
8502
- reasoning_level: z17.enum(TURN_REASONING_LEVELS).nullable().optional().describe(
8886
+ reasoning_level: z18.enum(TURN_REASONING_LEVELS).nullable().optional().describe(
8503
8887
  "Optional reasoning level for this delegated task only"
8504
8888
  )
8505
8889
  }).strict(),
@@ -8544,19 +8928,19 @@ function createSpawnAgentTool(spawnAgent) {
8544
8928
  }
8545
8929
 
8546
8930
  // src/chat/tools/list-resource-event-subscriptions.ts
8547
- import { z as z18 } from "zod";
8548
- var listedResourceWatchSchema = z18.object({
8549
- id: z18.string().min(1),
8550
- label: z18.string().min(1),
8551
- identifier: z18.string().min(1),
8552
- namespace: z18.string().min(1),
8553
- resourceType: z18.string().min(1),
8554
- events: z18.array(z18.string().min(1)).min(1),
8555
- match: z18.record(z18.string(), z18.unknown()).optional(),
8556
- intent: z18.string().min(1),
8557
- expiresAtMs: z18.number().finite()
8931
+ import { z as z19 } from "zod";
8932
+ var listedResourceWatchSchema = z19.object({
8933
+ id: z19.string().min(1),
8934
+ label: z19.string().min(1),
8935
+ identifier: z19.string().min(1),
8936
+ namespace: z19.string().min(1),
8937
+ resourceType: z19.string().min(1),
8938
+ events: z19.array(z19.string().min(1)).min(1),
8939
+ match: z19.record(z19.string(), z19.unknown()).optional(),
8940
+ intent: z19.string().min(1),
8941
+ expiresAtMs: z19.number().finite()
8558
8942
  }).strict();
8559
- var resultDataSchema = z18.object({ subscriptions: z18.array(listedResourceWatchSchema) }).strict();
8943
+ var resultDataSchema = z19.object({ subscriptions: z19.array(listedResourceWatchSchema) }).strict();
8560
8944
  var outputSchema = juniorToolOutputSchema.merge(resultDataSchema);
8561
8945
  function createListResourceEventSubscriptionsTool(context) {
8562
8946
  return zodTool({
@@ -8569,7 +8953,7 @@ function createListResourceEventSubscriptionsTool(context) {
8569
8953
  description: "List active resource event subscriptions for the current conversation.",
8570
8954
  exposure: "deferred",
8571
8955
  source: RESOURCE_WATCH_TOOL_SOURCE,
8572
- inputSchema: z18.object({}).strict(),
8956
+ inputSchema: z19.object({}).strict(),
8573
8957
  outputSchema,
8574
8958
  async execute() {
8575
8959
  const subscriptions = await listResourceEventSubscriptions({
@@ -8596,28 +8980,28 @@ function createListResourceEventSubscriptionsTool(context) {
8596
8980
  }
8597
8981
 
8598
8982
  // src/chat/tools/search-resource-event-types.ts
8599
- import { z as z19 } from "zod";
8983
+ import { z as z20 } from "zod";
8600
8984
  var DEFAULT_SEARCH_RESULTS = 10;
8601
8985
  var MAX_SEARCH_RESULTS = 20;
8602
- var searchedResourceTypeSchema = z19.object({
8603
- namespace: z19.string(),
8604
- type: z19.string(),
8605
- supportedEvents: z19.array(z19.string()),
8606
- suggestedEvents: z19.array(z19.string()).optional(),
8607
- matchFields: z19.record(
8608
- z19.string(),
8609
- z19.object({
8610
- kind: z19.enum(["boolean", "string", "number"]),
8611
- description: z19.string(),
8612
- enum: z19.array(z19.string()).optional()
8986
+ var searchedResourceTypeSchema = z20.object({
8987
+ namespace: z20.string(),
8988
+ type: z20.string(),
8989
+ supportedEvents: z20.array(z20.string()),
8990
+ suggestedEvents: z20.array(z20.string()).optional(),
8991
+ matchFields: z20.record(
8992
+ z20.string(),
8993
+ z20.object({
8994
+ kind: z20.enum(["boolean", "string", "number"]),
8995
+ description: z20.string(),
8996
+ enum: z20.array(z20.string()).optional()
8613
8997
  }).strict()
8614
8998
  ).optional()
8615
8999
  }).strict();
8616
9000
  var outputSchema2 = juniorToolOutputSchema.extend({
8617
- query: z19.string().nullable(),
8618
- namespace: z19.string().nullable(),
8619
- totalMatches: z19.number().int().nonnegative(),
8620
- resourceTypes: z19.array(searchedResourceTypeSchema)
9001
+ query: z20.string().nullable(),
9002
+ namespace: z20.string().nullable(),
9003
+ totalMatches: z20.number().int().nonnegative(),
9004
+ resourceTypes: z20.array(searchedResourceTypeSchema)
8621
9005
  }).strict();
8622
9006
  function normalizeSearchText(value) {
8623
9007
  return value.toLowerCase().replace(/[^a-z0-9_.-]+/g, " ").trim();
@@ -8644,12 +9028,12 @@ function createSearchResourceEventTypesTool(catalog) {
8644
9028
  readOnlyHint: true
8645
9029
  },
8646
9030
  description: "Search the resource event types currently enabled without creating anything. Includes plugin resources and core Workspace snapshot events. Use watchResourceEvents for temporary updates in the current conversation; use createEventTask for durable automation. This tool does not watch a resource, create a task, or list concrete resources.",
8647
- inputSchema: z19.object({
8648
- query: z19.string().nullable().describe(
9031
+ inputSchema: z20.object({
9032
+ query: z20.string().nullable().describe(
8649
9033
  "Optional terms matching a namespace, resource type, or event name. Empty lists all enabled resource event types."
8650
9034
  ).optional(),
8651
9035
  namespace: eventNamespaceSchema(catalog).nullable().describe("Optional enabled plugin namespace to search within.").optional(),
8652
- maxResults: z19.number().int().min(1).max(MAX_SEARCH_RESULTS).nullable().describe("Maximum matching resource types to return.").optional()
9036
+ maxResults: z20.number().int().min(1).max(MAX_SEARCH_RESULTS).nullable().describe("Maximum matching resource types to return.").optional()
8653
9037
  }).strict(),
8654
9038
  outputSchema: outputSchema2,
8655
9039
  async execute({ query, namespace, maxResults }) {
@@ -8688,10 +9072,10 @@ function createSearchResourceEventTypesTool(catalog) {
8688
9072
  }
8689
9073
 
8690
9074
  // src/chat/tools/stop-watching-resources.ts
8691
- import { z as z20 } from "zod";
8692
- var resultDataSchema2 = z20.object({
8693
- watching_status: z20.literal("stopped"),
8694
- stoppedIds: z20.array(z20.string().min(1))
9075
+ import { z as z21 } from "zod";
9076
+ var resultDataSchema2 = z21.object({
9077
+ watching_status: z21.literal("stopped"),
9078
+ stoppedIds: z21.array(z21.string().min(1))
8695
9079
  }).strict();
8696
9080
  var outputSchema3 = juniorToolOutputSchema.merge(resultDataSchema2);
8697
9081
  function createStopWatchingResourcesTool(context) {
@@ -8705,7 +9089,7 @@ function createStopWatchingResourcesTool(context) {
8705
9089
  description: "Stop one resource watch in the current conversation by id. Omit id only when the user explicitly asks to stop every watch in this conversation. Infer terse stop requests from context, inspect active watches when the target is unclear, and call this tool before confirming that watching stopped.",
8706
9090
  exposure: "deferred",
8707
9091
  source: RESOURCE_WATCH_TOOL_SOURCE,
8708
- inputSchema: z20.object({ id: z20.string().min(1).nullable().optional() }).strict(),
9092
+ inputSchema: z21.object({ id: z21.string().min(1).nullable().optional() }).strict(),
8709
9093
  outputSchema: outputSchema3,
8710
9094
  async execute({ id }) {
8711
9095
  let stoppedIds;
@@ -8739,25 +9123,25 @@ function createStopWatchingResourcesTool(context) {
8739
9123
  }
8740
9124
 
8741
9125
  // src/chat/tools/watch-resource-events.ts
8742
- import { z as z21 } from "zod";
9126
+ import { z as z22 } from "zod";
8743
9127
  function inputSchema(catalog) {
8744
- return z21.object({
8745
- identifier: z21.string().trim().min(1).describe("Plugin-defined resource identifier."),
9128
+ return z22.object({
9129
+ identifier: z22.string().trim().min(1).describe("Plugin-defined resource identifier."),
8746
9130
  namespace: eventNamespaceSchema(catalog).describe(
8747
9131
  "Enabled plugin namespace for this resource."
8748
9132
  ),
8749
9133
  resourceType: registeredResourceTypeSchema(catalog).describe(
8750
9134
  "Plugin-defined resource type."
8751
9135
  ),
8752
- label: z21.string().trim().min(1).max(500).describe("Human-readable resource label."),
8753
- events: z21.array(registeredEventTypeSchema(catalog)).min(1).describe(
9136
+ label: z22.string().trim().min(1).max(500).describe("Human-readable resource label."),
9137
+ events: z22.array(registeredEventTypeSchema(catalog)).min(1).describe(
8754
9138
  "High-signal event names to deliver to this conversation when they occur."
8755
9139
  ),
8756
9140
  match: registeredResourceEventMatchSchema(),
8757
- intent: z21.string().trim().min(1).max(4e3).describe(
9141
+ intent: z22.string().trim().min(1).max(4e3).describe(
8758
9142
  "Concise reason this conversation wants these events, used when an event arrives."
8759
9143
  ),
8760
- ttlMs: z21.coerce.number().describe(
9144
+ ttlMs: z22.coerce.number().describe(
8761
9145
  "How long to keep the subscription active. Defaults to 14 days and must not exceed 30 days."
8762
9146
  ).optional()
8763
9147
  }).strict().superRefine((subscription, context) => {
@@ -8777,20 +9161,20 @@ function inputSchema(catalog) {
8777
9161
  });
8778
9162
  });
8779
9163
  }
8780
- var stopWatchingActionSchema = z21.object({
8781
- execution_tool: z21.literal("executeTool"),
8782
- execution_example: z21.object({
8783
- tool_name: z21.literal(STOP_WATCHING_TOOL_NAME),
8784
- arguments: z21.object({ id: z21.string().min(1) }).strict()
9164
+ var stopWatchingActionSchema = z22.object({
9165
+ execution_tool: z22.literal("executeTool"),
9166
+ execution_example: z22.object({
9167
+ tool_name: z22.literal(STOP_WATCHING_TOOL_NAME),
9168
+ arguments: z22.object({ id: z22.string().min(1) }).strict()
8785
9169
  }).strict()
8786
9170
  }).strict();
8787
- var resultDataSchema3 = z21.object({
8788
- id: z21.string().min(1),
8789
- subscription_status: z21.enum(["active", "cancelled", "completed"]),
8790
- identifier: z21.string().min(1),
8791
- events: z21.array(z21.string().min(1)).min(1),
8792
- match: z21.record(z21.string(), z21.unknown()).optional(),
8793
- expiresAtMs: z21.number().finite(),
9171
+ var resultDataSchema3 = z22.object({
9172
+ id: z22.string().min(1),
9173
+ subscription_status: z22.enum(["active", "cancelled", "completed"]),
9174
+ identifier: z22.string().min(1),
9175
+ events: z22.array(z22.string().min(1)).min(1),
9176
+ match: z22.record(z22.string(), z22.unknown()).optional(),
9177
+ expiresAtMs: z22.number().finite(),
8794
9178
  stop_watching: stopWatchingActionSchema
8795
9179
  }).strict();
8796
9180
  var outputSchema4 = juniorToolOutputSchema.merge(resultDataSchema3);
@@ -8892,7 +9276,7 @@ function createResourceEventTools(context, catalog) {
8892
9276
 
8893
9277
  // src/chat/tools/create-event-task.ts
8894
9278
  import { createHash } from "crypto";
8895
- import { z as z22 } from "zod";
9279
+ import { z as z23 } from "zod";
8896
9280
  function buildEventTaskId(args) {
8897
9281
  const toolCallId = args.toolCallId?.trim();
8898
9282
  if (!toolCallId) {
@@ -8920,13 +9304,13 @@ function createEventTaskTool(context, catalog) {
8920
9304
  },
8921
9305
  executionMode: "sequential",
8922
9306
  description: "Create a durable event task that executes the supplied instruction for every matching resource event. Use for whenever-this-happens-do-X automation; ordinary watch, notify, or tell-me-when requests use watchResourceEvents instead. The task may use the creator's connected credentials. Prefer a subscribable tool result when available.",
8923
- inputSchema: z22.object({
8924
- task: z22.string().trim().min(1).max(4e3),
8925
- title: z22.string().trim().min(1).max(SHORT_TITLE_MAX_LENGTH).nullable().describe(
9307
+ inputSchema: z23.object({
9308
+ task: z23.string().trim().min(1).max(4e3),
9309
+ title: z23.string().trim().min(1).max(SHORT_TITLE_MAX_LENGTH).nullable().describe(
8926
9310
  "Optional short display title. Omit or use null to generate one from the task instruction."
8927
9311
  ).optional(),
8928
9312
  trigger,
8929
- credentialMode: z22.enum(["creator", "system"]).nullable().describe(
9313
+ credentialMode: z23.enum(["creator", "system"]).nullable().describe(
8930
9314
  "Use creator to make the task creator's connected credentials available, or system when the creator says not to use them. Omit or use null for the creator default."
8931
9315
  ).optional()
8932
9316
  }).strict(),
@@ -8957,7 +9341,9 @@ function createEventTaskTool(context, catalog) {
8957
9341
  if (!eventTaskMatchesDestination(existing, destination) || existing.createdBy.slackUserId !== actor.userId) {
8958
9342
  throw new ToolInputError("Event task operation identity is invalid.");
8959
9343
  }
8960
- return eventTaskSuccess(existing, catalog);
9344
+ if (existing.status !== "deleted") {
9345
+ return eventTaskSuccess(existing, catalog);
9346
+ }
8961
9347
  }
8962
9348
  const title = await resolveTaskTitle({
8963
9349
  completeText,
@@ -8996,7 +9382,7 @@ function createEventTaskTool(context, catalog) {
8996
9382
  }
8997
9383
 
8998
9384
  // src/chat/tools/delete-event-task.ts
8999
- import { z as z23 } from "zod";
9385
+ import { z as z24 } from "zod";
9000
9386
  function createDeleteEventTaskTool(context, catalog) {
9001
9387
  return zodTool({
9002
9388
  approvalMode: "review",
@@ -9008,7 +9394,7 @@ function createDeleteEventTaskTool(context, catalog) {
9008
9394
  },
9009
9395
  executionMode: "sequential",
9010
9396
  description: "Delete an event task.",
9011
- inputSchema: z23.object({ taskId: z23.string().min(1) }).strict(),
9397
+ inputSchema: z24.object({ taskId: z24.string().min(1) }).strict(),
9012
9398
  outputSchema: eventTaskToolResultSchema,
9013
9399
  async execute({ taskId }) {
9014
9400
  const current = await writableEventTask(context, taskId);
@@ -9022,7 +9408,7 @@ function createDeleteEventTaskTool(context, catalog) {
9022
9408
  }
9023
9409
 
9024
9410
  // src/chat/tools/list-event-tasks.ts
9025
- import { z as z24 } from "zod";
9411
+ import { z as z25 } from "zod";
9026
9412
  var MAX_LISTED_EVENT_TASKS = 50;
9027
9413
  function createListEventTasksTool(context, catalog) {
9028
9414
  return zodTool({
@@ -9033,7 +9419,7 @@ function createListEventTasksTool(context, catalog) {
9033
9419
  readOnlyHint: true
9034
9420
  },
9035
9421
  description: "List event tasks for the current destination. A false triggerAvailable value means the task remains stored but its plugin event is not currently enabled.",
9036
- inputSchema: z24.object({}).strict(),
9422
+ inputSchema: z25.object({}).strict(),
9037
9423
  outputSchema: eventTaskListToolResultSchema,
9038
9424
  async execute() {
9039
9425
  const { destination } = requireEventTaskSlackContext(context);
@@ -9049,7 +9435,7 @@ function createListEventTasksTool(context, catalog) {
9049
9435
 
9050
9436
  // src/chat/tools/update-event-task.ts
9051
9437
  import { stableResourceEventMatchKey } from "@sentry/junior-plugin-api";
9052
- import { z as z25 } from "zod";
9438
+ import { z as z26 } from "zod";
9053
9439
  function changesEventTaskTrigger(current, next) {
9054
9440
  const currentEvents = [...current.events].sort();
9055
9441
  const nextEvents = [...next.events].sort();
@@ -9066,11 +9452,11 @@ function createUpdateEventTaskTool(context, catalog) {
9066
9452
  },
9067
9453
  executionMode: "sequential",
9068
9454
  description: "Update the instruction, registered trigger, or credential use for an event task.",
9069
- inputSchema: z25.object({
9070
- taskId: z25.string().min(1),
9071
- task: z25.string().trim().min(1).max(4e3).nullable().optional(),
9455
+ inputSchema: z26.object({
9456
+ taskId: z26.string().min(1),
9457
+ task: z26.string().trim().min(1).max(4e3).nullable().optional(),
9072
9458
  trigger: registeredEventTaskTriggerSchema(catalog).nullable().optional(),
9073
- credentialMode: z25.enum(["system", "creator"]).nullable().describe(
9459
+ credentialMode: z26.enum(["system", "creator"]).nullable().describe(
9074
9460
  "Set creator to make the task's original creator credentials available, or system to disable them. Creator always means the task's createdBy actor, never the current requester. Only that original creator may enable creator mode. Omit or use null to leave unchanged."
9075
9461
  ).optional()
9076
9462
  }).strict(),
@@ -9152,10 +9538,10 @@ function createEventTaskTools(context, catalog) {
9152
9538
  }
9153
9539
 
9154
9540
  // src/chat/scheduled-tasks/tools/create.ts
9155
- import { z as z28 } from "zod";
9541
+ import { z as z29 } from "zod";
9156
9542
 
9157
9543
  // src/chat/scheduled-tasks/schedule-intent.ts
9158
- import { z as z26 } from "zod";
9544
+ import { z as z27 } from "zod";
9159
9545
 
9160
9546
  // src/chat/scheduled-tasks/cadence.ts
9161
9547
  var FORMATTERS = /* @__PURE__ */ new Map();
@@ -9446,12 +9832,12 @@ function getNextRunAtMs(task, scheduledForMs, afterMs = scheduledForMs) {
9446
9832
  }
9447
9833
 
9448
9834
  // src/chat/scheduled-tasks/schedule-intent.ts
9449
- var localDateSchema = z26.string().regex(/^\d{4}-\d{2}-\d{2}$/, "Use a local date in YYYY-MM-DD format.");
9450
- var localTimeSchema = z26.string().regex(/^([01]\d|2[0-3]):[0-5]\d$/, "Use local time in HH:MM format.");
9451
- var timezoneSchema = z26.string().min(1).max(80).describe(
9835
+ var localDateSchema = z27.string().regex(/^\d{4}-\d{2}-\d{2}$/, "Use a local date in YYYY-MM-DD format.");
9836
+ var localTimeSchema = z27.string().regex(/^([01]\d|2[0-3]):[0-5]\d$/, "Use local time in HH:MM format.");
9837
+ var timezoneSchema = z27.string().min(1).max(80).describe(
9452
9838
  "IANA timezone, for example America/Los_Angeles. Omit or use null for the scheduler default."
9453
9839
  ).nullable().optional();
9454
- var weekdaySchema = z26.enum([
9840
+ var weekdaySchema = z27.enum([
9455
9841
  "sunday",
9456
9842
  "monday",
9457
9843
  "tuesday",
@@ -9460,17 +9846,17 @@ var weekdaySchema = z26.enum([
9460
9846
  "friday",
9461
9847
  "saturday"
9462
9848
  ]);
9463
- var oneOffScheduleIntentSchema = z26.object({
9464
- kind: z26.literal("one_off").describe("A schedule that runs once."),
9849
+ var oneOffScheduleIntentSchema = z27.object({
9850
+ kind: z27.literal("one_off").describe("A schedule that runs once."),
9465
9851
  timezone: timezoneSchema,
9466
- timing: z26.discriminatedUnion("type", [
9467
- z26.object({
9468
- type: z26.literal("after").describe("Run after a relative delay from the server clock."),
9469
- value: z26.number().int().positive().max(1e5),
9470
- unit: z26.enum(["second", "minute", "hour", "day", "week"])
9852
+ timing: z27.discriminatedUnion("type", [
9853
+ z27.object({
9854
+ type: z27.literal("after").describe("Run after a relative delay from the server clock."),
9855
+ value: z27.number().int().positive().max(1e5),
9856
+ unit: z27.enum(["second", "minute", "hour", "day", "week"])
9471
9857
  }).strict(),
9472
- z26.object({
9473
- type: z26.literal("at").describe("Run at an explicit local calendar date and time."),
9858
+ z27.object({
9859
+ type: z27.literal("at").describe("Run at an explicit local calendar date and time."),
9474
9860
  date: localDateSchema.describe(
9475
9861
  "Requested local calendar date in YYYY-MM-DD format."
9476
9862
  ),
@@ -9480,16 +9866,16 @@ var oneOffScheduleIntentSchema = z26.object({
9480
9866
  }).strict()
9481
9867
  ]).describe("Relative delay or explicit local time for the one-off run.")
9482
9868
  }).strict();
9483
- var recurringScheduleIntentSchema = z26.object({
9484
- kind: z26.literal("recurring").describe("A repeating calendar schedule."),
9485
- frequency: z26.enum(["daily", "weekly", "monthly", "yearly"]).describe("Recurring tasks can run at most once per day."),
9486
- interval: z26.number().int().positive().max(365).describe("Repeat every N frequency units. Defaults to 1.").nullable().optional(),
9869
+ var recurringScheduleIntentSchema = z27.object({
9870
+ kind: z27.literal("recurring").describe("A repeating calendar schedule."),
9871
+ frequency: z27.enum(["daily", "weekly", "monthly", "yearly"]).describe("Recurring tasks can run at most once per day."),
9872
+ interval: z27.number().int().positive().max(365).describe("Repeat every N frequency units. Defaults to 1.").nullable().optional(),
9487
9873
  time: localTimeSchema.describe(
9488
9874
  "Local wall-clock time for each occurrence in HH:MM format."
9489
9875
  ),
9490
- weekdays: z26.array(weekdaySchema).min(1).max(7).describe("Required for weekly schedules.").nullable().optional(),
9491
- day_of_month: z26.number().int().min(1).max(31).describe("Required for monthly and yearly schedules.").nullable().optional(),
9492
- month: z26.number().int().min(1).max(12).describe("Required for yearly schedules, where January is 1.").nullable().optional(),
9876
+ weekdays: z27.array(weekdaySchema).min(1).max(7).describe("Required for weekly schedules.").nullable().optional(),
9877
+ day_of_month: z27.number().int().min(1).max(31).describe("Required for monthly and yearly schedules.").nullable().optional(),
9878
+ month: z27.number().int().min(1).max(12).describe("Required for yearly schedules, where January is 1.").nullable().optional(),
9493
9879
  start_date: localDateSchema.describe(
9494
9880
  "Optional local calendar date that anchors the recurrence. Omit to start with the next matching occurrence."
9495
9881
  ).nullable().optional(),
@@ -9538,7 +9924,7 @@ var recurringScheduleIntentSchema = z26.object({
9538
9924
  });
9539
9925
  }
9540
9926
  });
9541
- var scheduleIntentSchema = z26.union([
9927
+ var scheduleIntentSchema = z27.union([
9542
9928
  oneOffScheduleIntentSchema,
9543
9929
  recurringScheduleIntentSchema
9544
9930
  ]);
@@ -9733,7 +10119,7 @@ import { createHash as createHash2 } from "crypto";
9733
10119
  import {
9734
10120
  sourceSchema
9735
10121
  } from "@sentry/junior-plugin-api";
9736
- import { z as z27 } from "zod";
10122
+ import { z as z28 } from "zod";
9737
10123
 
9738
10124
  // src/chat/scheduled-tasks/identity.ts
9739
10125
  var SLACK_USER_ID_PATTERN = /^[UW][A-Z0-9]{5,}$/;
@@ -9770,36 +10156,36 @@ function sanitizeScheduledTaskPrincipal(principal) {
9770
10156
  var TASK_ID_PREFIX = "sched";
9771
10157
  var MAX_LISTED_TASKS = 50;
9772
10158
  var DEFAULT_SCHEDULE_TIMEZONE = "America/Los_Angeles";
9773
- var compactTaskResultSchema = z27.object({
9774
- id: z27.string(),
9775
- status: z27.enum(["active", "blocked", "completed", "deleted"]),
9776
- task: z27.string(),
9777
- schedule: z27.string(),
9778
- timezone: z27.string(),
9779
- recurrence: z27.unknown().nullable(),
9780
- next_run_at: z27.string().nullable(),
9781
- destination: z27.object({
9782
- platform: z27.literal("slack"),
9783
- team_id: z27.string().min(1),
9784
- channel_id: z27.string().min(1)
10159
+ var compactTaskResultSchema = z28.object({
10160
+ id: z28.string(),
10161
+ status: z28.enum(["active", "blocked", "completed", "deleted"]),
10162
+ task: z28.string(),
10163
+ schedule: z28.string(),
10164
+ timezone: z28.string(),
10165
+ recurrence: z28.unknown().nullable(),
10166
+ next_run_at: z28.string().nullable(),
10167
+ destination: z28.object({
10168
+ platform: z28.literal("slack"),
10169
+ team_id: z28.string().min(1),
10170
+ channel_id: z28.string().min(1)
9785
10171
  }).strict(),
9786
- conversation_access: z27.object({
9787
- audience: z27.enum(["direct", "group", "channel"]),
9788
- visibility: z27.enum(["private", "public"])
10172
+ conversation_access: z28.object({
10173
+ audience: z28.enum(["direct", "group", "channel"]),
10174
+ visibility: z28.enum(["private", "public"])
9789
10175
  }).strict(),
9790
- credential_mode: z27.enum(["system", "creator"]),
9791
- dashboard_url: z27.string().url().nullable(),
9792
- last_run_at: z27.string().nullable(),
9793
- run_now_at: z27.string().nullable()
10176
+ credential_mode: z28.enum(["system", "creator"]),
10177
+ dashboard_url: z28.string().url().nullable(),
10178
+ last_run_at: z28.string().nullable(),
10179
+ run_now_at: z28.string().nullable()
9794
10180
  }).strict();
9795
10181
  var scheduleTaskToolResultSchema = juniorToolOutputSchema.extend({
9796
- target: z27.string(),
10182
+ target: z28.string(),
9797
10183
  task: compactTaskResultSchema
9798
10184
  }).strict();
9799
10185
  var scheduleListToolResultSchema = juniorToolOutputSchema.extend({
9800
- target: z27.string(),
9801
- tasks: z27.array(compactTaskResultSchema),
9802
- truncated: z27.boolean()
10186
+ target: z28.string(),
10187
+ tasks: z28.array(compactTaskResultSchema),
10188
+ truncated: z28.boolean()
9803
10189
  }).strict();
9804
10190
  function throwToolInputError(error) {
9805
10191
  throw new ToolInputError(error);
@@ -9962,15 +10348,15 @@ function createSlackScheduleCreateTaskTool(context) {
9962
10348
  },
9963
10349
  description: "Create a one-time or recurring Junior task in the active Slack conversation when the user asks Junior to do work later or repeatedly.",
9964
10350
  executionMode: "sequential",
9965
- inputSchema: z28.object({
9966
- task: z28.string().min(1).max(4e3),
9967
- title: z28.string().trim().min(1).max(SHORT_TITLE_MAX_LENGTH).nullable().describe(
10351
+ inputSchema: z29.object({
10352
+ task: z29.string().min(1).max(4e3),
10353
+ title: z29.string().trim().min(1).max(SHORT_TITLE_MAX_LENGTH).nullable().describe(
9968
10354
  "Optional short display title. Omit or use null to generate one from the task instruction."
9969
10355
  ).optional(),
9970
10356
  schedule: scheduleIntentSchema.describe(
9971
10357
  "When the task runs. The scheduler computes the exact next run from this intent and the server clock."
9972
10358
  ),
9973
- credential_mode: z28.enum(["creator", "system"]).nullable().describe(
10359
+ credential_mode: z29.enum(["creator", "system"]).nullable().describe(
9974
10360
  "Use creator to make the task creator's connected credentials available, or system when the creator says not to use them. Omit or use null for the creator default."
9975
10361
  ).optional()
9976
10362
  }).strict(),
@@ -10069,7 +10455,7 @@ function createSlackScheduleCreateTaskTool(context) {
10069
10455
  }
10070
10456
 
10071
10457
  // src/chat/scheduled-tasks/tools/delete.ts
10072
- import { z as z29 } from "zod";
10458
+ import { z as z30 } from "zod";
10073
10459
  function createSlackScheduleDeleteTaskTool(context) {
10074
10460
  return zodTool({
10075
10461
  approvalMode: "review",
@@ -10081,8 +10467,8 @@ function createSlackScheduleDeleteTaskTool(context) {
10081
10467
  },
10082
10468
  description: "Delete one scheduled Junior task from the active Slack conversation. Use only task IDs returned for this conversation. Do not delete schedules from threads, other channels, or another user's DM.",
10083
10469
  executionMode: "sequential",
10084
- inputSchema: z29.object({
10085
- task_id: z29.string().min(1).describe(
10470
+ inputSchema: z30.object({
10471
+ task_id: z30.string().min(1).describe(
10086
10472
  "ID of the task to delete. Must be from this active Slack conversation."
10087
10473
  )
10088
10474
  }),
@@ -10106,12 +10492,12 @@ function createSlackScheduleDeleteTaskTool(context) {
10106
10492
  }
10107
10493
 
10108
10494
  // src/chat/slack/id-param.ts
10109
- import { z as z30 } from "zod";
10495
+ import { z as z31 } from "zod";
10110
10496
  function slackChannelIdParam(description) {
10111
- return z30.string().min(1).describe(description);
10497
+ return z31.string().min(1).describe(description);
10112
10498
  }
10113
10499
  function slackUserIdParam(description) {
10114
- return z30.string().min(1).describe(description);
10500
+ return z31.string().min(1).describe(description);
10115
10501
  }
10116
10502
  function parseRequiredSlackChannelIdParam(field, value) {
10117
10503
  const channelId = parseSlackChannelId(value);
@@ -10135,7 +10521,7 @@ function parseRequiredSlackUserIdParam(field, value) {
10135
10521
  }
10136
10522
 
10137
10523
  // src/chat/scheduled-tasks/tools/list.ts
10138
- import { z as z31 } from "zod";
10524
+ import { z as z32 } from "zod";
10139
10525
  function taskMatchesQuery(task, query) {
10140
10526
  const normalized = query.toLowerCase();
10141
10527
  return [
@@ -10155,11 +10541,11 @@ function createSlackScheduleListTasksTool(context) {
10155
10541
  openWorldHint: false,
10156
10542
  readOnlyHint: true
10157
10543
  },
10158
- inputSchema: z31.object({
10544
+ inputSchema: z32.object({
10159
10545
  channel_id: slackChannelIdParam(
10160
10546
  "Current destination channel ID to filter by. Use the ID from a channel mention; do not guess."
10161
10547
  ).nullable().optional(),
10162
- query: z31.string().trim().min(1).max(200).nullable().describe("Text to match in the requester's scheduled tasks.").optional()
10548
+ query: z32.string().trim().min(1).max(200).nullable().describe("Text to match in the requester's scheduled tasks.").optional()
10163
10549
  }).strict(),
10164
10550
  outputSchema: scheduleListToolResultSchema,
10165
10551
  execute: async (input) => {
@@ -10207,7 +10593,7 @@ function createSlackScheduleListTasksTool(context) {
10207
10593
  }
10208
10594
 
10209
10595
  // src/chat/scheduled-tasks/tools/run-now.ts
10210
- import { z as z32 } from "zod";
10596
+ import { z as z33 } from "zod";
10211
10597
  function createSlackScheduleRunTaskNowTool(context) {
10212
10598
  return zodTool({
10213
10599
  approvalMode: "review",
@@ -10219,8 +10605,8 @@ function createSlackScheduleRunTaskNowTool(context) {
10219
10605
  },
10220
10606
  description: "Queue an existing active scheduled Junior task to run as soon as possible, without changing its cadence. Use when the user asks to run an existing scheduled task now. Use only task IDs returned for this conversation.",
10221
10607
  executionMode: "sequential",
10222
- inputSchema: z32.object({
10223
- task_id: z32.string().min(1).describe(
10608
+ inputSchema: z33.object({
10609
+ task_id: z33.string().min(1).describe(
10224
10610
  "ID of the active task to run now. Must be from this active Slack conversation."
10225
10611
  )
10226
10612
  }),
@@ -10248,7 +10634,7 @@ function createSlackScheduleRunTaskNowTool(context) {
10248
10634
  }
10249
10635
 
10250
10636
  // src/chat/scheduled-tasks/tools/update.ts
10251
- import { z as z33 } from "zod";
10637
+ import { z as z34 } from "zod";
10252
10638
  import { and, eq, inArray } from "drizzle-orm";
10253
10639
  function createSlackScheduleUpdateTaskTool(context) {
10254
10640
  return zodTool({
@@ -10261,17 +10647,17 @@ function createSlackScheduleUpdateTaskTool(context) {
10261
10647
  },
10262
10648
  description: `Update a scheduled task. To move the requester's task into this Slack conversation, set destination to "here".`,
10263
10649
  executionMode: "sequential",
10264
- inputSchema: z33.object({
10265
- task_id: z33.string().min(1).describe("Scheduled task ID returned by slackScheduleListTasks."),
10266
- task: z33.string().min(1).max(4e3).optional(),
10650
+ inputSchema: z34.object({
10651
+ task_id: z34.string().min(1).describe("Scheduled task ID returned by slackScheduleListTasks."),
10652
+ task: z34.string().min(1).max(4e3).optional(),
10267
10653
  schedule: scheduleIntentSchema.describe("Complete replacement schedule. Omit to keep it unchanged.").nullable().optional(),
10268
- status: z33.enum(["active", "blocked"]).describe(
10654
+ status: z34.enum(["active", "blocked"]).describe(
10269
10655
  "Set active to resume a blocked task, or blocked to stop dispatch."
10270
10656
  ).optional(),
10271
- destination: z33.literal("here").nullable().describe(
10657
+ destination: z34.literal("here").nullable().describe(
10272
10658
  `Set to "here" to move the creator's task into this Slack conversation. Omit to keep its destination.`
10273
10659
  ).optional(),
10274
- credential_mode: z33.enum(["system", "creator"]).nullable().describe(
10660
+ credential_mode: z34.enum(["system", "creator"]).nullable().describe(
10275
10661
  "Use creator credentials or system credentials. Only the task creator may enable creator mode. Omit to keep unchanged."
10276
10662
  ).optional()
10277
10663
  }).strict(),
@@ -10630,9 +11016,9 @@ async function joinPublicChannelForRead(args) {
10630
11016
  }
10631
11017
 
10632
11018
  // src/chat/slack/tool-support/channel-target.ts
10633
- import { z as z34 } from "zod";
11019
+ import { z as z35 } from "zod";
10634
11020
  var SLACK_CHANNEL_REF_MAX_LENGTH = 160;
10635
- var slackChannelRefParam = z34.string().trim().min(1).max(SLACK_CHANNEL_REF_MAX_LENGTH).describe(
11021
+ var slackChannelRefParam = z35.string().trim().min(1).max(SLACK_CHANNEL_REF_MAX_LENGTH).describe(
10636
11022
  "Slack channel id (`C123`), mention (`<#C123>` / `<#C123|name>`), Junior slack reference (`slack:C123`), or a channel name Junior already knows in this workspace."
10637
11023
  );
10638
11024
  async function resolveSlackChannelRef(input) {
@@ -10680,7 +11066,7 @@ async function resolveOptionalSlackChannelRef(input) {
10680
11066
  }
10681
11067
 
10682
11068
  // src/chat/slack/tools/channel-join.ts
10683
- import { z as z35 } from "zod";
11069
+ import { z as z36 } from "zod";
10684
11070
  function createSlackChannelJoinTool(context) {
10685
11071
  return zodTool({
10686
11072
  description: "Join a public Slack channel.",
@@ -10690,7 +11076,7 @@ function createSlackChannelJoinTool(context) {
10690
11076
  openWorldHint: true,
10691
11077
  readOnlyHint: false
10692
11078
  },
10693
- inputSchema: z35.object({
11079
+ inputSchema: z36.object({
10694
11080
  channel_id: slackChannelRefParam
10695
11081
  }),
10696
11082
  outputSchema: juniorToolOutputSchema,
@@ -10747,11 +11133,11 @@ function createSlackChannelJoinTool(context) {
10747
11133
  }
10748
11134
 
10749
11135
  // src/chat/slack/timestamp-param.ts
10750
- import { z as z36 } from "zod";
11136
+ import { z as z37 } from "zod";
10751
11137
  function slackTimestampParam(description) {
10752
- return z36.preprocess(
11138
+ return z37.preprocess(
10753
11139
  (value) => typeof value === "number" && Number.isFinite(value) ? String(value) : value,
10754
- z36.string().min(1)
11140
+ z37.string().min(1)
10755
11141
  ).describe(description);
10756
11142
  }
10757
11143
  function parseSlackTimestampParam(field, value) {
@@ -10779,10 +11165,10 @@ function parseRequiredSlackTimestampParam(field, value) {
10779
11165
  }
10780
11166
 
10781
11167
  // src/chat/slack/tools/channel-list-messages.ts
10782
- import { z as z37 } from "zod";
10783
- var booleanInput2 = (description) => z37.preprocess(
11168
+ import { z as z38 } from "zod";
11169
+ var booleanInput2 = (description) => z38.preprocess(
10784
11170
  (value) => value === "true" ? true : value === "false" ? false : value,
10785
- z37.boolean()
11171
+ z38.boolean()
10786
11172
  ).describe(description);
10787
11173
  function normalizeRangeTimestamp(field, value, targetChannelId) {
10788
11174
  if (value === void 0) {
@@ -10814,10 +11200,10 @@ function createSlackChannelListMessagesTool(context) {
10814
11200
  openWorldHint: true,
10815
11201
  readOnlyHint: true
10816
11202
  },
10817
- inputSchema: z37.object({
11203
+ inputSchema: z38.object({
10818
11204
  channel_id: slackChannelRefParam.optional(),
10819
- limit: z37.coerce.number().int().min(1).max(1e3).describe("Maximum number of messages to return across pages.").optional(),
10820
- cursor: z37.string().min(1).describe("Optional cursor to continue from a prior call.").optional(),
11205
+ limit: z38.coerce.number().int().min(1).max(1e3).describe("Maximum number of messages to return across pages.").optional(),
11206
+ cursor: z38.string().min(1).describe("Optional cursor to continue from a prior call.").optional(),
10821
11207
  oldest: slackTimestampParam(
10822
11208
  "Oldest message timestamp (Slack ts) for range filtering."
10823
11209
  ).optional(),
@@ -10827,7 +11213,7 @@ function createSlackChannelListMessagesTool(context) {
10827
11213
  inclusive: booleanInput2(
10828
11214
  "Whether oldest/latest bounds should be inclusive."
10829
11215
  ).optional(),
10830
- max_pages: z37.coerce.number().int().min(1).max(10).describe("Maximum number of API pages to traverse in a single call.").optional()
11216
+ max_pages: z38.coerce.number().int().min(1).max(10).describe("Maximum number of API pages to traverse in a single call.").optional()
10831
11217
  }),
10832
11218
  outputSchema: juniorToolOutputSchema,
10833
11219
  execute: async ({
@@ -10950,7 +11336,7 @@ function createSlackChannelListMessagesTool(context) {
10950
11336
  }
10951
11337
 
10952
11338
  // src/chat/slack/tools/conversation-message-search.ts
10953
- import { z as z38 } from "zod";
11339
+ import { z as z39 } from "zod";
10954
11340
 
10955
11341
  // src/chat/conversations/tool-source.ts
10956
11342
  var CONVERSATIONS_TOOL_SOURCE = {
@@ -10962,23 +11348,23 @@ var CONVERSATIONS_TOOL_SOURCE = {
10962
11348
  var DEFAULT_LIMIT = 20;
10963
11349
  var MAX_LIMIT = 50;
10964
11350
  var conversationMessageSearchOutputSchema = juniorToolOutputSchema.extend({
10965
- after: z38.string().datetime().optional(),
10966
- annotation: z38.string().min(1).optional(),
10967
- before: z38.string().datetime().optional(),
10968
- channel_id: z38.string().min(1).optional(),
10969
- count: z38.number().int().nonnegative(),
10970
- query: z38.string().optional(),
10971
- matches: z38.array(
10972
- z38.object({
10973
- channel_id: z38.string().min(1),
10974
- channel_name: z38.string().min(1).optional(),
10975
- conversation_id: z38.string().min(1),
10976
- excerpt: z38.string(),
10977
- message_id: z38.string().min(1),
10978
- message_role: z38.enum(["assistant", "user"]),
10979
- message_timestamp: z38.string().datetime(),
10980
- permalink: z38.string().url().optional(),
10981
- thread_ts: z38.string().min(1)
11351
+ after: z39.string().datetime().optional(),
11352
+ annotation: z39.string().min(1).optional(),
11353
+ before: z39.string().datetime().optional(),
11354
+ channel_id: z39.string().min(1).optional(),
11355
+ count: z39.number().int().nonnegative(),
11356
+ query: z39.string().optional(),
11357
+ matches: z39.array(
11358
+ z39.object({
11359
+ channel_id: z39.string().min(1),
11360
+ channel_name: z39.string().min(1).optional(),
11361
+ conversation_id: z39.string().min(1),
11362
+ excerpt: z39.string(),
11363
+ message_id: z39.string().min(1),
11364
+ message_role: z39.enum(["assistant", "user"]),
11365
+ message_timestamp: z39.string().datetime(),
11366
+ permalink: z39.string().url().optional(),
11367
+ thread_ts: z39.string().min(1)
10982
11368
  }).strict()
10983
11369
  )
10984
11370
  });
@@ -11033,15 +11419,15 @@ function createSlackConversationMessageSearchTool(scope, currentConversationId)
11033
11419
  openWorldHint: false,
11034
11420
  readOnlyHint: true
11035
11421
  },
11036
- inputSchema: z38.object({
11037
- after: z38.string().datetime().nullable().describe("Include conversations active at or after this timestamp.").optional(),
11038
- annotation: z38.string().trim().min(1).max(256).nullable().describe(
11422
+ inputSchema: z39.object({
11423
+ after: z39.string().datetime().nullable().describe("Include conversations active at or after this timestamp.").optional(),
11424
+ annotation: z39.string().trim().min(1).max(256).nullable().describe(
11039
11425
  "Linked resource key. Matches that key, or nested children that continue with #."
11040
11426
  ).optional(),
11041
- before: z38.string().datetime().nullable().describe("Include conversations active before this timestamp.").optional(),
11427
+ before: z39.string().datetime().nullable().describe("Include conversations active before this timestamp.").optional(),
11042
11428
  channel_id: slackChannelRefParam.nullable().optional(),
11043
- query: z38.string().trim().min(1).max(200).nullable().describe("Words or phrase to match in message text.").optional(),
11044
- limit: z38.number().int().min(1).max(MAX_LIMIT).describe(
11429
+ query: z39.string().trim().min(1).max(200).nullable().describe("Words or phrase to match in message text.").optional(),
11430
+ limit: z39.number().int().min(1).max(MAX_LIMIT).describe(
11045
11431
  `Maximum conversations. Default ${DEFAULT_LIMIT}; max ${MAX_LIMIT}.`
11046
11432
  ).nullable().optional()
11047
11433
  }).strict(),
@@ -11100,13 +11486,13 @@ function createSlackConversationMessageSearchTool(scope, currentConversationId)
11100
11486
  }
11101
11487
 
11102
11488
  // src/chat/slack/tools/public-search.ts
11103
- import { z as z39 } from "zod";
11489
+ import { z as z40 } from "zod";
11104
11490
  var DEFAULT_LIMIT2 = 10;
11105
11491
  var DEFAULT_CONTENT_TYPES = ["messages"];
11106
11492
  var CONTENT_TYPES = ["messages", "files", "channels", "users"];
11107
- var unixTimestampParam = z39.coerce.number().int().nonnegative();
11493
+ var unixTimestampParam = z40.coerce.number().int().nonnegative();
11108
11494
  function optionalUnixTimestampParam(description) {
11109
- return z39.preprocess(
11495
+ return z40.preprocess(
11110
11496
  (value) => typeof value === "string" && value.trim() === "" ? void 0 : value,
11111
11497
  unixTimestampParam.optional()
11112
11498
  ).describe(description);
@@ -11120,64 +11506,64 @@ function normalizeOptionalUnixTimestamp(value) {
11120
11506
  }
11121
11507
  return unixTimestampParam.parse(value);
11122
11508
  }
11123
- var searchMessageSchema = z39.object({
11124
- author_name: z39.string().min(1).optional().describe("Author display name."),
11125
- author_user_id: z39.string().min(1).optional().describe("Author user ID."),
11126
- channel_id: z39.string().min(1).describe("Channel ID."),
11127
- channel_name: z39.string().min(1).optional().describe("Channel name."),
11128
- message_ts: z39.string().min(1).describe("Message timestamp."),
11129
- content: z39.string().describe("Message text."),
11130
- is_author_bot: z39.boolean().optional().describe("Whether the author is a bot."),
11131
- permalink: z39.string().url().describe("Message permalink.")
11509
+ var searchMessageSchema = z40.object({
11510
+ author_name: z40.string().min(1).optional().describe("Author display name."),
11511
+ author_user_id: z40.string().min(1).optional().describe("Author user ID."),
11512
+ channel_id: z40.string().min(1).describe("Channel ID."),
11513
+ channel_name: z40.string().min(1).optional().describe("Channel name."),
11514
+ message_ts: z40.string().min(1).describe("Message timestamp."),
11515
+ content: z40.string().describe("Message text."),
11516
+ is_author_bot: z40.boolean().optional().describe("Whether the author is a bot."),
11517
+ permalink: z40.string().url().describe("Message permalink.")
11132
11518
  });
11133
- var searchFileSchema = z39.object({
11134
- file_id: z39.string().min(1).describe("File ID."),
11135
- title: z39.string().min(1).optional().describe("File title."),
11136
- name: z39.string().min(1).optional().describe("File name."),
11137
- filetype: z39.string().min(1).optional().describe("File type."),
11138
- user_id: z39.string().min(1).optional().describe("Uploader user ID."),
11139
- user_name: z39.string().min(1).optional().describe("Uploader user name."),
11140
- channel_id: z39.string().min(1).optional().describe("Channel ID."),
11141
- channel_name: z39.string().min(1).optional().describe("Channel name."),
11142
- permalink: z39.string().url().optional().describe("File permalink."),
11143
- content: z39.string().min(1).optional().describe("File preview or content snippet.")
11519
+ var searchFileSchema = z40.object({
11520
+ file_id: z40.string().min(1).describe("File ID."),
11521
+ title: z40.string().min(1).optional().describe("File title."),
11522
+ name: z40.string().min(1).optional().describe("File name."),
11523
+ filetype: z40.string().min(1).optional().describe("File type."),
11524
+ user_id: z40.string().min(1).optional().describe("Uploader user ID."),
11525
+ user_name: z40.string().min(1).optional().describe("Uploader user name."),
11526
+ channel_id: z40.string().min(1).optional().describe("Channel ID."),
11527
+ channel_name: z40.string().min(1).optional().describe("Channel name."),
11528
+ permalink: z40.string().url().optional().describe("File permalink."),
11529
+ content: z40.string().min(1).optional().describe("File preview or content snippet.")
11144
11530
  });
11145
- var searchChannelSchema = z39.object({
11146
- channel_id: z39.string().min(1).describe("Channel ID."),
11147
- channel_name: z39.string().min(1).optional().describe("Channel name."),
11148
- is_private: z39.boolean().optional().describe("Whether the channel is private."),
11149
- is_member: z39.boolean().optional().describe("Whether the bot is a member."),
11150
- topic: z39.string().min(1).optional().describe("Channel topic."),
11151
- purpose: z39.string().min(1).optional().describe("Channel purpose."),
11152
- permalink: z39.string().url().optional().describe("Channel permalink.")
11531
+ var searchChannelSchema = z40.object({
11532
+ channel_id: z40.string().min(1).describe("Channel ID."),
11533
+ channel_name: z40.string().min(1).optional().describe("Channel name."),
11534
+ is_private: z40.boolean().optional().describe("Whether the channel is private."),
11535
+ is_member: z40.boolean().optional().describe("Whether the bot is a member."),
11536
+ topic: z40.string().min(1).optional().describe("Channel topic."),
11537
+ purpose: z40.string().min(1).optional().describe("Channel purpose."),
11538
+ permalink: z40.string().url().optional().describe("Channel permalink.")
11153
11539
  });
11154
- var searchUserSchema = z39.object({
11155
- user_id: z39.string().min(1).describe("User ID."),
11156
- user_name: z39.string().min(1).optional().describe("Username."),
11157
- real_name: z39.string().min(1).optional().describe("Real name."),
11158
- display_name: z39.string().min(1).optional().describe("Display name."),
11159
- title: z39.string().min(1).optional().describe("Profile title."),
11160
- permalink: z39.string().url().optional().describe("Profile permalink.")
11540
+ var searchUserSchema = z40.object({
11541
+ user_id: z40.string().min(1).describe("User ID."),
11542
+ user_name: z40.string().min(1).optional().describe("Username."),
11543
+ real_name: z40.string().min(1).optional().describe("Real name."),
11544
+ display_name: z40.string().min(1).optional().describe("Display name."),
11545
+ title: z40.string().min(1).optional().describe("Profile title."),
11546
+ permalink: z40.string().url().optional().describe("Profile permalink.")
11161
11547
  });
11162
11548
  var publicSearchOutputSchema = juniorToolOutputSchema.extend({
11163
- query: z39.string().describe("Search query."),
11164
- content_types: z39.array(z39.enum(CONTENT_TYPES)).describe("Content types included in the search."),
11165
- count: z39.number().int().nonnegative().describe("Total matched results."),
11166
- messages: z39.array(searchMessageSchema).describe("Matched messages."),
11167
- files: z39.array(searchFileSchema).describe("Matched files."),
11168
- channels: z39.array(searchChannelSchema).describe("Matched channels."),
11169
- users: z39.array(searchUserSchema).describe("Matched users."),
11170
- next_cursor: z39.string().min(1).optional().describe("Cursor for the next result page.")
11549
+ query: z40.string().describe("Search query."),
11550
+ content_types: z40.array(z40.enum(CONTENT_TYPES)).describe("Content types included in the search."),
11551
+ count: z40.number().int().nonnegative().describe("Total matched results."),
11552
+ messages: z40.array(searchMessageSchema).describe("Matched messages."),
11553
+ files: z40.array(searchFileSchema).describe("Matched files."),
11554
+ channels: z40.array(searchChannelSchema).describe("Matched channels."),
11555
+ users: z40.array(searchUserSchema).describe("Matched users."),
11556
+ next_cursor: z40.string().min(1).optional().describe("Cursor for the next result page.")
11171
11557
  });
11172
- var nonEmptyString = z39.string().trim().min(1);
11173
- var optionalWireString = z39.preprocess((value) => {
11558
+ var nonEmptyString = z40.string().trim().min(1);
11559
+ var optionalWireString = z40.preprocess((value) => {
11174
11560
  if (typeof value !== "string") {
11175
11561
  return void 0;
11176
11562
  }
11177
11563
  const trimmed = value.trim();
11178
11564
  return trimmed === "" ? void 0 : trimmed;
11179
11565
  }, nonEmptyString.optional());
11180
- var optionalWireUrl = z39.preprocess((value) => {
11566
+ var optionalWireUrl = z40.preprocess((value) => {
11181
11567
  if (typeof value !== "string") {
11182
11568
  return void 0;
11183
11569
  }
@@ -11191,20 +11577,20 @@ var optionalWireUrl = z39.preprocess((value) => {
11191
11577
  } catch {
11192
11578
  return void 0;
11193
11579
  }
11194
- }, z39.string().url().optional());
11195
- var optionalWireBoolean = z39.preprocess(
11580
+ }, z40.string().url().optional());
11581
+ var optionalWireBoolean = z40.preprocess(
11196
11582
  (value) => typeof value === "boolean" ? value : void 0,
11197
- z39.boolean().optional()
11583
+ z40.boolean().optional()
11198
11584
  );
11199
- var slackSearchMessageWireSchema = z39.object({
11585
+ var slackSearchMessageWireSchema = z40.object({
11200
11586
  author_name: optionalWireString,
11201
11587
  author_user_id: optionalWireString,
11202
11588
  channel_id: nonEmptyString,
11203
11589
  channel_name: optionalWireString,
11204
11590
  message_ts: nonEmptyString,
11205
- content: z39.string(),
11591
+ content: z40.string(),
11206
11592
  is_author_bot: optionalWireBoolean,
11207
- permalink: z39.string().url()
11593
+ permalink: z40.string().url()
11208
11594
  }).transform(
11209
11595
  (value) => ({
11210
11596
  channel_id: value.channel_id,
@@ -11217,7 +11603,7 @@ var slackSearchMessageWireSchema = z39.object({
11217
11603
  ...value.is_author_bot !== void 0 ? { is_author_bot: value.is_author_bot } : void 0
11218
11604
  })
11219
11605
  );
11220
- var slackSearchFileWireSchema = z39.object({
11606
+ var slackSearchFileWireSchema = z40.object({
11221
11607
  id: optionalWireString,
11222
11608
  file_id: optionalWireString,
11223
11609
  title: optionalWireString,
@@ -11251,7 +11637,7 @@ var slackSearchFileWireSchema = z39.object({
11251
11637
  ...value.content ?? value.preview ? { content: value.content ?? value.preview } : void 0
11252
11638
  };
11253
11639
  });
11254
- var slackSearchChannelWireSchema = z39.object({
11640
+ var slackSearchChannelWireSchema = z40.object({
11255
11641
  id: optionalWireString,
11256
11642
  channel_id: optionalWireString,
11257
11643
  name: optionalWireString,
@@ -11276,7 +11662,7 @@ var slackSearchChannelWireSchema = z39.object({
11276
11662
  ...value.permalink ? { permalink: value.permalink } : void 0
11277
11663
  };
11278
11664
  });
11279
- var slackSearchUserWireSchema = z39.object({
11665
+ var slackSearchUserWireSchema = z40.object({
11280
11666
  id: optionalWireString,
11281
11667
  user_id: optionalWireString,
11282
11668
  name: optionalWireString,
@@ -11300,12 +11686,12 @@ var slackSearchUserWireSchema = z39.object({
11300
11686
  ...value.permalink ? { permalink: value.permalink } : void 0
11301
11687
  };
11302
11688
  });
11303
- var slackSearchResponseSchema = z39.object({
11304
- results: z39.object({
11305
- messages: z39.array(z39.unknown()).default([]),
11306
- files: z39.array(z39.unknown()).default([]),
11307
- channels: z39.array(z39.unknown()).default([]),
11308
- users: z39.array(z39.unknown()).default([]),
11689
+ var slackSearchResponseSchema = z40.object({
11690
+ results: z40.object({
11691
+ messages: z40.array(z40.unknown()).default([]),
11692
+ files: z40.array(z40.unknown()).default([]),
11693
+ channels: z40.array(z40.unknown()).default([]),
11694
+ users: z40.array(z40.unknown()).default([]),
11309
11695
  // Slack often returns "" on the final page; omit rather than fail the parse.
11310
11696
  next_cursor: optionalWireString
11311
11697
  }).default({
@@ -11354,15 +11740,15 @@ function createSlackPublicSearchTool(actionToken) {
11354
11740
  openWorldHint: true,
11355
11741
  readOnlyHint: true
11356
11742
  },
11357
- inputSchema: z39.object({
11358
- query: z39.string().trim().min(1).max(500).describe("Slack search query."),
11359
- content_types: z39.array(z39.enum(CONTENT_TYPES)).min(1).max(4).describe("Content types to include. Defaults to messages.").optional(),
11743
+ inputSchema: z40.object({
11744
+ query: z40.string().trim().min(1).max(500).describe("Slack search query."),
11745
+ content_types: z40.array(z40.enum(CONTENT_TYPES)).min(1).max(4).describe("Content types to include. Defaults to messages.").optional(),
11360
11746
  after: optionalUnixTimestampParam("Unix timestamp lower bound."),
11361
11747
  before: optionalUnixTimestampParam("Unix timestamp upper bound."),
11362
- cursor: z39.string().min(1).describe("Cursor for the next result page.").optional(),
11363
- limit: z39.coerce.number().int().min(1).max(20).describe("Maximum results to return; Slack allows at most 20.").optional(),
11364
- sort: z39.enum(["score", "timestamp"]).describe("Rank by relevance or timestamp.").optional(),
11365
- sort_dir: z39.enum(["asc", "desc"]).describe("Sort direction.").optional()
11748
+ cursor: z40.string().min(1).describe("Cursor for the next result page.").optional(),
11749
+ limit: z40.coerce.number().int().min(1).max(20).describe("Maximum results to return; Slack allows at most 20.").optional(),
11750
+ sort: z40.enum(["score", "timestamp"]).describe("Rank by relevance or timestamp.").optional(),
11751
+ sort_dir: z40.enum(["asc", "desc"]).describe("Sort direction.").optional()
11366
11752
  }),
11367
11753
  outputSchema: publicSearchOutputSchema,
11368
11754
  execute: async ({
@@ -11447,7 +11833,7 @@ function createSlackPublicSearchTool(actionToken) {
11447
11833
  }
11448
11834
 
11449
11835
  // src/chat/slack/tools/message-add-reaction.ts
11450
- import { z as z40 } from "zod";
11836
+ import { z as z41 } from "zod";
11451
11837
 
11452
11838
  // src/chat/tools/idempotency.ts
11453
11839
  function stableSerialize(value) {
@@ -11478,8 +11864,8 @@ function createSlackMessageAddReactionTool(context, state) {
11478
11864
  readOnlyHint: false
11479
11865
  },
11480
11866
  description: "Add an emoji reaction to the current inbound Slack message.",
11481
- inputSchema: z40.object({
11482
- emoji: z40.string().min(1).max(64).describe(
11867
+ inputSchema: z41.object({
11868
+ emoji: z41.string().min(1).max(64).describe(
11483
11869
  "Slack emoji alias name to react with (for example `thumbsup`, `white_check_mark`, or `thumbsup::skin-tone-6`). Optional surrounding colons are allowed."
11484
11870
  )
11485
11871
  }),
@@ -11528,14 +11914,14 @@ function createSlackMessageAddReactionTool(context, state) {
11528
11914
 
11529
11915
  // src/chat/slack/tools/send-files.ts
11530
11916
  import { createHash as createHash3 } from "crypto";
11531
- import { z as z41 } from "zod";
11917
+ import { z as z42 } from "zod";
11532
11918
  var sendFilesResultSchema = juniorToolOutputSchema.extend({
11533
- deduplicated: z41.boolean().optional(),
11534
- attachment_refs: z41.array(
11535
- z41.object({
11536
- id: z41.string().min(1),
11919
+ deduplicated: z42.boolean().optional(),
11920
+ attachment_refs: z42.array(
11921
+ z42.object({
11922
+ id: z42.string().min(1),
11537
11923
  // Same noun as storage, delivery events, and the report API.
11538
- filename: z41.string().min(1)
11924
+ filename: z42.string().min(1)
11539
11925
  })
11540
11926
  )
11541
11927
  });
@@ -11567,8 +11953,8 @@ function createSendFilesTool(context, state, materializeFile, attachments) {
11567
11953
  readOnlyHint: false
11568
11954
  },
11569
11955
  description: "Send one or more sandbox files into the active Slack conversation.",
11570
- inputSchema: z41.object({
11571
- files: z41.array(sandboxFileReferenceSchema).min(1).describe(
11956
+ inputSchema: z42.object({
11957
+ files: z42.array(sandboxFileReferenceSchema).min(1).describe(
11572
11958
  "One or more existing sandbox files. Objects returned by imageGenerate or webFetch can be passed unchanged."
11573
11959
  )
11574
11960
  }),
@@ -11987,7 +12373,7 @@ async function readCanvas(canvasIdOrUrl) {
11987
12373
  }
11988
12374
 
11989
12375
  // src/chat/slack/tools/canvas/create.ts
11990
- import { z as z42 } from "zod";
12376
+ import { z as z43 } from "zod";
11991
12377
  function createSlackCanvasCreateTool(context, state) {
11992
12378
  return zodTool({
11993
12379
  annotations: {
@@ -11997,9 +12383,9 @@ function createSlackCanvasCreateTool(context, state) {
11997
12383
  readOnlyHint: false
11998
12384
  },
11999
12385
  description: "Create a Slack canvas in the active channel.",
12000
- inputSchema: z42.object({
12001
- title: z42.string().min(1).max(160).describe("Canvas title."),
12002
- markdown: z42.string().min(1).describe("Canvas markdown body content.")
12386
+ inputSchema: z43.object({
12387
+ title: z43.string().min(1).max(160).describe("Canvas title."),
12388
+ markdown: z43.string().min(1).describe("Canvas markdown body content.")
12003
12389
  }),
12004
12390
  outputSchema: juniorToolOutputSchema,
12005
12391
  execute: async ({ title, markdown }) => {
@@ -12043,8 +12429,8 @@ function createSlackCanvasCreateTool(context, state) {
12043
12429
  }
12044
12430
 
12045
12431
  // src/chat/slack/tool-support/canvas/context.ts
12046
- import { z as z43 } from "zod";
12047
- var slackCanvasRefParam = z43.string().min(1).describe("Slack canvas/file ID or canvas/docs URL.");
12432
+ import { z as z44 } from "zod";
12433
+ var slackCanvasRefParam = z44.string().min(1).describe("Slack canvas/file ID or canvas/docs URL.");
12048
12434
  function resolveCanvasTarget(canvas) {
12049
12435
  const canvasId = extractCanvasId(canvas);
12050
12436
  if (!canvasId) {
@@ -12057,26 +12443,26 @@ function resolveCanvasTarget(canvas) {
12057
12443
  }
12058
12444
 
12059
12445
  // src/chat/slack/tools/canvas/edit.ts
12060
- import { z as z44 } from "zod";
12446
+ import { z as z45 } from "zod";
12061
12447
  function prepareCanvasEditArguments(input) {
12062
12448
  return prepareTextReplacementArguments(input);
12063
12449
  }
12064
- var editReplacementSchema2 = z44.object({
12065
- oldText: z44.string().min(1).describe(
12450
+ var editReplacementSchema2 = z45.object({
12451
+ oldText: z45.string().min(1).describe(
12066
12452
  "Exact Canvas markdown to replace. It must be unique in the current Canvas body and must not overlap another edit."
12067
12453
  ),
12068
- newText: z44.string().describe("Replacement Canvas markdown for this edit.")
12454
+ newText: z45.string().describe("Replacement Canvas markdown for this edit.")
12069
12455
  });
12070
12456
  var slackCanvasEditOutputSchema = juniorToolOutputSchema.extend({
12071
- canvas_id: z44.string().optional(),
12072
- title: z44.string().optional(),
12073
- permalink: z44.string().optional(),
12074
- diff: z44.string().optional(),
12075
- first_changed_line: z44.number().int().positive().optional(),
12076
- replacements: z44.number().int().nonnegative().optional(),
12077
- normalized_heading_count: z44.number().int().nonnegative().optional(),
12078
- summary: z44.string().optional(),
12079
- deduplicated: z44.boolean().optional()
12457
+ canvas_id: z45.string().optional(),
12458
+ title: z45.string().optional(),
12459
+ permalink: z45.string().optional(),
12460
+ diff: z45.string().optional(),
12461
+ first_changed_line: z45.number().int().positive().optional(),
12462
+ replacements: z45.number().int().nonnegative().optional(),
12463
+ normalized_heading_count: z45.number().int().nonnegative().optional(),
12464
+ summary: z45.string().optional(),
12465
+ deduplicated: z45.boolean().optional()
12080
12466
  }).strict();
12081
12467
  function createSlackCanvasEditTool(state) {
12082
12468
  return zodTool({
@@ -12089,9 +12475,9 @@ function createSlackCanvasEditTool(state) {
12089
12475
  description: "Edit a Slack canvas with exact markdown replacements. Returns a diff.",
12090
12476
  prepareArguments: prepareCanvasEditArguments,
12091
12477
  executionMode: "sequential",
12092
- inputSchema: z44.object({
12478
+ inputSchema: z45.object({
12093
12479
  canvas: slackCanvasRefParam,
12094
- edits: z44.array(editReplacementSchema2).min(1).describe(
12480
+ edits: z45.array(editReplacementSchema2).min(1).describe(
12095
12481
  "Exact replacements matched against the current Canvas body, not incrementally."
12096
12482
  )
12097
12483
  }),
@@ -12144,18 +12530,18 @@ function createSlackCanvasEditTool(state) {
12144
12530
  }
12145
12531
 
12146
12532
  // src/chat/slack/tools/canvas/read.ts
12147
- import { z as z45 } from "zod";
12533
+ import { z as z46 } from "zod";
12148
12534
  var slackCanvasReadOutputSchema = juniorToolOutputSchema.extend({
12149
- canvas_id: z45.string().optional(),
12150
- title: z45.string().optional(),
12151
- permalink: z45.string().optional(),
12152
- mimetype: z45.string().optional(),
12153
- filetype: z45.string().optional(),
12154
- original_byte_length: z45.number().int().nonnegative().optional(),
12155
- content: z45.string().optional(),
12156
- start_line: z45.number().int().positive().optional(),
12157
- end_line: z45.number().int().nonnegative().optional(),
12158
- total_lines: z45.number().int().nonnegative().optional()
12535
+ canvas_id: z46.string().optional(),
12536
+ title: z46.string().optional(),
12537
+ permalink: z46.string().optional(),
12538
+ mimetype: z46.string().optional(),
12539
+ filetype: z46.string().optional(),
12540
+ original_byte_length: z46.number().int().nonnegative().optional(),
12541
+ content: z46.string().optional(),
12542
+ start_line: z46.number().int().positive().optional(),
12543
+ end_line: z46.number().int().nonnegative().optional(),
12544
+ total_lines: z46.number().int().nonnegative().optional()
12159
12545
  }).strict();
12160
12546
  function createSlackCanvasReadTool() {
12161
12547
  return zodTool({
@@ -12166,10 +12552,10 @@ function createSlackCanvasReadTool() {
12166
12552
  openWorldHint: true,
12167
12553
  readOnlyHint: true
12168
12554
  },
12169
- inputSchema: z45.object({
12555
+ inputSchema: z46.object({
12170
12556
  canvas: slackCanvasRefParam,
12171
- offset: z45.coerce.number().int().min(1).describe("1-indexed line number to start reading from.").optional(),
12172
- limit: z45.coerce.number().int().min(1).describe("Maximum number of lines to read. Defaults to 1000.").optional()
12557
+ offset: z46.coerce.number().int().min(1).describe("1-indexed line number to start reading from.").optional(),
12558
+ limit: z46.coerce.number().int().min(1).describe("Maximum number of lines to read. Defaults to 1000.").optional()
12173
12559
  }),
12174
12560
  outputSchema: slackCanvasReadOutputSchema,
12175
12561
  execute: async ({ canvas, offset, limit }) => {
@@ -12205,7 +12591,7 @@ function createSlackCanvasReadTool() {
12205
12591
  }
12206
12592
 
12207
12593
  // src/chat/slack/tools/canvas/write.ts
12208
- import { z as z46 } from "zod";
12594
+ import { z as z47 } from "zod";
12209
12595
  function createSlackCanvasWriteTool(state) {
12210
12596
  return zodTool({
12211
12597
  annotations: {
@@ -12216,9 +12602,9 @@ function createSlackCanvasWriteTool(state) {
12216
12602
  },
12217
12603
  description: "Replace the full markdown body of a Slack canvas.",
12218
12604
  executionMode: "sequential",
12219
- inputSchema: z46.object({
12605
+ inputSchema: z47.object({
12220
12606
  canvas: slackCanvasRefParam,
12221
- content: z46.string().describe("UTF-8 markdown content to write.")
12607
+ content: z47.string().describe("UTF-8 markdown content to write.")
12222
12608
  }),
12223
12609
  outputSchema: juniorToolOutputSchema,
12224
12610
  execute: async ({ canvas, content }) => {
@@ -12440,12 +12826,12 @@ async function updateListItem(input) {
12440
12826
  }
12441
12827
 
12442
12828
  // src/chat/slack/tool-support/list/params.ts
12443
- import { z as z47 } from "zod";
12444
- var slackListIdParam = z47.string().min(1).describe("Slack list ID.");
12445
- var slackListItemIdParam = z47.string().min(1).describe("Slack list item ID.");
12829
+ import { z as z48 } from "zod";
12830
+ var slackListIdParam = z48.string().min(1).describe("Slack list ID.");
12831
+ var slackListItemIdParam = z48.string().min(1).describe("Slack list item ID.");
12446
12832
 
12447
12833
  // src/chat/slack/tools/list/add-items.ts
12448
- import { z as z48 } from "zod";
12834
+ import { z as z49 } from "zod";
12449
12835
  function createSlackListAddItemsTool(state) {
12450
12836
  return zodTool({
12451
12837
  annotations: {
@@ -12455,13 +12841,13 @@ function createSlackListAddItemsTool(state) {
12455
12841
  readOnlyHint: false
12456
12842
  },
12457
12843
  description: "Add tasks to a Slack list.",
12458
- inputSchema: z48.object({
12844
+ inputSchema: z49.object({
12459
12845
  list_id: slackListIdParam,
12460
- items: z48.array(z48.string().min(1)).min(1).max(25).describe("List item titles to create."),
12846
+ items: z49.array(z49.string().min(1)).min(1).max(25).describe("List item titles to create."),
12461
12847
  assignee_user_id: slackUserIdParam(
12462
12848
  "Optional Slack user ID assigned to all created items."
12463
12849
  ).optional(),
12464
- due_date: z48.string().regex(/^\d{4}-\d{2}-\d{2}$/).describe("Optional due date in YYYY-MM-DD format.").optional()
12850
+ due_date: z49.string().regex(/^\d{4}-\d{2}-\d{2}$/).describe("Optional due date in YYYY-MM-DD format.").optional()
12465
12851
  }),
12466
12852
  outputSchema: juniorToolOutputSchema,
12467
12853
  execute: async ({ list_id, items, assignee_user_id, due_date }) => {
@@ -12500,7 +12886,7 @@ function createSlackListAddItemsTool(state) {
12500
12886
  }
12501
12887
 
12502
12888
  // src/chat/slack/tools/list/create.ts
12503
- import { z as z49 } from "zod";
12889
+ import { z as z50 } from "zod";
12504
12890
  function createSlackListCreateTool(state) {
12505
12891
  return zodTool({
12506
12892
  annotations: {
@@ -12510,8 +12896,8 @@ function createSlackListCreateTool(state) {
12510
12896
  readOnlyHint: false
12511
12897
  },
12512
12898
  description: "Create a Slack todo list.",
12513
- inputSchema: z49.object({
12514
- name: z49.string().min(1).max(160).describe("Name for the new Slack list.")
12899
+ inputSchema: z50.object({
12900
+ name: z50.string().min(1).max(160).describe("Name for the new Slack list.")
12515
12901
  }),
12516
12902
  outputSchema: juniorToolOutputSchema,
12517
12903
  execute: async ({ name }) => {
@@ -12536,7 +12922,7 @@ function createSlackListCreateTool(state) {
12536
12922
  }
12537
12923
 
12538
12924
  // src/chat/slack/tools/list/get-items.ts
12539
- import { z as z50 } from "zod";
12925
+ import { z as z51 } from "zod";
12540
12926
  function createSlackListGetItemsTool() {
12541
12927
  return zodTool({
12542
12928
  description: "Read items from a Slack list.",
@@ -12546,9 +12932,9 @@ function createSlackListGetItemsTool() {
12546
12932
  openWorldHint: true,
12547
12933
  readOnlyHint: true
12548
12934
  },
12549
- inputSchema: z50.object({
12935
+ inputSchema: z51.object({
12550
12936
  list_id: slackListIdParam,
12551
- limit: z50.coerce.number().int().min(1).max(200).describe("Maximum number of list items to return.").optional()
12937
+ limit: z51.coerce.number().int().min(1).max(200).describe("Maximum number of list items to return.").optional()
12552
12938
  }),
12553
12939
  outputSchema: juniorToolOutputSchema,
12554
12940
  execute: async ({ list_id, limit }) => {
@@ -12563,23 +12949,23 @@ function createSlackListGetItemsTool() {
12563
12949
  }
12564
12950
 
12565
12951
  // src/chat/slack/tools/list/update-item.ts
12566
- import { z as z51 } from "zod";
12567
- var booleanInput3 = (description) => z51.preprocess(
12952
+ import { z as z52 } from "zod";
12953
+ var booleanInput3 = (description) => z52.preprocess(
12568
12954
  (value) => value === "true" ? true : value === "false" ? false : value,
12569
- z51.boolean()
12955
+ z52.boolean()
12570
12956
  ).describe(description);
12571
- var updateListItemInputSchema = z51.union([
12572
- z51.object({
12957
+ var updateListItemInputSchema = z52.union([
12958
+ z52.object({
12573
12959
  list_id: slackListIdParam,
12574
12960
  item_id: slackListItemIdParam,
12575
12961
  completed: booleanInput3("Optional completion status update."),
12576
- title: z51.string().min(1).describe("Optional new item title.").optional()
12962
+ title: z52.string().min(1).describe("Optional new item title.").optional()
12577
12963
  }),
12578
- z51.object({
12964
+ z52.object({
12579
12965
  list_id: slackListIdParam,
12580
12966
  item_id: slackListItemIdParam,
12581
12967
  completed: booleanInput3("Optional completion status update.").optional(),
12582
- title: z51.string().min(1).describe("Optional new item title.")
12968
+ title: z52.string().min(1).describe("Optional new item title.")
12583
12969
  })
12584
12970
  ]);
12585
12971
  function createSlackListUpdateItemTool(state) {
@@ -12627,7 +13013,7 @@ function createSlackListUpdateItemTool(state) {
12627
13013
  }
12628
13014
 
12629
13015
  // src/chat/slack/tools/thread-read.ts
12630
- import { z as z52 } from "zod";
13016
+ import { z as z53 } from "zod";
12631
13017
 
12632
13018
  // src/chat/slack/tool-support/slack-message-url.ts
12633
13019
  var SLACK_HOST_PATTERN = /^[a-z0-9-]+\.slack(?:-gov)?\.com$/;
@@ -12893,14 +13279,14 @@ function createSlackThreadReadTool(context) {
12893
13279
  openWorldHint: true,
12894
13280
  readOnlyHint: true
12895
13281
  },
12896
- inputSchema: z52.object({
12897
- url: z52.string().min(1).describe("Slack message archive URL.").optional(),
13282
+ inputSchema: z53.object({
13283
+ url: z53.string().min(1).describe("Slack message archive URL.").optional(),
12898
13284
  channel_id: slackChannelRefParam.optional(),
12899
13285
  ts: slackTimestampParam(
12900
13286
  "Slack message timestamp. May be the thread root or any message in the thread."
12901
13287
  ).optional(),
12902
- limit: z52.coerce.number().int().min(1).max(1e3).describe("Maximum number of thread messages to fetch.").optional(),
12903
- max_pages: z52.coerce.number().int().min(1).max(10).describe("Maximum number of Slack API pages to traverse.").optional()
13288
+ limit: z53.coerce.number().int().min(1).max(1e3).describe("Maximum number of thread messages to fetch.").optional(),
13289
+ max_pages: z53.coerce.number().int().min(1).max(10).describe("Maximum number of Slack API pages to traverse.").optional()
12904
13290
  }),
12905
13291
  outputSchema: juniorToolOutputSchema,
12906
13292
  execute: async ({ url, channel_id, ts, limit, max_pages }) => {
@@ -13027,7 +13413,7 @@ function createSlackThreadReadTool(context) {
13027
13413
  // src/chat/tools/user-lookup.ts
13028
13414
  import { and as and2, eq as eq2, or, sql } from "drizzle-orm";
13029
13415
  import { alias } from "drizzle-orm/pg-core";
13030
- import { z as z53 } from "zod";
13416
+ import { z as z54 } from "zod";
13031
13417
  var linkedSlackIdentity = alias(juniorIdentities, "user_lookup_slack_identity");
13032
13418
  function explicitUserLookupError(error) {
13033
13419
  if (error.apiError === "user_not_found" || error.code === "not_found") {
@@ -13176,9 +13562,9 @@ function createUserLookupTool(teamId, providers) {
13176
13562
  openWorldHint: true,
13177
13563
  readOnlyHint: true
13178
13564
  },
13179
- inputSchema: z53.object({
13180
- provider: z53.enum(providers).describe("Enabled identity provider to query."),
13181
- query: z53.string().trim().min(1).describe("Provider subject ID, handle, Slack email, or Slack name.")
13565
+ inputSchema: z54.object({
13566
+ provider: z54.enum(providers).describe("Enabled identity provider to query."),
13567
+ query: z54.string().trim().min(1).describe("Provider subject ID, handle, Slack email, or Slack name.")
13182
13568
  }).strict(),
13183
13569
  outputSchema: juniorToolOutputSchema,
13184
13570
  execute: async ({ provider, query }) => {
@@ -13198,18 +13584,18 @@ function createUserLookupTool(teamId, providers) {
13198
13584
  }
13199
13585
 
13200
13586
  // src/chat/tools/system-time.ts
13201
- import { z as z54 } from "zod";
13202
- var systemTimeInputSchema = z54.object({
13203
- timezone: z54.string().trim().min(1).optional().describe(
13587
+ import { z as z55 } from "zod";
13588
+ var systemTimeInputSchema = z55.object({
13589
+ timezone: z55.string().trim().min(1).optional().describe(
13204
13590
  "Optional IANA timezone, for example America/Los_Angeles. When set, iso_local and timezone_offset_minutes are for that zone."
13205
13591
  )
13206
13592
  });
13207
13593
  var systemTimeOutputSchema = juniorToolOutputSchema.extend({
13208
- unix_ms: z54.number(),
13209
- iso_utc: z54.string(),
13210
- iso_local: z54.string(),
13211
- timezone: z54.string().nullable(),
13212
- timezone_offset_minutes: z54.number()
13594
+ unix_ms: z55.number(),
13595
+ iso_utc: z55.string(),
13596
+ iso_local: z55.string(),
13597
+ timezone: z55.string().nullable(),
13598
+ timezone_offset_minutes: z55.number()
13213
13599
  });
13214
13600
  function createSystemTimeTool() {
13215
13601
  return zodTool({
@@ -13289,7 +13675,7 @@ function getTimeZoneOffsetMinutes(timestampMs, timezone) {
13289
13675
  }
13290
13676
 
13291
13677
  // src/chat/tools/publish-image.ts
13292
- import { z as z55 } from "zod";
13678
+ import { z as z56 } from "zod";
13293
13679
 
13294
13680
  // src/chat/artifacts/store.ts
13295
13681
  import { createHash as createHash4, randomUUID as randomUUID4 } from "crypto";
@@ -13490,10 +13876,10 @@ function unpublishedArtifactHeaders() {
13490
13876
 
13491
13877
  // src/chat/tools/publish-image.ts
13492
13878
  var outputSchema5 = juniorToolOutputSchema.extend({
13493
- bytes: z55.number().int().positive(),
13494
- content_type: z55.string().min(1),
13495
- public: z55.literal(true),
13496
- url: z55.string().url()
13879
+ bytes: z56.number().int().positive(),
13880
+ content_type: z56.string().min(1),
13881
+ public: z56.literal(true),
13882
+ url: z56.string().url()
13497
13883
  });
13498
13884
  function createPublishImageTool(args) {
13499
13885
  return zodTool({
@@ -13507,8 +13893,8 @@ function createPublishImageTool(args) {
13507
13893
  description: "Publish one sandbox image to a durable public HTTPS URL. Anyone on the internet with the URL can view the image. Use only when an external destination needs a public image URL. Do not use for private file sharing or private conversation storage. Supports PNG, JPEG, GIF, and WebP up to 10 MB.",
13508
13894
  describeProposal: ({ path: path8 }) => `Publish sandbox image ${path8} to a public internet URL.`,
13509
13895
  executionMode: "sequential",
13510
- inputSchema: z55.object({
13511
- path: z55.string().min(1).describe("Exact sandbox path of an existing image file.")
13896
+ inputSchema: z56.object({
13897
+ path: z56.string().min(1).describe("Exact sandbox path of an existing image file.")
13512
13898
  }).strict(),
13513
13899
  outputSchema: outputSchema5,
13514
13900
  async execute({ path: path8 }) {
@@ -13541,10 +13927,10 @@ function createPublishImageTool(args) {
13541
13927
  }
13542
13928
 
13543
13929
  // src/chat/tools/unpublish-image.ts
13544
- import { z as z56 } from "zod";
13930
+ import { z as z57 } from "zod";
13545
13931
  var outputSchema6 = juniorToolOutputSchema.extend({
13546
- filename: z56.string().min(1),
13547
- unpublished: z56.literal(true)
13932
+ filename: z57.string().min(1),
13933
+ unpublished: z57.literal(true)
13548
13934
  });
13549
13935
  function createUnpublishImageTool(args) {
13550
13936
  return zodTool({
@@ -13558,8 +13944,8 @@ function createUnpublishImageTool(args) {
13558
13944
  description: "Unpublish one public image previously published in this conversation so its public URL stops serving. Pass the public artifact URL or `<id>.<ext>` filename. Only images owned by this conversation can be unpublished. Republishing the same image bytes later in this conversation restores a live URL for this conversation. Does not remove copies already fetched by browsers or GitHub.",
13559
13945
  describeProposal: ({ ref }) => `Unpublish public image ${ref}.`,
13560
13946
  executionMode: "sequential",
13561
- inputSchema: z56.object({
13562
- ref: z56.string().min(1).describe(
13947
+ inputSchema: z57.object({
13948
+ ref: z57.string().min(1).describe(
13563
13949
  "Public artifact URL or artifact filename (`<id>.<ext>`)."
13564
13950
  )
13565
13951
  }).strict(),
@@ -13579,27 +13965,27 @@ function createUnpublishImageTool(args) {
13579
13965
  }
13580
13966
 
13581
13967
  // src/chat/tools/search-conversation-events.ts
13582
- import { z as z57 } from "zod";
13968
+ import { z as z58 } from "zod";
13583
13969
  var DEFAULT_LIMIT3 = 25;
13584
13970
  var MAX_LIMIT2 = 100;
13585
13971
  var MAX_EVENT_DATA_BYTES = 4e3;
13586
13972
  var MAX_EVENTS_JSON_BYTES = 2e4;
13587
13973
  var MAX_IDENTITY_CHARS = 256;
13588
13974
  var textEncoder = new TextEncoder();
13589
- var knownEventTypeSchema = z57.enum(KNOWN_CONVERSATION_EVENT_TYPES);
13590
- var projectedEventSchema = z57.object({
13591
- seq: z57.number().int().nonnegative().describe("Stable event position for pagination."),
13592
- history_version: z57.number().int().nonnegative().describe("Agent history generation after replacement."),
13593
- created_at: z57.iso.datetime().describe("When the event was recorded."),
13594
- idempotency_key: z57.string().min(1).optional().describe("Retry-stable event identity, when assigned."),
13595
- data: z57.record(z57.string(), z57.unknown()).describe("Bounded event data.")
13975
+ var knownEventTypeSchema = z58.enum(KNOWN_CONVERSATION_EVENT_TYPES);
13976
+ var projectedEventSchema = z58.object({
13977
+ seq: z58.number().int().nonnegative().describe("Stable event position for pagination."),
13978
+ history_version: z58.number().int().nonnegative().describe("Agent history generation after replacement."),
13979
+ created_at: z58.iso.datetime().describe("When the event was recorded."),
13980
+ idempotency_key: z58.string().min(1).optional().describe("Retry-stable event identity, when assigned."),
13981
+ data: z58.record(z58.string(), z58.unknown()).describe("Bounded event data.")
13596
13982
  }).strict();
13597
13983
  var searchConversationEventsOutputSchema = juniorToolOutputSchema.extend({
13598
- conversation_id: z57.string().min(1),
13599
- events: z57.array(projectedEventSchema),
13600
- has_older: z57.boolean().describe("Whether matching older events exist."),
13601
- has_newer: z57.boolean().describe("Whether matching newer events exist."),
13602
- omitted_event_count: z57.number().int().nonnegative().optional().describe("Events omitted by the response byte limit.")
13984
+ conversation_id: z58.string().min(1),
13985
+ events: z58.array(projectedEventSchema),
13986
+ has_older: z58.boolean().describe("Whether matching older events exist."),
13987
+ has_newer: z58.boolean().describe("Whether matching newer events exist."),
13988
+ omitted_event_count: z58.number().int().nonnegative().optional().describe("Events omitted by the response byte limit.")
13603
13989
  });
13604
13990
  function createSearchConversationEventsTool(context) {
13605
13991
  return zodTool({
@@ -13612,16 +13998,16 @@ function createSearchConversationEventsTool(context) {
13612
13998
  openWorldHint: false,
13613
13999
  readOnlyHint: true
13614
14000
  },
13615
- inputSchema: z57.object({
13616
- conversation_id: z57.string().trim().min(1).nullable().describe(
14001
+ inputSchema: z58.object({
14002
+ conversation_id: z58.string().trim().min(1).nullable().describe(
13617
14003
  "Conversation ID to search. Omit or null for the current conversation."
13618
14004
  ).optional(),
13619
- after_seq: z57.number().int().nonnegative().nullable().describe("Exclusive event sequence lower bound; returns ascending.").optional(),
13620
- before_seq: z57.number().int().nonnegative().nullable().describe("Exclusive event sequence upper bound.").optional(),
13621
- limit: z57.number().int().min(1).max(MAX_LIMIT2).nullable().describe(
14005
+ after_seq: z58.number().int().nonnegative().nullable().describe("Exclusive event sequence lower bound; returns ascending.").optional(),
14006
+ before_seq: z58.number().int().nonnegative().nullable().describe("Exclusive event sequence upper bound.").optional(),
14007
+ limit: z58.number().int().min(1).max(MAX_LIMIT2).nullable().describe(
13622
14008
  `Maximum events. Default ${DEFAULT_LIMIT3}; max ${MAX_LIMIT2}.`
13623
14009
  ).optional(),
13624
- types: z57.array(knownEventTypeSchema).min(1).nullable().describe("Event types to include; omit for all types.").optional()
14010
+ types: z58.array(knownEventTypeSchema).min(1).nullable().describe("Event types to include; omit for all types.").optional()
13625
14011
  }).strict(),
13626
14012
  outputSchema: searchConversationEventsOutputSchema,
13627
14013
  execute: async (input) => {
@@ -13870,10 +14256,10 @@ function stripReplacementHistoryField(value) {
13870
14256
  }
13871
14257
 
13872
14258
  // src/chat/tools/handoff/tool.ts
13873
- import { z as z58 } from "zod";
14259
+ import { z as z59 } from "zod";
13874
14260
  var HANDOFF_TOOL_NAME = "handoff";
13875
14261
  function createHandoffTool(handoff) {
13876
- const profileSchema = z58.enum(handoff.profiles);
14262
+ const profileSchema = z59.enum(handoff.profiles);
13877
14263
  const handoffResultSchema = juniorToolOutputSchema.extend({
13878
14264
  model_profile: modelProfileSchema
13879
14265
  });
@@ -13887,7 +14273,7 @@ function createHandoffTool(handoff) {
13887
14273
  },
13888
14274
  description: `Switch to another model profile and continue the same task. Profiles: ${profileNames}. Call this as the only tool.`,
13889
14275
  executionMode: "sequential",
13890
- inputSchema: z58.object({
14276
+ inputSchema: z59.object({
13891
14277
  profile: profileSchema.describe("Target model profile")
13892
14278
  }).strict(),
13893
14279
  outputSchema: handoffResultSchema,
@@ -13908,7 +14294,7 @@ function createHandoffTool(handoff) {
13908
14294
  }
13909
14295
 
13910
14296
  // src/chat/tools/web/fetch-tool.ts
13911
- import { z as z59 } from "zod";
14297
+ import { z as z60 } from "zod";
13912
14298
 
13913
14299
  // src/chat/tools/web/constants.ts
13914
14300
  var USER_AGENT = "junior-bot/0.1";
@@ -14357,9 +14743,9 @@ function createWebFetchTool(hooks, options = {}) {
14357
14743
  openWorldHint: true,
14358
14744
  readOnlyHint: true
14359
14745
  },
14360
- inputSchema: z59.object({
14361
- url: z59.string().min(1).describe("HTTP(S) URL to fetch."),
14362
- max_chars: z59.coerce.number().int().min(500).max(MAX_FETCH_CHARS).describe("Optional maximum number of extracted characters to return.").optional()
14746
+ inputSchema: z60.object({
14747
+ url: z60.string().min(1).describe("HTTP(S) URL to fetch."),
14748
+ max_chars: z60.coerce.number().int().min(500).max(MAX_FETCH_CHARS).describe("Optional maximum number of extracted characters to return.").optional()
14363
14749
  }),
14364
14750
  outputSchema: juniorToolOutputSchema,
14365
14751
  execute: async ({ url, max_chars }) => {
@@ -14404,7 +14790,7 @@ function createWebFetchTool(hooks, options = {}) {
14404
14790
  }
14405
14791
 
14406
14792
  // src/chat/tools/web/search.ts
14407
- import { z as z60 } from "zod";
14793
+ import { z as z61 } from "zod";
14408
14794
  import { generateText } from "ai";
14409
14795
  import { createGatewayProvider } from "@ai-sdk/gateway";
14410
14796
  var SEARCH_TIMEOUT_MS = 6e4;
@@ -14446,9 +14832,9 @@ function createWebSearchTool(modelId, override) {
14446
14832
  openWorldHint: true,
14447
14833
  readOnlyHint: true
14448
14834
  },
14449
- inputSchema: z60.object({
14450
- query: z60.string().min(1).max(500).describe("Search query."),
14451
- max_results: z60.coerce.number().int().min(1).max(MAX_RESULTS2).describe("Max results to return.").optional()
14835
+ inputSchema: z61.object({
14836
+ query: z61.string().min(1).max(500).describe("Search query."),
14837
+ max_results: z61.coerce.number().int().min(1).max(MAX_RESULTS2).describe("Max results to return.").optional()
14452
14838
  }),
14453
14839
  outputSchema: juniorToolOutputSchema,
14454
14840
  execute: async ({ query, max_results }) => {
@@ -14490,7 +14876,7 @@ function createWebSearchTool(modelId, override) {
14490
14876
  }
14491
14877
 
14492
14878
  // src/chat/tools/sandbox/write-file.ts
14493
- import { z as z61 } from "zod";
14879
+ import { z as z62 } from "zod";
14494
14880
  function createWriteFileTool() {
14495
14881
  return zodTool({
14496
14882
  annotations: {
@@ -14501,9 +14887,9 @@ function createWriteFileTool() {
14501
14887
  },
14502
14888
  description: "Write UTF-8 content to a file in the sandbox workspace. Use for intentional file creation or deliberate full-file replacement after validation; use editFile instead for targeted changes to existing files. Do not use for exploratory analysis-only turns.",
14503
14889
  executionMode: "sequential",
14504
- inputSchema: z61.object({
14505
- path: z61.string().min(1).describe("Path to write in the sandbox workspace."),
14506
- content: z61.string().describe("UTF-8 file content to write.")
14890
+ inputSchema: z62.object({
14891
+ path: z62.string().min(1).describe("Path to write in the sandbox workspace."),
14892
+ content: z62.string().describe("UTF-8 file content to write.")
14507
14893
  }),
14508
14894
  outputSchema: juniorToolOutputSchema,
14509
14895
  execute: async () => {
@@ -14515,7 +14901,7 @@ function createWriteFileTool() {
14515
14901
  }
14516
14902
 
14517
14903
  // src/chat/workspaces/tools.ts
14518
- import { z as z62 } from "zod";
14904
+ import { z as z63 } from "zod";
14519
14905
  import {
14520
14906
  resourceEventSubscriptionResultSchema
14521
14907
  } from "@sentry/junior-plugin-api";
@@ -14547,16 +14933,16 @@ async function stopWorkspaceSnapshotWatch(input) {
14547
14933
  });
14548
14934
  }
14549
14935
  }
14550
- var repoSchema = z62.object({
14551
- provider: z62.string(),
14552
- repo: z62.string(),
14553
- checkout_path: z62.string()
14936
+ var repoSchema = z63.object({
14937
+ provider: z63.string(),
14938
+ repo: z63.string(),
14939
+ checkout_path: z63.string()
14554
14940
  });
14555
- var workspaceSchema = z62.object({
14556
- id: z62.string(),
14557
- name: z62.string(),
14558
- setup_script: z62.string(),
14559
- repos: z62.array(repoSchema)
14941
+ var workspaceSchema = z63.object({
14942
+ id: z63.string(),
14943
+ name: z63.string(),
14944
+ setup_script: z63.string(),
14945
+ repos: z63.array(repoSchema)
14560
14946
  });
14561
14947
  function view(workspace) {
14562
14948
  return {
@@ -14589,18 +14975,18 @@ function workspaceProviderNames() {
14589
14975
  }
14590
14976
  function workspaceWriteSchemas(providers) {
14591
14977
  const providerNames = providers.map((provider) => `\`${provider}\``).join(", ");
14592
- const repoInputSchema = z62.object({
14593
- provider: z62.enum(providers).describe(`Repository provider. Supported: ${providerNames}.`),
14594
- repo: z62.string().trim().min(1).describe("Repository in owner/name format.")
14978
+ const repoInputSchema = z63.object({
14979
+ provider: z63.enum(providers).describe(`Repository provider. Supported: ${providerNames}.`),
14980
+ repo: z63.string().trim().min(1).describe("Repository in owner/name format.")
14595
14981
  }).strict();
14596
- const workspaceInputSchema = z62.object({
14597
- name: z62.string().trim().min(1).describe(
14982
+ const workspaceInputSchema = z63.object({
14983
+ name: z63.string().trim().min(1).describe(
14598
14984
  "Workspace name. Use lowercase letters, digits, underscores, or hyphens."
14599
14985
  ),
14600
- setup_script: z62.string().nullable().describe(
14986
+ setup_script: z63.string().nullable().describe(
14601
14987
  "Optional shell script to run after repository checkout whenever this Workspace starts. Omit or use null for no setup script."
14602
14988
  ).optional(),
14603
- repos: z62.array(repoInputSchema).max(32).describe("Complete repository list.")
14989
+ repos: z63.array(repoInputSchema).max(32).describe("Complete repository list.")
14604
14990
  }).strict();
14605
14991
  return { providerNames, workspaceInputSchema };
14606
14992
  }
@@ -14675,7 +15061,7 @@ function createWorkspaceWriteTools(providers) {
14675
15061
  },
14676
15062
  description: `Replace an install-wide Workspace recipe. Repository providers: ${providerNames}. Use the Workspace ID returned by listWorkspaces.`,
14677
15063
  inputSchema: workspaceInputSchema.extend({
14678
- id: z62.string().uuid().describe("Workspace ID from listWorkspaces.")
15064
+ id: z63.string().uuid().describe("Workspace ID from listWorkspaces.")
14679
15065
  }).strict(),
14680
15066
  prepareArguments(args) {
14681
15067
  const input = args;
@@ -14708,11 +15094,11 @@ function createWorkspaceWriteTools(providers) {
14708
15094
  readOnlyHint: false
14709
15095
  },
14710
15096
  description: "Delete one install-wide Workspace recipe. Use the Workspace ID returned by listWorkspaces.",
14711
- inputSchema: z62.object({
14712
- id: z62.string().uuid().describe("Workspace ID from listWorkspaces.")
15097
+ inputSchema: z63.object({
15098
+ id: z63.string().uuid().describe("Workspace ID from listWorkspaces.")
14713
15099
  }).strict(),
14714
15100
  outputSchema: juniorToolOutputSchema.extend({
14715
- deleted: z62.literal(true)
15101
+ deleted: z63.literal(true)
14716
15102
  }),
14717
15103
  async execute({ id }) {
14718
15104
  const deleted = await workspaceWrite(() => deleteWorkspace(id));
@@ -14737,10 +15123,10 @@ function createWorkspaceTools(context) {
14737
15123
  readOnlyHint: true
14738
15124
  },
14739
15125
  description: "List named repository workspaces that can replace the current sandbox.",
14740
- inputSchema: z62.object({}).strict(),
15126
+ inputSchema: z63.object({}).strict(),
14741
15127
  outputSchema: juniorToolOutputSchema.extend({
14742
- active_workspace_id: z62.string().nullable(),
14743
- workspaces: z62.array(workspaceSchema)
15128
+ active_workspace_id: z63.string().nullable(),
15129
+ workspaces: z63.array(workspaceSchema)
14744
15130
  }),
14745
15131
  async execute() {
14746
15132
  return {
@@ -14758,12 +15144,12 @@ function createWorkspaceTools(context) {
14758
15144
  readOnlyHint: false
14759
15145
  },
14760
15146
  description: "Replace the current sandbox with a named repository Workspace. Files in the old sandbox do not carry over. Returns ready after the switch, or building with a temporary subscription when the snapshot is still being prepared. When building, wait for the ready event and call switchWorkspace again with the same name.",
14761
- inputSchema: z62.object({
14762
- name: z62.string().trim().min(1).describe("Exact workspace name.")
15147
+ inputSchema: z63.object({
15148
+ name: z63.string().trim().min(1).describe("Exact workspace name.")
14763
15149
  }).strict(),
14764
15150
  outputSchema: juniorToolOutputSchema.extend({
14765
15151
  workspace: workspaceSchema,
14766
- status: z62.enum(["ready", "building"]),
15152
+ status: z63.enum(["ready", "building"]),
14767
15153
  subscription: resourceEventSubscriptionResultSchema.optional().describe(
14768
15154
  "Present when the snapshot ready and failed events are already watched for this conversation."
14769
15155
  )
@@ -15549,7 +15935,7 @@ function handleToolExecutionError(error, toolName, toolCallId, shouldTrace, conv
15549
15935
  }
15550
15936
 
15551
15937
  // src/chat/tools/execute-tool.ts
15552
- import { z as z63 } from "zod";
15938
+ import { z as z64 } from "zod";
15553
15939
  var EXECUTE_TOOL_NAME = "executeTool";
15554
15940
  function createExecuteToolTool() {
15555
15941
  return zodTool({
@@ -15561,11 +15947,11 @@ function createExecuteToolTool() {
15561
15947
  },
15562
15948
  description: "Execute any catalog tool by exact tool_name from searchTools or a tool-result execution hint. Put tool-specific parameters inside arguments.",
15563
15949
  executionMode: "sequential",
15564
- inputSchema: z63.object({
15565
- tool_name: z63.string().min(1).describe(
15950
+ inputSchema: z64.object({
15951
+ tool_name: z64.string().min(1).describe(
15566
15952
  "Exact catalog tool_name returned by searchTools or a tool-result execution hint."
15567
15953
  ),
15568
- arguments: z63.record(z63.string(), z63.unknown()).describe(
15954
+ arguments: z64.record(z64.string(), z64.unknown()).describe(
15569
15955
  'Arguments matching the selected catalog tool schema, for example { "query": "..." }.'
15570
15956
  ).optional()
15571
15957
  }).strict(),
@@ -15605,7 +15991,7 @@ function planToolExposure(tools) {
15605
15991
  }
15606
15992
 
15607
15993
  // src/chat/tools/search-tools.ts
15608
- import { z as z64 } from "zod";
15994
+ import { z as z65 } from "zod";
15609
15995
  var SEARCH_TOOLS_NAME = "searchTools";
15610
15996
  var DEFAULT_MAX_RESULTS2 = 5;
15611
15997
  var MAX_RESULTS3 = 20;
@@ -15650,29 +16036,29 @@ var SEARCH_STOP_WORDS = /* @__PURE__ */ new Set([
15650
16036
  "you",
15651
16037
  "your"
15652
16038
  ]);
15653
- var searchToolsSourceSchema = z64.object({
15654
- id: z64.string(),
15655
- description: z64.string()
16039
+ var searchToolsSourceSchema = z65.object({
16040
+ id: z65.string(),
16041
+ description: z65.string()
15656
16042
  }).strict();
15657
- var searchToolsToolSchema = z64.object({
15658
- tool_name: z64.string(),
15659
- description: z64.string(),
15660
- exposure: z64.enum(["direct", "deferred", "modelOnly", "hidden"]),
15661
- source: z64.string().optional(),
15662
- input_schema: z64.unknown(),
15663
- call_notes: z64.array(z64.string()),
15664
- annotations: z64.record(z64.string(), z64.unknown())
16043
+ var searchToolsToolSchema = z65.object({
16044
+ tool_name: z65.string(),
16045
+ description: z65.string(),
16046
+ exposure: z65.enum(["direct", "deferred", "modelOnly", "hidden"]),
16047
+ source: z65.string().optional(),
16048
+ input_schema: z65.unknown(),
16049
+ call_notes: z65.array(z65.string()),
16050
+ annotations: z65.record(z65.string(), z65.unknown())
15665
16051
  }).strict();
15666
16052
  var searchToolsOutputSchema = juniorToolOutputSchema.extend({
15667
- query: z64.string().nullable(),
15668
- source: z64.string().nullable(),
15669
- sources: z64.array(searchToolsSourceSchema),
15670
- total_catalog_tools: z64.number().int().nonnegative(),
15671
- total_eligible_tools: z64.number().int().nonnegative(),
15672
- total_matches: z64.number().int().nonnegative(),
15673
- returned_tools: z64.number().int().nonnegative(),
15674
- execution_tool: z64.literal("executeTool"),
15675
- tools: z64.array(searchToolsToolSchema)
16053
+ query: z65.string().nullable(),
16054
+ source: z65.string().nullable(),
16055
+ sources: z65.array(searchToolsSourceSchema),
16056
+ total_catalog_tools: z65.number().int().nonnegative(),
16057
+ total_eligible_tools: z65.number().int().nonnegative(),
16058
+ total_matches: z65.number().int().nonnegative(),
16059
+ returned_tools: z65.number().int().nonnegative(),
16060
+ execution_tool: z65.literal("executeTool"),
16061
+ tools: z65.array(searchToolsToolSchema)
15676
16062
  }).strict();
15677
16063
  function terms(value) {
15678
16064
  const chunks = value.match(/[\p{L}\p{N}]+/gu) ?? [];
@@ -15883,14 +16269,14 @@ function createSearchToolsTool(catalogTools) {
15883
16269
  openWorldHint: false,
15884
16270
  readOnlyHint: true
15885
16271
  },
15886
- inputSchema: z64.object({
15887
- query: z64.string().nullable().describe(
16272
+ inputSchema: z65.object({
16273
+ query: z65.string().nullable().describe(
15888
16274
  "Optional search terms describing the tool, owner, action, or arguments needed. Empty string lists catalog tools."
15889
16275
  ).optional(),
15890
- source: z64.string().nullable().describe(
16276
+ source: z65.string().nullable().describe(
15891
16277
  "Optional source id to search within, such as a plugin source returned in sources."
15892
16278
  ).optional(),
15893
- max_results: z64.number().int().min(1).max(MAX_RESULTS3).nullable().describe("Maximum matching catalog tool descriptors to return.").optional()
16279
+ max_results: z65.number().int().min(1).max(MAX_RESULTS3).nullable().describe("Maximum matching catalog tool descriptors to return.").optional()
15894
16280
  }).strict(),
15895
16281
  outputSchema: searchToolsOutputSchema,
15896
16282
  privateTraceResult: (result) => ({
@@ -17188,7 +17574,7 @@ function createPluginEgress(deps) {
17188
17574
  }
17189
17575
 
17190
17576
  // src/chat/services/guardian-action-review.ts
17191
- import { z as z65 } from "zod";
17577
+ import { z as z66 } from "zod";
17192
17578
 
17193
17579
  // src/chat/services/guardian-action-policy.ts
17194
17580
  var GUARDIAN_ACTION_POLICY = `You are judging one planned Junior agent action.
@@ -17262,17 +17648,17 @@ Assess the exact action's intrinsic risk and whether the user's intent authorize
17262
17648
  - Keep the reason to one concise, specific sentence grounded in the main risk or authorization fact. For ask, name the exact action, target, and material side effects the user must confirm.`;
17263
17649
 
17264
17650
  // src/chat/services/guardian-action-review.ts
17265
- var guardianDecisionSchema = z65.object({
17266
- decision: z65.enum(["allow", "ask", "deny"]),
17267
- reason: z65.string().trim().min(1).max(500),
17268
- riskLevel: z65.enum(["low", "medium", "high", "critical"]),
17269
- userAuthorization: z65.enum(["high", "medium", "low", "unknown"])
17651
+ var guardianDecisionSchema = z66.object({
17652
+ decision: z66.enum(["allow", "ask", "deny"]),
17653
+ reason: z66.string().trim().min(1).max(500),
17654
+ riskLevel: z66.enum(["low", "medium", "high", "critical"]),
17655
+ userAuthorization: z66.enum(["high", "medium", "low", "unknown"])
17270
17656
  }).strict();
17271
17657
  var GUARDIAN_REVIEW_TIMEOUT_MS = 6e4;
17272
17658
  var GUARDIAN_REVIEW_MAX_TOKENS = 2e3;
17273
17659
  var MAX_PROPOSAL_CHARS = 192e3;
17274
17660
  function guardianPrompt(proposal) {
17275
- const proposalJson = JSON.stringify(z65.json().parse(proposal), null, 2);
17661
+ const proposalJson = JSON.stringify(z66.json().parse(proposal), null, 2);
17276
17662
  if (proposalJson.length > MAX_PROPOSAL_CHARS) {
17277
17663
  throw new Error(
17278
17664
  `Guardian action proposal exceeds ${MAX_PROPOSAL_CHARS} characters.`
@@ -19910,6 +20296,10 @@ export {
19910
20296
  normalizeSandboxEgressTracePropagationDomains,
19911
20297
  shouldPropagateSandboxEgressTrace,
19912
20298
  resolveSandboxEgressProviderForHost,
20299
+ admitAutomatedTurn,
20300
+ recordFinishedTurnForAutomatedLimit,
20301
+ postAutomatedTurnLimitNoticeForDestination,
20302
+ maybePostAutomatedTurnLimitNotice,
19913
20303
  renderTaskInput,
19914
20304
  RESOURCE_EVENT_MESSAGE_AUTHOR,
19915
20305
  RESOURCE_EVENT_SYSTEM_ACTOR,