@sentry/junior 0.126.1 → 0.127.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 (57) hide show
  1. package/dist/{agent-hooks-U5YGLX6Y.js → agent-hooks-HMCMFIIO.js} +8 -8
  2. package/dist/api/people/spend.d.ts +4 -0
  3. package/dist/api/people/spend.query.d.ts +3 -0
  4. package/dist/api/schema/person.d.ts +9 -0
  5. package/dist/api/schema.d.ts +2 -2
  6. package/dist/api/schema.js +3 -1
  7. package/dist/api.js +133 -33
  8. package/dist/app.js +29 -29
  9. package/dist/{catalog-runtime-OUPLWD7F.js → catalog-runtime-MI5UNBZ7.js} +5 -5
  10. package/dist/chat/plugins/agent-hooks.d.ts +4 -2
  11. package/dist/chat/resource-events/catalog.d.ts +21 -0
  12. package/dist/chat/resource-events/ingest.d.ts +1 -1
  13. package/dist/chat/resource-events/notification.d.ts +2 -2
  14. package/dist/chat/resource-events/store.d.ts +9 -9
  15. package/dist/chat/resource-events/tool-support.d.ts +10 -0
  16. package/dist/chat/task-execution/slack-work.d.ts +4 -4
  17. package/dist/chat/tools/list-resource-event-subscriptions.d.ts +80 -0
  18. package/dist/chat/tools/resource-events.d.ts +2 -1
  19. package/dist/chat/tools/search-resource-event-types.d.ts +60 -0
  20. package/dist/chat/tools/stop-watching-resources.d.ts +50 -0
  21. package/dist/chat/tools/watch-resource-events.d.ts +105 -0
  22. package/dist/{chunk-QMK2VF6K.js → chunk-2M6LYDTB.js} +1 -1
  23. package/dist/{chunk-JKV244BI.js → chunk-2N6EL22B.js} +1 -1
  24. package/dist/{chunk-OG6E44DH.js → chunk-4H2NZPFJ.js} +6 -6
  25. package/dist/{chunk-7VF3JAVF.js → chunk-6DU2ZNF7.js} +7 -7
  26. package/dist/{chunk-6ZBSTNYN.js → chunk-AFJF3RGU.js} +9 -0
  27. package/dist/{chunk-7ZMY4GCG.js → chunk-AKL3BAYJ.js} +1 -1
  28. package/dist/{chunk-PD6J33TO.js → chunk-AYICPT5T.js} +1 -1
  29. package/dist/{chunk-YUPNY2HZ.js → chunk-C7AVHH3H.js} +2 -2
  30. package/dist/{chunk-HXWOZ4HG.js → chunk-FVIU6NQO.js} +1 -1
  31. package/dist/{chunk-R3GXQJEE.js → chunk-JNYR4G7A.js} +2 -2
  32. package/dist/{chunk-W3JHZHAN.js → chunk-JXQWTNDI.js} +1 -1
  33. package/dist/{chunk-WIIPHGJY.js → chunk-L7L7RYJM.js} +2 -2
  34. package/dist/{chunk-U36WL4OL.js → chunk-NK7QVIMJ.js} +1 -1
  35. package/dist/{chunk-Y2QRKPI7.js → chunk-NYVMPADK.js} +1 -1
  36. package/dist/{chunk-S4LM6UB7.js → chunk-PDG3BSOD.js} +2 -2
  37. package/dist/{chunk-F2ARYRKC.js → chunk-SH7HDO2D.js} +1 -1
  38. package/dist/{chunk-YZHA2L7P.js → chunk-TLMI3Q4Q.js} +35 -12
  39. package/dist/{chunk-GLNB2R42.js → chunk-UEMGGJZD.js} +12 -12
  40. package/dist/{chunk-YFE6VNHU.js → chunk-VHUMNUJL.js} +1 -1
  41. package/dist/{chunk-KBW6J5GA.js → chunk-WXP2ZXC7.js} +4 -4
  42. package/dist/{chunk-QVSYR5CV.js → chunk-YSOZT72W.js} +4 -4
  43. package/dist/{chunk-SD2VFSN6.js → chunk-Z5LLJNTL.js} +669 -390
  44. package/dist/cli/chat.js +23 -23
  45. package/dist/cli/check.js +6 -6
  46. package/dist/cli/plugins.js +11 -11
  47. package/dist/cli/snapshot-create.js +9 -9
  48. package/dist/cli/upgrade.js +6 -6
  49. package/dist/{db-FQID26JW.js → db-N4EY57ZJ.js} +6 -6
  50. package/dist/instrumentation.js +4 -4
  51. package/dist/nitro.js +2 -2
  52. package/dist/{oauth-callback-server-Z5MHHKFD.js → oauth-callback-server-O62UOQSS.js} +16 -16
  53. package/dist/{runner-PGPGKYSF.js → runner-SRHRD3NX.js} +10 -10
  54. package/dist/{skills-BCQHR636.js → skills-V6X3JVVA.js} +6 -6
  55. package/dist/{validation-QP3FYBLZ.js → validation-ZZXZELGH.js} +6 -6
  56. package/dist/version.js +1 -1
  57. package/package.json +6 -6
@@ -30,7 +30,7 @@ import {
30
30
  toMcpProviderError,
31
31
  toolInvocationDestination,
32
32
  uploadFilesToConversation
33
- } from "./chunk-7VF3JAVF.js";
33
+ } from "./chunk-6DU2ZNF7.js";
34
34
  import {
35
35
  CooperativeTurnYieldError,
36
36
  JUNIOR_THREAD_STATE_TTL_MS,
@@ -80,7 +80,7 @@ import {
80
80
  stripRuntimeTurnContext,
81
81
  trimTrailingAssistantMessages,
82
82
  updateConversationStats
83
- } from "./chunk-KBW6J5GA.js";
83
+ } from "./chunk-WXP2ZXC7.js";
84
84
  import {
85
85
  parseSandboxEgressAuthRequiredSignal,
86
86
  parseSandboxEgressPermissionDeniedSignal,
@@ -104,13 +104,13 @@ import {
104
104
  runNonInteractiveCommand,
105
105
  throwSandboxOperationError,
106
106
  wrapSandboxSetupError
107
- } from "./chunk-QVSYR5CV.js";
107
+ } from "./chunk-YSOZT72W.js";
108
108
  import {
109
109
  incrementStat
110
- } from "./chunk-YFE6VNHU.js";
110
+ } from "./chunk-VHUMNUJL.js";
111
111
  import {
112
112
  parseSlackThreadId
113
- } from "./chunk-QMK2VF6K.js";
113
+ } from "./chunk-2M6LYDTB.js";
114
114
  import {
115
115
  addAgentTurnUsage,
116
116
  hasAgentTurnUsage
@@ -126,13 +126,14 @@ import {
126
126
  getPluginSystemPromptContributions,
127
127
  getPluginTools,
128
128
  getPluginUserPromptContributions,
129
+ getPlugins,
129
130
  getSlackClient,
130
131
  getSlackToolContext,
131
132
  isConversationScopedChannel,
132
133
  normalizeSlackConversationId,
133
134
  resolveChannelCapabilities,
134
135
  withSlackRetries
135
- } from "./chunk-YZHA2L7P.js";
136
+ } from "./chunk-TLMI3Q4Q.js";
136
137
  import {
137
138
  KNOWN_CONVERSATION_EVENT_TYPES,
138
139
  contextProvenance,
@@ -142,7 +143,7 @@ import {
142
143
  instructionActors,
143
144
  instructionProvenanceFor,
144
145
  sameActorIdentity
145
- } from "./chunk-S4LM6UB7.js";
146
+ } from "./chunk-PDG3BSOD.js";
146
147
  import {
147
148
  SANDBOX_DATA_ROOT,
148
149
  SANDBOX_SKILLS_ROOT,
@@ -152,7 +153,7 @@ import {
152
153
  sandboxSkillFile,
153
154
  sandboxSkillPathResolution,
154
155
  sleep
155
- } from "./chunk-F2ARYRKC.js";
156
+ } from "./chunk-SH7HDO2D.js";
156
157
  import {
157
158
  ACTIVE_TURN_COMPACTION_SUMMARY_PREFIX,
158
159
  COMPACTION_SUMMARY_PREFIX,
@@ -186,7 +187,7 @@ import {
186
187
  renderCurrentInstruction,
187
188
  resolveGatewayModel,
188
189
  unwrapCurrentInstruction
189
- } from "./chunk-WIIPHGJY.js";
190
+ } from "./chunk-L7L7RYJM.js";
190
191
  import {
191
192
  canExposeConversationPayload,
192
193
  resolveConversationPrivacy,
@@ -196,16 +197,16 @@ import {
196
197
  toGenAiMessagesTraceAttributes,
197
198
  toGenAiPayloadMetadata,
198
199
  toGenAiPayloadTraceAttributes
199
- } from "./chunk-U36WL4OL.js";
200
+ } from "./chunk-NK7QVIMJ.js";
200
201
  import {
201
202
  discoverSkills,
202
203
  findSkillByName,
203
204
  loadSkillsByName,
204
205
  parseSkillInvocation
205
- } from "./chunk-R3GXQJEE.js";
206
+ } from "./chunk-JNYR4G7A.js";
206
207
  import {
207
208
  pluginCatalogRuntime
208
- } from "./chunk-JKV244BI.js";
209
+ } from "./chunk-2N6EL22B.js";
209
210
  import {
210
211
  CredentialUnavailableError,
211
212
  OAuthProviderError,
@@ -213,7 +214,7 @@ import {
213
214
  getOAuthProviderErrorAttributes,
214
215
  resolveAuthTokenPlaceholder,
215
216
  resolvePluginCommandEnv
216
- } from "./chunk-HXWOZ4HG.js";
217
+ } from "./chunk-FVIU6NQO.js";
217
218
  import {
218
219
  credentialUserSubjectId
219
220
  } from "./chunk-W3U3YQYI.js";
