@sentry/junior 0.137.0 → 0.138.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 (87) hide show
  1. package/dist/{agent-hooks-MZOKEP3J.js → agent-hooks-SCR74Q3E.js} +11 -9
  2. package/dist/api.js +21 -18
  3. package/dist/app.d.ts +7 -0
  4. package/dist/app.js +248 -689
  5. package/dist/{catalog-runtime-MD66YLFV.js → catalog-runtime-IU3QF4GG.js} +5 -5
  6. package/dist/chat/agent/request.d.ts +32 -2
  7. package/dist/chat/agent-dispatch/heartbeat.d.ts +5 -0
  8. package/dist/chat/agent-dispatch/types.d.ts +1 -1
  9. package/dist/chat/agent-invocations/errors.d.ts +8 -0
  10. package/dist/chat/agent-invocations/spawn.d.ts +12 -0
  11. package/dist/chat/agent-invocations/store.d.ts +44 -0
  12. package/dist/chat/agent-invocations/types.d.ts +449 -0
  13. package/dist/chat/agent-invocations/work.d.ts +31 -0
  14. package/dist/chat/config.d.ts +1 -0
  15. package/dist/chat/conversations/sql/store.d.ts +8 -0
  16. package/dist/chat/conversations/store.d.ts +7 -0
  17. package/dist/chat/experimental.d.ts +16 -0
  18. package/dist/chat/runtime/agent-runner.d.ts +2 -1
  19. package/dist/chat/services/auth-pause.d.ts +0 -1
  20. package/dist/chat/services/mcp-auth-orchestration.d.ts +3 -2
  21. package/dist/chat/services/plugin-auth-orchestration.d.ts +3 -2
  22. package/dist/chat/state/turn-session.d.ts +0 -2
  23. package/dist/chat/task-execution/state.d.ts +23 -11
  24. package/dist/chat/task-execution/store.d.ts +20 -11
  25. package/dist/chat/task-execution/worker.d.ts +2 -2
  26. package/dist/chat/tools/runtime/spawn-agent.d.ts +31 -0
  27. package/dist/chat/tools/types.d.ts +2 -0
  28. package/dist/chunk-3Y47VMHV.js +6 -0
  29. package/dist/chunk-5IDFPCON.js +46 -0
  30. package/dist/chunk-5LTJ4ITU.js +1523 -0
  31. package/dist/{chunk-WPPXIAFB.js → chunk-5MXWHTCK.js} +17 -434
  32. package/dist/{chunk-UOXATPSI.js → chunk-A7WCHXZV.js} +7 -5
  33. package/dist/{chunk-5G34IEK2.js → chunk-BOLJOV5T.js} +2 -56
  34. package/dist/{chunk-UG6ZYPBI.js → chunk-BYW4B4PR.js} +73 -60
  35. package/dist/{chunk-XZ7NPXAB.js → chunk-C7ZVPO4Z.js} +1 -1
  36. package/dist/{chunk-RB4NJKEX.js → chunk-DCLLQGS6.js} +119 -50
  37. package/dist/{chunk-DQXAAVTR.js → chunk-E5UYAIKJ.js} +44 -1467
  38. package/dist/{chunk-6QW2RRQT.js → chunk-ELKW5FIB.js} +5 -5
  39. package/dist/chunk-EM225ITJ.js +56 -0
  40. package/dist/{chunk-SYCX4DOK.js → chunk-FEUNPTGV.js} +7 -60
  41. package/dist/{chunk-YRPC6MJY.js → chunk-FNLBTB4K.js} +1 -1
  42. package/dist/chunk-HIWJWWMT.js +668 -0
  43. package/dist/chunk-IUFM5JWV.js +24 -0
  44. package/dist/{chunk-T6Z5S6PQ.js → chunk-JNNJZURV.js} +1 -1
  45. package/dist/{chunk-6ZK6FZIV.js → chunk-KCBZSJRU.js} +6 -27
  46. package/dist/{chunk-5PNJMOY5.js → chunk-KDCHVT25.js} +1 -1
  47. package/dist/{chunk-BZAMASJP.js → chunk-KFRHRSCJ.js} +1 -1
  48. package/dist/chunk-LPVUNO2W.js +320 -0
  49. package/dist/{chunk-EWDSB24B.js → chunk-N7WARMC6.js} +16 -776
  50. package/dist/chunk-PB3CXNVL.js +41 -0
  51. package/dist/chunk-Q6QZTTLS.js +55 -0
  52. package/dist/{chunk-36EG34YI.js → chunk-QS527AV5.js} +1 -1
  53. package/dist/chunk-R776HKPK.js +81 -0
  54. package/dist/{chunk-KJ4HGRHN.js → chunk-RZIBSCYC.js} +507 -596
  55. package/dist/chunk-SD3OFRWY.js +714 -0
  56. package/dist/{chunk-ZFS67WIR.js → chunk-SIPKWSXK.js} +57 -6
  57. package/dist/chunk-TCS76X5D.js +441 -0
  58. package/dist/{chunk-K2NCQJKH.js → chunk-TDJCLNDH.js} +3 -3
  59. package/dist/{chunk-POBSY47Q.js → chunk-TUUDXEXU.js} +336 -302
  60. package/dist/{chunk-YNFERGKP.js → chunk-VPZFVJND.js} +1 -1
  61. package/dist/{chunk-UZQ4VY3M.js → chunk-YU5QUF67.js} +1 -1
  62. package/dist/chunk-ZBSMCXKV.js +710 -0
  63. package/dist/{chunk-3Q342EJJ.js → chunk-ZXNTJJIE.js} +2 -2
  64. package/dist/cli/chat.js +65 -26
  65. package/dist/cli/check.js +6 -6
  66. package/dist/cli/plugins.js +14 -12
  67. package/dist/cli/snapshot-create.js +10 -9
  68. package/dist/cli/upgrade.js +7 -7
  69. package/dist/conversation-work-KATFHLG3.js +56 -0
  70. package/dist/db/schema/agent-invocations.d.ts +544 -0
  71. package/dist/db/schema.d.ts +543 -1
  72. package/dist/{db-66E7VDNC.js → db-UO2IWXGA.js} +7 -7
  73. package/dist/experimental-HH6OM6UH.js +13 -0
  74. package/dist/instrumentation.js +4 -4
  75. package/dist/nitro.js +4 -3
  76. package/dist/{oauth-callback-server-7QPD4Q7P.js → oauth-callback-server-MAQI43LX.js} +26 -18
  77. package/dist/{runner-L2BKJKOD.js → runner-PIUQEXKE.js} +26 -14
  78. package/dist/{skills-HOQ2NSPW.js → skills-4ARJADHQ.js} +6 -6
  79. package/dist/spawn-G2AWPMCT.js +38 -0
  80. package/dist/{validation-ENHI7S2C.js → validation-S3EE3HWL.js} +6 -6
  81. package/dist/version.js +1 -1
  82. package/dist/work-UARRUAW3.js +46 -0
  83. package/dist/worker-DOCIRVD3.js +24 -0
  84. package/migrations/0021_first_warhawk.sql +35 -0
  85. package/migrations/meta/0021_snapshot.json +2176 -0
  86. package/migrations/meta/_journal.json +8 -1
  87. package/package.json +5 -5
@@ -1,42 +1,55 @@
1
+ import {
2
+ AgentInvocationBusyError,
3
+ AgentInvocationLimitError,
4
+ AuthPausePersistenceError,
5
+ AuthorizationFlowDisabledError,
6
+ AuthorizationPauseError,
7
+ PluginCredentialFailureError,
8
+ agentNameSchema,
9
+ createPluginAuthOrchestration
10
+ } from "./chunk-LPVUNO2W.js";
1
11
  import {
2
12
  authorizationId
3
13
  } from "./chunk-DIB4GX3G.js";
4
14
  import {
5
15
  McpProviderError,
6
16
  McpToolError,
7
- RetryableDeliveryError,
8
- actorFromRouting,
9
- addReactionToMessage,
10
- assertRunRoutingConsistency,
11
17
  createMcpOAuthClientProvider,
12
18
  createUserTokenStore,
13
19
  deleteMcpAuthSession,
14
- deliverOAuthAuthorization,
15
- formatProviderLabel,
16
20
  getMcpAuthSession,
17
21
  getMcpAwareErrorType,
18
22
  getMcpAwareTelemetryMessage,
19
23
  getMcpProviderErrorAttributes,
20
- getSlackMessagePermalink,
21
24
  hasEgressCredentialHooks,
22
25
  issuePluginCredential,
23
26
  issueProviderCredentialLease,
24
27
  onPluginEgressResponse,
25
28
  patchMcpAuthSession,
26
- resolveBaseUrl,
27
29
  selectPluginGrant,
28
- startOAuthFlow,
30
+ toMcpProviderError
31
+ } from "./chunk-N7WARMC6.js";
32
+ import {
33
+ RetryableDeliveryError,
34
+ actorFromRouting,
35
+ assertRunRoutingConsistency,
36
+ isAgentRunFeatureDisabled,
29
37
  surfaceFromRouting,
30
- toMcpProviderError,
31
- toolInvocationDestination,
38
+ toolInvocationDestination
39
+ } from "./chunk-R776HKPK.js";
40
+ import {
41
+ addReactionToMessage,
42
+ deliverOAuthAuthorization,
43
+ formatProviderLabel,
44
+ getSlackMessagePermalink,
45
+ resolveBaseUrl,
32
46
  uploadFilesToConversation
33
- } from "./chunk-EWDSB24B.js";
47
+ } from "./chunk-SD3OFRWY.js";
34
48
  import {
35
49
  AGENTS_REMOVAL_NOTICE,
36
50
  AGENTS_REPLACEMENT_NOTICE,
37
51
  CooperativeTurnYieldError,
38
52
  DEFAULT_SEARCH_COMMAND_TIMEOUT_MS,
39
- JUNIOR_THREAD_STATE_TTL_MS,
40
53
  MAX_TEXT_CHARS,
41
54
  NO_REPLY_MARKER,
42
55
  RIPGREP_EXCLUDED_GLOBS,
@@ -98,13 +111,19 @@ import {
98
111
  trimTrailingAssistantMessages,
99
112
  truncateText,
100
113
  updateConversationStats
101
- } from "./chunk-POBSY47Q.js";
114
+ } from "./chunk-TUUDXEXU.js";
115
+ import {
116
+ JUNIOR_THREAD_STATE_TTL_MS
117
+ } from "./chunk-3Y47VMHV.js";
102
118
  import {
103
119
  parseSandboxEgressAuthRequiredSignal,
104
120
  parseSandboxEgressPermissionDeniedSignal,
105
121
  sandboxEgressCredentialContextSchema,
106
122
  sandboxEgressCredentialLeaseSchema
107
123
  } from "./chunk-EPBBYMNE.js";
124
+ import {
125
+ isExperimentalFeatureEnabled
126
+ } from "./chunk-5IDFPCON.js";
108
127
  import {
109
128
  bindSandboxFileSystem,
110
129
  buildCommandScript,
@@ -124,7 +143,7 @@ import {
124
143
  runNonInteractiveCommand,
125
144
  throwSandboxOperationError,
126
145
  wrapSandboxSetupError
127
- } from "./chunk-UOXATPSI.js";
146
+ } from "./chunk-A7WCHXZV.js";
128
147
  import {
129
148
  SCHEDULED_TASK_SYSTEM_ACTOR,
130
149
  compactEventTask,
@@ -155,10 +174,10 @@ import {
155
174
  resolveLocalScheduleAtMs,
156
175
  saveEventTask,
157
176
  writableEventTask
158
- } from "./chunk-K2NCQJKH.js";
177
+ } from "./chunk-TDJCLNDH.js";
159
178
  import {
160
179
  parseSlackThreadId
161
- } from "./chunk-YRPC6MJY.js";
180
+ } from "./chunk-FNLBTB4K.js";
162
181
  import {
163
182
  ToolInputError,
164
183
  addAgentTurnUsage,
@@ -168,21 +187,23 @@ import {
168
187
  privateTraceResultAttributes
169
188
  } from "./chunk-UIE3R5XU.js";
170
189
  import {
171
- SlackActionError,
172
190
  createPluginHookRunner,
173
- downloadPrivateSlackFile,
174
- getFilePermalink,
175
191
  getPluginSystemPromptContributions,
176
192
  getPluginTools,
177
193
  getPluginUserPromptContributions,
178
- getSlackClient,
179
194
  getSlackToolContext,
195
+ readActorIdentity,
196
+ resolveChannelCapabilities
197
+ } from "./chunk-5MXWHTCK.js";
198
+ import {
199
+ SlackActionError,
200
+ downloadPrivateSlackFile,
201
+ getFilePermalink,
202
+ getSlackClient,
180
203
  isConversationScopedChannel,
181
204
  normalizeSlackConversationId,
182
- readActorIdentity,
183
- resolveChannelCapabilities,
184
205
  withSlackRetries
185
- } from "./chunk-WPPXIAFB.js";
206
+ } from "./chunk-TCS76X5D.js";
186
207
  import {
187
208
  KNOWN_CONVERSATION_EVENT_TYPES,
188
209
  contextProvenance,
@@ -193,17 +214,19 @@ import {
193
214
  instructionActors,
194
215
  instructionProvenanceFor,
195
216
  sameActorIdentity
196
- } from "./chunk-ZFS67WIR.js";
217
+ } from "./chunk-SIPKWSXK.js";
197
218
  import {
198
219
  SANDBOX_DATA_ROOT,
199
220
  SANDBOX_SKILLS_ROOT,
200
221
  SANDBOX_WORKSPACE_ROOT,
201
- getStateAdapter,
202
222
  sandboxSkillDir,
203
223
  sandboxSkillFile,
204
224
  sandboxSkillPathResolution,
205
225
  sleep
206
- } from "./chunk-5G34IEK2.js";
226
+ } from "./chunk-EM225ITJ.js";
227
+ import {
228
+ getStateAdapter
229
+ } from "./chunk-BOLJOV5T.js";
207
230
  import {
208
231
  ACTIVE_TURN_COMPACTION_SUMMARY_PREFIX,
209
232
  COMPACTION_SUMMARY_PREFIX,
@@ -237,7 +260,7 @@ import {
237
260
  resolveGatewayCredential,
238
261
  resolveGatewayModel,
239
262
  unwrapCurrentInstruction
240
- } from "./chunk-UG6ZYPBI.js";
263
+ } from "./chunk-BYW4B4PR.js";
241
264
  import {
242
265
  canExposeConversationPayload,
243
266
  resolveConversationPrivacy,
@@ -247,16 +270,16 @@ import {
247
270
  toGenAiMessagesTraceAttributes,
248
271
  toGenAiPayloadMetadata,
249
272
  toGenAiPayloadTraceAttributes
250
- } from "./chunk-YNFERGKP.js";
273
+ } from "./chunk-VPZFVJND.js";
251
274
  import {
252
275
  discoverSkills,
253
276
  findSkillByName,
254
277
  loadSkillsByName,
255
278
  parseSkillInvocation
256
- } from "./chunk-3Q342EJJ.js";
279
+ } from "./chunk-ZXNTJJIE.js";
257
280
  import {
258
281
  pluginCatalogRuntime
259
- } from "./chunk-36EG34YI.js";
282
+ } from "./chunk-QS527AV5.js";
260
283
  import {
261
284
  CredentialUnavailableError,
262
285
  OAuthProviderError,
@@ -264,7 +287,7 @@ import {
264
287
  getOAuthProviderErrorAttributes,
265
288
  resolveAuthTokenPlaceholder,
266
289
  resolvePluginCommandEnv
267
- } from "./chunk-BZAMASJP.js";
290
+ } from "./chunk-KFRHRSCJ.js";
268
291
  import {
269
292
  credentialUserSubjectId
270
293
  } from "./chunk-77VDLF3Z.js";
