@sentry/junior 0.104.2 → 0.106.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-EOFSY2PD.js → agent-hooks-KR5BCWOK.js} +5 -5
- package/dist/api/conversations/schema.d.ts +13 -0
- package/dist/api/schema.d.ts +1 -1
- package/dist/api/schema.js +1 -1
- package/dist/api.js +76 -39
- package/dist/app.js +68 -17
- package/dist/chat/agent/request.d.ts +9 -0
- package/dist/chat/agent-dispatch/types.d.ts +2 -1
- package/dist/chat/config.d.ts +1 -0
- package/dist/chat/no-reply.d.ts +0 -2
- package/dist/chat/services/turn-limit.d.ts +6 -0
- package/dist/chat/services/turn-session-record.d.ts +0 -1
- package/dist/chat/slack/action-token.d.ts +6 -0
- package/dist/chat/slack/tools/public-search.d.ts +74 -0
- package/dist/chat/tools/definition.d.ts +2 -0
- package/dist/chat/tools/index.d.ts +2 -2
- package/dist/chat/tools/types.d.ts +3 -0
- package/dist/{chunk-CCTCIISK.js → chunk-3MPPVPGZ.js} +1 -1
- package/dist/{chunk-7G4J3CR7.js → chunk-3NYUCBLE.js} +1 -1
- package/dist/{chunk-U26ZWZCN.js → chunk-3OUSJPR7.js} +1 -1
- package/dist/{chunk-M3UAVLEN.js → chunk-4UYIRWDW.js} +2 -0
- package/dist/{chunk-QVTVCJR4.js → chunk-4W4O4DCV.js} +7 -7
- package/dist/{chunk-4PDVOHXP.js → chunk-AZ5OMSN5.js} +1 -1
- package/dist/{chunk-RMZ65YAA.js → chunk-BKM4UXUD.js} +21 -6
- package/dist/{chunk-AIRE7Q2W.js → chunk-CCFROYAV.js} +7 -0
- package/dist/{chunk-QDKRE3LS.js → chunk-DDRQ4U7I.js} +3 -3
- package/dist/{chunk-TMWUGGSA.js → chunk-GPPUTY5M.js} +327 -187
- package/dist/{chunk-RYDF4GOX.js → chunk-P4P7O5WG.js} +3 -3
- package/dist/{chunk-O7ILGCMJ.js → chunk-R5BFYK2O.js} +1 -1
- package/dist/{chunk-BCULHGZK.js → chunk-XTKJPSMF.js} +1 -1
- package/dist/{chunk-VDHMFCDY.js → chunk-ZMRLBBD5.js} +4 -4
- package/dist/cli/chat.js +13 -13
- package/dist/cli/plugins.js +5 -5
- package/dist/cli/snapshot-warmup.js +2 -2
- package/dist/cli/upgrade.js +6 -6
- package/dist/{db-PDMC67T3.js → db-S33LFWG2.js} +2 -2
- package/dist/{legacy-import-G333RHJZ.js → legacy-import-TMJISRKO.js} +3 -3
- package/dist/{runner-6A7MQRUE.js → runner-HA5XAL6K.js} +9 -9
- package/package.json +6 -6
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import {
|
|
2
2
|
CooperativeTurnYieldError,
|
|
3
3
|
TurnInputCommitLostError,
|
|
4
|
+
TurnSliceLimitExceededError,
|
|
4
5
|
abandonReplacedPendingAuth,
|
|
5
6
|
canReusePendingAuthLink,
|
|
6
7
|
getInterruptionMarker,
|
|
@@ -11,7 +12,7 @@ import {
|
|
|
11
12
|
persistRunningSessionRecord,
|
|
12
13
|
persistTimeoutSessionRecord,
|
|
13
14
|
persistYieldSessionRecord
|
|
14
|
-
} from "./chunk-
|
|
15
|
+
} from "./chunk-BKM4UXUD.js";
|
|
15
16
|
import {
|
|
16
17
|
JUNIOR_THREAD_STATE_TTL_MS
|
|
17
18
|
} from "./chunk-XIMUQ4IU.js";
|
|
@@ -24,7 +25,7 @@ import {
|
|
|
24
25
|
isSnapshotMissingError,
|
|
25
26
|
resolveRuntimeDependencySnapshot,
|
|
26
27
|
runNonInteractiveCommand
|
|
27
|
-
} from "./chunk-
|
|
28
|
+
} from "./chunk-3NYUCBLE.js";
|
|
28
29
|
import {
|
|
29
30
|
addAgentTurnUsage,
|
|
30
31
|
hasAgentTurnUsage,
|
|
@@ -34,12 +35,12 @@ import {
|
|
|
34
35
|
recordAuthorizationRequested,
|
|
35
36
|
recordMcpProviderConnected,
|
|
36
37
|
recordToolExecutionStarted
|
|
37
|
-
} from "./chunk-
|
|
38
|
+
} from "./chunk-DDRQ4U7I.js";
|
|
38
39
|
import {
|
|
39
40
|
estimateTextTokens,
|
|
40
41
|
getAgentContextCompactionTriggerTokens,
|
|
41
42
|
updateConversationStats
|
|
42
|
-
} from "./chunk-
|
|
43
|
+
} from "./chunk-P4P7O5WG.js";
|
|
43
44
|
import {
|
|
44
45
|
privateTraceResultAttributes
|
|
45
46
|
} from "./chunk-UIE3R5XU.js";
|
|
@@ -51,10 +52,10 @@ import {
|
|
|
51
52
|
getPlugins,
|
|
52
53
|
getSlackToolContext,
|
|
53
54
|
resolveChannelCapabilities
|
|
54
|
-
} from "./chunk-
|
|
55
|
+
} from "./chunk-ZMRLBBD5.js";
|
|
55
56
|
import {
|
|
56
57
|
createPluginLogger
|
|
57
|
-
} from "./chunk-
|
|
58
|
+
} from "./chunk-AZ5OMSN5.js";
|
|
58
59
|
import {
|
|
59
60
|
SANDBOX_DATA_ROOT,
|
|
60
61
|
SANDBOX_SKILLS_ROOT,
|
|
@@ -71,7 +72,7 @@ import {
|
|
|
71
72
|
isDmChannel,
|
|
72
73
|
normalizeSlackConversationId,
|
|
73
74
|
withSlackRetries
|
|
74
|
-
} from "./chunk-
|
|
75
|
+
} from "./chunk-3MPPVPGZ.js";
|
|
75
76
|
import {
|
|
76
77
|
contextProvenance,
|
|
77
78
|
getAgentStepStore,
|
|
@@ -80,7 +81,7 @@ import {
|
|
|
80
81
|
getDb,
|
|
81
82
|
instructionActors,
|
|
82
83
|
instructionProvenanceFor
|
|
83
|
-
} from "./chunk-
|
|
84
|
+
} from "./chunk-XTKJPSMF.js";
|
|
84
85
|
import {
|
|
85
86
|
sleep
|
|
86
87
|
} from "./chunk-4ZNGQH7C.js";
|
|
@@ -123,7 +124,7 @@ import {
|
|
|
123
124
|
stripRuntimeTurnContext,
|
|
124
125
|
trimTrailingAssistantMessages,
|
|
125
126
|
unwrapCurrentInstruction
|
|
126
|
-
} from "./chunk-
|
|
127
|
+
} from "./chunk-4UYIRWDW.js";
|
|
127
128
|
import {
|
|
128
129
|
parseSlackThreadId,
|
|
129
130
|
resolveConversationPrivacy,
|
|
@@ -616,9 +617,6 @@ function isNoReplyMarker(text) {
|
|
|
616
617
|
function containsNoReplyMarker(text) {
|
|
617
618
|
return text.includes(NO_REPLY_MARKER);
|
|
618
619
|
}
|
|
619
|
-
function stripNoReplyMarker(text) {
|
|
620
|
-
return text.replaceAll(NO_REPLY_MARKER, "").trim();
|
|
621
|
-
}
|
|
622
620
|
|
|
623
621
|
// src/chat/services/turn-result.ts
|
|
624
622
|
function isExecutionDeferralResponse(text) {
|
|
@@ -731,7 +729,8 @@ function buildTurnResult(input) {
|
|
|
731
729
|
).trim();
|
|
732
730
|
const exactNoReplyMarker = isNoReplyMarker(rawPrimaryText);
|
|
733
731
|
const mixedNoReplyMarker = !exactNoReplyMarker && containsNoReplyMarker(rawPrimaryText);
|
|
734
|
-
const
|
|
732
|
+
const noReplyRequested = exactNoReplyMarker || mixedNoReplyMarker;
|
|
733
|
+
const primaryText = noReplyRequested ? "" : rawPrimaryText;
|
|
735
734
|
const toolErrorCount = toolResults.filter((result) => result.isError).length;
|
|
736
735
|
const successfulToolResults = toolResults.filter(
|
|
737
736
|
(result) => !isToolResultError(result)
|
|
@@ -741,7 +740,7 @@ function buildTurnResult(input) {
|
|
|
741
740
|
);
|
|
742
741
|
const canvasCreated = successfulToolNames.has("slackCanvasCreate");
|
|
743
742
|
const reactionPerformed = successfulToolNames.has("addReaction");
|
|
744
|
-
const silentCompletionSuccess =
|
|
743
|
+
const silentCompletionSuccess = noReplyRequested;
|
|
745
744
|
const baseDeliveryPlan = {
|
|
746
745
|
mode: "thread",
|
|
747
746
|
postThreadText: true
|
|
@@ -2103,7 +2102,7 @@ var SKILL_POLICY_RULES = [
|
|
|
2103
2102
|
var EXECUTION_CONTRACT_RULES = [
|
|
2104
2103
|
"- Actionable request: act in this turn.",
|
|
2105
2104
|
"- Continue until done or genuinely blocked. Do not finish with a plan, promise, or offer to check next when an available tool or source can move the request forward.",
|
|
2106
|
-
"-
|
|
2105
|
+
"- Complete the full task, but report only the result and evidence the user needs; do not narrate every step, check, or detail.",
|
|
2107
2106
|
"- Ask the user only for missing access, approval, or a decision that blocks safe progress. Ask one focused question; otherwise infer conservatively and continue.",
|
|
2108
2107
|
"- For conflicting evidence, compare sources and state which source is authoritative for the answer.",
|
|
2109
2108
|
"- For non-trivial or long-running work, call `reportProgress` early when available, then only when the major phase changes. Routine tool calls should stay silent."
|
|
@@ -2168,8 +2167,8 @@ function buildOutputSection(platform) {
|
|
|
2168
2167
|
openTag,
|
|
2169
2168
|
"- Start with the answer or result, not internal process narration.",
|
|
2170
2169
|
"- Use Slack-flavored Markdown: **bold** section labels, `code`, [text](url) links, bullet lists, and fenced code blocks. No hash-prefixed headings and no tables. When the answer primarily lists several URLs, show each URL bare instead of as a labeled link.",
|
|
2171
|
-
"-
|
|
2172
|
-
"-
|
|
2170
|
+
"- Default to one compact thread reply containing the conclusion and only decisive evidence or action. Do not split an explainer across multiple Slack messages.",
|
|
2171
|
+
"- Put plans, research, and other long or multi-section explainers in a Slack canvas; reply with one or two short sentences plus the link, without recapping the canvas.",
|
|
2173
2172
|
"- End every turn with a final user-facing markdown response unless the Slack action rules allow a no-reply completion.",
|
|
2174
2173
|
"</output>"
|
|
2175
2174
|
].join("\n");
|
|
@@ -6814,8 +6813,129 @@ function createSlackConversationSearchTool(scope, currentConversationId, deps =
|
|
|
6814
6813
|
});
|
|
6815
6814
|
}
|
|
6816
6815
|
|
|
6817
|
-
// src/chat/slack/tools/
|
|
6816
|
+
// src/chat/slack/tools/public-search.ts
|
|
6818
6817
|
import { z as z20 } from "zod";
|
|
6818
|
+
var DEFAULT_LIMIT2 = 10;
|
|
6819
|
+
var optionalTimestampSchema = z20.preprocess(
|
|
6820
|
+
(value) => typeof value === "string" && value.trim() === "" ? void 0 : value,
|
|
6821
|
+
z20.coerce.number().int().nonnegative().describe("Optional Unix timestamp bound.").optional()
|
|
6822
|
+
);
|
|
6823
|
+
var searchMessageSchema = z20.object({
|
|
6824
|
+
author_name: z20.string().optional(),
|
|
6825
|
+
author_user_id: z20.string().optional(),
|
|
6826
|
+
channel_id: z20.string().min(1),
|
|
6827
|
+
channel_name: z20.string().optional(),
|
|
6828
|
+
message_ts: z20.string().min(1),
|
|
6829
|
+
content: z20.string(),
|
|
6830
|
+
is_author_bot: z20.boolean().optional(),
|
|
6831
|
+
permalink: z20.string().url()
|
|
6832
|
+
});
|
|
6833
|
+
var publicSearchOutputSchema = juniorToolResultSchema.extend({
|
|
6834
|
+
query: z20.string(),
|
|
6835
|
+
count: z20.number().int().nonnegative(),
|
|
6836
|
+
messages: z20.array(searchMessageSchema),
|
|
6837
|
+
next_cursor: z20.string().optional()
|
|
6838
|
+
});
|
|
6839
|
+
function normalizeMessage(value) {
|
|
6840
|
+
const parsed = searchMessageSchema.safeParse(value);
|
|
6841
|
+
return parsed.success ? parsed.data : void 0;
|
|
6842
|
+
}
|
|
6843
|
+
function explicitSearchError(error) {
|
|
6844
|
+
if (error.code === "missing_scope") {
|
|
6845
|
+
return "Public Slack search is unavailable because this installation is missing the `search:read.public` scope.";
|
|
6846
|
+
}
|
|
6847
|
+
if (error.code === "feature_unavailable") {
|
|
6848
|
+
return "Public Slack search is not available for this Slack workspace or app installation.";
|
|
6849
|
+
}
|
|
6850
|
+
if (error.apiError === "invalid_action_token") {
|
|
6851
|
+
return "Public Slack search could not use the current Slack interaction token. Ask again in a new message or mention.";
|
|
6852
|
+
}
|
|
6853
|
+
return void 0;
|
|
6854
|
+
}
|
|
6855
|
+
function createSlackPublicSearchTool(actionToken) {
|
|
6856
|
+
return zodTool({
|
|
6857
|
+
description: "Search public Slack channel messages across the current workspace. Use when the user asks about company activity, announcements, public mentions, or context outside the active channel. Search only when requested or clearly needed, prefer focused keywords and time bounds, and cite returned permalinks. This never searches private channels or DMs.",
|
|
6858
|
+
annotations: { readOnlyHint: true, destructiveHint: false },
|
|
6859
|
+
inputSchema: z20.object({
|
|
6860
|
+
query: z20.string().trim().min(1).max(500).describe(
|
|
6861
|
+
"A focused Slack search query, including Slack search filters when useful."
|
|
6862
|
+
),
|
|
6863
|
+
after: optionalTimestampSchema.describe(
|
|
6864
|
+
"Optional Unix timestamp lower bound."
|
|
6865
|
+
),
|
|
6866
|
+
before: optionalTimestampSchema.describe(
|
|
6867
|
+
"Optional Unix timestamp upper bound."
|
|
6868
|
+
),
|
|
6869
|
+
cursor: z20.string().min(1).describe("Cursor for the next result page.").optional(),
|
|
6870
|
+
limit: z20.coerce.number().int().min(1).max(20).describe("Maximum results to return; Slack allows at most 20.").optional(),
|
|
6871
|
+
sort: z20.enum(["score", "timestamp"]).describe("Rank by relevance or timestamp.").optional(),
|
|
6872
|
+
sort_dir: z20.enum(["asc", "desc"]).describe("Sort direction.").optional()
|
|
6873
|
+
}),
|
|
6874
|
+
outputSchema: publicSearchOutputSchema,
|
|
6875
|
+
execute: async ({
|
|
6876
|
+
query,
|
|
6877
|
+
after,
|
|
6878
|
+
before,
|
|
6879
|
+
cursor,
|
|
6880
|
+
limit,
|
|
6881
|
+
sort,
|
|
6882
|
+
sort_dir
|
|
6883
|
+
}) => {
|
|
6884
|
+
try {
|
|
6885
|
+
const normalizedAfter = optionalTimestampSchema.parse(after);
|
|
6886
|
+
const normalizedBefore = optionalTimestampSchema.parse(before);
|
|
6887
|
+
const response = await withSlackRetries(
|
|
6888
|
+
() => getSlackClient().apiCall("assistant.search.context", {
|
|
6889
|
+
action_token: actionToken,
|
|
6890
|
+
query,
|
|
6891
|
+
channel_types: ["public_channel"],
|
|
6892
|
+
content_types: ["messages"],
|
|
6893
|
+
include_bots: true,
|
|
6894
|
+
limit: limit ?? DEFAULT_LIMIT2,
|
|
6895
|
+
...normalizedAfter !== void 0 ? { after: normalizedAfter } : {},
|
|
6896
|
+
...normalizedBefore !== void 0 ? { before: normalizedBefore } : {},
|
|
6897
|
+
...cursor ? { cursor } : {},
|
|
6898
|
+
...sort ? { sort } : {},
|
|
6899
|
+
...sort_dir ? { sort_dir } : {}
|
|
6900
|
+
}),
|
|
6901
|
+
3,
|
|
6902
|
+
{
|
|
6903
|
+
action: "assistant.search.context",
|
|
6904
|
+
idempotent: true
|
|
6905
|
+
}
|
|
6906
|
+
);
|
|
6907
|
+
const messages = (response.results?.messages ?? []).map(normalizeMessage).filter((message) => Boolean(message));
|
|
6908
|
+
const nextCursor = response.results?.next_cursor;
|
|
6909
|
+
return {
|
|
6910
|
+
ok: true,
|
|
6911
|
+
status: "success",
|
|
6912
|
+
query,
|
|
6913
|
+
count: messages.length,
|
|
6914
|
+
messages,
|
|
6915
|
+
...typeof nextCursor === "string" && nextCursor ? { next_cursor: nextCursor } : {}
|
|
6916
|
+
};
|
|
6917
|
+
} catch (error) {
|
|
6918
|
+
if (error instanceof SlackActionError) {
|
|
6919
|
+
const message = explicitSearchError(error);
|
|
6920
|
+
if (message) {
|
|
6921
|
+
return {
|
|
6922
|
+
ok: false,
|
|
6923
|
+
status: "error",
|
|
6924
|
+
error: message,
|
|
6925
|
+
query,
|
|
6926
|
+
count: 0,
|
|
6927
|
+
messages: []
|
|
6928
|
+
};
|
|
6929
|
+
}
|
|
6930
|
+
}
|
|
6931
|
+
throw error;
|
|
6932
|
+
}
|
|
6933
|
+
}
|
|
6934
|
+
});
|
|
6935
|
+
}
|
|
6936
|
+
|
|
6937
|
+
// src/chat/slack/tools/message-add-reaction.ts
|
|
6938
|
+
import { z as z21 } from "zod";
|
|
6819
6939
|
|
|
6820
6940
|
// src/chat/tools/idempotency.ts
|
|
6821
6941
|
function stableSerialize(value) {
|
|
@@ -6839,8 +6959,8 @@ function createOperationKey(toolName, input) {
|
|
|
6839
6959
|
function createSlackMessageAddReactionTool(context, state) {
|
|
6840
6960
|
return zodTool({
|
|
6841
6961
|
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.",
|
|
6842
|
-
inputSchema:
|
|
6843
|
-
emoji:
|
|
6962
|
+
inputSchema: z21.object({
|
|
6963
|
+
emoji: z21.string().min(1).max(64).describe(
|
|
6844
6964
|
"Slack emoji alias name to react with (for example `thumbsup`, `white_check_mark`, or `thumbsup::skin-tone-6`). Optional surrounding colons are allowed."
|
|
6845
6965
|
)
|
|
6846
6966
|
}),
|
|
@@ -6891,15 +7011,15 @@ function createSlackMessageAddReactionTool(context, state) {
|
|
|
6891
7011
|
|
|
6892
7012
|
// src/chat/slack/tools/send-message.ts
|
|
6893
7013
|
import { createHash as createHash2 } from "crypto";
|
|
6894
|
-
import { z as
|
|
6895
|
-
var fileInputSchema =
|
|
6896
|
-
path:
|
|
7014
|
+
import { z as z22 } from "zod";
|
|
7015
|
+
var fileInputSchema = z22.object({
|
|
7016
|
+
path: z22.string().min(1).describe(
|
|
6897
7017
|
"Sandbox file path to include in the message. Absolute paths and workspace-relative paths are supported."
|
|
6898
7018
|
),
|
|
6899
|
-
filename:
|
|
7019
|
+
filename: z22.string().min(1).nullable().optional().describe(
|
|
6900
7020
|
"Optional filename override shown in Slack. Null is treated as omitted."
|
|
6901
7021
|
),
|
|
6902
|
-
mimeType:
|
|
7022
|
+
mimeType: z22.string().min(1).nullable().optional().describe("Optional MIME type override. Null is treated as omitted.")
|
|
6903
7023
|
});
|
|
6904
7024
|
function hasText(text) {
|
|
6905
7025
|
return typeof text === "string" && text.trim().length > 0;
|
|
@@ -6926,9 +7046,9 @@ function fileOperationInput(files) {
|
|
|
6926
7046
|
function createSendMessageTool(context, state, materializeFile) {
|
|
6927
7047
|
return zodTool({
|
|
6928
7048
|
description: "Send a Slack message with optional 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. The message can contain text, files, or both; file-only messages are allowed. Do not use for top-level channel posts, other named channels, inline @mentions, or pinging mentioned users.",
|
|
6929
|
-
inputSchema:
|
|
6930
|
-
text:
|
|
6931
|
-
files:
|
|
7049
|
+
inputSchema: z22.object({
|
|
7050
|
+
text: z22.string().max(4e4).nullable().optional().describe("Slack mrkdwn text to send. Null is treated as omitted."),
|
|
7051
|
+
files: z22.array(fileInputSchema).min(1).nullable().optional().describe(
|
|
6932
7052
|
"Sandbox files to include in the message. Null is treated as omitted."
|
|
6933
7053
|
)
|
|
6934
7054
|
}),
|
|
@@ -7256,13 +7376,13 @@ function storedCanvasUrl(state, canvasId) {
|
|
|
7256
7376
|
}
|
|
7257
7377
|
|
|
7258
7378
|
// src/chat/slack/tools/canvas/create.ts
|
|
7259
|
-
import { z as
|
|
7379
|
+
import { z as z23 } from "zod";
|
|
7260
7380
|
function createSlackCanvasCreateTool(context, state) {
|
|
7261
7381
|
return zodTool({
|
|
7262
7382
|
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.",
|
|
7263
|
-
inputSchema:
|
|
7264
|
-
title:
|
|
7265
|
-
markdown:
|
|
7383
|
+
inputSchema: z23.object({
|
|
7384
|
+
title: z23.string().min(1).max(160).describe("Canvas title."),
|
|
7385
|
+
markdown: z23.string().min(1).describe("Canvas markdown body content.")
|
|
7266
7386
|
}),
|
|
7267
7387
|
outputSchema: juniorToolResultSchema,
|
|
7268
7388
|
execute: async ({ title, markdown }) => {
|
|
@@ -7325,35 +7445,35 @@ function createSlackCanvasCreateTool(context, state) {
|
|
|
7325
7445
|
}
|
|
7326
7446
|
|
|
7327
7447
|
// src/chat/slack/tools/canvas/edit.ts
|
|
7328
|
-
import { z as
|
|
7448
|
+
import { z as z24 } from "zod";
|
|
7329
7449
|
function prepareCanvasEditArguments(input) {
|
|
7330
7450
|
return prepareTextReplacementArguments(input);
|
|
7331
7451
|
}
|
|
7332
|
-
var editReplacementSchema2 =
|
|
7333
|
-
oldText:
|
|
7452
|
+
var editReplacementSchema2 = z24.object({
|
|
7453
|
+
oldText: z24.string().min(1).describe(
|
|
7334
7454
|
"Exact Canvas markdown to replace. It must be unique in the current Canvas body and must not overlap another edit."
|
|
7335
7455
|
),
|
|
7336
|
-
newText:
|
|
7456
|
+
newText: z24.string().describe("Replacement Canvas markdown for this edit.")
|
|
7337
7457
|
});
|
|
7338
7458
|
var slackCanvasEditOutputSchema = juniorToolResultSchema.extend({
|
|
7339
|
-
canvas_id:
|
|
7340
|
-
title:
|
|
7341
|
-
permalink:
|
|
7342
|
-
diff:
|
|
7343
|
-
first_changed_line:
|
|
7344
|
-
replacements:
|
|
7345
|
-
normalized_heading_count:
|
|
7346
|
-
summary:
|
|
7347
|
-
deduplicated:
|
|
7459
|
+
canvas_id: z24.string().optional(),
|
|
7460
|
+
title: z24.string().optional(),
|
|
7461
|
+
permalink: z24.string().optional(),
|
|
7462
|
+
diff: z24.string().optional(),
|
|
7463
|
+
first_changed_line: z24.number().int().positive().optional(),
|
|
7464
|
+
replacements: z24.number().int().nonnegative().optional(),
|
|
7465
|
+
normalized_heading_count: z24.number().int().nonnegative().optional(),
|
|
7466
|
+
summary: z24.string().optional(),
|
|
7467
|
+
deduplicated: z24.boolean().optional()
|
|
7348
7468
|
}).strict();
|
|
7349
7469
|
function createSlackCanvasEditTool(state) {
|
|
7350
7470
|
return zodTool({
|
|
7351
7471
|
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.",
|
|
7352
7472
|
prepareArguments: prepareCanvasEditArguments,
|
|
7353
7473
|
executionMode: "sequential",
|
|
7354
|
-
inputSchema:
|
|
7355
|
-
canvas:
|
|
7356
|
-
edits:
|
|
7474
|
+
inputSchema: z24.object({
|
|
7475
|
+
canvas: z24.string().min(1).describe("Canvas/file ID (e.g. `F0ABCDEF`) or Slack canvas/docs URL."),
|
|
7476
|
+
edits: z24.array(editReplacementSchema2).min(1).describe(
|
|
7357
7477
|
"Exact replacements matched against the current Canvas body, not incrementally."
|
|
7358
7478
|
)
|
|
7359
7479
|
}),
|
|
@@ -7431,29 +7551,29 @@ function createSlackCanvasEditTool(state) {
|
|
|
7431
7551
|
}
|
|
7432
7552
|
|
|
7433
7553
|
// src/chat/slack/tools/canvas/read.ts
|
|
7434
|
-
import { z as
|
|
7554
|
+
import { z as z25 } from "zod";
|
|
7435
7555
|
var slackCanvasReadOutputSchema = juniorToolResultSchema.extend({
|
|
7436
|
-
canvas_id:
|
|
7437
|
-
title:
|
|
7438
|
-
permalink:
|
|
7439
|
-
mimetype:
|
|
7440
|
-
filetype:
|
|
7441
|
-
original_byte_length:
|
|
7442
|
-
content:
|
|
7443
|
-
start_line:
|
|
7444
|
-
end_line:
|
|
7445
|
-
total_lines:
|
|
7556
|
+
canvas_id: z25.string().optional(),
|
|
7557
|
+
title: z25.string().optional(),
|
|
7558
|
+
permalink: z25.string().optional(),
|
|
7559
|
+
mimetype: z25.string().optional(),
|
|
7560
|
+
filetype: z25.string().optional(),
|
|
7561
|
+
original_byte_length: z25.number().int().nonnegative().optional(),
|
|
7562
|
+
content: z25.string().optional(),
|
|
7563
|
+
start_line: z25.number().int().positive().optional(),
|
|
7564
|
+
end_line: z25.number().int().nonnegative().optional(),
|
|
7565
|
+
total_lines: z25.number().int().nonnegative().optional()
|
|
7446
7566
|
}).strict();
|
|
7447
7567
|
function createSlackCanvasReadTool() {
|
|
7448
7568
|
return zodTool({
|
|
7449
7569
|
description: "Read a bounded line range from a Slack canvas as markdown. Use when you need exact Canvas contents to verify facts or make edits safely. Do not use for generic web pages \u2014 use webFetch for those.",
|
|
7450
7570
|
annotations: { readOnlyHint: true, destructiveHint: false },
|
|
7451
|
-
inputSchema:
|
|
7452
|
-
canvas:
|
|
7571
|
+
inputSchema: z25.object({
|
|
7572
|
+
canvas: z25.string().min(1).describe(
|
|
7453
7573
|
"Canvas/file ID (e.g. `F0ABCDEF`) or Slack canvas/docs URL (e.g. `https://team.slack.com/docs/T.../F...`)."
|
|
7454
7574
|
),
|
|
7455
|
-
offset:
|
|
7456
|
-
limit:
|
|
7575
|
+
offset: z25.coerce.number().int().min(1).describe("1-indexed line number to start reading from.").optional(),
|
|
7576
|
+
limit: z25.coerce.number().int().min(1).describe("Maximum number of lines to read. Defaults to 1000.").optional()
|
|
7457
7577
|
}),
|
|
7458
7578
|
outputSchema: slackCanvasReadOutputSchema,
|
|
7459
7579
|
execute: async ({ canvas, offset, limit }) => {
|
|
@@ -7510,14 +7630,14 @@ function createSlackCanvasReadTool() {
|
|
|
7510
7630
|
}
|
|
7511
7631
|
|
|
7512
7632
|
// src/chat/slack/tools/canvas/write.ts
|
|
7513
|
-
import { z as
|
|
7633
|
+
import { z as z26 } from "zod";
|
|
7514
7634
|
function createSlackCanvasWriteTool(state) {
|
|
7515
7635
|
return zodTool({
|
|
7516
7636
|
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.",
|
|
7517
7637
|
executionMode: "sequential",
|
|
7518
|
-
inputSchema:
|
|
7519
|
-
canvas:
|
|
7520
|
-
content:
|
|
7638
|
+
inputSchema: z26.object({
|
|
7639
|
+
canvas: z26.string().min(1).describe("Canvas/file ID (e.g. `F0ABCDEF`) or Slack canvas/docs URL."),
|
|
7640
|
+
content: z26.string().describe("UTF-8 markdown content to write.")
|
|
7521
7641
|
}),
|
|
7522
7642
|
outputSchema: juniorToolResultSchema,
|
|
7523
7643
|
execute: async ({ canvas, content }) => {
|
|
@@ -7753,12 +7873,12 @@ async function updateListItem(input) {
|
|
|
7753
7873
|
}
|
|
7754
7874
|
|
|
7755
7875
|
// src/chat/slack/id-param.ts
|
|
7756
|
-
import { z as
|
|
7876
|
+
import { z as z27 } from "zod";
|
|
7757
7877
|
function slackChannelIdParam(description) {
|
|
7758
|
-
return
|
|
7878
|
+
return z27.string().min(1).describe(description);
|
|
7759
7879
|
}
|
|
7760
7880
|
function slackUserIdParam(description) {
|
|
7761
|
-
return
|
|
7881
|
+
return z27.string().min(1).describe(description);
|
|
7762
7882
|
}
|
|
7763
7883
|
function parseRequiredSlackChannelIdParam(field, value) {
|
|
7764
7884
|
const channelId = parseSlackChannelId(value);
|
|
@@ -7782,16 +7902,16 @@ function parseRequiredSlackUserIdParam(field, value) {
|
|
|
7782
7902
|
}
|
|
7783
7903
|
|
|
7784
7904
|
// src/chat/slack/tools/list/add-items.ts
|
|
7785
|
-
import { z as
|
|
7905
|
+
import { z as z28 } from "zod";
|
|
7786
7906
|
function createSlackListAddItemsTool(state) {
|
|
7787
7907
|
return zodTool({
|
|
7788
7908
|
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.",
|
|
7789
|
-
inputSchema:
|
|
7790
|
-
items:
|
|
7909
|
+
inputSchema: z28.object({
|
|
7910
|
+
items: z28.array(z28.string().min(1)).min(1).max(25).describe("List item titles to create."),
|
|
7791
7911
|
assignee_user_id: slackUserIdParam(
|
|
7792
7912
|
"Optional Slack user ID assigned to all created items."
|
|
7793
7913
|
).optional(),
|
|
7794
|
-
due_date:
|
|
7914
|
+
due_date: z28.string().regex(/^\d{4}-\d{2}-\d{2}$/).describe("Optional due date in YYYY-MM-DD format.").optional()
|
|
7795
7915
|
}),
|
|
7796
7916
|
outputSchema: juniorToolResultSchema,
|
|
7797
7917
|
execute: async ({ items, assignee_user_id, due_date }) => {
|
|
@@ -7845,12 +7965,12 @@ function createSlackListAddItemsTool(state) {
|
|
|
7845
7965
|
}
|
|
7846
7966
|
|
|
7847
7967
|
// src/chat/slack/tools/list/create.ts
|
|
7848
|
-
import { z as
|
|
7968
|
+
import { z as z29 } from "zod";
|
|
7849
7969
|
function createSlackListCreateTool(state) {
|
|
7850
7970
|
return zodTool({
|
|
7851
7971
|
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.",
|
|
7852
|
-
inputSchema:
|
|
7853
|
-
name:
|
|
7972
|
+
inputSchema: z29.object({
|
|
7973
|
+
name: z29.string().min(1).max(160).describe("Name for the new Slack list.")
|
|
7854
7974
|
}),
|
|
7855
7975
|
outputSchema: juniorToolResultSchema,
|
|
7856
7976
|
execute: async ({ name }) => {
|
|
@@ -7882,13 +8002,13 @@ function createSlackListCreateTool(state) {
|
|
|
7882
8002
|
}
|
|
7883
8003
|
|
|
7884
8004
|
// src/chat/slack/tools/list/get-items.ts
|
|
7885
|
-
import { z as
|
|
8005
|
+
import { z as z30 } from "zod";
|
|
7886
8006
|
function createSlackListGetItemsTool(state) {
|
|
7887
8007
|
return zodTool({
|
|
7888
8008
|
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.",
|
|
7889
8009
|
annotations: { readOnlyHint: true, destructiveHint: false },
|
|
7890
|
-
inputSchema:
|
|
7891
|
-
limit:
|
|
8010
|
+
inputSchema: z30.object({
|
|
8011
|
+
limit: z30.coerce.number().int().min(1).max(200).describe("Maximum number of list items to return.").optional()
|
|
7892
8012
|
}),
|
|
7893
8013
|
outputSchema: juniorToolResultSchema,
|
|
7894
8014
|
execute: async ({ limit }) => {
|
|
@@ -7913,21 +8033,21 @@ function createSlackListGetItemsTool(state) {
|
|
|
7913
8033
|
}
|
|
7914
8034
|
|
|
7915
8035
|
// src/chat/slack/tools/list/update-item.ts
|
|
7916
|
-
import { z as
|
|
7917
|
-
var booleanInput3 = (description) =>
|
|
8036
|
+
import { z as z31 } from "zod";
|
|
8037
|
+
var booleanInput3 = (description) => z31.preprocess(
|
|
7918
8038
|
(value) => value === "true" ? true : value === "false" ? false : value,
|
|
7919
|
-
|
|
8039
|
+
z31.boolean()
|
|
7920
8040
|
).describe(description);
|
|
7921
|
-
var updateListItemInputSchema =
|
|
7922
|
-
|
|
7923
|
-
item_id:
|
|
8041
|
+
var updateListItemInputSchema = z31.union([
|
|
8042
|
+
z31.object({
|
|
8043
|
+
item_id: z31.string().min(1).describe("ID of the Slack list item to update."),
|
|
7924
8044
|
completed: booleanInput3("Optional completion status update."),
|
|
7925
|
-
title:
|
|
8045
|
+
title: z31.string().min(1).describe("Optional new item title.").optional()
|
|
7926
8046
|
}),
|
|
7927
|
-
|
|
7928
|
-
item_id:
|
|
8047
|
+
z31.object({
|
|
8048
|
+
item_id: z31.string().min(1).describe("ID of the Slack list item to update."),
|
|
7929
8049
|
completed: booleanInput3("Optional completion status update.").optional(),
|
|
7930
|
-
title:
|
|
8050
|
+
title: z31.string().min(1).describe("Optional new item title.")
|
|
7931
8051
|
})
|
|
7932
8052
|
]);
|
|
7933
8053
|
function createSlackListUpdateItemTool(state) {
|
|
@@ -8003,7 +8123,7 @@ async function checkSlackChannelReadAccess(args) {
|
|
|
8003
8123
|
}
|
|
8004
8124
|
|
|
8005
8125
|
// src/chat/slack/tools/thread-read.ts
|
|
8006
|
-
import { z as
|
|
8126
|
+
import { z as z32 } from "zod";
|
|
8007
8127
|
|
|
8008
8128
|
// src/chat/slack/tools/slack-message-url.ts
|
|
8009
8129
|
var SLACK_HOST_PATTERN = /^[a-z0-9-]+\.slack(?:-gov)?\.com$/;
|
|
@@ -8176,8 +8296,8 @@ function createSlackThreadReadTool(context, deps = {}) {
|
|
|
8176
8296
|
return zodTool({
|
|
8177
8297
|
description: "Read a Slack thread from a shared Slack message archive URL or explicit channel + timestamp. Use when the user shares a Slack message link (https://*.slack.com/archives/...) and you need the referenced message and its thread context. Only the current conversation and public channels Junior has seen in this workspace are readable.",
|
|
8178
8298
|
annotations: { readOnlyHint: true, destructiveHint: false },
|
|
8179
|
-
inputSchema:
|
|
8180
|
-
url:
|
|
8299
|
+
inputSchema: z32.object({
|
|
8300
|
+
url: z32.string().min(1).describe(
|
|
8181
8301
|
"Slack message archive URL, e.g. https://workspace.slack.com/archives/C123/p1700000000123456"
|
|
8182
8302
|
).optional(),
|
|
8183
8303
|
channel_id: slackChannelIdParam(
|
|
@@ -8186,8 +8306,8 @@ function createSlackThreadReadTool(context, deps = {}) {
|
|
|
8186
8306
|
ts: slackTimestampParam(
|
|
8187
8307
|
"Slack message timestamp (e.g. 1700000000.123456). May be the thread root or any message in the thread."
|
|
8188
8308
|
).optional(),
|
|
8189
|
-
limit:
|
|
8190
|
-
max_pages:
|
|
8309
|
+
limit: z32.coerce.number().int().min(1).max(1e3).describe("Maximum number of thread messages to fetch.").optional(),
|
|
8310
|
+
max_pages: z32.coerce.number().int().min(1).max(10).describe("Maximum number of Slack API pages to traverse.").optional()
|
|
8191
8311
|
}),
|
|
8192
8312
|
outputSchema: juniorToolResultSchema,
|
|
8193
8313
|
execute: async ({ url, channel_id, ts, limit, max_pages }) => {
|
|
@@ -8443,29 +8563,29 @@ async function searchSlackUsers(options) {
|
|
|
8443
8563
|
}
|
|
8444
8564
|
|
|
8445
8565
|
// src/chat/slack/tools/user-lookup.ts
|
|
8446
|
-
import { z as
|
|
8447
|
-
var booleanInput4 = (description) =>
|
|
8566
|
+
import { z as z33 } from "zod";
|
|
8567
|
+
var booleanInput4 = (description) => z33.preprocess(
|
|
8448
8568
|
(value) => value === "true" ? true : value === "false" ? false : value,
|
|
8449
|
-
|
|
8569
|
+
z33.boolean()
|
|
8450
8570
|
).describe(description);
|
|
8451
8571
|
function createSlackUserLookupTool() {
|
|
8452
8572
|
return zodTool({
|
|
8453
8573
|
description: "Look up Slack user profiles by user ID, email, or name search. Use when you need to identify a user, resolve cross-platform identity, or look up profile details like title or status. Returns profile fields including custom fields. For user ID lookup, pass a Slack user ID (e.g. U039RR91S). For search, pass a name query.",
|
|
8454
8574
|
annotations: { readOnlyHint: true, destructiveHint: false },
|
|
8455
|
-
inputSchema:
|
|
8575
|
+
inputSchema: z33.object({
|
|
8456
8576
|
user_id: slackUserIdParam(
|
|
8457
8577
|
"Slack user ID to look up (e.g. U039RR91S). Mutually exclusive with email and query."
|
|
8458
8578
|
).optional(),
|
|
8459
|
-
email:
|
|
8579
|
+
email: z33.string().min(3).describe(
|
|
8460
8580
|
"Email address to look up. Mutually exclusive with user_id and query."
|
|
8461
8581
|
).optional(),
|
|
8462
|
-
query:
|
|
8582
|
+
query: z33.string().min(2).describe(
|
|
8463
8583
|
"Name to search for (matches against username, display name, real name). Mutually exclusive with user_id and email."
|
|
8464
8584
|
).optional(),
|
|
8465
|
-
limit:
|
|
8585
|
+
limit: z33.coerce.number().int().min(1).max(20).describe(
|
|
8466
8586
|
"Maximum number of results to return for name search. Defaults to 10."
|
|
8467
8587
|
).optional(),
|
|
8468
|
-
max_pages:
|
|
8588
|
+
max_pages: z33.coerce.number().int().min(1).max(5).describe(
|
|
8469
8589
|
"Maximum number of Slack API pages to scan for name search. Defaults to 3."
|
|
8470
8590
|
).optional(),
|
|
8471
8591
|
include_bots: booleanInput4(
|
|
@@ -8569,18 +8689,18 @@ function createSlackUserLookupTool() {
|
|
|
8569
8689
|
}
|
|
8570
8690
|
|
|
8571
8691
|
// src/chat/tools/system-time.ts
|
|
8572
|
-
import { z as
|
|
8692
|
+
import { z as z34 } from "zod";
|
|
8573
8693
|
var systemTimeOutputSchema = juniorToolResultSchema.extend({
|
|
8574
|
-
unix_ms:
|
|
8575
|
-
iso_utc:
|
|
8576
|
-
iso_local:
|
|
8577
|
-
timezone_offset_minutes:
|
|
8694
|
+
unix_ms: z34.number(),
|
|
8695
|
+
iso_utc: z34.string(),
|
|
8696
|
+
iso_local: z34.string(),
|
|
8697
|
+
timezone_offset_minutes: z34.number()
|
|
8578
8698
|
});
|
|
8579
8699
|
function createSystemTimeTool() {
|
|
8580
8700
|
return zodTool({
|
|
8581
8701
|
description: "Return current system time in UTC and local ISO formats. Use when the user asks for current time/date context. Do not use as a substitute for historical or timezone-conversion research.",
|
|
8582
8702
|
annotations: { readOnlyHint: true, destructiveHint: false },
|
|
8583
|
-
inputSchema:
|
|
8703
|
+
inputSchema: z34.object({}),
|
|
8584
8704
|
outputSchema: systemTimeOutputSchema,
|
|
8585
8705
|
privateTraceResult: (result) => ({
|
|
8586
8706
|
ok: result.ok,
|
|
@@ -8609,10 +8729,10 @@ function createSystemTimeTool() {
|
|
|
8609
8729
|
}
|
|
8610
8730
|
|
|
8611
8731
|
// src/chat/tools/handoff/tool.ts
|
|
8612
|
-
import { z as
|
|
8732
|
+
import { z as z35 } from "zod";
|
|
8613
8733
|
var HANDOFF_TOOL_NAME = "handoff";
|
|
8614
8734
|
function createHandoffTool(handoff) {
|
|
8615
|
-
const profileSchema =
|
|
8735
|
+
const profileSchema = z35.enum(handoff.profiles);
|
|
8616
8736
|
const defaultProfile = handoff.profiles[0];
|
|
8617
8737
|
const handoffResultSchema = juniorToolResultSchema.extend({
|
|
8618
8738
|
model_profile: profileSchema
|
|
@@ -8621,7 +8741,7 @@ function createHandoffTool(handoff) {
|
|
|
8621
8741
|
return zodTool({
|
|
8622
8742
|
description: `Permanently switch this conversation to a more capable model profile, replace prior context with a continuation summary, and continue the same task with the same workspace and all other normal tools. Available profiles: ${profileNames}. Omit profile to use \`${defaultProfile}\`. Call it as the only tool in the assistant message when the system tool policy requires a model upgrade.`,
|
|
8623
8743
|
executionMode: "sequential",
|
|
8624
|
-
inputSchema:
|
|
8744
|
+
inputSchema: z35.object({
|
|
8625
8745
|
profile: profileSchema.nullish().describe(
|
|
8626
8746
|
"Named model profile to use for the rest of the conversation; omit or pass null for the default"
|
|
8627
8747
|
)
|
|
@@ -8640,7 +8760,7 @@ function createHandoffTool(handoff) {
|
|
|
8640
8760
|
}
|
|
8641
8761
|
|
|
8642
8762
|
// src/chat/tools/web/fetch-tool.ts
|
|
8643
|
-
import { z as
|
|
8763
|
+
import { z as z36 } from "zod";
|
|
8644
8764
|
|
|
8645
8765
|
// src/chat/tools/web/constants.ts
|
|
8646
8766
|
var USER_AGENT = "junior-bot/0.1";
|
|
@@ -9087,9 +9207,9 @@ function createWebFetchTool(hooks, options = {}) {
|
|
|
9087
9207
|
destructiveHint: false,
|
|
9088
9208
|
openWorldHint: true
|
|
9089
9209
|
},
|
|
9090
|
-
inputSchema:
|
|
9091
|
-
url:
|
|
9092
|
-
max_chars:
|
|
9210
|
+
inputSchema: z36.object({
|
|
9211
|
+
url: z36.string().min(1).describe("HTTP(S) URL to fetch."),
|
|
9212
|
+
max_chars: z36.coerce.number().int().min(500).max(MAX_FETCH_CHARS).describe("Optional maximum number of extracted characters to return.").optional()
|
|
9093
9213
|
}),
|
|
9094
9214
|
outputSchema: juniorToolResultSchema,
|
|
9095
9215
|
execute: async ({ url, max_chars }) => {
|
|
@@ -9156,7 +9276,7 @@ function createWebFetchTool(hooks, options = {}) {
|
|
|
9156
9276
|
}
|
|
9157
9277
|
|
|
9158
9278
|
// src/chat/tools/web/search.ts
|
|
9159
|
-
import { z as
|
|
9279
|
+
import { z as z37 } from "zod";
|
|
9160
9280
|
import { generateText } from "ai";
|
|
9161
9281
|
import { createGatewayProvider } from "@ai-sdk/gateway";
|
|
9162
9282
|
import { getModel } from "@earendil-works/pi-ai/compat";
|
|
@@ -9207,9 +9327,9 @@ function createWebSearchTool(override) {
|
|
|
9207
9327
|
destructiveHint: false,
|
|
9208
9328
|
openWorldHint: true
|
|
9209
9329
|
},
|
|
9210
|
-
inputSchema:
|
|
9211
|
-
query:
|
|
9212
|
-
max_results:
|
|
9330
|
+
inputSchema: z37.object({
|
|
9331
|
+
query: z37.string().min(1).max(500).describe("Search query."),
|
|
9332
|
+
max_results: z37.coerce.number().int().min(1).max(MAX_RESULTS2).describe("Max results to return.").optional()
|
|
9213
9333
|
}),
|
|
9214
9334
|
outputSchema: juniorToolResultSchema,
|
|
9215
9335
|
execute: async ({ query, max_results }) => {
|
|
@@ -9279,14 +9399,14 @@ function createWebSearchTool(override) {
|
|
|
9279
9399
|
}
|
|
9280
9400
|
|
|
9281
9401
|
// src/chat/tools/sandbox/write-file.ts
|
|
9282
|
-
import { z as
|
|
9402
|
+
import { z as z38 } from "zod";
|
|
9283
9403
|
function createWriteFileTool() {
|
|
9284
9404
|
return zodTool({
|
|
9285
9405
|
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.",
|
|
9286
9406
|
executionMode: "sequential",
|
|
9287
|
-
inputSchema:
|
|
9288
|
-
path:
|
|
9289
|
-
content:
|
|
9407
|
+
inputSchema: z38.object({
|
|
9408
|
+
path: z38.string().min(1).describe("Path to write in the sandbox workspace."),
|
|
9409
|
+
content: z38.string().describe("UTF-8 file content to write.")
|
|
9290
9410
|
}),
|
|
9291
9411
|
outputSchema: juniorToolResultSchema,
|
|
9292
9412
|
execute: async () => {
|
|
@@ -9389,6 +9509,11 @@ function createTools(availableSkills, hooks = {}, context) {
|
|
|
9389
9509
|
context.conversationId
|
|
9390
9510
|
);
|
|
9391
9511
|
}
|
|
9512
|
+
if (context.source.platform === "slack" && context.slackActionToken) {
|
|
9513
|
+
tools.slackPublicSearch = createSlackPublicSearchTool(
|
|
9514
|
+
context.slackActionToken
|
|
9515
|
+
);
|
|
9516
|
+
}
|
|
9392
9517
|
tools.slackUserLookup = createSlackUserLookupTool();
|
|
9393
9518
|
tools.slackListCreate = createSlackListCreateTool(state);
|
|
9394
9519
|
tools.slackListAddItems = createSlackListAddItemsTool(state);
|
|
@@ -10001,59 +10126,59 @@ async function startOAuthFlow(provider, input) {
|
|
|
10001
10126
|
}
|
|
10002
10127
|
|
|
10003
10128
|
// src/chat/sandbox/egress/schemas.ts
|
|
10004
|
-
import { z as
|
|
10129
|
+
import { z as z39 } from "zod";
|
|
10005
10130
|
import {
|
|
10006
10131
|
pluginAuthorizationSchema,
|
|
10007
10132
|
pluginCredentialHeaderTransformSchema,
|
|
10008
10133
|
pluginGrantSchema,
|
|
10009
10134
|
pluginProviderAccountSchema
|
|
10010
10135
|
} from "@sentry/junior-plugin-api";
|
|
10011
|
-
var finiteNumberSchema =
|
|
10012
|
-
var httpStatusSchema =
|
|
10013
|
-
var providerNameSchema =
|
|
10014
|
-
var credentialSignalKindSchema =
|
|
10136
|
+
var finiteNumberSchema = z39.number().refine(Number.isFinite);
|
|
10137
|
+
var httpStatusSchema = z39.number().int().min(100).max(599);
|
|
10138
|
+
var providerNameSchema = z39.string().regex(/^[a-z][a-z0-9-]*$/);
|
|
10139
|
+
var credentialSignalKindSchema = z39.enum(["auth_required", "unavailable"]);
|
|
10015
10140
|
var sandboxEgressGrantSchema = pluginGrantSchema;
|
|
10016
|
-
var sandboxEgressCredentialContextSchema =
|
|
10141
|
+
var sandboxEgressCredentialContextSchema = z39.object({
|
|
10017
10142
|
credentials: credentialContextSchema,
|
|
10018
|
-
egressId:
|
|
10143
|
+
egressId: z39.string().min(1),
|
|
10019
10144
|
expiresAtMs: finiteNumberSchema,
|
|
10020
|
-
contextId:
|
|
10145
|
+
contextId: z39.string().min(1)
|
|
10021
10146
|
}).strict();
|
|
10022
|
-
var sandboxEgressCredentialLeaseSchema =
|
|
10147
|
+
var sandboxEgressCredentialLeaseSchema = z39.object({
|
|
10023
10148
|
account: pluginProviderAccountSchema.optional(),
|
|
10024
10149
|
authorization: pluginAuthorizationSchema.optional(),
|
|
10025
10150
|
grant: sandboxEgressGrantSchema,
|
|
10026
10151
|
provider: providerNameSchema,
|
|
10027
|
-
expiresAt:
|
|
10028
|
-
headerTransforms:
|
|
10152
|
+
expiresAt: z39.string().min(1),
|
|
10153
|
+
headerTransforms: z39.array(pluginCredentialHeaderTransformSchema).min(1)
|
|
10029
10154
|
}).strict();
|
|
10030
|
-
var sandboxEgressAuthRequiredSignalSchema =
|
|
10155
|
+
var sandboxEgressAuthRequiredSignalSchema = z39.object({
|
|
10031
10156
|
authorization: pluginAuthorizationSchema.optional(),
|
|
10032
10157
|
grant: sandboxEgressGrantSchema,
|
|
10033
10158
|
kind: credentialSignalKindSchema.default("auth_required"),
|
|
10034
10159
|
provider: providerNameSchema,
|
|
10035
|
-
message:
|
|
10160
|
+
message: z39.string().optional(),
|
|
10036
10161
|
createdAtMs: finiteNumberSchema
|
|
10037
10162
|
}).strict().superRefine((signal, ctx) => {
|
|
10038
10163
|
if (signal.authorization && signal.authorization.provider !== signal.provider) {
|
|
10039
10164
|
ctx.addIssue({
|
|
10040
|
-
code:
|
|
10165
|
+
code: z39.ZodIssueCode.custom,
|
|
10041
10166
|
message: "Auth signal authorization provider must match provider",
|
|
10042
10167
|
path: ["authorization", "provider"]
|
|
10043
10168
|
});
|
|
10044
10169
|
}
|
|
10045
10170
|
});
|
|
10046
|
-
var sandboxEgressPermissionDeniedSignalSchema =
|
|
10171
|
+
var sandboxEgressPermissionDeniedSignalSchema = z39.object({
|
|
10047
10172
|
account: pluginProviderAccountSchema.optional(),
|
|
10048
|
-
acceptedPermissions:
|
|
10173
|
+
acceptedPermissions: z39.string().optional(),
|
|
10049
10174
|
grant: sandboxEgressGrantSchema,
|
|
10050
|
-
message:
|
|
10175
|
+
message: z39.string().min(1),
|
|
10051
10176
|
provider: providerNameSchema,
|
|
10052
|
-
source:
|
|
10053
|
-
sso:
|
|
10177
|
+
source: z39.literal("upstream"),
|
|
10178
|
+
sso: z39.string().optional(),
|
|
10054
10179
|
status: httpStatusSchema,
|
|
10055
|
-
upstreamHost:
|
|
10056
|
-
upstreamPath:
|
|
10180
|
+
upstreamHost: z39.string().min(1),
|
|
10181
|
+
upstreamPath: z39.string().min(1),
|
|
10057
10182
|
createdAtMs: finiteNumberSchema
|
|
10058
10183
|
}).strict();
|
|
10059
10184
|
function parseSandboxEgressAuthRequiredSignal(value) {
|
|
@@ -10314,15 +10439,15 @@ function handleToolExecutionError(error, toolName, toolCallId, shouldTrace, trac
|
|
|
10314
10439
|
}
|
|
10315
10440
|
|
|
10316
10441
|
// src/chat/tools/execute-tool.ts
|
|
10317
|
-
import { z as
|
|
10442
|
+
import { z as z40 } from "zod";
|
|
10318
10443
|
var EXECUTE_TOOL_NAME = "executeTool";
|
|
10319
10444
|
function createExecuteToolTool() {
|
|
10320
10445
|
return zodTool({
|
|
10321
10446
|
description: "Execute any catalog tool by exact tool_name from searchTools. Put tool-specific parameters inside arguments.",
|
|
10322
10447
|
executionMode: "sequential",
|
|
10323
|
-
inputSchema:
|
|
10324
|
-
tool_name:
|
|
10325
|
-
arguments:
|
|
10448
|
+
inputSchema: z40.object({
|
|
10449
|
+
tool_name: z40.string().min(1).describe("Exact catalog tool_name returned by searchTools."),
|
|
10450
|
+
arguments: z40.record(z40.string(), z40.unknown()).describe(
|
|
10326
10451
|
'Arguments matching the selected catalog tool schema, for example { "query": "..." }.'
|
|
10327
10452
|
).optional()
|
|
10328
10453
|
}).strict(),
|
|
@@ -10362,42 +10487,42 @@ function planToolExposure(tools) {
|
|
|
10362
10487
|
}
|
|
10363
10488
|
|
|
10364
10489
|
// src/chat/tools/search-tools.ts
|
|
10365
|
-
import { z as
|
|
10490
|
+
import { z as z41 } from "zod";
|
|
10366
10491
|
var SEARCH_TOOLS_NAME = "searchTools";
|
|
10367
10492
|
var DEFAULT_MAX_RESULTS2 = 5;
|
|
10368
10493
|
var MAX_RESULTS3 = 20;
|
|
10369
10494
|
var MODEL_VISIBLE_DESCRIPTION_CAP = 180;
|
|
10370
|
-
var searchToolsSourceSchema =
|
|
10371
|
-
id:
|
|
10372
|
-
description:
|
|
10495
|
+
var searchToolsSourceSchema = z41.object({
|
|
10496
|
+
id: z41.string(),
|
|
10497
|
+
description: z41.string()
|
|
10373
10498
|
}).strict();
|
|
10374
|
-
var toolCallExampleSchema =
|
|
10375
|
-
tool_name:
|
|
10376
|
-
arguments:
|
|
10499
|
+
var toolCallExampleSchema = z41.object({
|
|
10500
|
+
tool_name: z41.string(),
|
|
10501
|
+
arguments: z41.record(z41.string(), z41.string())
|
|
10377
10502
|
}).strict();
|
|
10378
|
-
var searchToolsToolSchema =
|
|
10379
|
-
tool_name:
|
|
10380
|
-
description:
|
|
10381
|
-
exposure:
|
|
10382
|
-
source:
|
|
10383
|
-
signature:
|
|
10503
|
+
var searchToolsToolSchema = z41.object({
|
|
10504
|
+
tool_name: z41.string(),
|
|
10505
|
+
description: z41.string(),
|
|
10506
|
+
exposure: z41.enum(["direct", "deferred", "modelOnly", "hidden"]),
|
|
10507
|
+
source: z41.string().optional(),
|
|
10508
|
+
signature: z41.string(),
|
|
10384
10509
|
call: toolCallExampleSchema,
|
|
10385
|
-
input_schema:
|
|
10386
|
-
input_schema_summary:
|
|
10387
|
-
call_notes:
|
|
10388
|
-
annotations:
|
|
10510
|
+
input_schema: z41.unknown(),
|
|
10511
|
+
input_schema_summary: z41.string(),
|
|
10512
|
+
call_notes: z41.array(z41.string()),
|
|
10513
|
+
annotations: z41.record(z41.string(), z41.unknown())
|
|
10389
10514
|
}).strict();
|
|
10390
10515
|
var searchToolsOutputSchema = juniorToolResultSchema.extend({
|
|
10391
|
-
query:
|
|
10392
|
-
source:
|
|
10393
|
-
sources:
|
|
10394
|
-
total_catalog_tools:
|
|
10395
|
-
total_eligible_tools:
|
|
10396
|
-
total_matches:
|
|
10397
|
-
returned_tools:
|
|
10398
|
-
execution_tool:
|
|
10516
|
+
query: z41.string().nullable(),
|
|
10517
|
+
source: z41.string().nullable(),
|
|
10518
|
+
sources: z41.array(searchToolsSourceSchema),
|
|
10519
|
+
total_catalog_tools: z41.number().int().nonnegative(),
|
|
10520
|
+
total_eligible_tools: z41.number().int().nonnegative(),
|
|
10521
|
+
total_matches: z41.number().int().nonnegative(),
|
|
10522
|
+
returned_tools: z41.number().int().nonnegative(),
|
|
10523
|
+
execution_tool: z41.literal("executeTool"),
|
|
10399
10524
|
execution_example: toolCallExampleSchema,
|
|
10400
|
-
tools:
|
|
10525
|
+
tools: z41.array(searchToolsToolSchema)
|
|
10401
10526
|
}).strict();
|
|
10402
10527
|
function normalize2(value) {
|
|
10403
10528
|
return value.toLowerCase().replace(/[^a-z0-9_]+/g, " ").trim();
|
|
@@ -10589,14 +10714,14 @@ function createSearchToolsTool(catalogTools) {
|
|
|
10589
10714
|
return zodTool({
|
|
10590
10715
|
description: renderSearchToolsDescription(knownSources),
|
|
10591
10716
|
annotations: { readOnlyHint: true, destructiveHint: false },
|
|
10592
|
-
inputSchema:
|
|
10593
|
-
query:
|
|
10717
|
+
inputSchema: z41.object({
|
|
10718
|
+
query: z41.string().nullable().describe(
|
|
10594
10719
|
"Optional search terms describing the tool, owner, action, or arguments needed. Empty string lists catalog tools."
|
|
10595
10720
|
).optional(),
|
|
10596
|
-
source:
|
|
10721
|
+
source: z41.string().nullable().describe(
|
|
10597
10722
|
"Optional source id to search within, such as a plugin source returned in sources."
|
|
10598
10723
|
).optional(),
|
|
10599
|
-
max_results:
|
|
10724
|
+
max_results: z41.number().int().min(1).max(MAX_RESULTS3).nullable().describe("Maximum matching catalog tool descriptors to return.").optional()
|
|
10600
10725
|
}).strict(),
|
|
10601
10726
|
outputSchema: searchToolsOutputSchema,
|
|
10602
10727
|
privateTraceResult: (result) => ({
|
|
@@ -11306,6 +11431,19 @@ function findInErrorChain(error, predicate) {
|
|
|
11306
11431
|
}
|
|
11307
11432
|
return false;
|
|
11308
11433
|
}
|
|
11434
|
+
function isRecord5(value) {
|
|
11435
|
+
return typeof value === "object" && value !== null;
|
|
11436
|
+
}
|
|
11437
|
+
function isInvalidSandboxSessionError(error) {
|
|
11438
|
+
if (!isRecord5(error)) {
|
|
11439
|
+
return false;
|
|
11440
|
+
}
|
|
11441
|
+
if (isRecord5(error.json) && error.json.invalidToken === true) {
|
|
11442
|
+
return true;
|
|
11443
|
+
}
|
|
11444
|
+
const response = error.response;
|
|
11445
|
+
return isRecord5(response) && response.status === 403 && typeof response.url === "string" && response.url.includes("/sandboxes/sessions");
|
|
11446
|
+
}
|
|
11309
11447
|
function getFirstErrorMessage(error) {
|
|
11310
11448
|
const seen = /* @__PURE__ */ new Set();
|
|
11311
11449
|
let current = error;
|
|
@@ -11327,9 +11465,12 @@ function isAlreadyExistsError(error) {
|
|
|
11327
11465
|
}
|
|
11328
11466
|
function isSandboxUnavailableError(error) {
|
|
11329
11467
|
return findInErrorChain(error, (candidate) => {
|
|
11468
|
+
if (isInvalidSandboxSessionError(candidate)) {
|
|
11469
|
+
return true;
|
|
11470
|
+
}
|
|
11330
11471
|
const details = getSandboxErrorDetails(candidate);
|
|
11331
11472
|
const searchable = `${details.searchableText} ${details.summary}`.toLowerCase();
|
|
11332
|
-
return searchable.includes("sandbox_stopped") || searchable.includes("status=410") || searchable.includes("status code 410") || searchable.includes("no longer available");
|
|
11473
|
+
return searchable.includes("sandbox_stopped") || searchable.includes("status=410") || searchable.includes("status code 410") || searchable.includes("no longer available") || searchable.includes("stream was closed and is not accepting commands");
|
|
11333
11474
|
});
|
|
11334
11475
|
}
|
|
11335
11476
|
function isSnapshottingError(error) {
|
|
@@ -14642,7 +14783,8 @@ async function wireAgentTools(args) {
|
|
|
14642
14783
|
...commonToolRuntimeContext,
|
|
14643
14784
|
destination: toolDestination,
|
|
14644
14785
|
actor: args.currentActor?.platform === "slack" ? args.currentActor : void 0,
|
|
14645
|
-
source: runSource
|
|
14786
|
+
source: runSource,
|
|
14787
|
+
slackActionToken: args.routing.slackActionToken
|
|
14646
14788
|
};
|
|
14647
14789
|
} else {
|
|
14648
14790
|
if (toolDestination.platform !== "local") {
|
|
@@ -14957,9 +15099,7 @@ function createResumeState(args) {
|
|
|
14957
15099
|
}
|
|
14958
15100
|
};
|
|
14959
15101
|
}
|
|
14960
|
-
throw new
|
|
14961
|
-
sessionRecord.errorMessage ?? (error instanceof Error ? error.message : String(error))
|
|
14962
|
-
);
|
|
15102
|
+
throw new TurnSliceLimitExceededError(botConfig.maxSlicesPerTurn);
|
|
14963
15103
|
}
|
|
14964
15104
|
if (error instanceof AuthorizationPauseError) {
|
|
14965
15105
|
const usage = args2.currentUsage ?? (resumeMessages.length > 0 ? extractSliceUsage(resumeMessages, beforeMessageCount) : void 0);
|
|
@@ -15340,9 +15480,9 @@ async function executeAgentRun(request) {
|
|
|
15340
15480
|
const conversationPrivacy = resolveConversationPrivacy({
|
|
15341
15481
|
channelId: request.routing.correlation?.channelId,
|
|
15342
15482
|
conversationId: request.routing.correlation?.conversationId ?? request.routing.correlation?.threadId ?? request.routing.correlation?.runId,
|
|
15343
|
-
//
|
|
15344
|
-
//
|
|
15345
|
-
visibility: request.routing.slackConversation?.visibility
|
|
15483
|
+
// Destination visibility is provider-neutral. Slack event context remains
|
|
15484
|
+
// a compatibility fallback for callers that have not projected it yet.
|
|
15485
|
+
visibility: request.routing.destinationVisibility ?? request.routing.slackConversation?.visibility
|
|
15346
15486
|
});
|
|
15347
15487
|
return runWithConversationPrivacy(
|
|
15348
15488
|
conversationPrivacy ?? "private",
|