@@ -242,7 +243,7 @@ import {
242
243
  summarizeMessageText,
243
244
  withLogContext,
244
245
  withSpan
245
- } from "./chunk-PD6J33TO.js";
246
+ } from "./chunk-AYICPT5T.js";
246
247
  import {
247
248
  startInactiveSpan,
248
249
  withActiveSpan
@@ -1818,7 +1819,8 @@ var TOOL_POLICY_RULES = [
1818
1819
  "- After changing files, name the changed paths and summarize the completed result in the final answer.",
1819
1820
  "- If a sandbox-backed tool reports that sandbox execution is unavailable, treat that as a blocker for local file/shell inspection; do not pretend host files were inspected.",
1820
1821
  "- For user-provided URLs, use `webFetch`; for discovery, use `webSearch` then fetch/read promising sources; for current time/date context, use `systemTime`.",
1821
- "- When a tool result includes a subscribable resource, use resource-event subscriptions for high-signal provider changes that serve the user's current intent; do not create scheduled polling tasks for events the subscription can deliver. Use the suggested events when they fit and write a concise intent summary.",
1822
+ "- When searchResourceEventTypes is exposed, use it only when the user asks what resource events are supported or the required resource type or event name is unclear. It discovers options but does not watch a resource.",
1823
+ "- When a tool result includes a subscribable resource, use watchResourceEvents for high-signal provider changes that serve the user's current intent; do not create scheduled polling tasks for events the watch can deliver. Use the suggested events when they fit, write a concise intent summary, and tell the user when the temporary watch expires. Stop only the requested watch by id unless the user explicitly asks to stop every watch in the thread.",
1822
1824
  "- For code changes, debugging or root-cause analysis, broad refactors, and software architecture decisions, use `handoff` before substantive analysis only when it offers a profile that better matches the task. Do not switch merely because the task involves code.",
1823
1825
  "- Run `jr-rpc config get|set|unset|list` for provider defaults and `jr-rpc plugins list` for installed plugin introspection as standalone bash commands; do not chain them with `cd`, `&&`, pipes, or provider commands.",
1824
1826
  "- If the first result is empty, stale, ambiguous, or incomplete, try a focused alternate query, path, command, or source before concluding the answer cannot be verified."
@@ -4345,10 +4347,10 @@ function parseToolInput(schema, args) {
4345
4347
  return result.data;
4346
4348
  }
4347
4349
  function zodTool(definition) {
4348
- const { inputSchema, outputSchema, prepareArguments, execute, ...toolDef } = definition;
4350
+ const { inputSchema: inputSchema2, outputSchema: outputSchema5, prepareArguments, execute, ...toolDef } = definition;
4349
4351
  let modelInputSchema;
4350
4352
  try {
4351
- modelInputSchema = z4.toJSONSchema(inputSchema);
4353
+ modelInputSchema = z4.toJSONSchema(inputSchema2);
4352
4354
  } catch (error) {
4353
4355
  throw new TypeError(
4354
4356
  "zodTool() inputSchema must be representable as JSON Schema.",
@@ -4356,9 +4358,9 @@ function zodTool(definition) {
4356
4358
  );
4357
4359
  }
4358
4360
  let modelOutputSchema;
4359
- if (outputSchema) {
4361
+ if (outputSchema5) {
4360
4362
  try {
4361
- modelOutputSchema = z4.toJSONSchema(outputSchema);
4363
+ modelOutputSchema = z4.toJSONSchema(outputSchema5);
4362
4364
  } catch (error) {
4363
4365
  throw new TypeError(
4364
4366
  "zodTool() outputSchema must be representable as JSON Schema.",
@@ -4372,7 +4374,7 @@ function zodTool(definition) {
4372
4374
  ...modelOutputSchema ? { outputSchema: modelOutputSchema } : {},
4373
4375
  prepareArguments(args) {
4374
4376
  return parseToolInput(
4375
- inputSchema,
4377
+ inputSchema2,
4376
4378
  prepareArguments ? prepareArguments(args) : args
4377
4379
  );
4378
4380
  },
@@ -4382,7 +4384,7 @@ function zodTool(definition) {
4382
4384
  input,
4383
4385
  options
4384
4386
  );
4385
- if (!outputSchema) {
4387
+ if (!outputSchema5) {
4386
4388
  if (isContentOnlyToolResult(result)) {
4387
4389
  return result;
4388
4390
  }
@@ -4393,12 +4395,12 @@ function zodTool(definition) {
4393
4395
  if (isStructuredToolResultEnvelope(result)) {
4394
4396
  return {
4395
4397
  content: parseToolContent(result.content),
4396
- details: outputSchema.parse(
4398
+ details: outputSchema5.parse(
4397
4399
  juniorToolResultSchema.parse(result.details)
4398
4400
  )
4399
4401
  };
4400
4402
  }
4401
- return outputSchema.parse(juniorToolResultSchema.parse(result));
4403
+ return outputSchema5.parse(juniorToolResultSchema.parse(result));
4402
4404
  }
4403
4405
  } : {}
4404
4406
  };
@@ -6727,7 +6729,7 @@ var McpToolManager = class {
6727
6729
  return client;
6728
6730
  }
6729
6731
  toManagedTool(plugin, client, tool) {
6730
- const outputSchema = toOptionalRecord(tool.outputSchema);
6732
+ const outputSchema5 = toOptionalRecord(tool.outputSchema);
6731
6733
  const annotations = tool.annotations;
6732
6734
  const missingAnnotationKeys = missingToolAnnotationKeys(annotations);
6733
6735
  if (missingAnnotationKeys.length > 0) {
@@ -6744,7 +6746,7 @@ var McpToolManager = class {
6744
6746
  provider: plugin.manifest.name,
6745
6747
  rawName: tool.name,
6746
6748
  ...tool.title?.trim() ? { title: tool.title.trim() } : {},
6747
- ...outputSchema ? { outputSchema } : {},
6749
+ ...outputSchema5 ? { outputSchema: outputSchema5 } : {},
6748
6750
  ...annotations ? { annotations } : {},
6749
6751
  execute: async (args, options) => {
6750
6752
  const resolvedArgs = typeof args === "object" && args !== null ? args : {};
@@ -7627,14 +7629,51 @@ function createReportProgressTool() {
7627
7629
  });
7628
7630
  }
7629
7631
 
7630
- // src/chat/tools/resource-events.ts
7632
+ // src/chat/resource-events/tool-support.ts
7633
+ var STOP_WATCHING_TOOL_NAME = "stopWatchingResources";
7634
+ var RESOURCE_WATCH_TOOL_SOURCE = {
7635
+ id: "resource-watches",
7636
+ description: "Inspect or stop resource watches for the current conversation."
7637
+ };
7638
+ function requireResourceWatchConversation(context) {
7639
+ if (!context.conversationId) {
7640
+ throw new ToolInputError(
7641
+ "Resource event subscriptions require a conversation"
7642
+ );
7643
+ }
7644
+ if (context.destination.platform !== "slack") {
7645
+ throw new ToolInputError(
7646
+ "Resource event subscriptions currently require Slack delivery"
7647
+ );
7648
+ }
7649
+ if (!isSlackThreadConversationId(context.conversationId)) {
7650
+ throw new ToolInputError(
7651
+ "Resource event subscriptions require a Slack thread conversation"
7652
+ );
7653
+ }
7654
+ return context.conversationId;
7655
+ }
7656
+ function canUseResourceEventSubscriptionTools(context) {
7657
+ return context.destination.platform === "slack" && Boolean(
7658
+ context.conversationId && isSlackThreadConversationId(context.conversationId)
7659
+ );
7660
+ }
7661
+ function isSlackThreadConversationId(conversationId) {
7662
+ const parts = conversationId.split(":");
7663
+ return parts.length === 3 && parts[0] === "slack" && Boolean(parts[1]) && Boolean(parts[2]);
7664
+ }
7665
+
7666
+ // src/chat/tools/list-resource-event-subscriptions.ts
7631
7667
  import { z as z19 } from "zod";
7632
7668
 
7633
7669
  // src/chat/resource-events/store.ts
7634
7670
  import { createHash } from "crypto";
7635
- import { destinationSchema } from "@sentry/junior-plugin-api";
7671
+ import {
7672
+ destinationSchema,
7673
+ resourceEventTypeSchema
7674
+ } from "@sentry/junior-plugin-api";
7636
7675
  import { z as z18 } from "zod";
7637
- var RESOURCE_EVENT_PREFIX = "junior:resource_event_subscription";
7676
+ var RESOURCE_EVENT_PREFIX = "junior:resource_event_subscription:v2";
7638
7677
  var INDEX_LOCK_TTL_MS = 1e4;
7639
7678
  var SUBSCRIPTION_LOCK_TTL_MS = 1e4;
7640
7679
  var SUBSCRIPTION_LOCK_WAIT_MS = 1e4;
@@ -7646,13 +7685,13 @@ var subscriptionSchema = z18.object({
7646
7685
  conversationId: z18.string().min(1),
7647
7686
  createdAtMs: z18.number().finite(),
7648
7687
  destination: destinationSchema,
7649
- events: z18.array(z18.string().min(1)).min(1),
7688
+ events: z18.array(resourceEventTypeSchema).min(1),
7650
7689
  expiresAtMs: z18.number().finite(),
7651
7690
  id: z18.string().min(1),
7652
7691
  intent: z18.string().min(1),
7653
7692
  label: z18.string().min(1),
7654
- provider: z18.string().min(1),
7655
- resourceRef: z18.string().min(1),
7693
+ namespace: z18.string().min(1),
7694
+ identifier: z18.string().min(1),
7656
7695
  resourceType: z18.string().min(1),
7657
7696
  status: subscriptionStatusSchema,
7658
7697
  updatedAtMs: z18.number().finite()
@@ -7666,8 +7705,8 @@ function subscriptionKey(id) {
7666
7705
  function subscriptionLockKey(id) {
7667
7706
  return `${RESOURCE_EVENT_PREFIX}:lock:${id}`;
7668
7707
  }
7669
- function resourceIndexKey(provider, resourceRef) {
7670
- return `${RESOURCE_EVENT_PREFIX}:resource:${digest(`${provider}\0${resourceRef}`)}`;
7708
+ function resourceIndexKey(namespace, identifier) {
7709
+ return `${RESOURCE_EVENT_PREFIX}:resource:${digest(`${namespace}\0${identifier}`)}`;
7671
7710
  }
7672
7711
  function conversationIndexKey(conversationId) {
7673
7712
  return `${RESOURCE_EVENT_PREFIX}:conversation:${digest(conversationId)}`;
@@ -7753,7 +7792,7 @@ async function readSubscriptionIdIndex(state, key) {
7753
7792
  function buildSubscriptionId(input) {
7754
7793
  const eventKey = [...new Set(input.events)].sort().join("\0");
7755
7794
  return `resub_${digest(
7756
- `${input.provider}\0${input.resourceRef}\0${input.conversationId}\0${eventKey}`
7795
+ `${input.namespace}\0${input.identifier}\0${input.conversationId}\0${eventKey}`
7757
7796
  )}`;
7758
7797
  }
7759
7798
  async function withIndexLock(state, key, callback) {
@@ -7805,7 +7844,7 @@ function activeAt(subscription, nowMs) {
7805
7844
  return subscription.status === "active" && subscription.expiresAtMs > nowMs;
7806
7845
  }
7807
7846
  function matchesEvent(subscription, input) {
7808
- return subscription.provider === input.provider && subscription.resourceRef === input.resourceRef && subscription.events.includes(input.eventType) && activeAt(subscription, input.nowMs);
7847
+ return subscription.namespace === input.namespace && subscription.identifier === input.identifier && subscription.events.includes(input.eventType) && activeAt(subscription, input.nowMs);
7809
7848
  }
7810
7849
  async function createResourceEventSubscription(input, options = {}) {
7811
7850
  const state = options.state ?? getStateAdapter();
@@ -7823,8 +7862,8 @@ async function createResourceEventSubscription(input, options = {}) {
7823
7862
  const id = buildSubscriptionId({
7824
7863
  conversationId: input.conversationId,
7825
7864
  events,
7826
- provider: input.provider,
7827
- resourceRef: input.resourceRef
7865
+ namespace: input.namespace,
7866
+ identifier: input.identifier
7828
7867
  });
7829
7868
  const record = {
7830
7869
  conversationId: input.conversationId,
@@ -7835,8 +7874,8 @@ async function createResourceEventSubscription(input, options = {}) {
7835
7874
  id,
7836
7875
  intent: input.intent,
7837
7876
  label: input.label,
7838
- provider: input.provider,
7839
- resourceRef: input.resourceRef,
7877
+ namespace: input.namespace,
7878
+ identifier: input.identifier,
7840
7879
  resourceType: input.resourceType,
7841
7880
  status: "active",
7842
7881
  updatedAtMs: nowMs
@@ -7849,7 +7888,7 @@ async function createResourceEventSubscription(input, options = {}) {
7849
7888
  );
7850
7889
  await addToIndex(
7851
7890
  state,
7852
- resourceIndexKey(input.provider, input.resourceRef),
7891
+ resourceIndexKey(input.namespace, input.identifier),
7853
7892
  id,
7854
7893
  nowMs
7855
7894
  );
@@ -7901,7 +7940,7 @@ async function cancelResourceEventSubscription(input) {
7901
7940
  );
7902
7941
  await removeFromIndex(
7903
7942
  state,
7904
- resourceIndexKey(current.provider, current.resourceRef),
7943
+ resourceIndexKey(current.namespace, current.identifier),
7905
7944
  input.id,
7906
7945
  nowMs
7907
7946
  );
@@ -7931,7 +7970,7 @@ async function findMatchingResourceEventSubscriptions(input) {
7931
7970
  const nowMs = input.nowMs ?? Date.now();
7932
7971
  const ids = await readSubscriptionIdIndex(
7933
7972
  state,
7934
- resourceIndexKey(input.provider, input.resourceRef)
7973
+ resourceIndexKey(input.namespace, input.identifier)
7935
7974
  );
7936
7975
  const records = await Promise.all(
7937
7976
  ids.map(
@@ -7942,8 +7981,8 @@ async function findMatchingResourceEventSubscriptions(input) {
7942
7981
  (record) => record !== void 0 && matchesEvent(record, {
7943
7982
  eventType: input.eventType,
7944
7983
  nowMs,
7945
- provider: input.provider,
7946
- resourceRef: input.resourceRef
7984
+ namespace: input.namespace,
7985
+ identifier: input.identifier
7947
7986
  })
7948
7987
  );
7949
7988
  }
@@ -7961,8 +8000,8 @@ async function deliverResourceEventSubscription(input) {
7961
8000
  if (!current || !matchesEvent(current, {
7962
8001
  eventType: input.eventType,
7963
8002
  nowMs,
7964
- provider: input.provider,
7965
- resourceRef: input.resourceRef
8003
+ namespace: input.namespace,
8004
+ identifier: input.identifier
7966
8005
  })) {
7967
8006
  return false;
7968
8007
  }
@@ -7986,7 +8025,7 @@ async function deliverResourceEventSubscription(input) {
7986
8025
  );
7987
8026
  await removeFromIndex(
7988
8027
  state,
7989
- resourceIndexKey(current.provider, current.resourceRef),
8028
+ resourceIndexKey(current.namespace, current.identifier),
7990
8029
  current.id,
7991
8030
  nowMs
7992
8031
  );
@@ -8003,119 +8042,24 @@ async function deliverResourceEventSubscription(input) {
8003
8042
  );
8004
8043
  }
8005
8044
 
8006
- // src/chat/tools/resource-events.ts
8007
- var DEFAULT_TTL_MS = 14 * 24 * 60 * 60 * 1e3;
8008
- var MAX_TTL_MS = 30 * 24 * 60 * 60 * 1e3;
8009
- var STOP_WATCHING_TOOL_NAME = "stopWatchingResources";
8010
- var RESOURCE_WATCH_TOOL_SOURCE = {
8011
- id: "resource-watches",
8012
- description: "Inspect or stop resource watches for the current conversation."
8013
- };
8014
- var subscribeInputSchema = z19.object({
8015
- resourceRef: z19.string().describe("Opaque resource ref copied from a subscribable tool result."),
8016
- provider: z19.string().describe("Provider that owns the resource ref."),
8017
- resourceType: z19.string().describe("Provider-defined resource type from the subscribable hint."),
8018
- label: z19.string().describe("Human-readable resource label from the subscribable hint."),
8019
- events: z19.array(z19.string()).min(1).describe(
8020
- "High-signal event names to deliver to this conversation when they occur."
8021
- ),
8022
- intent: z19.string().describe(
8023
- "Concise reason this conversation wants these events, used when an event arrives."
8024
- ),
8025
- ttlMs: z19.coerce.number().describe(
8026
- "How long to keep the subscription active. Defaults to 14 days and is capped at 30 days."
8027
- ).optional()
8028
- });
8029
- function requireConversationContext(context) {
8030
- if (!context.conversationId) {
8031
- throw new Error("Resource event subscriptions require a conversation");
8032
- }
8033
- if (context.destination.platform !== "slack") {
8034
- throw new Error(
8035
- "Resource event subscriptions currently require Slack delivery"
8036
- );
8037
- }
8038
- if (!isSlackThreadConversationId(context.conversationId)) {
8039
- throw new Error(
8040
- "Resource event subscriptions require a Slack thread conversation"
8041
- );
8042
- }
8043
- return context.conversationId;
8044
- }
8045
- function canUseResourceEventSubscriptionTools(context) {
8046
- return context.destination.platform === "slack" && Boolean(
8047
- context.conversationId && isSlackThreadConversationId(context.conversationId)
8048
- );
8049
- }
8050
- function isSlackThreadConversationId(conversationId) {
8051
- const parts = conversationId.split(":");
8052
- return parts.length === 3 && parts[0] === "slack" && Boolean(parts[1]) && Boolean(parts[2]);
8053
- }
8054
- function cleanStrings(values) {
8055
- return [...new Set(values.map((value) => value.trim()).filter(Boolean))];
8056
- }
8057
- function ttlMs(input) {
8058
- if (input.ttlMs === void 0) {
8059
- return DEFAULT_TTL_MS;
8060
- }
8061
- if (!Number.isFinite(input.ttlMs) || input.ttlMs <= 0) {
8062
- throw new Error("ttlMs must be a positive finite number");
8063
- }
8064
- return Math.min(input.ttlMs, MAX_TTL_MS);
8065
- }
8066
- function createSubscribeToResourceEventsTool(context) {
8067
- return zodTool({
8068
- annotations: {
8069
- destructiveHint: false,
8070
- idempotentHint: false,
8071
- openWorldHint: true,
8072
- readOnlyHint: false
8073
- },
8074
- description: "Subscribe the current conversation to high-signal events for a resource returned by a subscribable tool result. Matching events are queued as normal conversation messages; they do not interrupt active work.",
8075
- inputSchema: subscribeInputSchema,
8076
- outputSchema: juniorToolResultSchema,
8077
- async execute(input) {
8078
- const conversationId = requireConversationContext(context);
8079
- const events = cleanStrings(input.events);
8080
- const intent = input.intent.trim();
8081
- if (!intent) {
8082
- throw new Error("intent is required");
8083
- }
8084
- const nowMs = Date.now();
8085
- const subscription = await createResourceEventSubscription({
8086
- conversationId,
8087
- destination: context.destination,
8088
- events,
8089
- expiresAtMs: nowMs + ttlMs(input),
8090
- intent,
8091
- label: input.label.trim(),
8092
- provider: input.provider.trim(),
8093
- resourceRef: input.resourceRef.trim(),
8094
- resourceType: input.resourceType.trim()
8095
- });
8096
- const details = {
8097
- id: subscription.id,
8098
- subscription_status: subscription.status,
8099
- resourceRef: subscription.resourceRef,
8100
- events: subscription.events,
8101
- expiresAtMs: subscription.expiresAtMs,
8102
- stop_watching: {
8103
- execution_tool: "executeTool",
8104
- execution_example: {
8105
- tool_name: STOP_WATCHING_TOOL_NAME,
8106
- arguments: {}
8107
- }
8108
- }
8109
- };
8110
- return {
8111
- ok: true,
8112
- status: "success",
8113
- data: details,
8114
- ...details
8115
- };
8116
- }
8117
- });
8118
- }
8045
+ // src/chat/tools/list-resource-event-subscriptions.ts
8046
+ var listedResourceWatchSchema = z19.object({
8047
+ id: z19.string().min(1),
8048
+ label: z19.string().min(1),
8049
+ identifier: z19.string().min(1),
8050
+ namespace: z19.string().min(1),
8051
+ resourceType: z19.string().min(1),
8052
+ events: z19.array(z19.string().min(1)).min(1),
8053
+ intent: z19.string().min(1),
8054
+ expiresAtMs: z19.number().finite()
8055
+ }).strict();
8056
+ var resultDataSchema = z19.object({ subscriptions: z19.array(listedResourceWatchSchema) }).strict();
8057
+ var outputSchema = juniorToolResultSchema.extend({
8058
+ ok: z19.literal(true),
8059
+ status: z19.literal("success"),
8060
+ data: resultDataSchema,
8061
+ subscriptions: z19.array(listedResourceWatchSchema)
8062
+ }).strict();
8119
8063
  function createListResourceEventSubscriptionsTool(context) {
8120
8064
  return zodTool({
8121
8065
  annotations: {
@@ -8127,10 +8071,10 @@ function createListResourceEventSubscriptionsTool(context) {
8127
8071
  description: "List active resource event subscriptions for the current conversation.",
8128
8072
  exposure: "deferred",
8129
8073
  source: RESOURCE_WATCH_TOOL_SOURCE,
8130
- inputSchema: z19.object({}),
8131
- outputSchema: juniorToolResultSchema,
8074
+ inputSchema: z19.object({}).strict(),
8075
+ outputSchema,
8132
8076
  async execute() {
8133
- const conversationId = requireConversationContext(context);
8077
+ const conversationId = requireResourceWatchConversation(context);
8134
8078
  const subscriptions = await listResourceEventSubscriptions({
8135
8079
  conversationId
8136
8080
  });
@@ -8138,8 +8082,8 @@ function createListResourceEventSubscriptionsTool(context) {
8138
8082
  subscriptions: subscriptions.map((subscription) => ({
8139
8083
  id: subscription.id,
8140
8084
  label: subscription.label,
8141
- resourceRef: subscription.resourceRef,
8142
- provider: subscription.provider,
8085
+ identifier: subscription.identifier,
8086
+ namespace: subscription.namespace,
8143
8087
  resourceType: subscription.resourceType,
8144
8088
  events: subscription.events,
8145
8089
  intent: subscription.intent,
@@ -8155,6 +8099,157 @@ function createListResourceEventSubscriptionsTool(context) {
8155
8099
  }
8156
8100
  });
8157
8101
  }
8102
+
8103
+ // src/chat/tools/search-resource-event-types.ts
8104
+ import { z as z21 } from "zod";
8105
+
8106
+ // src/chat/resource-events/catalog.ts
8107
+ import {
8108
+ normalizeResourceEventIdentifier
8109
+ } from "@sentry/junior-plugin-api";
8110
+ import { z as z20 } from "zod";
8111
+ function enumSchema(values, unavailableMessage) {
8112
+ if (values.length === 0) {
8113
+ return z20.string().refine(() => false, unavailableMessage);
8114
+ }
8115
+ return z20.enum(values);
8116
+ }
8117
+ function eventNamespaceSchema(catalog) {
8118
+ return enumSchema(
8119
+ Object.keys(catalog).sort(),
8120
+ "No resource event namespaces are enabled."
8121
+ );
8122
+ }
8123
+ function registeredEventTypeSchema(catalog) {
8124
+ return enumSchema(
8125
+ [
8126
+ ...new Set(
8127
+ Object.values(catalog).flatMap(
8128
+ (registration) => registration.resourceTypes.flatMap(
8129
+ (resourceType) => resourceType.supportedEvents
8130
+ )
8131
+ )
8132
+ )
8133
+ ].sort(),
8134
+ "No resource event types are enabled."
8135
+ );
8136
+ }
8137
+ function registeredResourceTypeSchema(catalog) {
8138
+ return enumSchema(
8139
+ [
8140
+ ...new Set(
8141
+ Object.values(catalog).flatMap(
8142
+ (registration) => registration.resourceTypes.map((resourceType) => resourceType.type)
8143
+ )
8144
+ )
8145
+ ].sort(),
8146
+ "No resource types are enabled."
8147
+ );
8148
+ }
8149
+ function pluginSupportsEvent(catalog, namespace, resourceType, eventType) {
8150
+ return catalog[namespace]?.resourceTypes.find((candidate) => candidate.type === resourceType)?.supportedEvents.includes(eventType) ?? false;
8151
+ }
8152
+ function normalizeEventIdentifier(catalog, namespace, identifier) {
8153
+ return normalizeResourceEventIdentifier(catalog[namespace], identifier);
8154
+ }
8155
+
8156
+ // src/chat/tools/search-resource-event-types.ts
8157
+ var DEFAULT_SEARCH_RESULTS = 10;
8158
+ var MAX_SEARCH_RESULTS = 20;
8159
+ var searchedResourceTypeSchema = z21.object({
8160
+ namespace: z21.string(),
8161
+ type: z21.string(),
8162
+ supportedEvents: z21.array(z21.string()),
8163
+ suggestedEvents: z21.array(z21.string()).optional()
8164
+ }).strict();
8165
+ var outputSchema2 = juniorToolResultSchema.extend({
8166
+ query: z21.string().nullable(),
8167
+ namespace: z21.string().nullable(),
8168
+ totalMatches: z21.number().int().nonnegative(),
8169
+ resourceTypes: z21.array(searchedResourceTypeSchema)
8170
+ }).strict();
8171
+ function normalizeSearchText(value) {
8172
+ return value.toLowerCase().replace(/[^a-z0-9_.-]+/g, " ").trim();
8173
+ }
8174
+ function searchableResourceTypes(catalog) {
8175
+ return Object.entries(catalog).flatMap(
8176
+ ([namespace, registration]) => registration.resourceTypes.map((resourceType) => ({
8177
+ namespace,
8178
+ type: resourceType.type,
8179
+ supportedEvents: [...resourceType.supportedEvents].sort(),
8180
+ ...resourceType.suggestedEvents ? { suggestedEvents: [...resourceType.suggestedEvents].sort() } : {}
8181
+ }))
8182
+ ).sort(
8183
+ (left, right) => left.namespace.localeCompare(right.namespace) || left.type.localeCompare(right.type)
8184
+ );
8185
+ }
8186
+ function createSearchResourceEventTypesTool(catalog) {
8187
+ return zodTool({
8188
+ annotations: {
8189
+ destructiveHint: false,
8190
+ idempotentHint: true,
8191
+ openWorldHint: false,
8192
+ readOnlyHint: true
8193
+ },
8194
+ description: "Search the resource event types currently enabled by plugins without creating anything. Use watchResourceEvents to receive temporary updates in the current Slack thread. This tool does not watch a resource or enumerate concrete resources.",
8195
+ inputSchema: z21.object({
8196
+ query: z21.string().nullable().describe(
8197
+ "Optional terms matching a namespace, resource type, or event name. Empty lists all enabled resource event types."
8198
+ ).optional(),
8199
+ namespace: eventNamespaceSchema(catalog).nullable().describe("Optional enabled plugin namespace to search within.").optional(),
8200
+ maxResults: z21.number().int().min(1).max(MAX_SEARCH_RESULTS).nullable().describe("Maximum matching resource types to return.").optional()
8201
+ }).strict(),
8202
+ outputSchema: outputSchema2,
8203
+ async execute({ query, namespace, maxResults }) {
8204
+ const normalizedQuery = normalizeSearchText(query ?? "");
8205
+ const terms = normalizedQuery.split(/\s+/).filter(Boolean);
8206
+ const matches = searchableResourceTypes(catalog).filter(
8207
+ (resourceType) => {
8208
+ if (namespace && resourceType.namespace !== namespace) return false;
8209
+ const text = normalizeSearchText(
8210
+ [
8211
+ resourceType.namespace,
8212
+ resourceType.type,
8213
+ ...resourceType.supportedEvents,
8214
+ ...resourceType.suggestedEvents ?? []
8215
+ ].join(" ")
8216
+ );
8217
+ return terms.every((term) => text.includes(term));
8218
+ }
8219
+ );
8220
+ const resourceTypes = matches.slice(
8221
+ 0,
8222
+ maxResults ?? DEFAULT_SEARCH_RESULTS
8223
+ );
8224
+ const details = {
8225
+ query: query ?? null,
8226
+ namespace: namespace ?? null,
8227
+ totalMatches: matches.length,
8228
+ resourceTypes
8229
+ };
8230
+ return {
8231
+ ok: true,
8232
+ status: "success",
8233
+ data: details,
8234
+ ...details
8235
+ };
8236
+ }
8237
+ });
8238
+ }
8239
+
8240
+ // src/chat/tools/stop-watching-resources.ts
8241
+ import { z as z22 } from "zod";
8242
+ var resultDataSchema2 = z22.object({
8243
+ watching_status: z22.literal("stopped"),
8244
+ stoppedIds: z22.array(z22.string().min(1))
8245
+ }).strict();
8246
+ var outputSchema3 = juniorToolResultSchema.extend({
8247
+ ok: z22.literal(true),
8248
+ status: z22.literal("success"),
8249
+ data: resultDataSchema2,
8250
+ watching_status: z22.literal("stopped"),
8251
+ stoppedIds: z22.array(z22.string().min(1))
8252
+ }).strict();
8158
8253
  function createStopWatchingResourcesTool(context) {
8159
8254
  return zodTool({
8160
8255
  annotations: {
@@ -8163,16 +8258,182 @@ function createStopWatchingResourcesTool(context) {
8163
8258
  openWorldHint: false,
8164
8259
  readOnlyHint: false
8165
8260
  },
8166
- description: "Stop every resource watch for the current conversation. Infer the user's intent from context instead of requiring a special command, and call this tool before confirming that watching stopped.",
8261
+ 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.",
8167
8262
  exposure: "deferred",
8168
8263
  source: RESOURCE_WATCH_TOOL_SOURCE,
8169
- inputSchema: z19.object({}),
8170
- outputSchema: juniorToolResultSchema,
8171
- async execute() {
8172
- const conversationId = requireConversationContext(context);
8173
- await cancelSubscriptions({ conversationId });
8264
+ inputSchema: z22.object({ id: z22.string().min(1).nullable().optional() }).strict(),
8265
+ outputSchema: outputSchema3,
8266
+ async execute({ id }) {
8267
+ const conversationId = requireResourceWatchConversation(context);
8268
+ let stoppedIds;
8269
+ if (id) {
8270
+ const stopped = await cancelResourceEventSubscription({
8271
+ conversationId,
8272
+ id
8273
+ });
8274
+ if (!stopped) {
8275
+ throw new ToolInputError(
8276
+ "Resource watch was not found in the current Slack thread."
8277
+ );
8278
+ }
8279
+ stoppedIds = [stopped.id];
8280
+ } else {
8281
+ const subscriptions = await listResourceEventSubscriptions({
8282
+ conversationId
8283
+ });
8284
+ await cancelSubscriptions({ conversationId });
8285
+ stoppedIds = subscriptions.map((subscription) => subscription.id);
8286
+ }
8287
+ const details = {
8288
+ watching_status: "stopped",
8289
+ stoppedIds
8290
+ };
8291
+ return {
8292
+ ok: true,
8293
+ status: "success",
8294
+ data: details,
8295
+ ...details
8296
+ };
8297
+ }
8298
+ });
8299
+ }
8300
+
8301
+ // src/chat/tools/watch-resource-events.ts
8302
+ import { z as z23 } from "zod";
8303
+ var DEFAULT_TTL_MS = 14 * 24 * 60 * 60 * 1e3;
8304
+ var MAX_TTL_MS = 30 * 24 * 60 * 60 * 1e3;
8305
+ function inputSchema(catalog) {
8306
+ return z23.object({
8307
+ identifier: z23.string().trim().min(1).describe("Plugin-defined resource identifier."),
8308
+ namespace: eventNamespaceSchema(catalog).describe(
8309
+ "Enabled plugin namespace for this resource."
8310
+ ),
8311
+ resourceType: registeredResourceTypeSchema(catalog).describe(
8312
+ "Plugin-defined resource type."
8313
+ ),
8314
+ label: z23.string().trim().min(1).max(500).describe("Human-readable resource label."),
8315
+ events: z23.array(registeredEventTypeSchema(catalog)).min(1).describe(
8316
+ "High-signal event names to deliver to this conversation when they occur."
8317
+ ),
8318
+ intent: z23.string().trim().min(1).max(4e3).describe(
8319
+ "Concise reason this conversation wants these events, used when an event arrives."
8320
+ ),
8321
+ ttlMs: z23.coerce.number().describe(
8322
+ "How long to keep the subscription active. Defaults to 14 days and must not exceed 30 days."
8323
+ ).optional()
8324
+ }).strict().superRefine((subscription, context) => {
8325
+ subscription.events.forEach((eventType, index) => {
8326
+ if (!pluginSupportsEvent(
8327
+ catalog,
8328
+ subscription.namespace,
8329
+ subscription.resourceType,
8330
+ eventType
8331
+ )) {
8332
+ context.addIssue({
8333
+ code: "custom",
8334
+ message: `Resource type "${subscription.namespace}:${subscription.resourceType}" does not support event "${eventType}".`,
8335
+ path: ["events", index]
8336
+ });
8337
+ }
8338
+ });
8339
+ });
8340
+ }
8341
+ var stopWatchingActionSchema = z23.object({
8342
+ execution_tool: z23.literal("executeTool"),
8343
+ execution_example: z23.object({
8344
+ tool_name: z23.literal(STOP_WATCHING_TOOL_NAME),
8345
+ arguments: z23.object({ id: z23.string().min(1) }).strict()
8346
+ }).strict()
8347
+ }).strict();
8348
+ var resultDataSchema3 = z23.object({
8349
+ id: z23.string().min(1),
8350
+ subscription_status: z23.enum(["active", "cancelled", "completed"]),
8351
+ identifier: z23.string().min(1),
8352
+ events: z23.array(z23.string().min(1)).min(1),
8353
+ expiresAtMs: z23.number().finite(),
8354
+ stop_watching: stopWatchingActionSchema
8355
+ }).strict();
8356
+ var outputSchema4 = juniorToolResultSchema.extend({
8357
+ ok: z23.literal(true),
8358
+ status: z23.literal("success"),
8359
+ data: resultDataSchema3,
8360
+ id: resultDataSchema3.shape.id,
8361
+ subscription_status: resultDataSchema3.shape.subscription_status,
8362
+ identifier: resultDataSchema3.shape.identifier,
8363
+ events: resultDataSchema3.shape.events,
8364
+ expiresAtMs: resultDataSchema3.shape.expiresAtMs,
8365
+ stop_watching: stopWatchingActionSchema
8366
+ }).strict();
8367
+ function cleanStrings(values) {
8368
+ return [...new Set(values.map((value) => value.trim()).filter(Boolean))];
8369
+ }
8370
+ function ttlMs(input) {
8371
+ if (input.ttlMs === void 0) return DEFAULT_TTL_MS;
8372
+ if (!Number.isFinite(input.ttlMs) || input.ttlMs <= 0) {
8373
+ throw new ToolInputError("ttlMs must be a positive finite number");
8374
+ }
8375
+ if (input.ttlMs > MAX_TTL_MS) {
8376
+ throw new ToolInputError("Resource watches cannot exceed 30 days");
8377
+ }
8378
+ return input.ttlMs;
8379
+ }
8380
+ function createWatchResourceEventsTool(context, catalog) {
8381
+ return zodTool({
8382
+ annotations: {
8383
+ destructiveHint: false,
8384
+ idempotentHint: false,
8385
+ openWorldHint: true,
8386
+ readOnlyHint: false
8387
+ },
8388
+ description: "Watch one plugin resource in the current Slack thread for a limited time; matching events return to this conversation as updates. Use for watch, notify, or tell-me-when requests. This does not create a scheduled polling task. Prefer a subscribable tool result when available.",
8389
+ inputSchema: inputSchema(catalog),
8390
+ outputSchema: outputSchema4,
8391
+ async execute(input) {
8392
+ const conversationId = requireResourceWatchConversation(context);
8393
+ const events = cleanStrings(input.events);
8394
+ for (const eventType of events) {
8395
+ if (!pluginSupportsEvent(
8396
+ catalog,
8397
+ input.namespace,
8398
+ input.resourceType,
8399
+ eventType
8400
+ )) {
8401
+ throw new ToolInputError(
8402
+ `Resource type "${input.namespace}:${input.resourceType}" does not support event "${eventType}".`
8403
+ );
8404
+ }
8405
+ }
8406
+ const intent = input.intent.trim();
8407
+ if (!intent) throw new ToolInputError("intent is required");
8408
+ const nowMs = Date.now();
8409
+ const subscription = await createResourceEventSubscription({
8410
+ conversationId,
8411
+ destination: context.destination,
8412
+ events,
8413
+ expiresAtMs: nowMs + ttlMs(input),
8414
+ intent,
8415
+ label: input.label.trim(),
8416
+ namespace: input.namespace.trim(),
8417
+ identifier: normalizeEventIdentifier(
8418
+ catalog,
8419
+ input.namespace,
8420
+ input.identifier
8421
+ ),
8422
+ resourceType: input.resourceType.trim()
8423
+ });
8174
8424
  const details = {
8175
- watching_status: "stopped"
8425
+ id: subscription.id,
8426
+ subscription_status: subscription.status,
8427
+ identifier: subscription.identifier,
8428
+ events: subscription.events,
8429
+ expiresAtMs: subscription.expiresAtMs,
8430
+ stop_watching: {
8431
+ execution_tool: "executeTool",
8432
+ execution_example: {
8433
+ tool_name: STOP_WATCHING_TOOL_NAME,
8434
+ arguments: { id: subscription.id }
8435
+ }
8436
+ }
8176
8437
  };
8177
8438
  return {
8178
8439
  ok: true,
@@ -8183,14 +8444,23 @@ function createStopWatchingResourcesTool(context) {
8183
8444
  }
8184
8445
  });
8185
8446
  }
8186
- function createResourceEventTools(context) {
8447
+
8448
+ // src/chat/tools/resource-events.ts
8449
+ function createResourceEventTools(context, catalog) {
8450
+ const enabled = Object.keys(catalog).length > 0;
8451
+ const discoveryTools = context.destination.platform === "slack" && enabled ? {
8452
+ searchResourceEventTypes: createSearchResourceEventTypesTool(catalog)
8453
+ } : {};
8187
8454
  if (!canUseResourceEventSubscriptionTools(context)) {
8188
- return {};
8455
+ return discoveryTools;
8189
8456
  }
8190
8457
  return {
8191
- subscribeToResourceEvents: createSubscribeToResourceEventsTool(context),
8458
+ ...discoveryTools,
8459
+ ...enabled ? {
8460
+ watchResourceEvents: createWatchResourceEventsTool(context, catalog)
8461
+ } : {},
8192
8462
  listResourceEventSubscriptions: createListResourceEventSubscriptionsTool(context),
8193
- [STOP_WATCHING_TOOL_NAME]: createStopWatchingResourcesTool(context)
8463
+ stopWatchingResources: createStopWatchingResourcesTool(context)
8194
8464
  };
8195
8465
  }
8196
8466
 
@@ -8273,11 +8543,11 @@ async function listThreadReplies(input) {
8273
8543
  }
8274
8544
 
8275
8545
  // src/chat/slack/timestamp-param.ts
8276
- import { z as z20 } from "zod";
8546
+ import { z as z24 } from "zod";
8277
8547
  function slackTimestampParam(description) {
8278
- return z20.preprocess(
8548
+ return z24.preprocess(
8279
8549
  (value) => typeof value === "number" && Number.isFinite(value) ? String(value) : value,
8280
- z20.string().min(1)
8550
+ z24.string().min(1)
8281
8551
  ).describe(description);
8282
8552
  }
8283
8553
  function optionalSlackTimestampParam(description) {
@@ -8308,10 +8578,10 @@ function parseRequiredSlackTimestampParam(field, value) {
8308
8578
  }
8309
8579
 
8310
8580
  // src/chat/slack/tools/channel-list-messages.ts
8311
- import { z as z21 } from "zod";
8312
- var booleanInput2 = (description) => z21.preprocess(
8581
+ import { z as z25 } from "zod";
8582
+ var booleanInput2 = (description) => z25.preprocess(
8313
8583
  (value) => value === "true" ? true : value === "false" ? false : value,
8314
- z21.boolean()
8584
+ z25.boolean()
8315
8585
  ).describe(description);
8316
8586
  function normalizeRangeTimestamp(field, value, targetChannelId) {
8317
8587
  if (value === void 0) {
@@ -8343,9 +8613,9 @@ function createSlackChannelListMessagesTool(context) {
8343
8613
  openWorldHint: true,
8344
8614
  readOnlyHint: true
8345
8615
  },
8346
- inputSchema: z21.object({
8347
- limit: z21.coerce.number().int().min(1).max(1e3).describe("Maximum number of messages to return across pages.").optional(),
8348
- cursor: z21.string().min(1).describe("Optional cursor to continue from a prior call.").optional(),
8616
+ inputSchema: z25.object({
8617
+ limit: z25.coerce.number().int().min(1).max(1e3).describe("Maximum number of messages to return across pages.").optional(),
8618
+ cursor: z25.string().min(1).describe("Optional cursor to continue from a prior call.").optional(),
8349
8619
  oldest: optionalSlackTimestampParam(
8350
8620
  "Optional oldest message timestamp (Slack ts) for range filtering."
8351
8621
  ),
@@ -8355,7 +8625,7 @@ function createSlackChannelListMessagesTool(context) {
8355
8625
  inclusive: booleanInput2(
8356
8626
  "Whether oldest/latest bounds should be inclusive."
8357
8627
  ).optional(),
8358
- max_pages: z21.coerce.number().int().min(1).max(10).describe("Maximum number of API pages to traverse in a single call.").optional()
8628
+ max_pages: z25.coerce.number().int().min(1).max(10).describe("Maximum number of API pages to traverse in a single call.").optional()
8359
8629
  }),
8360
8630
  outputSchema: juniorToolResultSchema,
8361
8631
  execute: async ({
@@ -8429,20 +8699,20 @@ function createSlackChannelListMessagesTool(context) {
8429
8699
  }
8430
8700
 
8431
8701
  // src/chat/slack/tools/conversation-search.ts
8432
- import { z as z22 } from "zod";
8702
+ import { z as z26 } from "zod";
8433
8703
  var DEFAULT_LIMIT = 5;
8434
8704
  var conversationSearchOutputSchema = juniorToolResultSchema.extend({
8435
- query: z22.string(),
8436
- count: z22.number().int().nonnegative(),
8437
- threads: z22.array(
8438
- z22.object({
8439
- conversation_id: z22.string().min(1),
8440
- thread_ts: z22.string().min(1),
8441
- message_id: z22.string().min(1),
8442
- message_role: z22.enum(["assistant", "user"]),
8443
- message_timestamp: z22.string().datetime(),
8444
- excerpt: z22.string(),
8445
- permalink: z22.string().url().optional()
8705
+ query: z26.string(),
8706
+ count: z26.number().int().nonnegative(),
8707
+ threads: z26.array(
8708
+ z26.object({
8709
+ conversation_id: z26.string().min(1),
8710
+ thread_ts: z26.string().min(1),
8711
+ message_id: z26.string().min(1),
8712
+ message_role: z26.enum(["assistant", "user"]),
8713
+ message_timestamp: z26.string().datetime(),
8714
+ excerpt: z26.string(),
8715
+ permalink: z26.string().url().optional()
8446
8716
  }).strict()
8447
8717
  )
8448
8718
  });
@@ -8460,9 +8730,9 @@ function createSlackConversationSearchTool(scope, currentConversationId, deps =
8460
8730
  openWorldHint: false,
8461
8731
  readOnlyHint: true
8462
8732
  },
8463
- inputSchema: z22.object({
8464
- query: z22.string().trim().min(1).max(200).describe("Words or a short phrase to find in prior conversations."),
8465
- limit: z22.number().int().min(1).max(10).describe("Maximum number of prior conversation threads to return.").nullable().optional()
8733
+ inputSchema: z26.object({
8734
+ query: z26.string().trim().min(1).max(200).describe("Words or a short phrase to find in prior conversations."),
8735
+ limit: z26.number().int().min(1).max(10).describe("Maximum number of prior conversation threads to return.").nullable().optional()
8466
8736
  }),
8467
8737
  outputSchema: conversationSearchOutputSchema,
8468
8738
  execute: async ({ query, limit }) => {
@@ -8509,27 +8779,27 @@ function createSlackConversationSearchTool(scope, currentConversationId, deps =
8509
8779
  }
8510
8780
 
8511
8781
  // src/chat/slack/tools/public-search.ts
8512
- import { z as z23 } from "zod";
8782
+ import { z as z27 } from "zod";
8513
8783
  var DEFAULT_LIMIT2 = 10;
8514
- var optionalTimestampSchema = z23.preprocess(
8784
+ var optionalTimestampSchema = z27.preprocess(
8515
8785
  (value) => typeof value === "string" && value.trim() === "" ? void 0 : value,
8516
- z23.coerce.number().int().nonnegative().describe("Optional Unix timestamp bound.").optional()
8786
+ z27.coerce.number().int().nonnegative().describe("Optional Unix timestamp bound.").optional()
8517
8787
  );
8518
- var searchMessageSchema = z23.object({
8519
- author_name: z23.string().optional(),
8520
- author_user_id: z23.string().optional(),
8521
- channel_id: z23.string().min(1),
8522
- channel_name: z23.string().optional(),
8523
- message_ts: z23.string().min(1),
8524
- content: z23.string(),
8525
- is_author_bot: z23.boolean().optional(),
8526
- permalink: z23.string().url()
8788
+ var searchMessageSchema = z27.object({
8789
+ author_name: z27.string().optional(),
8790
+ author_user_id: z27.string().optional(),
8791
+ channel_id: z27.string().min(1),
8792
+ channel_name: z27.string().optional(),
8793
+ message_ts: z27.string().min(1),
8794
+ content: z27.string(),
8795
+ is_author_bot: z27.boolean().optional(),
8796
+ permalink: z27.string().url()
8527
8797
  });
8528
8798
  var publicSearchOutputSchema = juniorToolResultSchema.extend({
8529
- query: z23.string(),
8530
- count: z23.number().int().nonnegative(),
8531
- messages: z23.array(searchMessageSchema),
8532
- next_cursor: z23.string().optional()
8799
+ query: z27.string(),
8800
+ count: z27.number().int().nonnegative(),
8801
+ messages: z27.array(searchMessageSchema),
8802
+ next_cursor: z27.string().optional()
8533
8803
  });
8534
8804
  function normalizeMessage(value) {
8535
8805
  const parsed = searchMessageSchema.safeParse(value);
@@ -8556,8 +8826,8 @@ function createSlackPublicSearchTool(actionToken) {
8556
8826
  openWorldHint: true,
8557
8827
  readOnlyHint: true
8558
8828
  },
8559
- inputSchema: z23.object({
8560
- query: z23.string().trim().min(1).max(500).describe(
8829
+ inputSchema: z27.object({
8830
+ query: z27.string().trim().min(1).max(500).describe(
8561
8831
  "A focused Slack search query, including Slack search filters when useful."
8562
8832
  ),
8563
8833
  after: optionalTimestampSchema.describe(
@@ -8566,10 +8836,10 @@ function createSlackPublicSearchTool(actionToken) {
8566
8836
  before: optionalTimestampSchema.describe(
8567
8837
  "Optional Unix timestamp upper bound."
8568
8838
  ),
8569
- cursor: z23.string().min(1).describe("Cursor for the next result page.").optional(),
8570
- limit: z23.coerce.number().int().min(1).max(20).describe("Maximum results to return; Slack allows at most 20.").optional(),
8571
- sort: z23.enum(["score", "timestamp"]).describe("Rank by relevance or timestamp.").optional(),
8572
- sort_dir: z23.enum(["asc", "desc"]).describe("Sort direction.").optional()
8839
+ cursor: z27.string().min(1).describe("Cursor for the next result page.").optional(),
8840
+ limit: z27.coerce.number().int().min(1).max(20).describe("Maximum results to return; Slack allows at most 20.").optional(),
8841
+ sort: z27.enum(["score", "timestamp"]).describe("Rank by relevance or timestamp.").optional(),
8842
+ sort_dir: z27.enum(["asc", "desc"]).describe("Sort direction.").optional()
8573
8843
  }),
8574
8844
  outputSchema: publicSearchOutputSchema,
8575
8845
  execute: async ({
@@ -8635,7 +8905,7 @@ function createSlackPublicSearchTool(actionToken) {
8635
8905
  }
8636
8906
 
8637
8907
  // src/chat/slack/tools/message-add-reaction.ts
8638
- import { z as z24 } from "zod";
8908
+ import { z as z28 } from "zod";
8639
8909
 
8640
8910
  // src/chat/tools/idempotency.ts
8641
8911
  function stableSerialize(value) {
@@ -8665,8 +8935,8 @@ function createSlackMessageAddReactionTool(context, state) {
8665
8935
  readOnlyHint: false
8666
8936
  },
8667
8937
  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.",
8668
- inputSchema: z24.object({
8669
- emoji: z24.string().min(1).max(64).describe(
8938
+ inputSchema: z28.object({
8939
+ emoji: z28.string().min(1).max(64).describe(
8670
8940
  "Slack emoji alias name to react with (for example `thumbsup`, `white_check_mark`, or `thumbsup::skin-tone-6`). Optional surrounding colons are allowed."
8671
8941
  )
8672
8942
  }),
@@ -8717,18 +8987,18 @@ function createSlackMessageAddReactionTool(context, state) {
8717
8987
 
8718
8988
  // src/chat/slack/tools/send-files.ts
8719
8989
  import { createHash as createHash2 } from "crypto";
8720
- import { z as z25 } from "zod";
8721
- var sendFilesDataSchema = z25.object({
8722
- channel_id: z25.string().min(1),
8723
- deduplicated: z25.boolean().optional(),
8724
- file_count: z25.number().int().nonnegative(),
8725
- file_ids: z25.array(z25.string().min(1)).optional(),
8726
- thread_ts: z25.string().min(1)
8990
+ import { z as z29 } from "zod";
8991
+ var sendFilesDataSchema = z29.object({
8992
+ channel_id: z29.string().min(1),
8993
+ deduplicated: z29.boolean().optional(),
8994
+ file_count: z29.number().int().nonnegative(),
8995
+ file_ids: z29.array(z29.string().min(1)).optional(),
8996
+ thread_ts: z29.string().min(1)
8727
8997
  });
8728
8998
  var sendFilesResultSchema = juniorToolResultSchema.extend({
8729
- ok: z25.literal(true),
8730
- status: z25.literal("success"),
8731
- target: z25.string().min(1),
8999
+ ok: z29.literal(true),
9000
+ status: z29.literal("success"),
9001
+ target: z29.string().min(1),
8732
9002
  data: sendFilesDataSchema
8733
9003
  });
8734
9004
  function normalizeFiles(files) {
@@ -8759,8 +9029,8 @@ function createSendFilesTool(context, state, materializeFile) {
8759
9029
  readOnlyHint: false
8760
9030
  },
8761
9031
  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.",
8762
- inputSchema: z25.object({
8763
- files: z25.array(sandboxFileReferenceSchema).min(1).describe(
9032
+ inputSchema: z29.object({
9033
+ files: z29.array(sandboxFileReferenceSchema).min(1).describe(
8764
9034
  "One or more existing sandbox files. Objects returned by imageGenerate or webFetch can be passed unchanged."
8765
9035
  )
8766
9036
  }),
@@ -9199,7 +9469,7 @@ function storedCanvasUrl(state, canvasId) {
9199
9469
  }
9200
9470
 
9201
9471
  // src/chat/slack/tools/canvas/create.ts
9202
- import { z as z26 } from "zod";
9472
+ import { z as z30 } from "zod";
9203
9473
  function createSlackCanvasCreateTool(context, state) {
9204
9474
  return zodTool({
9205
9475
  annotations: {
@@ -9209,9 +9479,9 @@ function createSlackCanvasCreateTool(context, state) {
9209
9479
  readOnlyHint: false
9210
9480
  },
9211
9481
  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.",
9212
- inputSchema: z26.object({
9213
- title: z26.string().min(1).max(160).describe("Canvas title."),
9214
- markdown: z26.string().min(1).describe("Canvas markdown body content.")
9482
+ inputSchema: z30.object({
9483
+ title: z30.string().min(1).max(160).describe("Canvas title."),
9484
+ markdown: z30.string().min(1).describe("Canvas markdown body content.")
9215
9485
  }),
9216
9486
  outputSchema: juniorToolResultSchema,
9217
9487
  execute: async ({ title, markdown }) => {
@@ -9269,26 +9539,26 @@ function createSlackCanvasCreateTool(context, state) {
9269
9539
  }
9270
9540
 
9271
9541
  // src/chat/slack/tools/canvas/edit.ts
9272
- import { z as z27 } from "zod";
9542
+ import { z as z31 } from "zod";
9273
9543
  function prepareCanvasEditArguments(input) {
9274
9544
  return prepareTextReplacementArguments(input);
9275
9545
  }
9276
- var editReplacementSchema2 = z27.object({
9277
- oldText: z27.string().min(1).describe(
9546
+ var editReplacementSchema2 = z31.object({
9547
+ oldText: z31.string().min(1).describe(
9278
9548
  "Exact Canvas markdown to replace. It must be unique in the current Canvas body and must not overlap another edit."
9279
9549
  ),
9280
- newText: z27.string().describe("Replacement Canvas markdown for this edit.")
9550
+ newText: z31.string().describe("Replacement Canvas markdown for this edit.")
9281
9551
  });
9282
9552
  var slackCanvasEditOutputSchema = juniorToolResultSchema.extend({
9283
- canvas_id: z27.string().optional(),
9284
- title: z27.string().optional(),
9285
- permalink: z27.string().optional(),
9286
- diff: z27.string().optional(),
9287
- first_changed_line: z27.number().int().positive().optional(),
9288
- replacements: z27.number().int().nonnegative().optional(),
9289
- normalized_heading_count: z27.number().int().nonnegative().optional(),
9290
- summary: z27.string().optional(),
9291
- deduplicated: z27.boolean().optional()
9553
+ canvas_id: z31.string().optional(),
9554
+ title: z31.string().optional(),
9555
+ permalink: z31.string().optional(),
9556
+ diff: z31.string().optional(),
9557
+ first_changed_line: z31.number().int().positive().optional(),
9558
+ replacements: z31.number().int().nonnegative().optional(),
9559
+ normalized_heading_count: z31.number().int().nonnegative().optional(),
9560
+ summary: z31.string().optional(),
9561
+ deduplicated: z31.boolean().optional()
9292
9562
  }).strict();
9293
9563
  function createSlackCanvasEditTool(state) {
9294
9564
  return zodTool({
@@ -9301,9 +9571,9 @@ function createSlackCanvasEditTool(state) {
9301
9571
  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.",
9302
9572
  prepareArguments: prepareCanvasEditArguments,
9303
9573
  executionMode: "sequential",
9304
- inputSchema: z27.object({
9305
- canvas: z27.string().min(1).describe("Canvas/file ID (e.g. `F0ABCDEF`) or Slack canvas/docs URL."),
9306
- edits: z27.array(editReplacementSchema2).min(1).describe(
9574
+ inputSchema: z31.object({
9575
+ canvas: z31.string().min(1).describe("Canvas/file ID (e.g. `F0ABCDEF`) or Slack canvas/docs URL."),
9576
+ edits: z31.array(editReplacementSchema2).min(1).describe(
9307
9577
  "Exact replacements matched against the current Canvas body, not incrementally."
9308
9578
  )
9309
9579
  }),
@@ -9376,18 +9646,18 @@ function createSlackCanvasEditTool(state) {
9376
9646
  }
9377
9647
 
9378
9648
  // src/chat/slack/tools/canvas/read.ts
9379
- import { z as z28 } from "zod";
9649
+ import { z as z32 } from "zod";
9380
9650
  var slackCanvasReadOutputSchema = juniorToolResultSchema.extend({
9381
- canvas_id: z28.string().optional(),
9382
- title: z28.string().optional(),
9383
- permalink: z28.string().optional(),
9384
- mimetype: z28.string().optional(),
9385
- filetype: z28.string().optional(),
9386
- original_byte_length: z28.number().int().nonnegative().optional(),
9387
- content: z28.string().optional(),
9388
- start_line: z28.number().int().positive().optional(),
9389
- end_line: z28.number().int().nonnegative().optional(),
9390
- total_lines: z28.number().int().nonnegative().optional()
9651
+ canvas_id: z32.string().optional(),
9652
+ title: z32.string().optional(),
9653
+ permalink: z32.string().optional(),
9654
+ mimetype: z32.string().optional(),
9655
+ filetype: z32.string().optional(),
9656
+ original_byte_length: z32.number().int().nonnegative().optional(),
9657
+ content: z32.string().optional(),
9658
+ start_line: z32.number().int().positive().optional(),
9659
+ end_line: z32.number().int().nonnegative().optional(),
9660
+ total_lines: z32.number().int().nonnegative().optional()
9391
9661
  }).strict();
9392
9662
  function createSlackCanvasReadTool() {
9393
9663
  return zodTool({
@@ -9398,12 +9668,12 @@ function createSlackCanvasReadTool() {
9398
9668
  openWorldHint: true,
9399
9669
  readOnlyHint: true
9400
9670
  },
9401
- inputSchema: z28.object({
9402
- canvas: z28.string().min(1).describe(
9671
+ inputSchema: z32.object({
9672
+ canvas: z32.string().min(1).describe(
9403
9673
  "Canvas/file ID (e.g. `F0ABCDEF`) or Slack canvas/docs URL (e.g. `https://team.slack.com/docs/T.../F...`)."
9404
9674
  ),
9405
- offset: z28.coerce.number().int().min(1).describe("1-indexed line number to start reading from.").optional(),
9406
- limit: z28.coerce.number().int().min(1).describe("Maximum number of lines to read. Defaults to 1000.").optional()
9675
+ offset: z32.coerce.number().int().min(1).describe("1-indexed line number to start reading from.").optional(),
9676
+ limit: z32.coerce.number().int().min(1).describe("Maximum number of lines to read. Defaults to 1000.").optional()
9407
9677
  }),
9408
9678
  outputSchema: slackCanvasReadOutputSchema,
9409
9679
  execute: async ({ canvas, offset, limit }) => {
@@ -9455,7 +9725,7 @@ function createSlackCanvasReadTool() {
9455
9725
  }
9456
9726
 
9457
9727
  // src/chat/slack/tools/canvas/write.ts
9458
- import { z as z29 } from "zod";
9728
+ import { z as z33 } from "zod";
9459
9729
  function createSlackCanvasWriteTool(state) {
9460
9730
  return zodTool({
9461
9731
  annotations: {
@@ -9466,9 +9736,9 @@ function createSlackCanvasWriteTool(state) {
9466
9736
  },
9467
9737
  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.",
9468
9738
  executionMode: "sequential",
9469
- inputSchema: z29.object({
9470
- canvas: z29.string().min(1).describe("Canvas/file ID (e.g. `F0ABCDEF`) or Slack canvas/docs URL."),
9471
- content: z29.string().describe("UTF-8 markdown content to write.")
9739
+ inputSchema: z33.object({
9740
+ canvas: z33.string().min(1).describe("Canvas/file ID (e.g. `F0ABCDEF`) or Slack canvas/docs URL."),
9741
+ content: z33.string().describe("UTF-8 markdown content to write.")
9472
9742
  }),
9473
9743
  outputSchema: juniorToolResultSchema,
9474
9744
  execute: async ({ canvas, content }) => {
@@ -9699,12 +9969,12 @@ async function updateListItem(input) {
9699
9969
  }
9700
9970
 
9701
9971
  // src/chat/slack/id-param.ts
9702
- import { z as z30 } from "zod";
9972
+ import { z as z34 } from "zod";
9703
9973
  function slackChannelIdParam(description) {
9704
- return z30.string().min(1).describe(description);
9974
+ return z34.string().min(1).describe(description);
9705
9975
  }
9706
9976
  function slackUserIdParam(description) {
9707
- return z30.string().min(1).describe(description);
9977
+ return z34.string().min(1).describe(description);
9708
9978
  }
9709
9979
  function parseRequiredSlackChannelIdParam(field, value) {
9710
9980
  const channelId = parseSlackChannelId(value);
@@ -9728,7 +9998,7 @@ function parseRequiredSlackUserIdParam(field, value) {
9728
9998
  }
9729
9999
 
9730
10000
  // src/chat/slack/tools/list/add-items.ts
9731
- import { z as z31 } from "zod";
10001
+ import { z as z35 } from "zod";
9732
10002
  function createSlackListAddItemsTool(state) {
9733
10003
  return zodTool({
9734
10004
  annotations: {
@@ -9738,12 +10008,12 @@ function createSlackListAddItemsTool(state) {
9738
10008
  readOnlyHint: false
9739
10009
  },
9740
10010
  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.",
9741
- inputSchema: z31.object({
9742
- items: z31.array(z31.string().min(1)).min(1).max(25).describe("List item titles to create."),
10011
+ inputSchema: z35.object({
10012
+ items: z35.array(z35.string().min(1)).min(1).max(25).describe("List item titles to create."),
9743
10013
  assignee_user_id: slackUserIdParam(
9744
10014
  "Optional Slack user ID assigned to all created items."
9745
10015
  ).optional(),
9746
- due_date: z31.string().regex(/^\d{4}-\d{2}-\d{2}$/).describe("Optional due date in YYYY-MM-DD format.").optional()
10016
+ due_date: z35.string().regex(/^\d{4}-\d{2}-\d{2}$/).describe("Optional due date in YYYY-MM-DD format.").optional()
9747
10017
  }),
9748
10018
  outputSchema: juniorToolResultSchema,
9749
10019
  execute: async ({ items, assignee_user_id, due_date }) => {
@@ -9797,7 +10067,7 @@ function createSlackListAddItemsTool(state) {
9797
10067
  }
9798
10068
 
9799
10069
  // src/chat/slack/tools/list/create.ts
9800
- import { z as z32 } from "zod";
10070
+ import { z as z36 } from "zod";
9801
10071
  function createSlackListCreateTool(state) {
9802
10072
  return zodTool({
9803
10073
  annotations: {
@@ -9807,8 +10077,8 @@ function createSlackListCreateTool(state) {
9807
10077
  readOnlyHint: false
9808
10078
  },
9809
10079
  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.",
9810
- inputSchema: z32.object({
9811
- name: z32.string().min(1).max(160).describe("Name for the new Slack list.")
10080
+ inputSchema: z36.object({
10081
+ name: z36.string().min(1).max(160).describe("Name for the new Slack list.")
9812
10082
  }),
9813
10083
  outputSchema: juniorToolResultSchema,
9814
10084
  execute: async ({ name }) => {
@@ -9840,7 +10110,7 @@ function createSlackListCreateTool(state) {
9840
10110
  }
9841
10111
 
9842
10112
  // src/chat/slack/tools/list/get-items.ts
9843
- import { z as z33 } from "zod";
10113
+ import { z as z37 } from "zod";
9844
10114
  function createSlackListGetItemsTool(state) {
9845
10115
  return zodTool({
9846
10116
  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.",
@@ -9850,8 +10120,8 @@ function createSlackListGetItemsTool(state) {
9850
10120
  openWorldHint: true,
9851
10121
  readOnlyHint: true
9852
10122
  },
9853
- inputSchema: z33.object({
9854
- limit: z33.coerce.number().int().min(1).max(200).describe("Maximum number of list items to return.").optional()
10123
+ inputSchema: z37.object({
10124
+ limit: z37.coerce.number().int().min(1).max(200).describe("Maximum number of list items to return.").optional()
9855
10125
  }),
9856
10126
  outputSchema: juniorToolResultSchema,
9857
10127
  execute: async ({ limit }) => {
@@ -9876,21 +10146,21 @@ function createSlackListGetItemsTool(state) {
9876
10146
  }
9877
10147
 
9878
10148
  // src/chat/slack/tools/list/update-item.ts
9879
- import { z as z34 } from "zod";
9880
- var booleanInput3 = (description) => z34.preprocess(
10149
+ import { z as z38 } from "zod";
10150
+ var booleanInput3 = (description) => z38.preprocess(
9881
10151
  (value) => value === "true" ? true : value === "false" ? false : value,
9882
- z34.boolean()
10152
+ z38.boolean()
9883
10153
  ).describe(description);
9884
- var updateListItemInputSchema = z34.union([
9885
- z34.object({
9886
- item_id: z34.string().min(1).describe("ID of the Slack list item to update."),
10154
+ var updateListItemInputSchema = z38.union([
10155
+ z38.object({
10156
+ item_id: z38.string().min(1).describe("ID of the Slack list item to update."),
9887
10157
  completed: booleanInput3("Optional completion status update."),
9888
- title: z34.string().min(1).describe("Optional new item title.").optional()
10158
+ title: z38.string().min(1).describe("Optional new item title.").optional()
9889
10159
  }),
9890
- z34.object({
9891
- item_id: z34.string().min(1).describe("ID of the Slack list item to update."),
10160
+ z38.object({
10161
+ item_id: z38.string().min(1).describe("ID of the Slack list item to update."),
9892
10162
  completed: booleanInput3("Optional completion status update.").optional(),
9893
- title: z34.string().min(1).describe("Optional new item title.")
10163
+ title: z38.string().min(1).describe("Optional new item title.")
9894
10164
  })
9895
10165
  ]);
9896
10166
  function createSlackListUpdateItemTool(state) {
@@ -9972,7 +10242,7 @@ async function checkSlackChannelReadAccess(args) {
9972
10242
  }
9973
10243
 
9974
10244
  // src/chat/slack/tools/thread-read.ts
9975
- import { z as z35 } from "zod";
10245
+ import { z as z39 } from "zod";
9976
10246
 
9977
10247
  // src/chat/slack/tools/slack-message-url.ts
9978
10248
  var SLACK_HOST_PATTERN = /^[a-z0-9-]+\.slack(?:-gov)?\.com$/;
@@ -10150,8 +10420,8 @@ function createSlackThreadReadTool(context, deps = {}) {
10150
10420
  openWorldHint: true,
10151
10421
  readOnlyHint: true
10152
10422
  },
10153
- inputSchema: z35.object({
10154
- url: z35.string().min(1).describe(
10423
+ inputSchema: z39.object({
10424
+ url: z39.string().min(1).describe(
10155
10425
  "Slack message archive URL, e.g. https://workspace.slack.com/archives/C123/p1700000000123456"
10156
10426
  ).optional(),
10157
10427
  channel_id: slackChannelIdParam(
@@ -10160,8 +10430,8 @@ function createSlackThreadReadTool(context, deps = {}) {
10160
10430
  ts: slackTimestampParam(
10161
10431
  "Slack message timestamp (e.g. 1700000000.123456). May be the thread root or any message in the thread."
10162
10432
  ).optional(),
10163
- limit: z35.coerce.number().int().min(1).max(1e3).describe("Maximum number of thread messages to fetch.").optional(),
10164
- max_pages: z35.coerce.number().int().min(1).max(10).describe("Maximum number of Slack API pages to traverse.").optional()
10433
+ limit: z39.coerce.number().int().min(1).max(1e3).describe("Maximum number of thread messages to fetch.").optional(),
10434
+ max_pages: z39.coerce.number().int().min(1).max(10).describe("Maximum number of Slack API pages to traverse.").optional()
10165
10435
  }),
10166
10436
  outputSchema: juniorToolResultSchema,
10167
10437
  execute: async ({ url, channel_id, ts, limit, max_pages }) => {
@@ -10417,10 +10687,10 @@ async function searchSlackUsers(options) {
10417
10687
  }
10418
10688
 
10419
10689
  // src/chat/slack/tools/user-lookup.ts
10420
- import { z as z36 } from "zod";
10421
- var booleanInput4 = (description) => z36.preprocess(
10690
+ import { z as z40 } from "zod";
10691
+ var booleanInput4 = (description) => z40.preprocess(
10422
10692
  (value) => value === "true" ? true : value === "false" ? false : value,
10423
- z36.boolean()
10693
+ z40.boolean()
10424
10694
  ).describe(description);
10425
10695
  function createSlackUserLookupTool() {
10426
10696
  return zodTool({
@@ -10431,20 +10701,20 @@ function createSlackUserLookupTool() {
10431
10701
  openWorldHint: true,
10432
10702
  readOnlyHint: true
10433
10703
  },
10434
- inputSchema: z36.object({
10704
+ inputSchema: z40.object({
10435
10705
  user_id: slackUserIdParam(
10436
10706
  "Slack user ID to look up (e.g. U039RR91S). Mutually exclusive with email and query."
10437
10707
  ).optional(),
10438
- email: z36.string().min(3).describe(
10708
+ email: z40.string().min(3).describe(
10439
10709
  "Email address to look up. Mutually exclusive with user_id and query."
10440
10710
  ).optional(),
10441
- query: z36.string().min(2).describe(
10711
+ query: z40.string().min(2).describe(
10442
10712
  "Name to search for (matches against username, display name, real name). Mutually exclusive with user_id and email."
10443
10713
  ).optional(),
10444
- limit: z36.coerce.number().int().min(1).max(20).describe(
10714
+ limit: z40.coerce.number().int().min(1).max(20).describe(
10445
10715
  "Maximum number of results to return for name search. Defaults to 10."
10446
10716
  ).optional(),
10447
- max_pages: z36.coerce.number().int().min(1).max(5).describe(
10717
+ max_pages: z40.coerce.number().int().min(1).max(5).describe(
10448
10718
  "Maximum number of Slack API pages to scan for name search. Defaults to 3."
10449
10719
  ).optional(),
10450
10720
  include_bots: booleanInput4(
@@ -10548,12 +10818,12 @@ function createSlackUserLookupTool() {
10548
10818
  }
10549
10819
 
10550
10820
  // src/chat/tools/system-time.ts
10551
- import { z as z37 } from "zod";
10821
+ import { z as z41 } from "zod";
10552
10822
  var systemTimeOutputSchema = juniorToolResultSchema.extend({
10553
- unix_ms: z37.number(),
10554
- iso_utc: z37.string(),
10555
- iso_local: z37.string(),
10556
- timezone_offset_minutes: z37.number()
10823
+ unix_ms: z41.number(),
10824
+ iso_utc: z41.string(),
10825
+ iso_local: z41.string(),
10826
+ timezone_offset_minutes: z41.number()
10557
10827
  });
10558
10828
  function createSystemTimeTool() {
10559
10829
  return zodTool({
@@ -10564,7 +10834,7 @@ function createSystemTimeTool() {
10564
10834
  openWorldHint: false,
10565
10835
  readOnlyHint: true
10566
10836
  },
10567
- inputSchema: z37.object({}),
10837
+ inputSchema: z41.object({}),
10568
10838
  outputSchema: systemTimeOutputSchema,
10569
10839
  privateTraceResult: (result) => ({
10570
10840
  ok: result.ok,
@@ -10593,7 +10863,7 @@ function createSystemTimeTool() {
10593
10863
  }
10594
10864
 
10595
10865
  // src/chat/tools/query-conversation-events.ts
10596
- import { z as z38 } from "zod";
10866
+ import { z as z42 } from "zod";
10597
10867
  var DEFAULT_LIMIT3 = 25;
10598
10868
  var MAX_LIMIT = 100;
10599
10869
  var MAX_EVENT_DATA_BYTES = 4e3;
@@ -10604,28 +10874,28 @@ var CONVERSATION_EVENTS_TOOL_SOURCE = {
10604
10874
  id: "conversation-events",
10605
10875
  description: "Inspect Junior's durable conversation event log for debugging runtime behavior."
10606
10876
  };
10607
- var knownEventTypeSchema = z38.enum(KNOWN_CONVERSATION_EVENT_TYPES);
10608
- var projectedEventSchema = z38.object({
10609
- seq: z38.number().int().nonnegative().describe("Stable event position; use it for pagination bounds."),
10610
- history_version: z38.number().int().nonnegative().describe(
10877
+ var knownEventTypeSchema = z42.enum(KNOWN_CONVERSATION_EVENT_TYPES);
10878
+ var projectedEventSchema = z42.object({
10879
+ seq: z42.number().int().nonnegative().describe("Stable event position; use it for pagination bounds."),
10880
+ history_version: z42.number().int().nonnegative().describe(
10611
10881
  "Model-history generation. It increments when handoff or compaction replaces active model context."
10612
10882
  ),
10613
- created_at: z38.iso.datetime().describe("When the event was recorded."),
10614
- idempotency_key: z38.string().min(1).optional().describe("Retry-stable event identity, when one was assigned."),
10615
- data: z38.record(z38.string(), z38.unknown()).describe(
10883
+ created_at: z42.iso.datetime().describe("When the event was recorded."),
10884
+ idempotency_key: z42.string().min(1).optional().describe("Retry-stable event identity, when one was assigned."),
10885
+ data: z42.record(z42.string(), z42.unknown()).describe(
10616
10886
  "Event data. Oversized payloads are replaced by identifying fields, payload_omitted, and payload_json_bytes."
10617
10887
  )
10618
10888
  }).strict();
10619
10889
  var queryConversationEventsOutputSchema = juniorToolResultSchema.extend({
10620
- conversation_id: z38.string().min(1),
10621
- events: z38.array(projectedEventSchema),
10622
- has_older: z38.boolean().describe(
10890
+ conversation_id: z42.string().min(1),
10891
+ events: z42.array(projectedEventSchema),
10892
+ has_older: z42.boolean().describe(
10623
10893
  "Whether matching events exist before this page; request them with before_seq set to the first returned seq."
10624
10894
  ),
10625
- has_newer: z38.boolean().describe(
10895
+ has_newer: z42.boolean().describe(
10626
10896
  "Whether matching events exist after this page; request them with after_seq set to the last returned seq."
10627
10897
  ),
10628
- omitted_event_count: z38.number().int().nonnegative().optional().describe(
10898
+ omitted_event_count: z42.number().int().nonnegative().optional().describe(
10629
10899
  "Fetched events omitted to keep this response bounded. Continue with the pagination cursor for the omitted direction."
10630
10900
  )
10631
10901
  });
@@ -10640,20 +10910,20 @@ function createQueryConversationEventsTool(context) {
10640
10910
  openWorldHint: false,
10641
10911
  readOnlyHint: true
10642
10912
  },
10643
- inputSchema: z38.object({
10644
- conversation_id: z38.string().trim().min(1).describe(
10913
+ inputSchema: z42.object({
10914
+ conversation_id: z42.string().trim().min(1).describe(
10645
10915
  "Conversation ID to inspect, such as slack:{channelId}:{threadTs} or a child conversation id."
10646
10916
  ),
10647
- after_seq: z38.number().int().nonnegative().nullable().describe(
10917
+ after_seq: z42.number().int().nonnegative().nullable().describe(
10648
10918
  "Exclusive lower bound on event seq. When set, returns the next newer page in ascending order."
10649
10919
  ).optional(),
10650
- before_seq: z38.number().int().nonnegative().nullable().describe(
10920
+ before_seq: z42.number().int().nonnegative().nullable().describe(
10651
10921
  "Exclusive upper bound on event seq. Combine with defaults or after_seq to page older or bounded ranges."
10652
10922
  ).optional(),
10653
- limit: z38.number().int().min(1).max(MAX_LIMIT).nullable().describe(
10923
+ limit: z42.number().int().min(1).max(MAX_LIMIT).nullable().describe(
10654
10924
  `Maximum events to return. Defaults to ${DEFAULT_LIMIT3}; max ${MAX_LIMIT}.`
10655
10925
  ).optional(),
10656
- types: z38.array(knownEventTypeSchema).min(1).nullable().describe(
10926
+ types: z42.array(knownEventTypeSchema).min(1).nullable().describe(
10657
10927
  "Optional event-type filter. Omit to return every durable event type."
10658
10928
  ).optional()
10659
10929
  }).strict(),
@@ -10903,10 +11173,10 @@ function stripReplacementHistoryField(value) {
10903
11173
  }
10904
11174
 
10905
11175
  // src/chat/tools/handoff/tool.ts
10906
- import { z as z39 } from "zod";
11176
+ import { z as z43 } from "zod";
10907
11177
  var HANDOFF_TOOL_NAME = "handoff";
10908
11178
  function createHandoffTool(handoff) {
10909
- const profileSchema = z39.enum(handoff.profiles);
11179
+ const profileSchema = z43.enum(handoff.profiles);
10910
11180
  const handoffResultSchema = juniorToolResultSchema.extend({
10911
11181
  model_profile: modelProfileSchema
10912
11182
  });
@@ -10920,7 +11190,7 @@ function createHandoffTool(handoff) {
10920
11190
  },
10921
11191
  description: `Switch to another execution profile and continue the same task. Profiles: ${profileNames}. Call this as the only tool.`,
10922
11192
  executionMode: "sequential",
10923
- inputSchema: z39.object({
11193
+ inputSchema: z43.object({
10924
11194
  profile: profileSchema.describe("Target execution profile")
10925
11195
  }).strict(),
10926
11196
  outputSchema: handoffResultSchema,
@@ -10943,7 +11213,7 @@ function createHandoffTool(handoff) {
10943
11213
  }
10944
11214
 
10945
11215
  // src/chat/tools/web/fetch-tool.ts
10946
- import { z as z40 } from "zod";
11216
+ import { z as z44 } from "zod";
10947
11217
 
10948
11218
  // src/chat/tools/web/constants.ts
10949
11219
  var USER_AGENT = "junior-bot/0.1";
@@ -11394,9 +11664,9 @@ function createWebFetchTool(hooks, options = {}) {
11394
11664
  openWorldHint: true,
11395
11665
  readOnlyHint: true
11396
11666
  },
11397
- inputSchema: z40.object({
11398
- url: z40.string().min(1).describe("HTTP(S) URL to fetch."),
11399
- max_chars: z40.coerce.number().int().min(500).max(MAX_FETCH_CHARS).describe("Optional maximum number of extracted characters to return.").optional()
11667
+ inputSchema: z44.object({
11668
+ url: z44.string().min(1).describe("HTTP(S) URL to fetch."),
11669
+ max_chars: z44.coerce.number().int().min(500).max(MAX_FETCH_CHARS).describe("Optional maximum number of extracted characters to return.").optional()
11400
11670
  }),
11401
11671
  outputSchema: juniorToolResultSchema,
11402
11672
  execute: async ({ url, max_chars }) => {
@@ -11457,7 +11727,7 @@ function createWebFetchTool(hooks, options = {}) {
11457
11727
  }
11458
11728
 
11459
11729
  // src/chat/tools/web/search.ts
11460
- import { z as z41 } from "zod";
11730
+ import { z as z45 } from "zod";
11461
11731
  import { generateText } from "ai";
11462
11732
  import { createGatewayProvider } from "@ai-sdk/gateway";
11463
11733
  var SEARCH_TIMEOUT_MS = 6e4;
@@ -11507,9 +11777,9 @@ function createWebSearchTool(modelId, override) {
11507
11777
  openWorldHint: true,
11508
11778
  readOnlyHint: true
11509
11779
  },
11510
- inputSchema: z41.object({
11511
- query: z41.string().min(1).max(500).describe("Search query."),
11512
- max_results: z41.coerce.number().int().min(1).max(MAX_RESULTS2).describe("Max results to return.").optional()
11780
+ inputSchema: z45.object({
11781
+ query: z45.string().min(1).max(500).describe("Search query."),
11782
+ max_results: z45.coerce.number().int().min(1).max(MAX_RESULTS2).describe("Max results to return.").optional()
11513
11783
  }),
11514
11784
  outputSchema: juniorToolResultSchema,
11515
11785
  execute: async ({ query, max_results }) => {
@@ -11572,7 +11842,7 @@ function createWebSearchTool(modelId, override) {
11572
11842
  }
11573
11843
 
11574
11844
  // src/chat/tools/sandbox/write-file.ts
11575
- import { z as z42 } from "zod";
11845
+ import { z as z46 } from "zod";
11576
11846
  function createWriteFileTool() {
11577
11847
  return zodTool({
11578
11848
  annotations: {
@@ -11583,9 +11853,9 @@ function createWriteFileTool() {
11583
11853
  },
11584
11854
  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.",
11585
11855
  executionMode: "sequential",
11586
- inputSchema: z42.object({
11587
- path: z42.string().min(1).describe("Path to write in the sandbox workspace."),
11588
- content: z42.string().describe("UTF-8 file content to write.")
11856
+ inputSchema: z46.object({
11857
+ path: z46.string().min(1).describe("Path to write in the sandbox workspace."),
11858
+ content: z46.string().describe("UTF-8 file content to write.")
11589
11859
  }),
11590
11860
  outputSchema: juniorToolResultSchema,
11591
11861
  execute: async () => {
@@ -11632,6 +11902,15 @@ function createTools(availableSkills, hooks = {}, context, options = {}) {
11632
11902
  const canSendFilesToActiveConversation = Boolean(
11633
11903
  slackContext && slackSourceCapabilities?.canSendFiles
11634
11904
  );
11905
+ const resourceEventCatalog = Object.fromEntries(
11906
+ getPlugins().flatMap((plugin) => {
11907
+ const registration = plugin.resourceEvents;
11908
+ if (!registration || registration.isEnabled?.() === false) {
11909
+ return [];
11910
+ }
11911
+ return [[plugin.manifest.name, registration]];
11912
+ })
11913
+ );
11635
11914
  const tools = {
11636
11915
  ...options.includeLoadSkill === false ? {} : {
11637
11916
  loadSkill: createLoadSkillTool(availableSkills, {
@@ -11654,7 +11933,7 @@ function createTools(availableSkills, hooks = {}, context, options = {}) {
11654
11933
  webFetch: createWebFetchTool(hooks, {
11655
11934
  canSendFilesToActiveConversation
11656
11935
  }),
11657
- ...createResourceEventTools(context)
11936
+ ...createResourceEventTools(context, resourceEventCatalog)
11658
11937
  };
11659
11938
  if (context.conversationId) {
11660
11939
  tools.queryConversationEvents = createQueryConversationEventsTool(context);
@@ -12629,7 +12908,7 @@ function handleToolExecutionError(error, toolName, toolCallId, shouldTrace, conv
12629
12908
  }
12630
12909
 
12631
12910
  // src/chat/tools/execute-tool.ts
12632
- import { z as z43 } from "zod";
12911
+ import { z as z47 } from "zod";
12633
12912
  var EXECUTE_TOOL_NAME = "executeTool";
12634
12913
  function createExecuteToolTool() {
12635
12914
  return zodTool({
@@ -12641,11 +12920,11 @@ function createExecuteToolTool() {
12641
12920
  },
12642
12921
  description: "Execute any catalog tool by exact tool_name from searchTools or a tool-result execution hint. Put tool-specific parameters inside arguments.",
12643
12922
  executionMode: "sequential",
12644
- inputSchema: z43.object({
12645
- tool_name: z43.string().min(1).describe(
12923
+ inputSchema: z47.object({
12924
+ tool_name: z47.string().min(1).describe(
12646
12925
  "Exact catalog tool_name returned by searchTools or a tool-result execution hint."
12647
12926
  ),
12648
- arguments: z43.record(z43.string(), z43.unknown()).describe(
12927
+ arguments: z47.record(z47.string(), z47.unknown()).describe(
12649
12928
  'Arguments matching the selected catalog tool schema, for example { "query": "..." }.'
12650
12929
  ).optional()
12651
12930
  }).strict(),
@@ -12685,34 +12964,34 @@ function planToolExposure(tools) {
12685
12964
  }
12686
12965
 
12687
12966
  // src/chat/tools/search-tools.ts
12688
- import { z as z44 } from "zod";
12967
+ import { z as z48 } from "zod";
12689
12968
  var SEARCH_TOOLS_NAME = "searchTools";
12690
12969
  var DEFAULT_MAX_RESULTS2 = 5;
12691
12970
  var MAX_RESULTS3 = 20;
12692
12971
  var MODEL_VISIBLE_DESCRIPTION_CAP = 180;
12693
- var searchToolsSourceSchema = z44.object({
12694
- id: z44.string(),
12695
- description: z44.string()
12972
+ var searchToolsSourceSchema = z48.object({
12973
+ id: z48.string(),
12974
+ description: z48.string()
12696
12975
  }).strict();
12697
- var searchToolsToolSchema = z44.object({
12698
- tool_name: z44.string(),
12699
- description: z44.string(),
12700
- exposure: z44.enum(["direct", "deferred", "modelOnly", "hidden"]),
12701
- source: z44.string().optional(),
12702
- input_schema: z44.unknown(),
12703
- call_notes: z44.array(z44.string()),
12704
- annotations: z44.record(z44.string(), z44.unknown())
12976
+ var searchToolsToolSchema = z48.object({
12977
+ tool_name: z48.string(),
12978
+ description: z48.string(),
12979
+ exposure: z48.enum(["direct", "deferred", "modelOnly", "hidden"]),
12980
+ source: z48.string().optional(),
12981
+ input_schema: z48.unknown(),
12982
+ call_notes: z48.array(z48.string()),
12983
+ annotations: z48.record(z48.string(), z48.unknown())
12705
12984
  }).strict();
12706
12985
  var searchToolsOutputSchema = juniorToolResultSchema.extend({
12707
- query: z44.string().nullable(),
12708
- source: z44.string().nullable(),
12709
- sources: z44.array(searchToolsSourceSchema),
12710
- total_catalog_tools: z44.number().int().nonnegative(),
12711
- total_eligible_tools: z44.number().int().nonnegative(),
12712
- total_matches: z44.number().int().nonnegative(),
12713
- returned_tools: z44.number().int().nonnegative(),
12714
- execution_tool: z44.literal("executeTool"),
12715
- tools: z44.array(searchToolsToolSchema)
12986
+ query: z48.string().nullable(),
12987
+ source: z48.string().nullable(),
12988
+ sources: z48.array(searchToolsSourceSchema),
12989
+ total_catalog_tools: z48.number().int().nonnegative(),
12990
+ total_eligible_tools: z48.number().int().nonnegative(),
12991
+ total_matches: z48.number().int().nonnegative(),
12992
+ returned_tools: z48.number().int().nonnegative(),
12993
+ execution_tool: z48.literal("executeTool"),
12994
+ tools: z48.array(searchToolsToolSchema)
12716
12995
  }).strict();
12717
12996
  function normalize2(value) {
12718
12997
  return value.toLowerCase().replace(/[^a-z0-9_]+/g, " ").trim();
@@ -12827,14 +13106,14 @@ function createSearchToolsTool(catalogTools) {
12827
13106
  openWorldHint: false,
12828
13107
  readOnlyHint: true
12829
13108
  },
12830
- inputSchema: z44.object({
12831
- query: z44.string().nullable().describe(
13109
+ inputSchema: z48.object({
13110
+ query: z48.string().nullable().describe(
12832
13111
  "Optional search terms describing the tool, owner, action, or arguments needed. Empty string lists catalog tools."
12833
13112
  ).optional(),
12834
- source: z44.string().nullable().describe(
13113
+ source: z48.string().nullable().describe(
12835
13114
  "Optional source id to search within, such as a plugin source returned in sources."
12836
13115
  ).optional(),
12837
- max_results: z44.number().int().min(1).max(MAX_RESULTS3).nullable().describe("Maximum matching catalog tool descriptors to return.").optional()
13116
+ max_results: z48.number().int().min(1).max(MAX_RESULTS3).nullable().describe("Maximum matching catalog tool descriptors to return.").optional()
12838
13117
  }).strict(),
12839
13118
  outputSchema: searchToolsOutputSchema,
12840
13119
  privateTraceResult: (result) => ({
@@ -14091,7 +14370,7 @@ function createPluginEgress(deps) {
14091
14370
  }
14092
14371
 
14093
14372
  // src/chat/services/guardian-action-review.ts
14094
- import { z as z45 } from "zod";
14373
+ import { z as z49 } from "zod";
14095
14374
 
14096
14375
  // src/chat/services/guardian-action-policy.ts
14097
14376
  var GUARDIAN_ACTION_POLICY = `You are judging one planned Junior agent action.
@@ -14155,17 +14434,17 @@ Assess the exact action's intrinsic risk and whether the user's intent authorize
14155
14434
  - 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.`;
14156
14435
 
14157
14436
  // src/chat/services/guardian-action-review.ts
14158
- var guardianDecisionSchema = z45.object({
14159
- decision: z45.enum(["allow", "ask", "deny"]),
14160
- reason: z45.string().trim().min(1).max(500),
14161
- riskLevel: z45.enum(["low", "medium", "high", "critical"]),
14162
- userAuthorization: z45.enum(["high", "medium", "low", "unknown"])
14437
+ var guardianDecisionSchema = z49.object({
14438
+ decision: z49.enum(["allow", "ask", "deny"]),
14439
+ reason: z49.string().trim().min(1).max(500),
14440
+ riskLevel: z49.enum(["low", "medium", "high", "critical"]),
14441
+ userAuthorization: z49.enum(["high", "medium", "low", "unknown"])
14163
14442
  }).strict();
14164
14443
  var GUARDIAN_REVIEW_TIMEOUT_MS = 6e4;
14165
14444
  var GUARDIAN_REVIEW_MAX_TOKENS = 2e3;
14166
14445
  var MAX_PROPOSAL_CHARS = 192e3;
14167
14446
  function guardianPrompt(proposal) {
14168
- const proposalJson = JSON.stringify(z45.json().parse(proposal), null, 2);
14447
+ const proposalJson = JSON.stringify(z49.json().parse(proposal), null, 2);
14169
14448
  if (proposalJson.length > MAX_PROPOSAL_CHARS) {
14170
14449
  throw new Error(
14171
14450
  `Guardian action proposal exceeds ${MAX_PROPOSAL_CHARS} characters.`