@@ -293,7 +316,7 @@ import {
293
316
  summarizeMessageText,
294
317
  withLogContext,
295
318
  withSpan
296
- } from "./chunk-T6Z5S6PQ.js";
319
+ } from "./chunk-JNNJZURV.js";
297
320
  import {
298
321
  startInactiveSpan,
299
322
  withActiveSpan
@@ -1238,47 +1261,6 @@ function toPiReasoningLevel(level) {
1238
1261
  }
1239
1262
  }
1240
1263
 
1241
- // src/chat/services/auth-pause.ts
1242
- var AuthorizationPauseError = class extends Error {
1243
- disposition;
1244
- kind;
1245
- provider;
1246
- providerDisplayName;
1247
- requestText;
1248
- constructor(kind, provider, providerDisplayName, disposition, requestText) {
1249
- super(
1250
- kind === "mcp" ? `MCP authorization started for ${provider}` : `Plugin authorization started for ${provider}`
1251
- );
1252
- this.name = kind === "mcp" ? "McpAuthorizationPauseError" : "PluginAuthorizationPauseError";
1253
- this.disposition = disposition;
1254
- this.kind = kind;
1255
- this.provider = provider;
1256
- this.providerDisplayName = providerDisplayName;
1257
- this.requestText = requestText;
1258
- }
1259
- };
1260
- var AuthPausePersistenceError = class extends Error {
1261
- constructor(conversationId, turnId, cause) {
1262
- super(
1263
- `Failed to persist auth pause for conversation=${conversationId} turn=${turnId}`,
1264
- cause === void 0 ? void 0 : { cause }
1265
- );
1266
- this.name = "AuthPausePersistenceError";
1267
- }
1268
- };
1269
- var AuthorizationFlowDisabledError = class extends Error {
1270
- kind;
1271
- provider;
1272
- constructor(kind, provider) {
1273
- super(
1274
- `Authorization is required for ${provider}, but this turn cannot start an authorization flow.`
1275
- );
1276
- this.name = "AuthorizationFlowDisabledError";
1277
- this.kind = kind;
1278
- this.provider = provider;
1279
- }
1280
- };
1281
-
1282
1264
  // src/chat/conversations/destination-visibility.ts
1283
1265
  async function resolveDestinationVisibility(args) {
1284
1266
  if (args.visibility) {
@@ -7560,6 +7542,67 @@ function createReportProgressTool() {
7560
7542
  });
7561
7543
  }
7562
7544
 
7545
+ // src/chat/tools/runtime/spawn-agent.ts
7546
+ import { z as z17 } from "zod";
7547
+ var spawnAgentOutputSchema = juniorToolOutputSchema.extend({
7548
+ invocation_id: z17.string().min(1)
7549
+ });
7550
+ function createSpawnAgentTool(spawnAgent) {
7551
+ return zodTool({
7552
+ description: "Start an asynchronous child agent on a delegated task. Give it a name to reuse the same child agent and its history on later calls; omit the name for a one-off agent. This call confirms durable scheduling, not task completion.",
7553
+ annotations: {
7554
+ destructiveHint: false,
7555
+ idempotentHint: true,
7556
+ openWorldHint: false,
7557
+ readOnlyHint: false
7558
+ },
7559
+ inputSchema: z17.object({
7560
+ task: z17.string().trim().min(1).describe("Task for the child agent"),
7561
+ name: agentNameSchema.nullable().optional().describe("Stable child-agent name, or omit for a one-off agent"),
7562
+ reasoning_level: z17.enum(TURN_REASONING_LEVELS).nullable().optional().describe(
7563
+ "Optional reasoning level for this delegated task only"
7564
+ )
7565
+ }).strict(),
7566
+ outputSchema: spawnAgentOutputSchema,
7567
+ execute: async (input, options) => {
7568
+ if (!options.toolCallId) {
7569
+ throw new ToolInputError("spawnAgent requires an active tool call ID");
7570
+ }
7571
+ let result;
7572
+ try {
7573
+ result = await spawnAgent(
7574
+ {
7575
+ task: input.task,
7576
+ ...input.name ? { name: input.name } : {},
7577
+ ...input.reasoning_level ? { reasoningLevel: input.reasoning_level } : {}
7578
+ },
7579
+ {
7580
+ ...options.signal ? { signal: options.signal } : {},
7581
+ toolCallId: options.toolCallId
7582
+ }
7583
+ );
7584
+ } catch (error) {
7585
+ if (error instanceof AgentInvocationBusyError) {
7586
+ throw new ToolInputError(
7587
+ `${error.message}. Wait for it to finish or use a different name.`,
7588
+ { cause: error }
7589
+ );
7590
+ }
7591
+ if (error instanceof AgentInvocationLimitError) {
7592
+ throw new ToolInputError(
7593
+ `${error.message}. Wait for active children to finish before spawning more.`,
7594
+ { cause: error }
7595
+ );
7596
+ }
7597
+ throw error;
7598
+ }
7599
+ return {
7600
+ invocation_id: result.invocationId
7601
+ };
7602
+ }
7603
+ });
7604
+ }
7605
+
7563
7606
  // src/chat/resource-events/tool-support.ts
7564
7607
  var STOP_WATCHING_TOOL_NAME = "stopWatchingResources";
