@sentry/junior 0.126.0 → 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.
- package/dist/{agent-hooks-HDSNWDQM.js → agent-hooks-HMCMFIIO.js} +8 -8
- package/dist/api/people/spend.d.ts +4 -0
- package/dist/api/people/spend.query.d.ts +3 -0
- package/dist/api/schema/person.d.ts +9 -0
- package/dist/api/schema.d.ts +2 -2
- package/dist/api/schema.js +3 -1
- package/dist/api.js +133 -33
- package/dist/app.js +29 -29
- package/dist/{catalog-runtime-BDC3UWPG.js → catalog-runtime-MI5UNBZ7.js} +5 -5
- package/dist/chat/plugins/agent-hooks.d.ts +4 -2
- package/dist/chat/resource-events/catalog.d.ts +21 -0
- package/dist/chat/resource-events/ingest.d.ts +1 -1
- package/dist/chat/resource-events/notification.d.ts +2 -2
- package/dist/chat/resource-events/store.d.ts +9 -9
- package/dist/chat/resource-events/tool-support.d.ts +10 -0
- package/dist/chat/task-execution/slack-work.d.ts +4 -4
- package/dist/chat/tools/list-resource-event-subscriptions.d.ts +80 -0
- package/dist/chat/tools/resource-events.d.ts +2 -1
- package/dist/chat/tools/search-resource-event-types.d.ts +60 -0
- package/dist/chat/tools/stop-watching-resources.d.ts +50 -0
- package/dist/chat/tools/watch-resource-events.d.ts +105 -0
- package/dist/{chunk-72SDEHFP.js → chunk-2M6LYDTB.js} +1 -1
- package/dist/{chunk-GHNO2WUH.js → chunk-2N6EL22B.js} +1 -1
- package/dist/{chunk-YMSVBWBY.js → chunk-4H2NZPFJ.js} +6 -6
- package/dist/{chunk-4PV73JHH.js → chunk-6DU2ZNF7.js} +7 -7
- package/dist/{chunk-6ZBSTNYN.js → chunk-AFJF3RGU.js} +9 -0
- package/dist/{chunk-LCRWDMCH.js → chunk-AKL3BAYJ.js} +1 -1
- package/dist/{chunk-JP2ZOSQK.js → chunk-AYICPT5T.js} +1 -1
- package/dist/{chunk-XVKJJXHF.js → chunk-C7AVHH3H.js} +2 -2
- package/dist/{chunk-EFQX6XBW.js → chunk-FVIU6NQO.js} +1 -1
- package/dist/{chunk-ACJZZY5W.js → chunk-JNYR4G7A.js} +2 -2
- package/dist/{chunk-JFW62B3Y.js → chunk-JXQWTNDI.js} +1 -1
- package/dist/{chunk-XLIAQRDI.js → chunk-L7L7RYJM.js} +2 -2
- package/dist/{chunk-VUBUFT66.js → chunk-NK7QVIMJ.js} +1 -1
- package/dist/{chunk-GK55KLEH.js → chunk-NYVMPADK.js} +1 -1
- package/dist/{chunk-KP7E267S.js → chunk-PDG3BSOD.js} +2 -2
- package/dist/{chunk-APYVVX2Y.js → chunk-SH7HDO2D.js} +1 -1
- package/dist/{chunk-6KWO5DU3.js → chunk-TLMI3Q4Q.js} +35 -12
- package/dist/{chunk-KISG7E24.js → chunk-UEMGGJZD.js} +12 -12
- package/dist/{chunk-EQMSKORN.js → chunk-VHUMNUJL.js} +1 -1
- package/dist/{chunk-WRH7DWFO.js → chunk-WXP2ZXC7.js} +4 -4
- package/dist/{chunk-LIDEU7QS.js → chunk-YSOZT72W.js} +4 -4
- package/dist/{chunk-TUHUIBDX.js → chunk-Z5LLJNTL.js} +669 -390
- package/dist/cli/chat.js +23 -23
- package/dist/cli/check.js +6 -6
- package/dist/cli/plugins.js +11 -11
- package/dist/cli/snapshot-create.js +9 -9
- package/dist/cli/upgrade.js +6 -6
- package/dist/{db-AZB6AGJL.js → db-N4EY57ZJ.js} +6 -6
- package/dist/instrumentation.js +4 -4
- package/dist/nitro.js +2 -2
- package/dist/{oauth-callback-server-XK4QJLPZ.js → oauth-callback-server-O62UOQSS.js} +16 -16
- package/dist/{runner-DSGDSATN.js → runner-SRHRD3NX.js} +10 -10
- package/dist/{skills-CO6E3BQJ.js → skills-V6X3JVVA.js} +6 -6
- package/dist/{validation-IHLISKM5.js → validation-ZZXZELGH.js} +6 -6
- package/dist/version.js +1 -1
- package/package.json +6 -6
|
@@ -30,7 +30,7 @@ import {
|
|
|
30
30
|
toMcpProviderError,
|
|
31
31
|
toolInvocationDestination,
|
|
32
32
|
uploadFilesToConversation
|
|
33
|
-
} from "./chunk-
|
|
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-
|
|
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-
|
|
107
|
+
} from "./chunk-YSOZT72W.js";
|
|
108
108
|
import {
|
|
109
109
|
incrementStat
|
|
110
|
-
} from "./chunk-
|
|
110
|
+
} from "./chunk-VHUMNUJL.js";
|
|
111
111
|
import {
|
|
112
112
|
parseSlackThreadId
|
|
113
|
-
} from "./chunk-
|
|
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-
|
|
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-
|
|
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-
|
|
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-
|
|
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-
|
|
200
|
+
} from "./chunk-NK7QVIMJ.js";
|
|
200
201
|
import {
|
|
201
202
|
discoverSkills,
|
|
202
203
|
findSkillByName,
|
|
203
204
|
loadSkillsByName,
|
|
204
205
|
parseSkillInvocation
|
|
205
|
-
} from "./chunk-
|
|
206
|
+
} from "./chunk-JNYR4G7A.js";
|
|
206
207
|
import {
|
|
207
208
|
pluginCatalogRuntime
|
|
208
|
-
} from "./chunk-
|
|
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-
|
|
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-
|
|
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
|
|
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(
|
|
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 (
|
|
4361
|
+
if (outputSchema5) {
|
|
4360
4362
|
try {
|
|
4361
|
-
modelOutputSchema = z4.toJSONSchema(
|
|
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
|
-
|
|
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 (!
|
|
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:
|
|
4398
|
+
details: outputSchema5.parse(
|
|
4397
4399
|
juniorToolResultSchema.parse(result.details)
|
|
4398
4400
|
)
|
|
4399
4401
|
};
|
|
4400
4402
|
}
|
|
4401
|
-
return
|
|
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
|
|
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
|
-
...
|
|
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/
|
|
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 {
|
|
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(
|
|
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
|
-
|
|
7655
|
-
|
|
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(
|
|
7670
|
-
return `${RESOURCE_EVENT_PREFIX}:resource:${digest(`${
|
|
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.
|
|
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.
|
|
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
|
-
|
|
7827
|
-
|
|
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
|
-
|
|
7839
|
-
|
|
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.
|
|
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.
|
|
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.
|
|
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
|
-
|
|
7946
|
-
|
|
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
|
-
|
|
7965
|
-
|
|
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.
|
|
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-
|
|
8007
|
-
var
|
|
8008
|
-
|
|
8009
|
-
|
|
8010
|
-
|
|
8011
|
-
|
|
8012
|
-
|
|
8013
|
-
|
|
8014
|
-
|
|
8015
|
-
|
|
8016
|
-
|
|
8017
|
-
|
|
8018
|
-
|
|
8019
|
-
|
|
8020
|
-
|
|
8021
|
-
|
|
8022
|
-
|
|
8023
|
-
|
|
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
|
|
8074
|
+
inputSchema: z19.object({}).strict(),
|
|
8075
|
+
outputSchema,
|
|
8132
8076
|
async execute() {
|
|
8133
|
-
const conversationId =
|
|
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
|
-
|
|
8142
|
-
|
|
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
|
|
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:
|
|
8170
|
-
outputSchema:
|
|
8171
|
-
async execute() {
|
|
8172
|
-
const conversationId =
|
|
8173
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
8458
|
+
...discoveryTools,
|
|
8459
|
+
...enabled ? {
|
|
8460
|
+
watchResourceEvents: createWatchResourceEventsTool(context, catalog)
|
|
8461
|
+
} : {},
|
|
8192
8462
|
listResourceEventSubscriptions: createListResourceEventSubscriptionsTool(context),
|
|
8193
|
-
|
|
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
|
|
8546
|
+
import { z as z24 } from "zod";
|
|
8277
8547
|
function slackTimestampParam(description) {
|
|
8278
|
-
return
|
|
8548
|
+
return z24.preprocess(
|
|
8279
8549
|
(value) => typeof value === "number" && Number.isFinite(value) ? String(value) : value,
|
|
8280
|
-
|
|
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
|
|
8312
|
-
var booleanInput2 = (description) =>
|
|
8581
|
+
import { z as z25 } from "zod";
|
|
8582
|
+
var booleanInput2 = (description) => z25.preprocess(
|
|
8313
8583
|
(value) => value === "true" ? true : value === "false" ? false : value,
|
|
8314
|
-
|
|
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:
|
|
8347
|
-
limit:
|
|
8348
|
-
cursor:
|
|
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:
|
|
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
|
|
8702
|
+
import { z as z26 } from "zod";
|
|
8433
8703
|
var DEFAULT_LIMIT = 5;
|
|
8434
8704
|
var conversationSearchOutputSchema = juniorToolResultSchema.extend({
|
|
8435
|
-
query:
|
|
8436
|
-
count:
|
|
8437
|
-
threads:
|
|
8438
|
-
|
|
8439
|
-
conversation_id:
|
|
8440
|
-
thread_ts:
|
|
8441
|
-
message_id:
|
|
8442
|
-
message_role:
|
|
8443
|
-
message_timestamp:
|
|
8444
|
-
excerpt:
|
|
8445
|
-
permalink:
|
|
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:
|
|
8464
|
-
query:
|
|
8465
|
-
limit:
|
|
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
|
|
8782
|
+
import { z as z27 } from "zod";
|
|
8513
8783
|
var DEFAULT_LIMIT2 = 10;
|
|
8514
|
-
var optionalTimestampSchema =
|
|
8784
|
+
var optionalTimestampSchema = z27.preprocess(
|
|
8515
8785
|
(value) => typeof value === "string" && value.trim() === "" ? void 0 : value,
|
|
8516
|
-
|
|
8786
|
+
z27.coerce.number().int().nonnegative().describe("Optional Unix timestamp bound.").optional()
|
|
8517
8787
|
);
|
|
8518
|
-
var searchMessageSchema =
|
|
8519
|
-
author_name:
|
|
8520
|
-
author_user_id:
|
|
8521
|
-
channel_id:
|
|
8522
|
-
channel_name:
|
|
8523
|
-
message_ts:
|
|
8524
|
-
content:
|
|
8525
|
-
is_author_bot:
|
|
8526
|
-
permalink:
|
|
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:
|
|
8530
|
-
count:
|
|
8531
|
-
messages:
|
|
8532
|
-
next_cursor:
|
|
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:
|
|
8560
|
-
query:
|
|
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:
|
|
8570
|
-
limit:
|
|
8571
|
-
sort:
|
|
8572
|
-
sort_dir:
|
|
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
|
|
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:
|
|
8669
|
-
emoji:
|
|
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
|
|
8721
|
-
var sendFilesDataSchema =
|
|
8722
|
-
channel_id:
|
|
8723
|
-
deduplicated:
|
|
8724
|
-
file_count:
|
|
8725
|
-
file_ids:
|
|
8726
|
-
thread_ts:
|
|
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:
|
|
8730
|
-
status:
|
|
8731
|
-
target:
|
|
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:
|
|
8763
|
-
files:
|
|
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
|
|
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:
|
|
9213
|
-
title:
|
|
9214
|
-
markdown:
|
|
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
|
|
9542
|
+
import { z as z31 } from "zod";
|
|
9273
9543
|
function prepareCanvasEditArguments(input) {
|
|
9274
9544
|
return prepareTextReplacementArguments(input);
|
|
9275
9545
|
}
|
|
9276
|
-
var editReplacementSchema2 =
|
|
9277
|
-
oldText:
|
|
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:
|
|
9550
|
+
newText: z31.string().describe("Replacement Canvas markdown for this edit.")
|
|
9281
9551
|
});
|
|
9282
9552
|
var slackCanvasEditOutputSchema = juniorToolResultSchema.extend({
|
|
9283
|
-
canvas_id:
|
|
9284
|
-
title:
|
|
9285
|
-
permalink:
|
|
9286
|
-
diff:
|
|
9287
|
-
first_changed_line:
|
|
9288
|
-
replacements:
|
|
9289
|
-
normalized_heading_count:
|
|
9290
|
-
summary:
|
|
9291
|
-
deduplicated:
|
|
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:
|
|
9305
|
-
canvas:
|
|
9306
|
-
edits:
|
|
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
|
|
9649
|
+
import { z as z32 } from "zod";
|
|
9380
9650
|
var slackCanvasReadOutputSchema = juniorToolResultSchema.extend({
|
|
9381
|
-
canvas_id:
|
|
9382
|
-
title:
|
|
9383
|
-
permalink:
|
|
9384
|
-
mimetype:
|
|
9385
|
-
filetype:
|
|
9386
|
-
original_byte_length:
|
|
9387
|
-
content:
|
|
9388
|
-
start_line:
|
|
9389
|
-
end_line:
|
|
9390
|
-
total_lines:
|
|
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:
|
|
9402
|
-
canvas:
|
|
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:
|
|
9406
|
-
limit:
|
|
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
|
|
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:
|
|
9470
|
-
canvas:
|
|
9471
|
-
content:
|
|
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
|
|
9972
|
+
import { z as z34 } from "zod";
|
|
9703
9973
|
function slackChannelIdParam(description) {
|
|
9704
|
-
return
|
|
9974
|
+
return z34.string().min(1).describe(description);
|
|
9705
9975
|
}
|
|
9706
9976
|
function slackUserIdParam(description) {
|
|
9707
|
-
return
|
|
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
|
|
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:
|
|
9742
|
-
items:
|
|
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:
|
|
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
|
|
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:
|
|
9811
|
-
name:
|
|
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
|
|
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:
|
|
9854
|
-
limit:
|
|
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
|
|
9880
|
-
var booleanInput3 = (description) =>
|
|
10149
|
+
import { z as z38 } from "zod";
|
|
10150
|
+
var booleanInput3 = (description) => z38.preprocess(
|
|
9881
10151
|
(value) => value === "true" ? true : value === "false" ? false : value,
|
|
9882
|
-
|
|
10152
|
+
z38.boolean()
|
|
9883
10153
|
).describe(description);
|
|
9884
|
-
var updateListItemInputSchema =
|
|
9885
|
-
|
|
9886
|
-
item_id:
|
|
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:
|
|
10158
|
+
title: z38.string().min(1).describe("Optional new item title.").optional()
|
|
9889
10159
|
}),
|
|
9890
|
-
|
|
9891
|
-
item_id:
|
|
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:
|
|
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
|
|
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:
|
|
10154
|
-
url:
|
|
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:
|
|
10164
|
-
max_pages:
|
|
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
|
|
10421
|
-
var booleanInput4 = (description) =>
|
|
10690
|
+
import { z as z40 } from "zod";
|
|
10691
|
+
var booleanInput4 = (description) => z40.preprocess(
|
|
10422
10692
|
(value) => value === "true" ? true : value === "false" ? false : value,
|
|
10423
|
-
|
|
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:
|
|
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:
|
|
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:
|
|
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:
|
|
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:
|
|
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
|
|
10821
|
+
import { z as z41 } from "zod";
|
|
10552
10822
|
var systemTimeOutputSchema = juniorToolResultSchema.extend({
|
|
10553
|
-
unix_ms:
|
|
10554
|
-
iso_utc:
|
|
10555
|
-
iso_local:
|
|
10556
|
-
timezone_offset_minutes:
|
|
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:
|
|
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
|
|
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 =
|
|
10608
|
-
var projectedEventSchema =
|
|
10609
|
-
seq:
|
|
10610
|
-
history_version:
|
|
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:
|
|
10614
|
-
idempotency_key:
|
|
10615
|
-
data:
|
|
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:
|
|
10621
|
-
events:
|
|
10622
|
-
has_older:
|
|
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:
|
|
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:
|
|
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:
|
|
10644
|
-
conversation_id:
|
|
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:
|
|
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:
|
|
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:
|
|
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:
|
|
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
|
|
11176
|
+
import { z as z43 } from "zod";
|
|
10907
11177
|
var HANDOFF_TOOL_NAME = "handoff";
|
|
10908
11178
|
function createHandoffTool(handoff) {
|
|
10909
|
-
const profileSchema =
|
|
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:
|
|
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
|
|
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:
|
|
11398
|
-
url:
|
|
11399
|
-
max_chars:
|
|
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
|
|
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:
|
|
11511
|
-
query:
|
|
11512
|
-
max_results:
|
|
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
|
|
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:
|
|
11587
|
-
path:
|
|
11588
|
-
content:
|
|
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
|
|
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:
|
|
12645
|
-
tool_name:
|
|
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:
|
|
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
|
|
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 =
|
|
12694
|
-
id:
|
|
12695
|
-
description:
|
|
12972
|
+
var searchToolsSourceSchema = z48.object({
|
|
12973
|
+
id: z48.string(),
|
|
12974
|
+
description: z48.string()
|
|
12696
12975
|
}).strict();
|
|
12697
|
-
var searchToolsToolSchema =
|
|
12698
|
-
tool_name:
|
|
12699
|
-
description:
|
|
12700
|
-
exposure:
|
|
12701
|
-
source:
|
|
12702
|
-
input_schema:
|
|
12703
|
-
call_notes:
|
|
12704
|
-
annotations:
|
|
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:
|
|
12708
|
-
source:
|
|
12709
|
-
sources:
|
|
12710
|
-
total_catalog_tools:
|
|
12711
|
-
total_eligible_tools:
|
|
12712
|
-
total_matches:
|
|
12713
|
-
returned_tools:
|
|
12714
|
-
execution_tool:
|
|
12715
|
-
tools:
|
|
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:
|
|
12831
|
-
query:
|
|
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:
|
|
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:
|
|
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
|
|
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 =
|
|
14159
|
-
decision:
|
|
14160
|
-
reason:
|
|
14161
|
-
riskLevel:
|
|
14162
|
-
userAuthorization:
|
|
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(
|
|
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.`
|