7565
7608
  var RESOURCE_WATCH_TOOL_SOURCE = {
@@ -7595,7 +7638,7 @@ function isSlackThreadConversationId(conversationId) {
7595
7638
  }
7596
7639
 
7597
7640
  // src/chat/tools/list-resource-event-subscriptions.ts
7598
- import { z as z18 } from "zod";
7641
+ import { z as z19 } from "zod";
7599
7642
 
7600
7643
  // src/chat/resource-events/store.ts
7601
7644
  import { createHash } from "crypto";
@@ -7603,29 +7646,29 @@ import {
7603
7646
  destinationSchema,
7604
7647
  resourceEventTypeSchema
7605
7648
  } from "@sentry/junior-plugin-api";
7606
- import { z as z17 } from "zod";
7649
+ import { z as z18 } from "zod";
7607
7650
  var RESOURCE_EVENT_PREFIX = "junior:resource_event_subscription:v3";
7608
7651
  var INDEX_LOCK_TTL_MS = 1e4;
7609
7652
  var SUBSCRIPTION_LOCK_TTL_MS = 1e4;
7610
7653
  var SUBSCRIPTION_LOCK_WAIT_MS = 1e4;
7611
7654
  var SUBSCRIPTION_LOCK_RETRY_MS = 25;
7612
7655
  var SUBSCRIPTION_LOCK_HEARTBEAT_MS = 3e3;
7613
- var subscriptionStatusSchema = z17.enum(["active", "cancelled", "completed"]);
7614
- var subscriptionIdIndexSchema = z17.array(z17.string().min(1));
7615
- var subscriptionSchema = z17.object({
7616
- conversationId: z17.string().min(1),
7617
- createdAtMs: z17.number().finite(),
7656
+ var subscriptionStatusSchema = z18.enum(["active", "cancelled", "completed"]);
7657
+ var subscriptionIdIndexSchema = z18.array(z18.string().min(1));
7658
+ var subscriptionSchema = z18.object({
7659
+ conversationId: z18.string().min(1),
7660
+ createdAtMs: z18.number().finite(),
7618
7661
  destination: destinationSchema,
7619
- events: z17.array(resourceEventTypeSchema).min(1),
7620
- expiresAtMs: z17.number().finite(),
7621
- id: z17.string().min(1),
7622
- intent: z17.string().min(1),
7623
- label: z17.string().min(1),
7624
- namespace: z17.string().min(1),
7625
- identifier: z17.string().min(1),
7626
- resourceType: z17.string().min(1),
7662
+ events: z18.array(resourceEventTypeSchema).min(1),
7663
+ expiresAtMs: z18.number().finite(),
7664
+ id: z18.string().min(1),
7665
+ intent: z18.string().min(1),
7666
+ label: z18.string().min(1),
7667
+ namespace: z18.string().min(1),
7668
+ identifier: z18.string().min(1),
7669
+ resourceType: z18.string().min(1),
7627
7670
  status: subscriptionStatusSchema,
7628
- updatedAtMs: z17.number().finite()
7671
+ updatedAtMs: z18.number().finite()
7629
7672
  }).strict();
7630
7673
  function digest(value) {
7631
7674
  return createHash("sha256").update(value).digest("hex").slice(0, 32);
@@ -7995,17 +8038,17 @@ async function deliverResourceEventSubscription(input) {
7995
8038
  }
7996
8039
 
7997
8040
  // src/chat/tools/list-resource-event-subscriptions.ts
7998
- var listedResourceWatchSchema = z18.object({
7999
- id: z18.string().min(1),
8000
- label: z18.string().min(1),
8001
- identifier: z18.string().min(1),
8002
- namespace: z18.string().min(1),
8003
- resourceType: z18.string().min(1),
8004
- events: z18.array(z18.string().min(1)).min(1),
8005
- intent: z18.string().min(1),
8006
- expiresAtMs: z18.number().finite()
8041
+ var listedResourceWatchSchema = z19.object({
8042
+ id: z19.string().min(1),
8043
+ label: z19.string().min(1),
8044
+ identifier: z19.string().min(1),
8045
+ namespace: z19.string().min(1),
8046
+ resourceType: z19.string().min(1),
8047
+ events: z19.array(z19.string().min(1)).min(1),
8048
+ intent: z19.string().min(1),
8049
+ expiresAtMs: z19.number().finite()
8007
8050
  }).strict();
8008
- var resultDataSchema = z18.object({ subscriptions: z18.array(listedResourceWatchSchema) }).strict();
8051
+ var resultDataSchema = z19.object({ subscriptions: z19.array(listedResourceWatchSchema) }).strict();
8009
8052
  var outputSchema = juniorToolOutputSchema.extend({
8010
8053
  ...resultDataSchema.shape
8011
8054
  }).strict();
@@ -8020,7 +8063,7 @@ function createListResourceEventSubscriptionsTool(context) {
8020
8063
  description: "List active resource event subscriptions for the current conversation.",
8021
8064
  exposure: "deferred",
8022
8065
  source: RESOURCE_WATCH_TOOL_SOURCE,
8023
- inputSchema: z18.object({}).strict(),
8066
+ inputSchema: z19.object({}).strict(),
8024
8067
  outputSchema,
8025
8068
  async execute() {
8026
8069
  const conversationId = requireResourceWatchConversation(context);
@@ -8047,20 +8090,20 @@ function createListResourceEventSubscriptionsTool(context) {
8047
8090
  }
8048
8091
 
8049
8092
  // src/chat/tools/search-resource-event-types.ts
8050
- import { z as z19 } from "zod";
8093
+ import { z as z20 } from "zod";
8051
8094
  var DEFAULT_SEARCH_RESULTS = 10;
8052
8095
  var MAX_SEARCH_RESULTS = 20;
8053
- var searchedResourceTypeSchema = z19.object({
8054
- namespace: z19.string(),
8055
- type: z19.string(),
8056
- supportedEvents: z19.array(z19.string()),
8057
- suggestedEvents: z19.array(z19.string()).optional()
8096
+ var searchedResourceTypeSchema = z20.object({
8097
+ namespace: z20.string(),
8098
+ type: z20.string(),
8099
+ supportedEvents: z20.array(z20.string()),
8100
+ suggestedEvents: z20.array(z20.string()).optional()
8058
8101
  }).strict();
8059
8102
  var outputSchema2 = juniorToolOutputSchema.extend({
8060
- query: z19.string().nullable(),
8061
- namespace: z19.string().nullable(),
8062
- totalMatches: z19.number().int().nonnegative(),
8063
- resourceTypes: z19.array(searchedResourceTypeSchema)
8103
+ query: z20.string().nullable(),
8104
+ namespace: z20.string().nullable(),
8105
+ totalMatches: z20.number().int().nonnegative(),
8106
+ resourceTypes: z20.array(searchedResourceTypeSchema)
8064
8107
  }).strict();
8065
8108
  function normalizeSearchText(value) {
8066
8109
  return value.toLowerCase().replace(/[^a-z0-9_.-]+/g, " ").trim();
@@ -8086,12 +8129,12 @@ function createSearchResourceEventTypesTool(catalog) {
8086
8129
  readOnlyHint: true
8087
8130
  },
8088
8131
  description: "Search the resource event types currently enabled by plugins without creating anything. Use watchResourceEvents to receive temporary updates in the current Slack thread; use createEventTask to execute a durable instruction for matching events. When explaining results, preserve that distinction. This tool does not watch a resource, create a task, or enumerate concrete resources.",
8089
- inputSchema: z19.object({
8090
- query: z19.string().nullable().describe(
8132
+ inputSchema: z20.object({
8133
+ query: z20.string().nullable().describe(
8091
8134
  "Optional terms matching a namespace, resource type, or event name. Empty lists all enabled resource event types."
8092
8135
  ).optional(),
8093
8136
  namespace: eventNamespaceSchema(catalog).nullable().describe("Optional enabled plugin namespace to search within.").optional(),
8094
- maxResults: z19.number().int().min(1).max(MAX_SEARCH_RESULTS).nullable().describe("Maximum matching resource types to return.").optional()
8137
+ maxResults: z20.number().int().min(1).max(MAX_SEARCH_RESULTS).nullable().describe("Maximum matching resource types to return.").optional()
8095
8138
  }).strict(),
8096
8139
  outputSchema: outputSchema2,
8097
8140
  async execute({ query, namespace, maxResults }) {
@@ -8129,10 +8172,10 @@ function createSearchResourceEventTypesTool(catalog) {
8129
8172
  }
8130
8173
 
8131
8174
  // src/chat/tools/stop-watching-resources.ts
8132
- import { z as z20 } from "zod";
8133
- var resultDataSchema2 = z20.object({
8134
- watching_status: z20.literal("stopped"),
8135
- stoppedIds: z20.array(z20.string().min(1))
8175
+ import { z as z21 } from "zod";
8176
+ var resultDataSchema2 = z21.object({
8177
+ watching_status: z21.literal("stopped"),
8178
+ stoppedIds: z21.array(z21.string().min(1))
8136
8179
  }).strict();
8137
8180
  var outputSchema3 = juniorToolOutputSchema.extend({
8138
8181
  ...resultDataSchema2.shape
@@ -8148,7 +8191,7 @@ function createStopWatchingResourcesTool(context) {
8148
8191
  description: "Stop one resource watch in the current Slack thread by id. Omit id only when the user explicitly asks to stop every watch in this thread. Infer terse stop requests from context, inspect active watches when the target is unclear, and call this tool before confirming that watching stopped.",
8149
8192
  exposure: "deferred",
8150
8193
  source: RESOURCE_WATCH_TOOL_SOURCE,
8151
- inputSchema: z20.object({ id: z20.string().min(1).nullable().optional() }).strict(),
8194
+ inputSchema: z21.object({ id: z21.string().min(1).nullable().optional() }).strict(),
8152
8195
  outputSchema: outputSchema3,
8153
8196
  async execute({ id }) {
8154
8197
  const conversationId = requireResourceWatchConversation(context);
@@ -8183,26 +8226,26 @@ function createStopWatchingResourcesTool(context) {
8183
8226
  }
8184
8227
 
8185
8228
  // src/chat/tools/watch-resource-events.ts
8186
- import { z as z21 } from "zod";
8229
+ import { z as z22 } from "zod";
8187
8230
  var DEFAULT_TTL_MS = 14 * 24 * 60 * 60 * 1e3;
8188
8231
  var MAX_TTL_MS = 30 * 24 * 60 * 60 * 1e3;
8189
8232
  function inputSchema(catalog) {
8190
- return z21.object({
8191
- identifier: z21.string().trim().min(1).describe("Plugin-defined resource identifier."),
8233
+ return z22.object({
8234
+ identifier: z22.string().trim().min(1).describe("Plugin-defined resource identifier."),
8192
8235
  namespace: eventNamespaceSchema(catalog).describe(
8193
8236
  "Enabled plugin namespace for this resource."
8194
8237
  ),
8195
8238
  resourceType: registeredResourceTypeSchema(catalog).describe(
8196
8239
  "Plugin-defined resource type."
8197
8240
  ),
8198
- label: z21.string().trim().min(1).max(500).describe("Human-readable resource label."),
8199
- events: z21.array(registeredEventTypeSchema(catalog)).min(1).describe(
8241
+ label: z22.string().trim().min(1).max(500).describe("Human-readable resource label."),
8242
+ events: z22.array(registeredEventTypeSchema(catalog)).min(1).describe(
8200
8243
  "High-signal event names to deliver to this conversation when they occur."
8201
8244
  ),
8202
- intent: z21.string().trim().min(1).max(4e3).describe(
8245
+ intent: z22.string().trim().min(1).max(4e3).describe(
8203
8246
  "Concise reason this conversation wants these events, used when an event arrives."
8204
8247
  ),
8205
- ttlMs: z21.coerce.number().describe(
8248
+ ttlMs: z22.coerce.number().describe(
8206
8249
  "How long to keep the subscription active. Defaults to 14 days and must not exceed 30 days."
8207
8250
  ).optional()
8208
8251
  }).strict().superRefine((subscription, context) => {
@@ -8222,19 +8265,19 @@ function inputSchema(catalog) {
8222
8265
  });
8223
8266
  });
8224
8267
  }
8225
- var stopWatchingActionSchema = z21.object({
8226
- execution_tool: z21.literal("executeTool"),
8227
- execution_example: z21.object({
8228
- tool_name: z21.literal(STOP_WATCHING_TOOL_NAME),
8229
- arguments: z21.object({ id: z21.string().min(1) }).strict()
8268
+ var stopWatchingActionSchema = z22.object({
8269
+ execution_tool: z22.literal("executeTool"),
8270
+ execution_example: z22.object({
8271
+ tool_name: z22.literal(STOP_WATCHING_TOOL_NAME),
8272
+ arguments: z22.object({ id: z22.string().min(1) }).strict()
8230
8273
  }).strict()
8231
8274
  }).strict();
8232
- var resultDataSchema3 = z21.object({
8233
- id: z21.string().min(1),
8234
- subscription_status: z21.enum(["active", "cancelled", "completed"]),
8235
- identifier: z21.string().min(1),
8236
- events: z21.array(z21.string().min(1)).min(1),
8237
- expiresAtMs: z21.number().finite(),
8275
+ var resultDataSchema3 = z22.object({
8276
+ id: z22.string().min(1),
8277
+ subscription_status: z22.enum(["active", "cancelled", "completed"]),
8278
+ identifier: z22.string().min(1),
8279
+ events: z22.array(z22.string().min(1)).min(1),
8280
+ expiresAtMs: z22.number().finite(),
8238
8281
  stop_watching: stopWatchingActionSchema
8239
8282
  }).strict();
8240
8283
  var outputSchema4 = juniorToolOutputSchema.extend({
@@ -8339,7 +8382,7 @@ function createResourceEventTools(context, catalog) {
8339
8382
 
8340
8383
  // src/chat/tools/create-event-task.ts
8341
8384
  import { createHash as createHash2 } from "crypto";
8342
- import { z as z22 } from "zod";
8385
+ import { z as z23 } from "zod";
8343
8386
  function buildEventTaskId(args) {
8344
8387
  const toolCallId = args.toolCallId?.trim();
8345
8388
  if (!toolCallId) {
@@ -8367,10 +8410,10 @@ function createEventTaskTool(context, catalog) {
8367
8410
  },
8368
8411
  executionMode: "sequential",
8369
8412
  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 remains configured for this Slack channel or DM until deleted and may use the creator's connected credentials. Prefer a subscribable tool result when available.",
8370
- inputSchema: z22.object({
8371
- task: z22.string().trim().min(1).max(4e3),
8413
+ inputSchema: z23.object({
8414
+ task: z23.string().trim().min(1).max(4e3),
8372
8415
  trigger,
8373
- credentialMode: z22.enum(["creator", "system"]).nullable().describe(
8416
+ credentialMode: z23.enum(["creator", "system"]).nullable().describe(
8374
8417
  "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."
8375
8418
  ).optional()
8376
8419
  }).strict(),
@@ -8431,7 +8474,7 @@ function createEventTaskTool(context, catalog) {
8431
8474
  }
8432
8475
 
8433
8476
  // src/chat/tools/delete-event-task.ts
8434
- import { z as z23 } from "zod";
8477
+ import { z as z24 } from "zod";
8435
8478
  function createDeleteEventTaskTool(context, catalog) {
8436
8479
  return zodTool({
8437
8480
  approvalMode: "review",
@@ -8443,7 +8486,7 @@ function createDeleteEventTaskTool(context, catalog) {
8443
8486
  },
8444
8487
  executionMode: "sequential",
8445
8488
  description: "Delete an event task from this Slack channel or DM, including a task created from another thread in the same destination.",
8446
- inputSchema: z23.object({ taskId: z23.string().min(1) }).strict(),
8489
+ inputSchema: z24.object({ taskId: z24.string().min(1) }).strict(),
8447
8490
  outputSchema: eventTaskToolResultSchema,
8448
8491
  async execute({ taskId }) {
8449
8492
  const current = await writableEventTask(context, taskId);
@@ -8459,7 +8502,7 @@ function createDeleteEventTaskTool(context, catalog) {
8459
8502
  }
8460
8503
 
8461
8504
  // src/chat/tools/list-event-tasks.ts
8462
- import { z as z24 } from "zod";
8505
+ import { z as z25 } from "zod";
8463
8506
  var MAX_LISTED_EVENT_TASKS = 50;
8464
8507
  function createListEventTasksTool(context, catalog) {
8465
8508
  return zodTool({
@@ -8470,7 +8513,7 @@ function createListEventTasksTool(context, catalog) {
8470
8513
  readOnlyHint: true
8471
8514
  },
8472
8515
  description: "List event tasks for this Slack channel or DM, including tasks created from other threads in the same destination. A false triggerAvailable value means the task remains stored but its plugin event is not currently enabled.",
8473
- inputSchema: z24.object({}).strict(),
8516
+ inputSchema: z25.object({}).strict(),
8474
8517
  outputSchema: eventTaskListToolResultSchema,
8475
8518
  async execute() {
8476
8519
  const { destination } = requireEventTaskSlackContext(context);
@@ -8485,7 +8528,7 @@ function createListEventTasksTool(context, catalog) {
8485
8528
  }
8486
8529
 
8487
8530
  // src/chat/tools/update-event-task.ts
8488
- import { z as z25 } from "zod";
8531
+ import { z as z26 } from "zod";
8489
8532
  function changesEventTaskTrigger(current, next) {
8490
8533
  const currentEvents = [...current.events].sort();
8491
8534
  const nextEvents = [...next.events].sort();
@@ -8502,11 +8545,11 @@ function createUpdateEventTaskTool(context, catalog) {
8502
8545
  },
8503
8546
  executionMode: "sequential",
8504
8547
  description: "Update the instruction, registered trigger, or credential use for an event task in this Slack channel or DM. Event tasks created from other threads in the same destination are manageable here.",
8505
- inputSchema: z25.object({
8506
- taskId: z25.string().min(1),
8507
- task: z25.string().trim().min(1).max(4e3).nullable().optional(),
8548
+ inputSchema: z26.object({
8549
+ taskId: z26.string().min(1),
8550
+ task: z26.string().trim().min(1).max(4e3).nullable().optional(),
8508
8551
  trigger: registeredEventTaskTriggerSchema(catalog).nullable().optional(),
8509
- credentialMode: z25.enum(["system", "creator"]).nullable().describe(
8552
+ credentialMode: z26.enum(["system", "creator"]).nullable().describe(
8510
8553
  "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."
8511
8554
  ).optional()
8512
8555
  }).strict(),
@@ -8580,16 +8623,16 @@ function createEventTaskTools(context, catalog) {
8580
8623
  }
8581
8624
 
8582
8625
  // src/chat/scheduled-tasks/tools/create.ts
8583
- import { z as z28 } from "zod";
8626
+ import { z as z29 } from "zod";
8584
8627
 
8585
8628
  // src/chat/scheduled-tasks/schedule-intent.ts
8586
- import { z as z26 } from "zod";
8587
- var localDateSchema = z26.string().regex(/^\d{4}-\d{2}-\d{2}$/, "Use a local date in YYYY-MM-DD format.");
8588
- var localTimeSchema = z26.string().regex(/^([01]\d|2[0-3]):[0-5]\d$/, "Use local time in HH:MM format.");
8589
- var timezoneSchema = z26.string().min(1).max(80).describe(
8629
+ import { z as z27 } from "zod";
8630
+ var localDateSchema = z27.string().regex(/^\d{4}-\d{2}-\d{2}$/, "Use a local date in YYYY-MM-DD format.");
8631
+ var localTimeSchema = z27.string().regex(/^([01]\d|2[0-3]):[0-5]\d$/, "Use local time in HH:MM format.");
8632
+ var timezoneSchema = z27.string().min(1).max(80).describe(
8590
8633
  "IANA timezone, for example America/Los_Angeles. Omit or use null for the scheduler default."
8591
8634
  ).nullable().optional();
8592
- var weekdaySchema = z26.enum([
8635
+ var weekdaySchema = z27.enum([
8593
8636
  "sunday",
8594
8637
  "monday",
8595
8638
  "tuesday",
@@ -8598,17 +8641,17 @@ var weekdaySchema = z26.enum([
8598
8641
  "friday",
8599
8642
  "saturday"
8600
8643
  ]);
8601
- var oneOffScheduleIntentSchema = z26.object({
8602
- kind: z26.literal("one_off").describe("A schedule that runs once."),
8644
+ var oneOffScheduleIntentSchema = z27.object({
8645
+ kind: z27.literal("one_off").describe("A schedule that runs once."),
8603
8646
  timezone: timezoneSchema,
8604
- timing: z26.discriminatedUnion("type", [
8605
- z26.object({
8606
- type: z26.literal("after").describe("Run after a relative delay from the server clock."),
8607
- value: z26.number().int().positive().max(1e5),
8608
- unit: z26.enum(["second", "minute", "hour", "day", "week"])
8647
+ timing: z27.discriminatedUnion("type", [
8648
+ z27.object({
8649
+ type: z27.literal("after").describe("Run after a relative delay from the server clock."),
8650
+ value: z27.number().int().positive().max(1e5),
8651
+ unit: z27.enum(["second", "minute", "hour", "day", "week"])
8609
8652
  }).strict(),
8610
- z26.object({
8611
- type: z26.literal("at").describe("Run at an explicit local calendar date and time."),
8653
+ z27.object({
8654
+ type: z27.literal("at").describe("Run at an explicit local calendar date and time."),
8612
8655
  date: localDateSchema.describe(
8613
8656
  "Requested local calendar date in YYYY-MM-DD format."
8614
8657
  ),
@@ -8618,16 +8661,16 @@ var oneOffScheduleIntentSchema = z26.object({
8618
8661
  }).strict()
8619
8662
  ]).describe("Relative delay or explicit local time for the one-off run.")
8620
8663
  }).strict();
8621
- var recurringScheduleIntentSchema = z26.object({
8622
- kind: z26.literal("recurring").describe("A repeating calendar schedule."),
8623
- frequency: z26.enum(["daily", "weekly", "monthly", "yearly"]).describe("Recurring tasks can run at most once per day."),
8624
- interval: z26.number().int().positive().max(365).describe("Repeat every N frequency units. Defaults to 1.").nullable().optional(),
8664
+ var recurringScheduleIntentSchema = z27.object({
8665
+ kind: z27.literal("recurring").describe("A repeating calendar schedule."),
8666
+ frequency: z27.enum(["daily", "weekly", "monthly", "yearly"]).describe("Recurring tasks can run at most once per day."),
8667
+ interval: z27.number().int().positive().max(365).describe("Repeat every N frequency units. Defaults to 1.").nullable().optional(),
8625
8668
  time: localTimeSchema.describe(
8626
8669
  "Local wall-clock time for each occurrence in HH:MM format."
8627
8670
  ),
8628
- weekdays: z26.array(weekdaySchema).min(1).max(7).describe("Required for weekly schedules.").nullable().optional(),
8629
- day_of_month: z26.number().int().min(1).max(31).describe("Required for monthly and yearly schedules.").nullable().optional(),
8630
- month: z26.number().int().min(1).max(12).describe("Required for yearly schedules, where January is 1.").nullable().optional(),
8671
+ weekdays: z27.array(weekdaySchema).min(1).max(7).describe("Required for weekly schedules.").nullable().optional(),
8672
+ day_of_month: z27.number().int().min(1).max(31).describe("Required for monthly and yearly schedules.").nullable().optional(),
8673
+ month: z27.number().int().min(1).max(12).describe("Required for yearly schedules, where January is 1.").nullable().optional(),
8631
8674
  start_date: localDateSchema.describe(
8632
8675
  "Optional local calendar date that anchors the recurrence. Omit to start with the next matching occurrence."
8633
8676
  ).nullable().optional(),
@@ -8676,7 +8719,7 @@ var recurringScheduleIntentSchema = z26.object({
8676
8719
  });
8677
8720
  }
8678
8721
  });
8679
- var scheduleIntentSchema = z26.union([
8722
+ var scheduleIntentSchema = z27.union([
8680
8723
  oneOffScheduleIntentSchema,
8681
8724
  recurringScheduleIntentSchema
8682
8725
  ]);
@@ -8836,7 +8879,7 @@ import { createHash as createHash3 } from "crypto";
8836
8879
  import {
8837
8880
  sourceSchema
8838
8881
  } from "@sentry/junior-plugin-api";
8839
- import { z as z27 } from "zod";
8882
+ import { z as z28 } from "zod";
8840
8883
 
8841
8884
  // src/chat/scheduled-tasks/identity.ts
8842
8885
  var SLACK_USER_ID_PATTERN = /^[UW][A-Z0-9]{5,}$/;
@@ -8873,30 +8916,30 @@ function sanitizeScheduledTaskPrincipal(principal) {
8873
8916
  var TASK_ID_PREFIX = "sched";
8874
8917
  var MAX_LISTED_TASKS = 50;
8875
8918
  var DEFAULT_SCHEDULE_TIMEZONE = "America/Los_Angeles";
8876
- var compactTaskResultSchema = z27.object({
8877
- id: z27.string(),
8878
- status: z27.enum(["active", "blocked", "deleted"]),
8879
- task: z27.string(),
8880
- schedule: z27.string(),
8881
- timezone: z27.string(),
8882
- recurrence: z27.unknown().nullable(),
8883
- next_run_at: z27.string().nullable(),
8884
- conversation_access: z27.object({
8885
- audience: z27.enum(["direct", "group", "channel"]),
8886
- visibility: z27.enum(["private", "public"])
8919
+ var compactTaskResultSchema = z28.object({
8920
+ id: z28.string(),
8921
+ status: z28.enum(["active", "blocked", "deleted"]),
8922
+ task: z28.string(),
8923
+ schedule: z28.string(),
8924
+ timezone: z28.string(),
8925
+ recurrence: z28.unknown().nullable(),
8926
+ next_run_at: z28.string().nullable(),
8927
+ conversation_access: z28.object({
8928
+ audience: z28.enum(["direct", "group", "channel"]),
8929
+ visibility: z28.enum(["private", "public"])
8887
8930
  }).strict(),
8888
- credential_mode: z27.enum(["system", "creator"]),
8889
- last_run_at: z27.string().nullable(),
8890
- run_now_at: z27.string().nullable()
8931
+ credential_mode: z28.enum(["system", "creator"]),
8932
+ last_run_at: z28.string().nullable(),
8933
+ run_now_at: z28.string().nullable()
8891
8934
  }).strict();
8892
8935
  var scheduleTaskToolResultSchema = juniorToolOutputSchema.extend({
8893
- target: z27.string(),
8936
+ target: z28.string(),
8894
8937
  task: compactTaskResultSchema
8895
8938
  }).strict();
8896
8939
  var scheduleListToolResultSchema = juniorToolOutputSchema.extend({
8897
- target: z27.string(),
8898
- tasks: z27.array(compactTaskResultSchema),
8899
- truncated: z27.boolean()
8940
+ target: z28.string(),
8941
+ tasks: z28.array(compactTaskResultSchema),
8942
+ truncated: z28.boolean()
8900
8943
  }).strict();
8901
8944
  function throwToolInputError(error) {
8902
8945
  throw new ToolInputError(error);
@@ -9056,12 +9099,12 @@ function createSlackScheduleCreateTaskTool(context) {
9056
9099
  },
9057
9100
  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.",
9058
9101
  executionMode: "sequential",
9059
- inputSchema: z28.object({
9060
- task: z28.string().min(1).max(4e3),
9102
+ inputSchema: z29.object({
9103
+ task: z29.string().min(1).max(4e3),
9061
9104
  schedule: scheduleIntentSchema.describe(
9062
9105
  "When the task runs. The scheduler computes the exact next run from this intent and the server clock."
9063
9106
  ),
9064
- credential_mode: z28.enum(["creator", "system"]).nullable().describe(
9107
+ credential_mode: z29.enum(["creator", "system"]).nullable().describe(
9065
9108
  "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."
9066
9109
  ).optional()
9067
9110
  }).strict(),
@@ -9148,7 +9191,7 @@ function createSlackScheduleCreateTaskTool(context) {
9148
9191
  }
9149
9192
 
9150
9193
  // src/chat/scheduled-tasks/tools/delete.ts
9151
- import { z as z29 } from "zod";
9194
+ import { z as z30 } from "zod";
9152
9195
  function createSlackScheduleDeleteTaskTool(context) {
9153
9196
  return zodTool({
9154
9197
  annotations: {
@@ -9159,8 +9202,8 @@ function createSlackScheduleDeleteTaskTool(context) {
9159
9202
  },
9160
9203
  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.",
9161
9204
  executionMode: "sequential",
9162
- inputSchema: z29.object({
9163
- task_id: z29.string().min(1).describe(
9205
+ inputSchema: z30.object({
9206
+ task_id: z30.string().min(1).describe(
9164
9207
  "ID of the task to delete. Must be from this active Slack conversation."
9165
9208
  )
9166
9209
  }),
@@ -9184,7 +9227,7 @@ function createSlackScheduleDeleteTaskTool(context) {
9184
9227
  }
9185
9228
 
9186
9229
  // src/chat/scheduled-tasks/tools/list.ts
9187
- import { z as z30 } from "zod";
9230
+ import { z as z31 } from "zod";
9188
9231
  function createSlackScheduleListTasksTool(context) {
9189
9232
  return zodTool({
9190
9233
  description: "List scheduled Junior tasks for the active Slack conversation. Use when the user asks what is scheduled here, or when task IDs are needed before editing, deleting, or running schedules. Only manages tasks for the active Slack DM or channel.",
@@ -9194,7 +9237,7 @@ function createSlackScheduleListTasksTool(context) {
9194
9237
  openWorldHint: false,
9195
9238
  readOnlyHint: true
9196
9239
  },
9197
- inputSchema: z30.object({}),
9240
+ inputSchema: z31.object({}),
9198
9241
  outputSchema: scheduleListToolResultSchema,
9199
9242
  execute: async () => {
9200
9243
  const destination = requireActiveConversation(context);
@@ -9215,7 +9258,7 @@ function createSlackScheduleListTasksTool(context) {
9215
9258
  }
9216
9259
 
9217
9260
  // src/chat/scheduled-tasks/tools/run-now.ts
9218
- import { z as z31 } from "zod";
9261
+ import { z as z32 } from "zod";
9219
9262
  function createSlackScheduleRunTaskNowTool(context) {
9220
9263
  return zodTool({
9221
9264
  annotations: {
@@ -9226,8 +9269,8 @@ function createSlackScheduleRunTaskNowTool(context) {
9226
9269
  },
9227
9270
  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.",
9228
9271
  executionMode: "sequential",
9229
- inputSchema: z31.object({
9230
- task_id: z31.string().min(1).describe(
9272
+ inputSchema: z32.object({
9273
+ task_id: z32.string().min(1).describe(
9231
9274
  "ID of the active task to run now. Must be from this active Slack conversation."
9232
9275
  )
9233
9276
  }),
@@ -9255,7 +9298,7 @@ function createSlackScheduleRunTaskNowTool(context) {
9255
9298
  }
9256
9299
 
9257
9300
  // src/chat/scheduled-tasks/tools/update.ts
9258
- import { z as z32 } from "zod";
9301
+ import { z as z33 } from "zod";
9259
9302
  function createSlackScheduleUpdateTaskTool(context) {
9260
9303
  return zodTool({
9261
9304
  approvalMode: "review",
@@ -9267,18 +9310,18 @@ function createSlackScheduleUpdateTaskTool(context) {
9267
9310
  },
9268
9311
  description: "Edit, reschedule, unblock, or change credential use for an existing Junior scheduled task in the active Slack conversation.",
9269
9312
  executionMode: "sequential",
9270
- inputSchema: z32.object({
9271
- task_id: z32.string().min(1).describe(
9313
+ inputSchema: z33.object({
9314
+ task_id: z33.string().min(1).describe(
9272
9315
  "ID of the task to update. Must be from this active Slack conversation."
9273
9316
  ),
9274
- task: z32.string().min(1).max(4e3).optional(),
9317
+ task: z33.string().min(1).max(4e3).optional(),
9275
9318
  schedule: scheduleIntentSchema.describe(
9276
9319
  "Complete replacement schedule when rescheduling. Omit for task, status, or credential-only changes; the scheduler computes the next run."
9277
9320
  ).nullable().optional(),
9278
- status: z32.enum(["active", "blocked"]).describe(
9321
+ status: z33.enum(["active", "blocked"]).describe(
9279
9322
  "Set to active to clear a blocked task, or blocked when dispatch cannot continue."
9280
9323
  ).optional(),
9281
- credential_mode: z32.enum(["system", "creator"]).nullable().describe(
9324
+ credential_mode: z33.enum(["system", "creator"]).nullable().describe(
9282
9325
  "Set creator to make the task's original creator credentials available, or system to disable them. Creator always means the task's created_by actor, never the current requester. Only that original creator may enable creator mode. Omit or use null to leave unchanged."
9283
9326
  ).optional()
9284
9327
  }).strict(),
@@ -9447,11 +9490,11 @@ async function listThreadReplies(input) {
9447
9490
  }
9448
9491
 
9449
9492
  // src/chat/slack/timestamp-param.ts
9450
- import { z as z33 } from "zod";
9493
+ import { z as z34 } from "zod";
9451
9494
  function slackTimestampParam(description) {
9452
- return z33.preprocess(
9495
+ return z34.preprocess(
9453
9496
  (value) => typeof value === "number" && Number.isFinite(value) ? String(value) : value,
9454
- z33.string().min(1)
9497
+ z34.string().min(1)
9455
9498
  ).describe(description);
9456
9499
  }
9457
9500
  function optionalSlackTimestampParam(description) {
@@ -9482,10 +9525,10 @@ function parseRequiredSlackTimestampParam(field, value) {
9482
9525
  }
9483
9526
 
9484
9527
  // src/chat/slack/tools/channel-list-messages.ts
9485
- import { z as z34 } from "zod";
9486
- var booleanInput2 = (description) => z34.preprocess(
9528
+ import { z as z35 } from "zod";
9529
+ var booleanInput2 = (description) => z35.preprocess(
9487
9530
  (value) => value === "true" ? true : value === "false" ? false : value,
9488
- z34.boolean()
9531
+ z35.boolean()
9489
9532
  ).describe(description);
9490
9533
  function normalizeRangeTimestamp(field, value, targetChannelId) {
9491
9534
  if (value === void 0) {
@@ -9517,9 +9560,9 @@ function createSlackChannelListMessagesTool(context) {
9517
9560
  openWorldHint: true,
9518
9561
  readOnlyHint: true
9519
9562
  },
9520
- inputSchema: z34.object({
9521
- limit: z34.coerce.number().int().min(1).max(1e3).describe("Maximum number of messages to return across pages.").optional(),
9522
- cursor: z34.string().min(1).describe("Optional cursor to continue from a prior call.").optional(),
9563
+ inputSchema: z35.object({
9564
+ limit: z35.coerce.number().int().min(1).max(1e3).describe("Maximum number of messages to return across pages.").optional(),
9565
+ cursor: z35.string().min(1).describe("Optional cursor to continue from a prior call.").optional(),
9523
9566
  oldest: optionalSlackTimestampParam(
9524
9567
  "Optional oldest message timestamp (Slack ts) for range filtering."
9525
9568
  ),
@@ -9529,7 +9572,7 @@ function createSlackChannelListMessagesTool(context) {
9529
9572
  inclusive: booleanInput2(
9530
9573
  "Whether oldest/latest bounds should be inclusive."
9531
9574
  ).optional(),
9532
- max_pages: z34.coerce.number().int().min(1).max(10).describe("Maximum number of API pages to traverse in a single call.").optional()
9575
+ max_pages: z35.coerce.number().int().min(1).max(10).describe("Maximum number of API pages to traverse in a single call.").optional()
9533
9576
  }),
9534
9577
  outputSchema: juniorToolOutputSchema,
9535
9578
  execute: async ({
@@ -9592,20 +9635,20 @@ function createSlackChannelListMessagesTool(context) {
9592
9635
  }
9593
9636
 
9594
9637
  // src/chat/slack/tools/conversation-search.ts
9595
- import { z as z35 } from "zod";
9638
+ import { z as z36 } from "zod";
9596
9639
  var DEFAULT_LIMIT = 5;
9597
9640
  var conversationSearchOutputSchema = juniorToolOutputSchema.extend({
9598
- query: z35.string(),
9599
- count: z35.number().int().nonnegative(),
9600
- threads: z35.array(
9601
- z35.object({
9602
- conversation_id: z35.string().min(1),
9603
- thread_ts: z35.string().min(1),
9604
- message_id: z35.string().min(1),
9605
- message_role: z35.enum(["assistant", "user"]),
9606
- message_timestamp: z35.string().datetime(),
9607
- excerpt: z35.string(),
9608
- permalink: z35.string().url().optional()
9641
+ query: z36.string(),
9642
+ count: z36.number().int().nonnegative(),
9643
+ threads: z36.array(
9644
+ z36.object({
9645
+ conversation_id: z36.string().min(1),
9646
+ thread_ts: z36.string().min(1),
9647
+ message_id: z36.string().min(1),
9648
+ message_role: z36.enum(["assistant", "user"]),
9649
+ message_timestamp: z36.string().datetime(),
9650
+ excerpt: z36.string(),
9651
+ permalink: z36.string().url().optional()
9609
9652
  }).strict()
9610
9653
  )
9611
9654
  });
@@ -9623,9 +9666,9 @@ function createSlackConversationSearchTool(scope, currentConversationId, deps =
9623
9666
  openWorldHint: false,
9624
9667
  readOnlyHint: true
9625
9668
  },
9626
- inputSchema: z35.object({
9627
- query: z35.string().trim().min(1).max(200).describe("Words or a short phrase to find in prior conversations."),
9628
- limit: z35.number().int().min(1).max(10).describe("Maximum number of prior conversation threads to return.").nullable().optional()
9669
+ inputSchema: z36.object({
9670
+ query: z36.string().trim().min(1).max(200).describe("Words or a short phrase to find in prior conversations."),
9671
+ limit: z36.number().int().min(1).max(10).describe("Maximum number of prior conversation threads to return.").nullable().optional()
9629
9672
  }),
9630
9673
  outputSchema: conversationSearchOutputSchema,
9631
9674
  execute: async ({ query, limit }) => {
@@ -9670,27 +9713,27 @@ function createSlackConversationSearchTool(scope, currentConversationId, deps =
9670
9713
  }
9671
9714
 
9672
9715
  // src/chat/slack/tools/public-search.ts
9673
- import { z as z36 } from "zod";
9716
+ import { z as z37 } from "zod";
9674
9717
  var DEFAULT_LIMIT2 = 10;
9675
- var optionalTimestampSchema = z36.preprocess(
9718
+ var optionalTimestampSchema = z37.preprocess(
9676
9719
  (value) => typeof value === "string" && value.trim() === "" ? void 0 : value,
9677
- z36.coerce.number().int().nonnegative().describe("Optional Unix timestamp bound.").optional()
9720
+ z37.coerce.number().int().nonnegative().describe("Optional Unix timestamp bound.").optional()
9678
9721
  );
9679
- var searchMessageSchema = z36.object({
9680
- author_name: z36.string().optional(),
9681
- author_user_id: z36.string().optional(),
9682
- channel_id: z36.string().min(1),
9683
- channel_name: z36.string().optional(),
9684
- message_ts: z36.string().min(1),
9685
- content: z36.string(),
9686
- is_author_bot: z36.boolean().optional(),
9687
- permalink: z36.string().url()
9722
+ var searchMessageSchema = z37.object({
9723
+ author_name: z37.string().optional(),
9724
+ author_user_id: z37.string().optional(),
9725
+ channel_id: z37.string().min(1),
9726
+ channel_name: z37.string().optional(),
9727
+ message_ts: z37.string().min(1),
9728
+ content: z37.string(),
9729
+ is_author_bot: z37.boolean().optional(),
9730
+ permalink: z37.string().url()
9688
9731
  });
9689
9732
  var publicSearchOutputSchema = juniorToolOutputSchema.extend({
9690
- query: z36.string(),
9691
- count: z36.number().int().nonnegative(),
9692
- messages: z36.array(searchMessageSchema),
9693
- next_cursor: z36.string().optional()
9733
+ query: z37.string(),
9734
+ count: z37.number().int().nonnegative(),
9735
+ messages: z37.array(searchMessageSchema),
9736
+ next_cursor: z37.string().optional()
9694
9737
  });
9695
9738
  function normalizeMessage(value) {
9696
9739
  const parsed = searchMessageSchema.safeParse(value);
@@ -9717,8 +9760,8 @@ function createSlackPublicSearchTool(actionToken) {
9717
9760
  openWorldHint: true,
9718
9761
  readOnlyHint: true
9719
9762
  },
9720
- inputSchema: z36.object({
9721
- query: z36.string().trim().min(1).max(500).describe(
9763
+ inputSchema: z37.object({
9764
+ query: z37.string().trim().min(1).max(500).describe(
9722
9765
  "A focused Slack search query, including Slack search filters when useful."
9723
9766
  ),
9724
9767
  after: optionalTimestampSchema.describe(
@@ -9727,10 +9770,10 @@ function createSlackPublicSearchTool(actionToken) {
9727
9770
  before: optionalTimestampSchema.describe(
9728
9771
  "Optional Unix timestamp upper bound."
9729
9772
  ),
9730
- cursor: z36.string().min(1).describe("Cursor for the next result page.").optional(),
9731
- limit: z36.coerce.number().int().min(1).max(20).describe("Maximum results to return; Slack allows at most 20.").optional(),
9732
- sort: z36.enum(["score", "timestamp"]).describe("Rank by relevance or timestamp.").optional(),
9733
- sort_dir: z36.enum(["asc", "desc"]).describe("Sort direction.").optional()
9773
+ cursor: z37.string().min(1).describe("Cursor for the next result page.").optional(),
9774
+ limit: z37.coerce.number().int().min(1).max(20).describe("Maximum results to return; Slack allows at most 20.").optional(),
9775
+ sort: z37.enum(["score", "timestamp"]).describe("Rank by relevance or timestamp.").optional(),
9776
+ sort_dir: z37.enum(["asc", "desc"]).describe("Sort direction.").optional()
9734
9777
  }),
9735
9778
  outputSchema: publicSearchOutputSchema,
9736
9779
  execute: async ({
@@ -9787,7 +9830,7 @@ function createSlackPublicSearchTool(actionToken) {
9787
9830
  }
9788
9831
 
9789
9832
  // src/chat/slack/tools/message-add-reaction.ts
9790
- import { z as z37 } from "zod";
9833
+ import { z as z38 } from "zod";
9791
9834
 
9792
9835
  // src/chat/tools/idempotency.ts
9793
9836
  function stableSerialize(value) {
@@ -9817,8 +9860,8 @@ function createSlackMessageAddReactionTool(context, state) {
9817
9860
  readOnlyHint: false
9818
9861
  },
9819
9862
  description: "Add an emoji reaction to the current inbound Slack message. Use when the user asks for a reaction on the current message without another target. Provide a Slack emoji alias name (for example `thumbsup`, `white_check_mark`, or `thumbsup::skin-tone-6`), not a unicode emoji glyph. The target message is injected by runtime context; do not use this for arbitrary historical messages.",
9820
- inputSchema: z37.object({
9821
- emoji: z37.string().min(1).max(64).describe(
9863
+ inputSchema: z38.object({
9864
+ emoji: z38.string().min(1).max(64).describe(
9822
9865
  "Slack emoji alias name to react with (for example `thumbsup`, `white_check_mark`, or `thumbsup::skin-tone-6`). Optional surrounding colons are allowed."
9823
9866
  )
9824
9867
  }),
@@ -9867,14 +9910,14 @@ function createSlackMessageAddReactionTool(context, state) {
9867
9910
 
9868
9911
  // src/chat/slack/tools/send-files.ts
9869
9912
  import { createHash as createHash4 } from "crypto";
9870
- import { z as z38 } from "zod";
9913
+ import { z as z39 } from "zod";
9871
9914
  var sendFilesResultSchema = juniorToolOutputSchema.extend({
9872
- target: z38.string().min(1),
9873
- channel_id: z38.string().min(1),
9874
- deduplicated: z38.boolean().optional(),
9875
- file_count: z38.number().int().nonnegative(),
9876
- file_ids: z38.array(z38.string().min(1)).optional(),
9877
- thread_ts: z38.string().min(1)
9915
+ target: z39.string().min(1),
9916
+ channel_id: z39.string().min(1),
9917
+ deduplicated: z39.boolean().optional(),
9918
+ file_count: z39.number().int().nonnegative(),
9919
+ file_ids: z39.array(z39.string().min(1)).optional(),
9920
+ thread_ts: z39.string().min(1)
9878
9921
  });
9879
9922
  function normalizeFiles(files) {
9880
9923
  return files.map((file) => ({
@@ -9904,8 +9947,8 @@ function createSendFilesTool(context, state, materializeFile) {
9904
9947
  readOnlyHint: false
9905
9948
  },
9906
9949
  description: "Send one or more sandbox files into the active Slack conversation. Use when the user asks to attach, send, or share files here, in this conversation, or in this thread. Do not use for ordinary assistant text, top-level channel posts, other named channels, inline @mentions, or pinging mentioned users.",
9907
- inputSchema: z38.object({
9908
- files: z38.array(sandboxFileReferenceSchema).min(1).describe(
9950
+ inputSchema: z39.object({
9951
+ files: z39.array(sandboxFileReferenceSchema).min(1).describe(
9909
9952
  "One or more existing sandbox files. Objects returned by imageGenerate or webFetch can be passed unchanged."
9910
9953
  )
9911
9954
  }),
@@ -10337,7 +10380,7 @@ function storedCanvasUrl(state, canvasId) {
10337
10380
  }
10338
10381
 
10339
10382
  // src/chat/slack/tools/canvas/create.ts
10340
- import { z as z39 } from "zod";
10383
+ import { z as z40 } from "zod";
10341
10384
  function createSlackCanvasCreateTool(context, state) {
10342
10385
  return zodTool({
10343
10386
  annotations: {
@@ -10347,9 +10390,9 @@ function createSlackCanvasCreateTool(context, state) {
10347
10390
  readOnlyHint: false
10348
10391
  },
10349
10392
  description: "Create a Slack canvas for long-form output in the active assistant context channel. Use when the answer is better as a reusable document than a thread reply: long-form research, timelines, bios/profiles, structured notes, plans, comparisons, or anything likely to exceed one compact Slack reply. After creating it, reply with one or two short sentences plus the canvas link; do not recap the canvas contents. Do not use for short answers that fit cleanly in one normal thread reply.",
10350
- inputSchema: z39.object({
10351
- title: z39.string().min(1).max(160).describe("Canvas title."),
10352
- markdown: z39.string().min(1).describe("Canvas markdown body content.")
10393
+ inputSchema: z40.object({
10394
+ title: z40.string().min(1).max(160).describe("Canvas title."),
10395
+ markdown: z40.string().min(1).describe("Canvas markdown body content.")
10353
10396
  }),
10354
10397
  outputSchema: juniorToolOutputSchema,
10355
10398
  execute: async ({ title, markdown }) => {
@@ -10405,26 +10448,26 @@ function createSlackCanvasCreateTool(context, state) {
10405
10448
  }
10406
10449
 
10407
10450
  // src/chat/slack/tools/canvas/edit.ts
10408
- import { z as z40 } from "zod";
10451
+ import { z as z41 } from "zod";
10409
10452
  function prepareCanvasEditArguments(input) {
10410
10453
  return prepareTextReplacementArguments(input);
10411
10454
  }
10412
- var editReplacementSchema2 = z40.object({
10413
- oldText: z40.string().min(1).describe(
10455
+ var editReplacementSchema2 = z41.object({
10456
+ oldText: z41.string().min(1).describe(
10414
10457
  "Exact Canvas markdown to replace. It must be unique in the current Canvas body and must not overlap another edit."
10415
10458
  ),
10416
- newText: z40.string().describe("Replacement Canvas markdown for this edit.")
10459
+ newText: z41.string().describe("Replacement Canvas markdown for this edit.")
10417
10460
  });
10418
10461
  var slackCanvasEditOutputSchema = juniorToolOutputSchema.extend({
10419
- canvas_id: z40.string().optional(),
10420
- title: z40.string().optional(),
10421
- permalink: z40.string().optional(),
10422
- diff: z40.string().optional(),
10423
- first_changed_line: z40.number().int().positive().optional(),
10424
- replacements: z40.number().int().nonnegative().optional(),
10425
- normalized_heading_count: z40.number().int().nonnegative().optional(),
10426
- summary: z40.string().optional(),
10427
- deduplicated: z40.boolean().optional()
10462
+ canvas_id: z41.string().optional(),
10463
+ title: z41.string().optional(),
10464
+ permalink: z41.string().optional(),
10465
+ diff: z41.string().optional(),
10466
+ first_changed_line: z41.number().int().positive().optional(),
10467
+ replacements: z41.number().int().nonnegative().optional(),
10468
+ normalized_heading_count: z41.number().int().nonnegative().optional(),
10469
+ summary: z41.string().optional(),
10470
+ deduplicated: z41.boolean().optional()
10428
10471
  }).strict();
10429
10472
  function createSlackCanvasEditTool(state) {
10430
10473
  return zodTool({
@@ -10437,9 +10480,9 @@ function createSlackCanvasEditTool(state) {
10437
10480
  description: "Edit one Slack canvas with exact markdown replacements. Use for precise changes to existing Canvas content; prefer this over slackCanvasWrite for targeted changes. Each oldText must match exactly, be unique, and not overlap another edit. Returns a diff. Multiple changes to the same canvas: use one edits[] call.",
10438
10481
  prepareArguments: prepareCanvasEditArguments,
10439
10482
  executionMode: "sequential",
10440
- inputSchema: z40.object({
10441
- canvas: z40.string().min(1).describe("Canvas/file ID (e.g. `F0ABCDEF`) or Slack canvas/docs URL."),
10442
- edits: z40.array(editReplacementSchema2).min(1).describe(
10483
+ inputSchema: z41.object({
10484
+ canvas: z41.string().min(1).describe("Canvas/file ID (e.g. `F0ABCDEF`) or Slack canvas/docs URL."),
10485
+ edits: z41.array(editReplacementSchema2).min(1).describe(
10443
10486
  "Exact replacements matched against the current Canvas body, not incrementally."
10444
10487
  )
10445
10488
  }),
@@ -10496,18 +10539,18 @@ function createSlackCanvasEditTool(state) {
10496
10539
  }
10497
10540
 
10498
10541
  // src/chat/slack/tools/canvas/read.ts
10499
- import { z as z41 } from "zod";
10542
+ import { z as z42 } from "zod";
10500
10543
  var slackCanvasReadOutputSchema = juniorToolOutputSchema.extend({
10501
- canvas_id: z41.string().optional(),
10502
- title: z41.string().optional(),
10503
- permalink: z41.string().optional(),
10504
- mimetype: z41.string().optional(),
10505
- filetype: z41.string().optional(),
10506
- original_byte_length: z41.number().int().nonnegative().optional(),
10507
- content: z41.string().optional(),
10508
- start_line: z41.number().int().positive().optional(),
10509
- end_line: z41.number().int().nonnegative().optional(),
10510
- total_lines: z41.number().int().nonnegative().optional()
10544
+ canvas_id: z42.string().optional(),
10545
+ title: z42.string().optional(),
10546
+ permalink: z42.string().optional(),
10547
+ mimetype: z42.string().optional(),
10548
+ filetype: z42.string().optional(),
10549
+ original_byte_length: z42.number().int().nonnegative().optional(),
10550
+ content: z42.string().optional(),
10551
+ start_line: z42.number().int().positive().optional(),
10552
+ end_line: z42.number().int().nonnegative().optional(),
10553
+ total_lines: z42.number().int().nonnegative().optional()
10511
10554
  }).strict();
10512
10555
  function createSlackCanvasReadTool() {
10513
10556
  return zodTool({
@@ -10518,12 +10561,12 @@ function createSlackCanvasReadTool() {
10518
10561
  openWorldHint: true,
10519
10562
  readOnlyHint: true
10520
10563
  },
10521
- inputSchema: z41.object({
10522
- canvas: z41.string().min(1).describe(
10564
+ inputSchema: z42.object({
10565
+ canvas: z42.string().min(1).describe(
10523
10566
  "Canvas/file ID (e.g. `F0ABCDEF`) or Slack canvas/docs URL (e.g. `https://team.slack.com/docs/T.../F...`)."
10524
10567
  ),
10525
- offset: z41.coerce.number().int().min(1).describe("1-indexed line number to start reading from.").optional(),
10526
- limit: z41.coerce.number().int().min(1).describe("Maximum number of lines to read. Defaults to 1000.").optional()
10568
+ offset: z42.coerce.number().int().min(1).describe("1-indexed line number to start reading from.").optional(),
10569
+ limit: z42.coerce.number().int().min(1).describe("Maximum number of lines to read. Defaults to 1000.").optional()
10527
10570
  }),
10528
10571
  outputSchema: slackCanvasReadOutputSchema,
10529
10572
  execute: async ({ canvas, offset, limit }) => {
@@ -10559,7 +10602,7 @@ function createSlackCanvasReadTool() {
10559
10602
  }
10560
10603
 
10561
10604
  // src/chat/slack/tools/canvas/write.ts
10562
- import { z as z42 } from "zod";
10605
+ import { z as z43 } from "zod";
10563
10606
  function createSlackCanvasWriteTool(state) {
10564
10607
  return zodTool({
10565
10608
  annotations: {
@@ -10570,9 +10613,9 @@ function createSlackCanvasWriteTool(state) {
10570
10613
  },
10571
10614
  description: "Write UTF-8 markdown content to a Slack canvas. Use for deliberate full-Canvas replacement after validation; use slackCanvasEdit for targeted changes to existing canvas content.",
10572
10615
  executionMode: "sequential",
10573
- inputSchema: z42.object({
10574
- canvas: z42.string().min(1).describe("Canvas/file ID (e.g. `F0ABCDEF`) or Slack canvas/docs URL."),
10575
- content: z42.string().describe("UTF-8 markdown content to write.")
10616
+ inputSchema: z43.object({
10617
+ canvas: z43.string().min(1).describe("Canvas/file ID (e.g. `F0ABCDEF`) or Slack canvas/docs URL."),
10618
+ content: z43.string().describe("UTF-8 markdown content to write.")
10576
10619
  }),
10577
10620
  outputSchema: juniorToolOutputSchema,
10578
10621
  execute: async ({ canvas, content }) => {
@@ -10787,12 +10830,12 @@ async function updateListItem(input) {
10787
10830
  }
10788
10831
 
10789
10832
  // src/chat/slack/id-param.ts
10790
- import { z as z43 } from "zod";
10833
+ import { z as z44 } from "zod";
10791
10834
  function slackChannelIdParam(description) {
10792
- return z43.string().min(1).describe(description);
10835
+ return z44.string().min(1).describe(description);
10793
10836
  }
10794
10837
  function slackUserIdParam(description) {
10795
- return z43.string().min(1).describe(description);
10838
+ return z44.string().min(1).describe(description);
10796
10839
  }
10797
10840
  function parseRequiredSlackChannelIdParam(field, value) {
10798
10841
  const channelId = parseSlackChannelId(value);
@@ -10816,7 +10859,7 @@ function parseRequiredSlackUserIdParam(field, value) {
10816
10859
  }
10817
10860
 
10818
10861
  // src/chat/slack/tools/list/add-items.ts
10819
- import { z as z44 } from "zod";
10862
+ import { z as z45 } from "zod";
10820
10863
  function createSlackListAddItemsTool(state) {
10821
10864
  return zodTool({
10822
10865
  annotations: {
@@ -10826,12 +10869,12 @@ function createSlackListAddItemsTool(state) {
10826
10869
  readOnlyHint: false
10827
10870
  },
10828
10871
  description: "Add tasks to the active Slack list tracked in artifact context. Use when the user wants actionable items recorded in the current thread list. Do not use when no list exists and list creation was not requested.",
10829
- inputSchema: z44.object({
10830
- items: z44.array(z44.string().min(1)).min(1).max(25).describe("List item titles to create."),
10872
+ inputSchema: z45.object({
10873
+ items: z45.array(z45.string().min(1)).min(1).max(25).describe("List item titles to create."),
10831
10874
  assignee_user_id: slackUserIdParam(
10832
10875
  "Optional Slack user ID assigned to all created items."
10833
10876
  ).optional(),
10834
- due_date: z44.string().regex(/^\d{4}-\d{2}-\d{2}$/).describe("Optional due date in YYYY-MM-DD format.").optional()
10877
+ due_date: z45.string().regex(/^\d{4}-\d{2}-\d{2}$/).describe("Optional due date in YYYY-MM-DD format.").optional()
10835
10878
  }),
10836
10879
  outputSchema: juniorToolOutputSchema,
10837
10880
  execute: async ({ items, assignee_user_id, due_date }) => {
@@ -10879,7 +10922,7 @@ function createSlackListAddItemsTool(state) {
10879
10922
  }
10880
10923
 
10881
10924
  // src/chat/slack/tools/list/create.ts
10882
- import { z as z45 } from "zod";
10925
+ import { z as z46 } from "zod";
10883
10926
  function createSlackListCreateTool(state) {
10884
10927
  return zodTool({
10885
10928
  annotations: {
@@ -10889,8 +10932,8 @@ function createSlackListCreateTool(state) {
10889
10932
  readOnlyHint: false
10890
10933
  },
10891
10934
  description: "Create a Slack todo list for action tracking. Use when the user needs structured tasks with ownership/completion tracking. Do not use for one-off notes without task management needs.",
10892
- inputSchema: z45.object({
10893
- name: z45.string().min(1).max(160).describe("Name for the new Slack list.")
10935
+ inputSchema: z46.object({
10936
+ name: z46.string().min(1).max(160).describe("Name for the new Slack list.")
10894
10937
  }),
10895
10938
  outputSchema: juniorToolOutputSchema,
10896
10939
  execute: async ({ name }) => {
@@ -10920,7 +10963,7 @@ function createSlackListCreateTool(state) {
10920
10963
  }
10921
10964
 
10922
10965
  // src/chat/slack/tools/list/get-items.ts
10923
- import { z as z46 } from "zod";
10966
+ import { z as z47 } from "zod";
10924
10967
  function createSlackListGetItemsTool(state) {
10925
10968
  return zodTool({
10926
10969
  description: "Read items from the active Slack list tracked in artifact context. Use when the user asks for task status, open items, or list contents. Do not use when list state is already known from the immediately prior result.",
@@ -10930,8 +10973,8 @@ function createSlackListGetItemsTool(state) {
10930
10973
  openWorldHint: true,
10931
10974
  readOnlyHint: true
10932
10975
  },
10933
- inputSchema: z46.object({
10934
- limit: z46.coerce.number().int().min(1).max(200).describe("Maximum number of list items to return.").optional()
10976
+ inputSchema: z47.object({
10977
+ limit: z47.coerce.number().int().min(1).max(200).describe("Maximum number of list items to return.").optional()
10935
10978
  }),
10936
10979
  outputSchema: juniorToolOutputSchema,
10937
10980
  execute: async ({ limit }) => {
@@ -10950,21 +10993,21 @@ function createSlackListGetItemsTool(state) {
10950
10993
  }
10951
10994
 
10952
10995
  // src/chat/slack/tools/list/update-item.ts
10953
- import { z as z47 } from "zod";
10954
- var booleanInput3 = (description) => z47.preprocess(
10996
+ import { z as z48 } from "zod";
10997
+ var booleanInput3 = (description) => z48.preprocess(
10955
10998
  (value) => value === "true" ? true : value === "false" ? false : value,
10956
- z47.boolean()
10999
+ z48.boolean()
10957
11000
  ).describe(description);
10958
- var updateListItemInputSchema = z47.union([
10959
- z47.object({
10960
- item_id: z47.string().min(1).describe("ID of the Slack list item to update."),
11001
+ var updateListItemInputSchema = z48.union([
11002
+ z48.object({
11003
+ item_id: z48.string().min(1).describe("ID of the Slack list item to update."),
10961
11004
  completed: booleanInput3("Optional completion status update."),
10962
- title: z47.string().min(1).describe("Optional new item title.").optional()
11005
+ title: z48.string().min(1).describe("Optional new item title.").optional()
10963
11006
  }),
10964
- z47.object({
10965
- item_id: z47.string().min(1).describe("ID of the Slack list item to update."),
11007
+ z48.object({
11008
+ item_id: z48.string().min(1).describe("ID of the Slack list item to update."),
10966
11009
  completed: booleanInput3("Optional completion status update.").optional(),
10967
- title: z47.string().min(1).describe("Optional new item title.")
11010
+ title: z48.string().min(1).describe("Optional new item title.")
10968
11011
  })
10969
11012
  ]);
10970
11013
  function createSlackListUpdateItemTool(state) {
@@ -11040,7 +11083,7 @@ async function checkSlackChannelReadAccess(args) {
11040
11083
  }
11041
11084
 
11042
11085
  // src/chat/slack/tools/thread-read.ts
11043
- import { z as z48 } from "zod";
11086
+ import { z as z49 } from "zod";
11044
11087
 
11045
11088
  // src/chat/slack/tools/slack-message-url.ts
11046
11089
  var SLACK_HOST_PATTERN = /^[a-z0-9-]+\.slack(?:-gov)?\.com$/;
@@ -11218,8 +11261,8 @@ function createSlackThreadReadTool(context, deps = {}) {
11218
11261
  openWorldHint: true,
11219
11262
  readOnlyHint: true
11220
11263
  },
11221
- inputSchema: z48.object({
11222
- url: z48.string().min(1).describe(
11264
+ inputSchema: z49.object({
11265
+ url: z49.string().min(1).describe(
11223
11266
  "Slack message archive URL, e.g. https://workspace.slack.com/archives/C123/p1700000000123456"
11224
11267
  ).optional(),
11225
11268
  channel_id: slackChannelIdParam(
@@ -11228,8 +11271,8 @@ function createSlackThreadReadTool(context, deps = {}) {
11228
11271
  ts: slackTimestampParam(
11229
11272
  "Slack message timestamp (e.g. 1700000000.123456). May be the thread root or any message in the thread."
11230
11273
  ).optional(),
11231
- limit: z48.coerce.number().int().min(1).max(1e3).describe("Maximum number of thread messages to fetch.").optional(),
11232
- max_pages: z48.coerce.number().int().min(1).max(10).describe("Maximum number of Slack API pages to traverse.").optional()
11274
+ limit: z49.coerce.number().int().min(1).max(1e3).describe("Maximum number of thread messages to fetch.").optional(),
11275
+ max_pages: z49.coerce.number().int().min(1).max(10).describe("Maximum number of Slack API pages to traverse.").optional()
11233
11276
  }),
11234
11277
  outputSchema: juniorToolOutputSchema,
11235
11278
  execute: async ({ url, channel_id, ts, limit, max_pages }) => {
@@ -11457,7 +11500,7 @@ async function searchSlackUsers(options) {
11457
11500
  }
11458
11501
 
11459
11502
  // src/chat/slack/tools/user-lookup.ts
11460
- import { z as z49 } from "zod";
11503
+ import { z as z50 } from "zod";
11461
11504
  function explicitUserLookupError(error) {
11462
11505
  if (error.apiError === "user_not_found") {
11463
11506
  return "No Slack user found for the supplied user ID.";
@@ -11485,11 +11528,11 @@ function createSlackUserLookupTool() {
11485
11528
  openWorldHint: true,
11486
11529
  readOnlyHint: true
11487
11530
  },
11488
- inputSchema: z49.object({
11489
- mode: z49.enum(["user_id", "email", "query"]).describe(
11531
+ inputSchema: z50.object({
11532
+ mode: z50.enum(["user_id", "email", "query"]).describe(
11490
11533
  "Lookup method: user_id for Slack IDs, email for email addresses, or query for name searches."
11491
11534
  ),
11492
- value: z49.string().trim().min(2).describe(
11535
+ value: z50.string().trim().min(2).describe(
11493
11536
  "The Slack user ID, email address, or name to look up, interpreted according to mode."
11494
11537
  )
11495
11538
  }).strict(),
@@ -11547,18 +11590,18 @@ function createSlackUserLookupTool() {
11547
11590
  }
11548
11591
 
11549
11592
  // src/chat/tools/system-time.ts
11550
- import { z as z50 } from "zod";
11551
- var systemTimeInputSchema = z50.object({
11552
- timezone: z50.string().trim().min(1).optional().describe(
11593
+ import { z as z51 } from "zod";
11594
+ var systemTimeInputSchema = z51.object({
11595
+ timezone: z51.string().trim().min(1).optional().describe(
11553
11596
  "Optional IANA timezone, for example America/Los_Angeles. When set, iso_local and timezone_offset_minutes are for that zone."
11554
11597
  )
11555
11598
  });
11556
11599
  var systemTimeOutputSchema = juniorToolOutputSchema.extend({
11557
- unix_ms: z50.number(),
11558
- iso_utc: z50.string(),
11559
- iso_local: z50.string(),
11560
- timezone: z50.string().nullable(),
11561
- timezone_offset_minutes: z50.number()
11600
+ unix_ms: z51.number(),
11601
+ iso_utc: z51.string(),
11602
+ iso_local: z51.string(),
11603
+ timezone: z51.string().nullable(),
11604
+ timezone_offset_minutes: z51.number()
11562
11605
  });
11563
11606
  function createSystemTimeTool() {
11564
11607
  return zodTool({
@@ -11638,7 +11681,7 @@ function getTimeZoneOffsetMinutes(timestampMs, timezone) {
11638
11681
  }
11639
11682
 
11640
11683
  // src/chat/tools/query-conversation-events.ts
11641
- import { z as z51 } from "zod";
11684
+ import { z as z52 } from "zod";
11642
11685
  var DEFAULT_LIMIT3 = 25;
11643
11686
  var MAX_LIMIT = 100;
11644
11687
  var MAX_EVENT_DATA_BYTES = 4e3;
@@ -11649,28 +11692,28 @@ var CONVERSATION_EVENTS_TOOL_SOURCE = {
11649
11692
  id: "conversation-events",
11650
11693
  description: "Inspect Junior's durable conversation event log for debugging runtime behavior."
11651
11694
  };
11652
- var knownEventTypeSchema = z51.enum(KNOWN_CONVERSATION_EVENT_TYPES);
11653
- var projectedEventSchema = z51.object({
11654
- seq: z51.number().int().nonnegative().describe("Stable event position; use it for pagination bounds."),
11655
- history_version: z51.number().int().nonnegative().describe(
11695
+ var knownEventTypeSchema = z52.enum(KNOWN_CONVERSATION_EVENT_TYPES);
11696
+ var projectedEventSchema = z52.object({
11697
+ seq: z52.number().int().nonnegative().describe("Stable event position; use it for pagination bounds."),
11698
+ history_version: z52.number().int().nonnegative().describe(
11656
11699
  "Model-history generation. It increments when handoff or compaction replaces active model context."
11657
11700
  ),
11658
- created_at: z51.iso.datetime().describe("When the event was recorded."),
11659
- idempotency_key: z51.string().min(1).optional().describe("Retry-stable event identity, when one was assigned."),
11660
- data: z51.record(z51.string(), z51.unknown()).describe(
11701
+ created_at: z52.iso.datetime().describe("When the event was recorded."),
11702
+ idempotency_key: z52.string().min(1).optional().describe("Retry-stable event identity, when one was assigned."),
11703
+ data: z52.record(z52.string(), z52.unknown()).describe(
11661
11704
  "Event data. Oversized payloads are replaced by identifying fields, payload_omitted, and payload_json_bytes."
11662
11705
  )
11663
11706
  }).strict();
11664
11707
  var queryConversationEventsOutputSchema = juniorToolOutputSchema.extend({
11665
- conversation_id: z51.string().min(1),
11666
- events: z51.array(projectedEventSchema),
11667
- has_older: z51.boolean().describe(
11708
+ conversation_id: z52.string().min(1),
11709
+ events: z52.array(projectedEventSchema),
11710
+ has_older: z52.boolean().describe(
11668
11711
  "Whether matching events exist before this page; request them with before_seq set to the first returned seq."
11669
11712
  ),
11670
- has_newer: z51.boolean().describe(
11713
+ has_newer: z52.boolean().describe(
11671
11714
  "Whether matching events exist after this page; request them with after_seq set to the last returned seq."
11672
11715
  ),
11673
- omitted_event_count: z51.number().int().nonnegative().optional().describe(
11716
+ omitted_event_count: z52.number().int().nonnegative().optional().describe(
11674
11717
  "Fetched events omitted to keep this response bounded. Continue with the pagination cursor for the omitted direction."
11675
11718
  )
11676
11719
  });
@@ -11685,20 +11728,20 @@ function createQueryConversationEventsTool(context) {
11685
11728
  openWorldHint: false,
11686
11729
  readOnlyHint: true
11687
11730
  },
11688
- inputSchema: z51.object({
11689
- conversation_id: z51.string().trim().min(1).describe(
11731
+ inputSchema: z52.object({
11732
+ conversation_id: z52.string().trim().min(1).describe(
11690
11733
  "Conversation ID to inspect, such as slack:{channelId}:{threadTs} or a child conversation id."
11691
11734
  ),
11692
- after_seq: z51.number().int().nonnegative().nullable().describe(
11735
+ after_seq: z52.number().int().nonnegative().nullable().describe(
11693
11736
  "Exclusive lower bound on event seq. When set, returns the next newer page in ascending order."
11694
11737
  ).optional(),
11695
- before_seq: z51.number().int().nonnegative().nullable().describe(
11738
+ before_seq: z52.number().int().nonnegative().nullable().describe(
11696
11739
  "Exclusive upper bound on event seq. Combine with defaults or after_seq to page older or bounded ranges."
11697
11740
  ).optional(),
11698
- limit: z51.number().int().min(1).max(MAX_LIMIT).nullable().describe(
11741
+ limit: z52.number().int().min(1).max(MAX_LIMIT).nullable().describe(
11699
11742
  `Maximum events to return. Defaults to ${DEFAULT_LIMIT3}; max ${MAX_LIMIT}.`
11700
11743
  ).optional(),
11701
- types: z51.array(knownEventTypeSchema).min(1).nullable().describe(
11744
+ types: z52.array(knownEventTypeSchema).min(1).nullable().describe(
11702
11745
  "Optional event-type filter. Omit to return every durable event type."
11703
11746
  ).optional()
11704
11747
  }).strict(),
@@ -11946,10 +11989,10 @@ function stripReplacementHistoryField(value) {
11946
11989
  }
11947
11990
 
11948
11991
  // src/chat/tools/handoff/tool.ts
11949
- import { z as z52 } from "zod";
11992
+ import { z as z53 } from "zod";
11950
11993
  var HANDOFF_TOOL_NAME = "handoff";
11951
11994
  function createHandoffTool(handoff) {
11952
- const profileSchema = z52.enum(handoff.profiles);
11995
+ const profileSchema = z53.enum(handoff.profiles);
11953
11996
  const handoffResultSchema = juniorToolOutputSchema.extend({
11954
11997
  model_profile: modelProfileSchema
11955
11998
  });
@@ -11963,7 +12006,7 @@ function createHandoffTool(handoff) {
11963
12006
  },
11964
12007
  description: `Switch to another execution profile and continue the same task. Profiles: ${profileNames}. Call this as the only tool.`,
11965
12008
  executionMode: "sequential",
11966
- inputSchema: z52.object({
12009
+ inputSchema: z53.object({
11967
12010
  profile: profileSchema.describe("Target execution profile")
11968
12011
  }).strict(),
11969
12012
  outputSchema: handoffResultSchema,
@@ -11984,7 +12027,7 @@ function createHandoffTool(handoff) {
11984
12027
  }
11985
12028
 
11986
12029
  // src/chat/tools/web/fetch-tool.ts
11987
- import { z as z53 } from "zod";
12030
+ import { z as z54 } from "zod";
11988
12031
 
11989
12032
  // src/chat/tools/web/constants.ts
11990
12033
  var USER_AGENT = "junior-bot/0.1";
@@ -12427,9 +12470,9 @@ function createWebFetchTool(hooks, options = {}) {
12427
12470
  openWorldHint: true,
12428
12471
  readOnlyHint: true
12429
12472
  },
12430
- inputSchema: z53.object({
12431
- url: z53.string().min(1).describe("HTTP(S) URL to fetch."),
12432
- max_chars: z53.coerce.number().int().min(500).max(MAX_FETCH_CHARS).describe("Optional maximum number of extracted characters to return.").optional()
12473
+ inputSchema: z54.object({
12474
+ url: z54.string().min(1).describe("HTTP(S) URL to fetch."),
12475
+ max_chars: z54.coerce.number().int().min(500).max(MAX_FETCH_CHARS).describe("Optional maximum number of extracted characters to return.").optional()
12433
12476
  }),
12434
12477
  outputSchema: juniorToolOutputSchema,
12435
12478
  execute: async ({ url, max_chars }) => {
@@ -12474,7 +12517,7 @@ function createWebFetchTool(hooks, options = {}) {
12474
12517
  }
12475
12518
 
12476
12519
  // src/chat/tools/web/search.ts
12477
- import { z as z54 } from "zod";
12520
+ import { z as z55 } from "zod";
12478
12521
  import { generateText } from "ai";
12479
12522
  import { createGatewayProvider } from "@ai-sdk/gateway";
12480
12523
  var SEARCH_TIMEOUT_MS = 6e4;
@@ -12516,9 +12559,9 @@ function createWebSearchTool(modelId, override) {
12516
12559
  openWorldHint: true,
12517
12560
  readOnlyHint: true
12518
12561
  },
12519
- inputSchema: z54.object({
12520
- query: z54.string().min(1).max(500).describe("Search query."),
12521
- max_results: z54.coerce.number().int().min(1).max(MAX_RESULTS2).describe("Max results to return.").optional()
12562
+ inputSchema: z55.object({
12563
+ query: z55.string().min(1).max(500).describe("Search query."),
12564
+ max_results: z55.coerce.number().int().min(1).max(MAX_RESULTS2).describe("Max results to return.").optional()
12522
12565
  }),
12523
12566
  outputSchema: juniorToolOutputSchema,
12524
12567
  execute: async ({ query, max_results }) => {
@@ -12560,7 +12603,7 @@ function createWebSearchTool(modelId, override) {
12560
12603
  }
12561
12604
 
12562
12605
  // src/chat/tools/sandbox/write-file.ts
12563
- import { z as z55 } from "zod";
12606
+ import { z as z56 } from "zod";
12564
12607
  function createWriteFileTool() {
12565
12608
  return zodTool({
12566
12609
  annotations: {
@@ -12571,9 +12614,9 @@ function createWriteFileTool() {
12571
12614
  },
12572
12615
  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.",
12573
12616
  executionMode: "sequential",
12574
- inputSchema: z55.object({
12575
- path: z55.string().min(1).describe("Path to write in the sandbox workspace."),
12576
- content: z55.string().describe("UTF-8 file content to write.")
12617
+ inputSchema: z56.object({
12618
+ path: z56.string().min(1).describe("Path to write in the sandbox workspace."),
12619
+ content: z56.string().describe("UTF-8 file content to write.")
12577
12620
  }),
12578
12621
  outputSchema: juniorToolOutputSchema,
12579
12622
  execute: async () => {
@@ -12672,6 +12715,9 @@ function createTools(availableSkills, hooks = {}, context, options = {}) {
12672
12715
  if (context.handoff) {
12673
12716
  tools.handoff = createHandoffTool(context.handoff);
12674
12717
  }
12718
+ if (context.spawnAgent) {
12719
+ tools.spawnAgent = createSpawnAgentTool(context.spawnAgent);
12720
+ }
12675
12721
  if (context.mcpToolManager) {
12676
12722
  tools.searchMcpTools = createSearchMcpToolsTool(context.mcpToolManager);
12677
12723
  tools.callMcpTool = createCallMcpToolTool(context.mcpToolManager);
@@ -12905,167 +12951,6 @@ function buildSandboxInput(toolName, params) {
12905
12951
  // src/chat/tools/execution/tool-error-handler.ts
12906
12952
  import { PluginToolInputError } from "@sentry/junior-plugin-api";
12907
12953
 
12908
- // src/chat/services/plugin-auth-orchestration.ts
12909
- var PluginAuthorizationPauseError = class extends AuthorizationPauseError {
12910
- constructor(provider, providerDisplayName, disposition, requestText) {
12911
- super("plugin", provider, providerDisplayName, disposition, requestText);
12912
- }
12913
- };
12914
- var PluginCredentialFailureError = class extends Error {
12915
- provider;
12916
- constructor(provider, message) {
12917
- super(message);
12918
- this.name = "PluginCredentialFailureError";
12919
- this.provider = provider;
12920
- }
12921
- };
12922
- function pluginAuthRequiredSignal(details) {
12923
- if (!details || typeof details !== "object") {
12924
- return void 0;
12925
- }
12926
- const signal = details.auth_required;
12927
- const parsedSignal = parseSandboxEgressAuthRequiredSignal(signal);
12928
- if (!parsedSignal) {
12929
- return void 0;
12930
- }
12931
- return {
12932
- provider: parsedSignal.provider,
12933
- grant: parsedSignal.grant,
12934
- kind: parsedSignal.kind,
12935
- ...parsedSignal.message ? { message: parsedSignal.message } : {},
12936
- ...parsedSignal.authorization ? { authorization: parsedSignal.authorization } : {}
12937
- };
12938
- }
12939
- function createPluginAuthOrchestration(input) {
12940
- let pendingPause;
12941
- const startAuthorizationPause = async (provider, options) => {
12942
- if (pendingPause) {
12943
- throw pendingPause;
12944
- }
12945
- if (!input.actorId || !pluginCatalogRuntime.getOAuthConfig(provider)) {
12946
- throw new Error(`Cannot start plugin authorization for ${provider}`);
12947
- }
12948
- if (input.authorizationFlowMode === "disabled") {
12949
- throw new AuthorizationFlowDisabledError("plugin", provider);
12950
- }
12951
- const recordPendingAuth = input.sessionId ? input.recordPendingAuth : void 0;
12952
- if (input.sessionId && !recordPendingAuth) {
12953
- throw new Error(
12954
- `Missing pending auth recorder for plugin authorization pause "${provider}"`
12955
- );
12956
- }
12957
- const providerLabel = formatProviderLabel(provider);
12958
- const reusingPendingLink = input.sessionId ? canReusePendingAuthLink({
12959
- pendingAuth: input.pendingAuth,
12960
- kind: "plugin",
12961
- provider,
12962
- actorId: input.actorId,
12963
- sessionId: input.sessionId,
12964
- ...options?.scope ? { scope: options.scope } : {}
12965
- }) : false;
12966
- if (!reusingPendingLink) {
12967
- const oauthResult = await startOAuthFlow(provider, {
12968
- actorId: input.actorId,
12969
- channelId: input.channelId,
12970
- destination: input.destination,
12971
- source: input.source,
12972
- threadTs: input.threadTs,
12973
- ...options?.scope ? { scope: options.scope } : {},
12974
- resumeConversationId: input.conversationId,
12975
- resumeSessionId: input.sessionId,
12976
- authorization: input.authorization
12977
- });
12978
- if (!oauthResult.ok) {
12979
- throw new Error(oauthResult.error);
12980
- }
12981
- if (!oauthResult.delivery) {
12982
- throw new Error(
12983
- `I need to connect your ${providerLabel} account first, but I wasn't able to send you a private authorization link. Please send me a direct message and try again.`
12984
- );
12985
- }
12986
- }
12987
- if (input.sessionId && recordPendingAuth) {
12988
- const nextPendingAuth = {
12989
- kind: "plugin",
12990
- provider,
12991
- actorId: input.actorId,
12992
- ...options?.scope ? { scope: options.scope } : {},
12993
- sessionId: input.sessionId,
12994
- linkSentAtMs: reusingPendingLink ? input.pendingAuth.linkSentAtMs : Date.now()
12995
- };
12996
- await recordPendingAuth(nextPendingAuth);
12997
- await abandonReplacedPendingAuth({
12998
- conversationId: input.conversationId,
12999
- previousPendingAuth: input.pendingAuth,
13000
- nextPendingAuth
13001
- });
13002
- }
13003
- if (input.conversationId && input.sessionId) {
13004
- await recordAuthorizationRequested({
13005
- conversationId: input.conversationId,
13006
- kind: "plugin",
13007
- provider,
13008
- actorId: input.actorId,
13009
- authorizationId: authorizationId({
13010
- kind: "plugin",
13011
- provider,
13012
- sessionId: input.sessionId
13013
- }),
13014
- delivery: reusingPendingLink ? "private_link_reused" : "private_link_sent"
13015
- });
13016
- }
13017
- pendingPause = new PluginAuthorizationPauseError(
13018
- provider,
13019
- providerLabel,
13020
- reusingPendingLink ? "link_already_sent" : "link_sent",
13021
- input.userMessage
13022
- );
13023
- input.abortAgent();
13024
- throw pendingPause;
13025
- };
13026
- return {
13027
- maybeHandleAuthSignal: async (details) => {
13028
- const signal = pluginAuthRequiredSignal(details);
13029
- if (!signal) {
13030
- return;
13031
- }
13032
- const { provider, authorization } = signal;
13033
- if (signal.kind === "unavailable") {
13034
- throw new PluginCredentialFailureError(
13035
- provider,
13036
- signal.message ?? `${formatProviderLabel(provider)} credentials are unavailable.`
13037
- );
13038
- }
13039
- if (!authorization) {
13040
- throw new PluginCredentialFailureError(
13041
- provider,
13042
- signal.message ?? `${formatProviderLabel(provider)} credentials are required but no OAuth flow is available for this provider.`
13043
- );
13044
- }
13045
- if (!input.actorId || !input.userTokenStore) {
13046
- if (input.authorizationFlowMode === "disabled") {
13047
- throw new AuthorizationFlowDisabledError("plugin", provider);
13048
- }
13049
- throw new PluginCredentialFailureError(
13050
- provider,
13051
- signal.message ?? `${formatProviderLabel(provider)} credentials are required. Please connect your ${formatProviderLabel(provider)} account and try again.`
13052
- );
13053
- }
13054
- if (!pluginCatalogRuntime.getOAuthConfig(authorization.provider)) {
13055
- throw new PluginCredentialFailureError(
13056
- provider,
13057
- signal.message ?? `${formatProviderLabel(provider)} credentials are required but the provider is not configured for OAuth.`
13058
- );
13059
- }
13060
- await startAuthorizationPause(
13061
- authorization.provider,
13062
- authorization.scope ? { scope: authorization.scope } : void 0
13063
- );
13064
- },
13065
- getPendingPause: () => pendingPause
13066
- };
13067
- }
13068
-
13069
12954
  // src/chat/tool-support/action-review.ts
13070
12955
  var ACTION_CONFIRMATION_INSTRUCTIONS = [
13071
12956
  "The action was not executed because explicit user confirmation is required.",
@@ -13441,7 +13326,7 @@ function handleToolExecutionError(error, toolName, toolCallId, shouldTrace, conv
13441
13326
  }
13442
13327
 
13443
13328
  // src/chat/tools/execute-tool.ts
13444
- import { z as z56 } from "zod";
13329
+ import { z as z57 } from "zod";
13445
13330
  var EXECUTE_TOOL_NAME = "executeTool";
13446
13331
  function createExecuteToolTool() {
13447
13332
  return zodTool({
@@ -13453,11 +13338,11 @@ function createExecuteToolTool() {
13453
13338
  },
13454
13339
  description: "Execute any catalog tool by exact tool_name from searchTools or a tool-result execution hint. Put tool-specific parameters inside arguments.",
13455
13340
  executionMode: "sequential",
13456
- inputSchema: z56.object({
13457
- tool_name: z56.string().min(1).describe(
13341
+ inputSchema: z57.object({
13342
+ tool_name: z57.string().min(1).describe(
13458
13343
  "Exact catalog tool_name returned by searchTools or a tool-result execution hint."
13459
13344
  ),
13460
- arguments: z56.record(z56.string(), z56.unknown()).describe(
13345
+ arguments: z57.record(z57.string(), z57.unknown()).describe(
13461
13346
  'Arguments matching the selected catalog tool schema, for example { "query": "..." }.'
13462
13347
  ).optional()
13463
13348
  }).strict(),
@@ -13497,34 +13382,34 @@ function planToolExposure(tools) {
13497
13382
  }
13498
13383
 
13499
13384
  // src/chat/tools/search-tools.ts
13500
- import { z as z57 } from "zod";
13385
+ import { z as z58 } from "zod";
13501
13386
  var SEARCH_TOOLS_NAME = "searchTools";
13502
13387
  var DEFAULT_MAX_RESULTS2 = 5;
13503
13388
  var MAX_RESULTS3 = 20;
13504
13389
  var MODEL_VISIBLE_DESCRIPTION_CAP = 180;
13505
- var searchToolsSourceSchema = z57.object({
13506
- id: z57.string(),
13507
- description: z57.string()
13390
+ var searchToolsSourceSchema = z58.object({
13391
+ id: z58.string(),
13392
+ description: z58.string()
13508
13393
  }).strict();
13509
- var searchToolsToolSchema = z57.object({
13510
- tool_name: z57.string(),
13511
- description: z57.string(),
13512
- exposure: z57.enum(["direct", "deferred", "modelOnly", "hidden"]),
13513
- source: z57.string().optional(),
13514
- input_schema: z57.unknown(),
13515
- call_notes: z57.array(z57.string()),
13516
- annotations: z57.record(z57.string(), z57.unknown())
13394
+ var searchToolsToolSchema = z58.object({
13395
+ tool_name: z58.string(),
13396
+ description: z58.string(),
13397
+ exposure: z58.enum(["direct", "deferred", "modelOnly", "hidden"]),
13398
+ source: z58.string().optional(),
13399
+ input_schema: z58.unknown(),
13400
+ call_notes: z58.array(z58.string()),
13401
+ annotations: z58.record(z58.string(), z58.unknown())
13517
13402
  }).strict();
13518
13403
  var searchToolsOutputSchema = juniorToolOutputSchema.extend({
13519
- query: z57.string().nullable(),
13520
- source: z57.string().nullable(),
13521
- sources: z57.array(searchToolsSourceSchema),
13522
- total_catalog_tools: z57.number().int().nonnegative(),
13523
- total_eligible_tools: z57.number().int().nonnegative(),
13524
- total_matches: z57.number().int().nonnegative(),
13525
- returned_tools: z57.number().int().nonnegative(),
13526
- execution_tool: z57.literal("executeTool"),
13527
- tools: z57.array(searchToolsToolSchema)
13404
+ query: z58.string().nullable(),
13405
+ source: z58.string().nullable(),
13406
+ sources: z58.array(searchToolsSourceSchema),
13407
+ total_catalog_tools: z58.number().int().nonnegative(),
13408
+ total_eligible_tools: z58.number().int().nonnegative(),
13409
+ total_matches: z58.number().int().nonnegative(),
13410
+ returned_tools: z58.number().int().nonnegative(),
13411
+ execution_tool: z58.literal("executeTool"),
13412
+ tools: z58.array(searchToolsToolSchema)
13528
13413
  }).strict();
13529
13414
  function normalize2(value) {
13530
13415
  return value.toLowerCase().replace(/[^a-z0-9_]+/g, " ").trim();
@@ -13639,14 +13524,14 @@ function createSearchToolsTool(catalogTools) {
13639
13524
  openWorldHint: false,
13640
13525
  readOnlyHint: true
13641
13526
  },
13642
- inputSchema: z57.object({
13643
- query: z57.string().nullable().describe(
13527
+ inputSchema: z58.object({
13528
+ query: z58.string().nullable().describe(
13644
13529
  "Optional search terms describing the tool, owner, action, or arguments needed. Empty string lists catalog tools."
13645
13530
  ).optional(),
13646
- source: z57.string().nullable().describe(
13531
+ source: z58.string().nullable().describe(
13647
13532
  "Optional source id to search within, such as a plugin source returned in sources."
13648
13533
  ).optional(),
13649
- max_results: z57.number().int().min(1).max(MAX_RESULTS3).nullable().describe("Maximum matching catalog tool descriptors to return.").optional()
13534
+ max_results: z58.number().int().min(1).max(MAX_RESULTS3).nullable().describe("Maximum matching catalog tool descriptors to return.").optional()
13650
13535
  }).strict(),
13651
13536
  outputSchema: searchToolsOutputSchema,
13652
13537
  privateTraceResult: (result) => ({
@@ -13961,7 +13846,7 @@ function createMcpAuthOrchestration(input) {
13961
13846
  if (!input.conversationId || !input.sessionId || !input.actorId) {
13962
13847
  return void 0;
13963
13848
  }
13964
- if (!input.recordPendingAuth && input.authorizationFlowMode !== "disabled") {
13849
+ if (!input.recordPendingAuth && input.interactiveAuthEnabled !== false) {
13965
13850
  throw new Error(
13966
13851
  `Missing pending auth recorder for MCP authorization pause "${plugin.manifest.name}"`
13967
13852
  );
@@ -13997,7 +13882,7 @@ function createMcpAuthOrchestration(input) {
13997
13882
  `Missing MCP auth session context for plugin "${provider}"`
13998
13883
  );
13999
13884
  }
14000
- if (input.authorizationFlowMode === "disabled") {
13885
+ if (input.interactiveAuthEnabled === false) {
14001
13886
  await deleteMcpAuthSession(authSessionId);
14002
13887
  throw new AuthorizationFlowDisabledError("mcp", provider);
14003
13888
  }
@@ -14891,7 +14776,7 @@ function createPluginEgress(deps) {
14891
14776
  }
14892
14777
 
14893
14778
  // src/chat/services/guardian-action-review.ts
14894
- import { z as z58 } from "zod";
14779
+ import { z as z59 } from "zod";
14895
14780
 
14896
14781
  // src/chat/services/guardian-action-policy.ts
14897
14782
  var GUARDIAN_ACTION_POLICY = `You are judging one planned Junior agent action.
@@ -14957,17 +14842,17 @@ Assess the exact action's intrinsic risk and whether the user's intent authorize
14957
14842
  - 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.`;
14958
14843
 
14959
14844
  // src/chat/services/guardian-action-review.ts
14960
- var guardianDecisionSchema = z58.object({
14961
- decision: z58.enum(["allow", "ask", "deny"]),
14962
- reason: z58.string().trim().min(1).max(500),
14963
- riskLevel: z58.enum(["low", "medium", "high", "critical"]),
14964
- userAuthorization: z58.enum(["high", "medium", "low", "unknown"])
14845
+ var guardianDecisionSchema = z59.object({
14846
+ decision: z59.enum(["allow", "ask", "deny"]),
14847
+ reason: z59.string().trim().min(1).max(500),
14848
+ riskLevel: z59.enum(["low", "medium", "high", "critical"]),
14849
+ userAuthorization: z59.enum(["high", "medium", "low", "unknown"])
14965
14850
  }).strict();
14966
14851
  var GUARDIAN_REVIEW_TIMEOUT_MS = 6e4;
14967
14852
  var GUARDIAN_REVIEW_MAX_TOKENS = 2e3;
14968
14853
  var MAX_PROPOSAL_CHARS = 192e3;
14969
14854
  function guardianPrompt(proposal) {
14970
- const proposalJson = JSON.stringify(z58.json().parse(proposal), null, 2);
14855
+ const proposalJson = JSON.stringify(z59.json().parse(proposal), null, 2);
14971
14856
  if (proposalJson.length > MAX_PROPOSAL_CHARS) {
14972
14857
  throw new Error(
14973
14858
  `Guardian action proposal exceeds ${MAX_PROPOSAL_CHARS} characters.`
@@ -15255,7 +15140,10 @@ async function wireAgentTools(args) {
15255
15140
  args.artifactStatePatch
15256
15141
  ),
15257
15142
  recordPendingAuth: args.durability.recordPendingAuth,
15258
- authorizationFlowMode: args.policy.authorizationFlowMode,
15143
+ interactiveAuthEnabled: !isAgentRunFeatureDisabled(
15144
+ args.policy,
15145
+ "interactive-auth"
15146
+ ),
15259
15147
  authorization: args.authorization
15260
15148
  });
15261
15149
  const pluginAuth = createPluginAuthOrchestration({
@@ -15270,7 +15158,10 @@ async function wireAgentTools(args) {
15270
15158
  userMessage: args.userInput,
15271
15159
  pendingAuth: args.state.pendingAuth,
15272
15160
  recordPendingAuth: args.durability.recordPendingAuth,
15273
- authorizationFlowMode: args.policy.authorizationFlowMode,
15161
+ interactiveAuthEnabled: !isAgentRunFeatureDisabled(
15162
+ args.policy,
15163
+ "interactive-auth"
15164
+ ),
15274
15165
  userTokenStore,
15275
15166
  authorization: args.authorization
15276
15167
  });
@@ -15323,6 +15214,7 @@ async function wireAgentTools(args) {
15323
15214
  ...args.currentActor ? {
15324
15215
  resolveActorIdentity: async () => await readActorIdentity(args.currentActor)
15325
15216
  } : {},
15217
+ ...args.durability.spawnAgent ? { spawnAgent: args.durability.spawnAgent } : {},
15326
15218
  ...args.requestHandoff ? { handoff: args.requestHandoff } : {}
15327
15219
  };
15328
15220
  const toolDestination = toolInvocationDestination(args.routing);
@@ -16504,9 +16396,10 @@ async function executeAgentRunInPrivacyContext(request, conversationPrivacy, run
16504
16396
  const explicitSkill = invokedSkill ? activeSkills.find((skill) => skill.name === invokedSkill.name) ?? null : null;
16505
16397
  const { contextContentParts, routerBlocks, userContentParts } = buildPromptInput(input);
16506
16398
  const preAgentPromptMessages = () => existingSessionRecord?.piMessages ?? [...input.piMessages ?? []];
16399
+ const handoffEnabled = !isAgentRunFeatureDisabled(policy, "handoff");
16507
16400
  const storedTurnRoute = await loadTurnRoute({ conversationId, turnId });
16508
16401
  if (storedTurnRoute) {
16509
- const resumedAfterHandoff = activeModelProfile !== STANDARD_MODEL_PROFILE && activeModelProfile !== storedTurnRoute.modelProfile;
16402
+ const resumedAfterHandoff = handoffEnabled && activeModelProfile !== STANDARD_MODEL_PROFILE && activeModelProfile !== storedTurnRoute.modelProfile;
16510
16403
  if (resumedAfterHandoff) {
16511
16404
  const activeProfileConfig = profileConfig(
16512
16405
  botConfig,
@@ -16527,7 +16420,7 @@ async function executeAgentRunInPrivacyContext(request, conversationPrivacy, run
16527
16420
  source: storedTurnRoute.source
16528
16421
  };
16529
16422
  }
16530
- } else if (activeModelProfile === STANDARD_MODEL_PROFILE) {
16423
+ } else if (activeModelProfile === STANDARD_MODEL_PROFILE && handoffEnabled) {
16531
16424
  turnRoute = await selectTurnRoute({
16532
16425
  completeObject,
16533
16426
  conversationContext: input.conversationContext,
@@ -16553,6 +16446,15 @@ async function executeAgentRunInPrivacyContext(request, conversationPrivacy, run
16553
16446
  reason: `configured:${policy.reasoningLevel ? "agent_config" : "default"}:${turnRoute.reason}`
16554
16447
  };
16555
16448
  }
16449
+ } else if (!handoffEnabled) {
16450
+ const activeProfileConfig = profileConfig(botConfig, activeModelProfile);
16451
+ const reasoningSource = policy.reasoningLevel ? "agent_config" : activeProfileConfig.reasoningLevel ? "profile" : "default";
16452
+ turnRoute = {
16453
+ profile: activeModelProfile,
16454
+ reasoningLevel: policy.reasoningLevel ?? activeProfileConfig.reasoningLevel ?? botConfig.reasoningLevel ?? "medium",
16455
+ reason: `fixed:${reasoningSource}`,
16456
+ source: "configured"
16457
+ };
16556
16458
  } else {
16557
16459
  const activeProfileConfig = profileConfig(botConfig, activeModelProfile);
16558
16460
  const reasoningSource = activeProfileConfig.reasoningLevel ? "profile" : policy.reasoningLevel ? "agent_config" : "default";
@@ -16672,7 +16574,7 @@ async function executeAgentRunInPrivacyContext(request, conversationPrivacy, run
16672
16574
  })
16673
16575
  } : void 0;
16674
16576
  };
16675
- const requestHandoff = handoffControlFor(activeModelProfile);
16577
+ const requestHandoff = handoffEnabled ? handoffControlFor(activeModelProfile) : void 0;
16676
16578
  setTags({
16677
16579
  ...runLogContext,
16678
16580
  modelId: activeModelId
@@ -16731,7 +16633,7 @@ async function executeAgentRunInPrivacyContext(request, conversationPrivacy, run
16731
16633
  (tool) => tool.name === HANDOFF_TOOL_NAME
16732
16634
  );
16733
16635
  const toolsForActiveProfile = () => {
16734
- const handoff = handoffControlFor(activeModelProfile);
16636
+ const handoff = handoffEnabled ? handoffControlFor(activeModelProfile) : void 0;
16735
16637
  if (!handoff) {
16736
16638
  return toolsWithoutHandoff;
16737
16639
  }
@@ -17436,17 +17338,28 @@ async function executeAgentRunInPrivacyContext(request, conversationPrivacy, run
17436
17338
  // src/chat/runtime/agent-runner.ts
17437
17339
  function createAgentRunner(run, options) {
17438
17340
  const tracePropagation = options?.tracePropagation;
17439
- if (!tracePropagation) {
17341
+ const bindSpawnAgent = options?.bindSpawnAgent;
17342
+ const canBindSpawn = Boolean(bindSpawnAgent) && isExperimentalFeatureEnabled("subagents");
17343
+ if (!tracePropagation && !canBindSpawn) {
17440
17344
  return { run };
17441
17345
  }
17442
17346
  return {
17443
- run: async (request) => await run({
17444
- ...request,
17445
- policy: {
17446
- ...request.policy,
17447
- sandboxTracePropagation: request.policy?.sandboxTracePropagation ?? tracePropagation
17448
- }
17449
- })
17347
+ run: async (request) => {
17348
+ const spawnAgent = bindSpawnAgent && canBindSpawn && !isAgentRunFeatureDisabled(request.policy, "subagents") ? bindSpawnAgent(request) : void 0;
17349
+ return await run({
17350
+ ...request,
17351
+ policy: {
17352
+ ...request.policy,
17353
+ sandboxTracePropagation: request.policy?.sandboxTracePropagation ?? tracePropagation
17354
+ },
17355
+ ...spawnAgent ? {
17356
+ durability: {
17357
+ ...request.durability,
17358
+ spawnAgent
17359
+ }
17360
+ } : {}
17361
+ });
17362
+ }
17450
17363
  };
17451
17364
  }
17452
17365
 
@@ -17454,7 +17367,6 @@ export {
17454
17367
  setConfigDefaults,
17455
17368
  getConfigDefaults,
17456
17369
  shouldEmitDevAgentTrace,
17457
- AuthorizationFlowDisabledError,
17458
17370
  resolveDestinationVisibility,
17459
17371
  buildSteeringPiMessage,
17460
17372
  SANDBOX_EGRESS_PROXY_PATH,
@@ -17473,7 +17385,6 @@ export {
17473
17385
  renderSlackLegacyAttachmentText,
17474
17386
  appendSlackLegacyAttachmentText,
17475
17387
  latestReportedProgress,
17476
- PluginCredentialFailureError,
17477
17388
  executeCredentialedEgressRequest,
17478
17389
  createContextCompactor,
17479
17390
  executeAgentRun,