@sentry/junior 0.147.0 → 0.149.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-HS6VGUPM.js → agent-hooks-CWMCXAMT.js} +10 -10
- package/dist/api/conversations/access.d.ts +2 -1
- package/dist/api/conversations/aggregate.d.ts +2 -0
- package/dist/api/conversations/archive.d.ts +3 -5
- package/dist/api/conversations/create.d.ts +6 -0
- package/dist/api/conversations/detail.d.ts +2 -296
- package/dist/api/conversations/event-list.d.ts +2 -193
- package/dist/api/conversations/list.d.ts +4 -66
- package/dist/api/conversations/pending-messages.d.ts +15 -0
- package/dist/api/conversations/routes.d.ts +1 -1
- package/dist/api/conversations/stats.d.ts +0 -54
- package/dist/api/http.d.ts +2 -6
- package/dist/api/locations/detail.d.ts +3 -111
- package/dist/api/locations/list.d.ts +0 -45
- package/dist/api/locations/query.d.ts +2 -1
- package/dist/api/locations/routes.d.ts +1 -1
- package/dist/api/people/list.d.ts +0 -29
- package/dist/api/people/profile.d.ts +2 -106
- package/dist/api/people/profile.query.d.ts +2 -1
- package/dist/api/people/routes.d.ts +1 -1
- package/dist/api/people/shared.d.ts +3 -1
- package/dist/api/people/spend.d.ts +3 -4
- package/dist/api/personal-tokens/routes.d.ts +2 -2
- package/dist/api/route.d.ts +8 -14
- package/dist/api/schema/conversation.d.ts +130 -25
- package/dist/api/schema/location.d.ts +4 -0
- package/dist/api/schema/person.d.ts +7 -3
- package/dist/api/schema.d.ts +2 -2
- package/dist/api/schema.js +13 -1
- package/dist/api/stats.d.ts +0 -13
- package/dist/api/validation.d.ts +7 -0
- package/dist/api/viewer.d.ts +3 -0
- package/dist/api.d.ts +2 -1
- package/dist/api.js +772 -561
- package/dist/app.js +241 -204
- package/dist/{catalog-runtime-M6ZTPYRV.js → catalog-runtime-GAW5APVI.js} +5 -5
- package/dist/chat/actor.d.ts +4 -1
- package/dist/chat/agent/request.d.ts +2 -0
- package/dist/chat/agent/resume.d.ts +1 -0
- package/dist/chat/agent-dispatch/context.d.ts +2 -2
- package/dist/chat/agent-invocations/types.d.ts +52 -0
- package/dist/chat/api-turns/work.d.ts +108 -0
- package/dist/chat/app/services.d.ts +1 -1
- package/dist/chat/conversations/history.d.ts +60 -0
- package/dist/chat/conversations/provenance.d.ts +6 -0
- package/dist/chat/conversations/sql/actor-identity.d.ts +19 -0
- package/dist/chat/conversations/store.d.ts +1 -1
- package/dist/chat/resource-events/store.d.ts +1 -1
- package/dist/chat/runtime/reply-executor.d.ts +1 -3
- package/dist/chat/runtime/slack-runtime.d.ts +2 -1
- package/dist/chat/runtime/turn-preparation.d.ts +9 -0
- package/dist/chat/scheduled-tasks/tool-support.d.ts +5 -5
- package/dist/chat/scheduled-tasks/tools/create.d.ts +2 -2
- package/dist/chat/scheduled-tasks/tools/delete.d.ts +2 -2
- package/dist/chat/scheduled-tasks/tools/list.d.ts +2 -2
- package/dist/chat/scheduled-tasks/tools/run-now.d.ts +2 -2
- package/dist/chat/scheduled-tasks/tools/update.d.ts +2 -2
- package/dist/chat/services/conversation-memory.d.ts +2 -2
- package/dist/chat/services/conversation-title.d.ts +20 -0
- package/dist/chat/slack/assistant-thread/title.d.ts +10 -27
- package/dist/chat/slack/channel.d.ts +26 -0
- package/dist/chat/slack/dispatch-turn.d.ts +1 -0
- package/dist/chat/slack/timestamp-param.d.ts +0 -2
- package/dist/chat/slack/{tools → tool-support}/canvas/api.d.ts +1 -1
- package/dist/chat/slack/{tools → tool-support}/canvas/context.d.ts +3 -0
- package/dist/chat/slack/tool-support/channel-access.d.ts +42 -0
- package/dist/chat/slack/tool-support/channel-target.d.ts +27 -0
- package/dist/chat/slack/tool-support/list/params.d.ts +5 -0
- package/dist/chat/slack/tools/canvas/create.d.ts +1 -1
- package/dist/chat/slack/tools/channel-join.d.ts +28 -0
- package/dist/chat/slack/tools/channel-list-messages.d.ts +3 -2
- package/dist/chat/slack/tools/conversation-message-search.d.ts +2 -8
- package/dist/chat/slack/tools/message-add-reaction.d.ts +1 -1
- package/dist/chat/slack/tools/public-search.d.ts +63 -2
- package/dist/chat/slack/tools/send-files.d.ts +1 -1
- package/dist/chat/slack/tools/thread-read.d.ts +2 -5
- package/dist/chat/source.d.ts +2 -0
- package/dist/chat/state/conversation.d.ts +1 -0
- package/dist/chat/task-execution/checkpoint.d.ts +1 -0
- package/dist/chat/task-execution/state.d.ts +9 -4
- package/dist/chat/task-execution/store.d.ts +3 -2
- package/dist/chat/task-execution/turn-cursor.d.ts +2 -0
- package/dist/chat/task-execution/worker.d.ts +2 -0
- package/dist/chat/tasks/read.d.ts +1 -1
- package/dist/chat/tools/search-conversation-events.d.ts +1 -1
- package/dist/chat/tools/types.d.ts +11 -4
- package/dist/chat/tools/watch-resource-events.d.ts +2 -2
- package/dist/{chunk-ORO3PWKQ.js → chunk-25SC7D6Z.js} +1 -1
- package/dist/{chunk-GGB4WL5A.js → chunk-2JHKISQA.js} +1 -1
- package/dist/{chunk-AVZDSUFB.js → chunk-2P6BQQER.js} +4 -4
- package/dist/{chunk-7NVJVJID.js → chunk-32CXPIZE.js} +2 -2
- package/dist/{chunk-YSB2N563.js → chunk-3GYZ5YEH.js} +121 -87
- package/dist/{chunk-DU74WPIC.js → chunk-3I2IVWSZ.js} +1 -1
- package/dist/{chunk-SVHUEHUL.js → chunk-3JVUWLR7.js} +65 -4
- package/dist/{chunk-RXBVB2JM.js → chunk-3KGQOKIG.js} +1 -1
- package/dist/{chunk-YBVXBNSV.js → chunk-4JGM7FXO.js} +2 -2
- package/dist/{chunk-AZ7EAOBE.js → chunk-4YKPOYRV.js} +5 -5
- package/dist/chunk-5CWUQXXT.js +806 -0
- package/dist/{chunk-DLDRQHG5.js → chunk-6G5RCDKP.js} +1 -1
- package/dist/{chunk-AYU72WO7.js → chunk-75DSYFFB.js} +47 -70
- package/dist/{chunk-YHDERDRO.js → chunk-7BH46NB4.js} +91 -75
- package/dist/{chunk-745QJ3ZA.js → chunk-ALJG73MQ.js} +2 -2
- package/dist/chunk-ART7P442.js +48 -0
- package/dist/{chunk-7A4M7PCV.js → chunk-DK5UT6PQ.js} +1180 -556
- package/dist/{chunk-AIOK6LAG.js → chunk-EW2LNCRL.js} +813 -44
- package/dist/chunk-EXW76GW4.js +36 -0
- package/dist/chunk-GDFF3BQG.js +136 -0
- package/dist/{chunk-7UQIVT6G.js → chunk-JMH3DBM5.js} +6 -6
- package/dist/{chunk-CWP5RHVX.js → chunk-JMSMXXED.js} +12 -5
- package/dist/{chunk-CSZINQJ2.js → chunk-MEMURSBG.js} +1 -1
- package/dist/{chunk-YNTTROJT.js → chunk-QIW7OQEO.js} +1 -1
- package/dist/{chunk-Q4R73I43.js → chunk-RB26T3LU.js} +58 -28
- package/dist/{chunk-4LJO56OJ.js → chunk-RLVZIWNQ.js} +1 -1
- package/dist/{chunk-SGZO7UWH.js → chunk-SWHPVZBV.js} +2 -2
- package/dist/{chunk-PVNG6UMU.js → chunk-TFBNBXPU.js} +22 -10
- package/dist/{chunk-EFLJ2WJH.js → chunk-URDCZAL4.js} +5 -5
- package/dist/{chunk-6H5SZR24.js → chunk-UZGASGOD.js} +300 -383
- package/dist/{chunk-YEO3VX72.js → chunk-W7UONUIZ.js} +8 -6
- package/dist/{chunk-JUUKWRBE.js → chunk-X22XXSZA.js} +1 -1
- package/dist/{chunk-X5UY34KT.js → chunk-XPYWWMHR.js} +8 -8
- package/dist/{chunk-IIOOO4FQ.js → chunk-ZYMYLLWG.js} +2 -1
- package/dist/cli/chat.js +32 -35
- package/dist/cli/check.js +6 -6
- package/dist/cli/plugins.js +13 -13
- package/dist/cli/snapshot-create.js +9 -9
- package/dist/cli/upgrade.js +7 -7
- package/dist/db/schema/agent-invocations.d.ts +20 -0
- package/dist/db/schema/conversation-annotations.d.ts +2 -2
- package/dist/db/schema.d.ts +22 -2
- package/dist/{db-CSEW4RII.js → db-JBZLRIVY.js} +7 -7
- package/dist/instrumentation.js +4 -4
- package/dist/nitro.js +2 -2
- package/dist/{oauth-callback-server-FUEV5HNG.js → oauth-callback-server-MNTVYY2I.js} +24 -26
- package/dist/{runner-U3XHSKSH.js → runner-K24BWZSZ.js} +23 -25
- package/dist/{skills-AKE6W3WI.js → skills-AU5ST2CG.js} +6 -6
- package/dist/spawn-6PO7CVJ6.js +38 -0
- package/dist/{validation-WDTAULUF.js → validation-IXGZCFRO.js} +6 -6
- package/dist/version.js +1 -1
- package/dist/{work-C3HAO2BG.js → work-WCZIYILX.js} +18 -19
- package/dist/{worker-LNP4YKBM.js → worker-U2AACBEY.js} +11 -10
- package/package.json +6 -5
- package/dist/api/health.d.ts +0 -7
- package/dist/api/personal-tokens/create.d.ts +0 -11
- package/dist/api/personal-tokens/list.d.ts +0 -12
- package/dist/api/personal-tokens/revoke.d.ts +0 -5
- package/dist/api/plugin-reports.d.ts +0 -63
- package/dist/api/plugins.d.ts +0 -8
- package/dist/api/runtime.d.ts +0 -24
- package/dist/api/skills.d.ts +0 -6
- package/dist/chat/slack/tools/channel-access.d.ts +0 -30
- package/dist/chunk-34GS7B6L.js +0 -115
- package/dist/chunk-AVOCH2Z5.js +0 -285
- package/dist/chunk-HLXXQI5Q.js +0 -238
- package/dist/chunk-K4SZAP3K.js +0 -67
- package/dist/chunk-R776HKPK.js +0 -81
- package/dist/chunk-Z4YU7Z4L.js +0 -76
- package/dist/spawn-B6GDTWJ4.js +0 -39
- /package/dist/chat/slack/{tools → tool-support}/canvas/markdown.d.ts +0 -0
- /package/dist/chat/slack/{tools → tool-support}/channel-capabilities.d.ts +0 -0
- /package/dist/chat/slack/{tools → tool-support}/context.d.ts +0 -0
- /package/dist/chat/slack/{tools → tool-support}/list/api.d.ts +0 -0
- /package/dist/chat/slack/{tools → tool-support}/slack-message-url.d.ts +0 -0
|
@@ -7,7 +7,7 @@ import {
|
|
|
7
7
|
PluginCredentialFailureError,
|
|
8
8
|
agentNameSchema,
|
|
9
9
|
createPluginAuthOrchestration
|
|
10
|
-
} from "./chunk-
|
|
10
|
+
} from "./chunk-XPYWWMHR.js";
|
|
11
11
|
import {
|
|
12
12
|
authorizationId
|
|
13
13
|
} from "./chunk-DIB4GX3G.js";
|
|
@@ -32,7 +32,7 @@ import {
|
|
|
32
32
|
searchSlackUsers,
|
|
33
33
|
selectPluginGrant,
|
|
34
34
|
toMcpProviderError
|
|
35
|
-
} from "./chunk-
|
|
35
|
+
} from "./chunk-RB26T3LU.js";
|
|
36
36
|
import {
|
|
37
37
|
RetryableDeliveryError,
|
|
38
38
|
actorFromRouting,
|
|
@@ -40,7 +40,7 @@ import {
|
|
|
40
40
|
isAgentRunFeatureDisabled,
|
|
41
41
|
surfaceFromRouting,
|
|
42
42
|
toolInvocationDestination
|
|
43
|
-
} from "./chunk-
|
|
43
|
+
} from "./chunk-GDFF3BQG.js";
|
|
44
44
|
import {
|
|
45
45
|
addReactionToMessage,
|
|
46
46
|
deliverOAuthAuthorization,
|
|
@@ -48,76 +48,7 @@ import {
|
|
|
48
48
|
getSlackMessagePermalink,
|
|
49
49
|
resolveBaseUrl,
|
|
50
50
|
uploadFilesToConversation
|
|
51
|
-
} from "./chunk-
|
|
52
|
-
import {
|
|
53
|
-
estimateTextTokens,
|
|
54
|
-
getAgentContextCompactionTriggerTokens,
|
|
55
|
-
getAgentContextInputLimitTokens
|
|
56
|
-
} from "./chunk-K4SZAP3K.js";
|
|
57
|
-
import {
|
|
58
|
-
AGENTS_REMOVAL_NOTICE,
|
|
59
|
-
AGENTS_REPLACEMENT_NOTICE,
|
|
60
|
-
CooperativeTurnYieldError,
|
|
61
|
-
DEFAULT_SEARCH_COMMAND_TIMEOUT_MS,
|
|
62
|
-
MAX_TEXT_CHARS,
|
|
63
|
-
NO_REPLY_MARKER,
|
|
64
|
-
RIPGREP_EXCLUDED_GLOBS,
|
|
65
|
-
TURN_CONTEXT_TAG,
|
|
66
|
-
TurnInputCommitLostError,
|
|
67
|
-
TurnSliceLimitExceededError,
|
|
68
|
-
abandonReplacedPendingAuth,
|
|
69
|
-
buildAgentsInstructionsMessage,
|
|
70
|
-
canReusePendingAuthLink,
|
|
71
|
-
collectFiles,
|
|
72
|
-
containsNoReplyMarker,
|
|
73
|
-
continuableMessages,
|
|
74
|
-
decideReply,
|
|
75
|
-
extractAssistantText,
|
|
76
|
-
findSingleRepositoryDirectory,
|
|
77
|
-
findVisibleAgentsInstructions,
|
|
78
|
-
getAssistantReplyText,
|
|
79
|
-
getPiMessageRole,
|
|
80
|
-
getRipgrepSearchLocation,
|
|
81
|
-
getTerminalAssistantMessages,
|
|
82
|
-
getUserMessageInstructionText,
|
|
83
|
-
hasRuntimeTurnContext,
|
|
84
|
-
historyItemFromPiMessage,
|
|
85
|
-
isAssistantMessage,
|
|
86
|
-
isContinuablePiBoundary,
|
|
87
|
-
isMissingPathError,
|
|
88
|
-
isNoReplyMarker,
|
|
89
|
-
isToolResultError,
|
|
90
|
-
isToolResultMessage,
|
|
91
|
-
isTurnInputCommitLostError,
|
|
92
|
-
loadConnectedMcpProviders,
|
|
93
|
-
loadConversationProjection,
|
|
94
|
-
loadTurnCheckpoint,
|
|
95
|
-
loadTurnRoute,
|
|
96
|
-
missingPathSearchResult,
|
|
97
|
-
normalizeToLf,
|
|
98
|
-
normalizeToolNameFromResult,
|
|
99
|
-
openConversationProjection,
|
|
100
|
-
piMessageFromHistoryItem,
|
|
101
|
-
positiveInteger,
|
|
102
|
-
recordAgentsInstructionsUpdated,
|
|
103
|
-
recordAuthorizationRequested,
|
|
104
|
-
recordGuardianActionReviewed,
|
|
105
|
-
recordMcpProviderConnected,
|
|
106
|
-
recordToolExecutionStarted,
|
|
107
|
-
recordTurnRoute,
|
|
108
|
-
renderAgentsInstructions,
|
|
109
|
-
resolveRepositoryInstructions,
|
|
110
|
-
resolveWorkspacePath,
|
|
111
|
-
retainRuntimeTurnContext,
|
|
112
|
-
sanitizeAssistantText,
|
|
113
|
-
saveTurnCheckpoint,
|
|
114
|
-
stripRuntimeTurnContext,
|
|
115
|
-
trimTrailingAssistantMessages,
|
|
116
|
-
truncateText
|
|
117
|
-
} from "./chunk-AIOK6LAG.js";
|
|
118
|
-
import {
|
|
119
|
-
JUNIOR_THREAD_STATE_TTL_MS
|
|
120
|
-
} from "./chunk-3Y47VMHV.js";
|
|
51
|
+
} from "./chunk-JMH3DBM5.js";
|
|
121
52
|
import {
|
|
122
53
|
parseSandboxEgressAuthRequiredSignal,
|
|
123
54
|
parseSandboxEgressPermissionDeniedSignal,
|
|
@@ -146,7 +77,7 @@ import {
|
|
|
146
77
|
runNonInteractiveCommand,
|
|
147
78
|
throwSandboxOperationError,
|
|
148
79
|
wrapSandboxSetupError
|
|
149
|
-
} from "./chunk-
|
|
80
|
+
} from "./chunk-2P6BQQER.js";
|
|
150
81
|
import {
|
|
151
82
|
SCHEDULED_TASK_SYSTEM_ACTOR,
|
|
152
83
|
compactEventTask,
|
|
@@ -178,20 +109,83 @@ import {
|
|
|
178
109
|
saveEventTask,
|
|
179
110
|
scheduledTaskAttributes,
|
|
180
111
|
writableEventTask
|
|
181
|
-
} from "./chunk-
|
|
112
|
+
} from "./chunk-URDCZAL4.js";
|
|
182
113
|
import {
|
|
183
114
|
parseSlackThreadId
|
|
184
|
-
} from "./chunk-
|
|
115
|
+
} from "./chunk-MEMURSBG.js";
|
|
185
116
|
import {
|
|
117
|
+
AGENTS_REMOVAL_NOTICE,
|
|
118
|
+
AGENTS_REPLACEMENT_NOTICE,
|
|
119
|
+
CooperativeTurnYieldError,
|
|
120
|
+
DEFAULT_SEARCH_COMMAND_TIMEOUT_MS,
|
|
121
|
+
MAX_TEXT_CHARS,
|
|
122
|
+
NO_REPLY_MARKER,
|
|
123
|
+
RIPGREP_EXCLUDED_GLOBS,
|
|
186
124
|
SHORT_TITLE_MAX_LENGTH,
|
|
187
|
-
|
|
188
|
-
resolveTaskTitle
|
|
189
|
-
} from "./chunk-Z4YU7Z4L.js";
|
|
190
|
-
import {
|
|
125
|
+
TURN_CONTEXT_TAG,
|
|
191
126
|
ToolInputError,
|
|
127
|
+
TurnInputCommitLostError,
|
|
128
|
+
TurnSliceLimitExceededError,
|
|
129
|
+
abandonReplacedPendingAuth,
|
|
192
130
|
addAgentTurnUsage,
|
|
193
|
-
|
|
194
|
-
|
|
131
|
+
buildAgentsInstructionsMessage,
|
|
132
|
+
canReusePendingAuthLink,
|
|
133
|
+
collectFiles,
|
|
134
|
+
containsNoReplyMarker,
|
|
135
|
+
continuableMessages,
|
|
136
|
+
decideReply,
|
|
137
|
+
estimateTextTokens,
|
|
138
|
+
extractAssistantText,
|
|
139
|
+
findSingleRepositoryDirectory,
|
|
140
|
+
findVisibleAgentsInstructions,
|
|
141
|
+
generateShortTitle,
|
|
142
|
+
getAgentContextCompactionTriggerTokens,
|
|
143
|
+
getAgentContextInputLimitTokens,
|
|
144
|
+
getAssistantReplyText,
|
|
145
|
+
getPiMessageRole,
|
|
146
|
+
getRipgrepSearchLocation,
|
|
147
|
+
getTerminalAssistantMessages,
|
|
148
|
+
getUserMessageInstructionText,
|
|
149
|
+
hasAgentTurnUsage,
|
|
150
|
+
hasRuntimeTurnContext,
|
|
151
|
+
historyItemFromPiMessage,
|
|
152
|
+
isAssistantMessage,
|
|
153
|
+
isContinuablePiBoundary,
|
|
154
|
+
isMissingPathError,
|
|
155
|
+
isNoReplyMarker,
|
|
156
|
+
isToolResultError,
|
|
157
|
+
isToolResultMessage,
|
|
158
|
+
isTurnInputCommitLostError,
|
|
159
|
+
loadConnectedMcpProviders,
|
|
160
|
+
loadConversationProjection,
|
|
161
|
+
loadTurnCheckpoint,
|
|
162
|
+
loadTurnRoute,
|
|
163
|
+
missingPathSearchResult,
|
|
164
|
+
normalizeToLf,
|
|
165
|
+
normalizeToolNameFromResult,
|
|
166
|
+
openConversationProjection,
|
|
167
|
+
piMessageFromHistoryItem,
|
|
168
|
+
positiveInteger,
|
|
169
|
+
recordAgentsInstructionsUpdated,
|
|
170
|
+
recordAuthorizationRequested,
|
|
171
|
+
recordGuardianActionReviewed,
|
|
172
|
+
recordMcpProviderConnected,
|
|
173
|
+
recordToolExecutionStarted,
|
|
174
|
+
recordTurnRoute,
|
|
175
|
+
renderAgentsInstructions,
|
|
176
|
+
resolveRepositoryInstructions,
|
|
177
|
+
resolveTaskTitle,
|
|
178
|
+
resolveWorkspacePath,
|
|
179
|
+
retainRuntimeTurnContext,
|
|
180
|
+
sanitizeAssistantText,
|
|
181
|
+
saveTurnCheckpoint,
|
|
182
|
+
stripRuntimeTurnContext,
|
|
183
|
+
trimTrailingAssistantMessages,
|
|
184
|
+
truncateText
|
|
185
|
+
} from "./chunk-EW2LNCRL.js";
|
|
186
|
+
import {
|
|
187
|
+
JUNIOR_THREAD_STATE_TTL_MS
|
|
188
|
+
} from "./chunk-3Y47VMHV.js";
|
|
195
189
|
import {
|
|
196
190
|
privateTraceResultAttributes
|
|
197
191
|
} from "./chunk-UIE3R5XU.js";
|
|
@@ -204,7 +198,7 @@ import {
|
|
|
204
198
|
getSlackToolContext,
|
|
205
199
|
readActorIdentity,
|
|
206
200
|
resolveChannelCapabilities
|
|
207
|
-
} from "./chunk-
|
|
201
|
+
} from "./chunk-7BH46NB4.js";
|
|
208
202
|
import {
|
|
209
203
|
SlackActionError,
|
|
210
204
|
downloadPrivateSlackFile,
|
|
@@ -213,7 +207,7 @@ import {
|
|
|
213
207
|
isConversationScopedChannel,
|
|
214
208
|
normalizeSlackConversationId,
|
|
215
209
|
withSlackRetries
|
|
216
|
-
} from "./chunk-
|
|
210
|
+
} from "./chunk-SWHPVZBV.js";
|
|
217
211
|
import {
|
|
218
212
|
KNOWN_CONVERSATION_EVENT_TYPES,
|
|
219
213
|
contextProvenance,
|
|
@@ -225,10 +219,10 @@ import {
|
|
|
225
219
|
instructionActors,
|
|
226
220
|
instructionProvenanceFor,
|
|
227
221
|
sameActorIdentity
|
|
228
|
-
} from "./chunk-
|
|
222
|
+
} from "./chunk-3GYZ5YEH.js";
|
|
229
223
|
import {
|
|
230
224
|
juniorIdentities
|
|
231
|
-
} from "./chunk-
|
|
225
|
+
} from "./chunk-3I2IVWSZ.js";
|
|
232
226
|
import {
|
|
233
227
|
SANDBOX_DATA_ROOT,
|
|
234
228
|
SANDBOX_SKILLS_ROOT,
|
|
@@ -240,7 +234,7 @@ import {
|
|
|
240
234
|
} from "./chunk-EM225ITJ.js";
|
|
241
235
|
import {
|
|
242
236
|
getStateAdapter
|
|
243
|
-
} from "./chunk-
|
|
237
|
+
} from "./chunk-25SC7D6Z.js";
|
|
244
238
|
import {
|
|
245
239
|
ACTIVE_TURN_COMPACTION_SUMMARY_PREFIX,
|
|
246
240
|
COMPACTION_SUMMARY_PREFIX,
|
|
@@ -273,7 +267,7 @@ import {
|
|
|
273
267
|
resolveGatewayCredential,
|
|
274
268
|
resolveGatewayModel,
|
|
275
269
|
unwrapCurrentInstruction
|
|
276
|
-
} from "./chunk-
|
|
270
|
+
} from "./chunk-32CXPIZE.js";
|
|
277
271
|
import {
|
|
278
272
|
canExposeConversationPayload,
|
|
279
273
|
resolveConversationPrivacy,
|
|
@@ -283,16 +277,16 @@ import {
|
|
|
283
277
|
toGenAiMessagesTraceAttributes,
|
|
284
278
|
toGenAiPayloadMetadata,
|
|
285
279
|
toGenAiPayloadTraceAttributes
|
|
286
|
-
} from "./chunk-
|
|
280
|
+
} from "./chunk-3KGQOKIG.js";
|
|
287
281
|
import {
|
|
288
282
|
discoverSkills,
|
|
289
283
|
findSkillByName,
|
|
290
284
|
loadSkillsByName,
|
|
291
285
|
parseSkillInvocation
|
|
292
|
-
} from "./chunk-
|
|
286
|
+
} from "./chunk-4JGM7FXO.js";
|
|
293
287
|
import {
|
|
294
288
|
pluginCatalogRuntime
|
|
295
|
-
} from "./chunk-
|
|
289
|
+
} from "./chunk-X22XXSZA.js";
|
|
296
290
|
import {
|
|
297
291
|
CredentialUnavailableError,
|
|
298
292
|
OAuthProviderError,
|
|
@@ -300,7 +294,7 @@ import {
|
|
|
300
294
|
getOAuthProviderErrorAttributes,
|
|
301
295
|
resolveAuthTokenPlaceholder,
|
|
302
296
|
resolvePluginCommandEnv
|
|
303
|
-
} from "./chunk-
|
|
297
|
+
} from "./chunk-2JHKISQA.js";
|
|
304
298
|
import {
|
|
305
299
|
credentialUserSubjectId
|
|
306
300
|
} from "./chunk-RUIXF3YQ.js";
|
|
@@ -330,7 +324,7 @@ import {
|
|
|
330
324
|
summarizeMessageText,
|
|
331
325
|
withLogContext,
|
|
332
326
|
withSpan
|
|
333
|
-
} from "./chunk-
|
|
327
|
+
} from "./chunk-RLVZIWNQ.js";
|
|
334
328
|
import {
|
|
335
329
|
startInactiveSpan,
|
|
336
330
|
withActiveSpan
|
|
@@ -1903,19 +1897,22 @@ function buildRuntimeSection(params) {
|
|
|
1903
1897
|
return renderTagBlock("runtime", lines.join("\n"));
|
|
1904
1898
|
}
|
|
1905
1899
|
function formatSourceLines(source) {
|
|
1906
|
-
|
|
1907
|
-
|
|
1908
|
-
|
|
1909
|
-
|
|
1910
|
-
|
|
1900
|
+
switch (source.platform) {
|
|
1901
|
+
case "web":
|
|
1902
|
+
case "local":
|
|
1903
|
+
return [
|
|
1904
|
+
`- source.platform: ${source.platform}`,
|
|
1905
|
+
`- source.conversation_id: ${escapeXml(source.conversationId)}`
|
|
1906
|
+
];
|
|
1907
|
+
case "slack":
|
|
1908
|
+
return [
|
|
1909
|
+
"- source.platform: slack",
|
|
1910
|
+
`- source.team_id: ${escapeXml(source.teamId)}`,
|
|
1911
|
+
`- source.channel_id: ${escapeXml(source.channelId)}`,
|
|
1912
|
+
...source.messageTs ? [`- source.message_ts: ${escapeXml(source.messageTs)}`] : [],
|
|
1913
|
+
...source.threadTs ? [`- source.thread_ts: ${escapeXml(source.threadTs)}`] : []
|
|
1914
|
+
];
|
|
1911
1915
|
}
|
|
1912
|
-
return [
|
|
1913
|
-
"- source.platform: slack",
|
|
1914
|
-
`- source.team_id: ${escapeXml(source.teamId)}`,
|
|
1915
|
-
`- source.channel_id: ${escapeXml(source.channelId)}`,
|
|
1916
|
-
...source.messageTs ? [`- source.message_ts: ${escapeXml(source.messageTs)}`] : [],
|
|
1917
|
-
...source.threadTs ? [`- source.thread_ts: ${escapeXml(source.threadTs)}`] : []
|
|
1918
|
-
];
|
|
1919
1916
|
}
|
|
1920
1917
|
function formatDestinationLines(destination) {
|
|
1921
1918
|
if (destination.platform === "local") {
|
|
@@ -2059,7 +2056,8 @@ var STATIC_SYSTEM_PROMPTS = {
|
|
|
2059
2056
|
slack: buildStaticSystemPrompt("slack")
|
|
2060
2057
|
};
|
|
2061
2058
|
function buildSystemPrompt(params) {
|
|
2062
|
-
|
|
2059
|
+
const platform = params.source.platform === "slack" ? "slack" : "local";
|
|
2060
|
+
return STATIC_SYSTEM_PROMPTS[platform];
|
|
2063
2061
|
}
|
|
2064
2062
|
function buildTurnContextPrompt(params) {
|
|
2065
2063
|
const includeSessionContext = params.includeSessionContext ?? true;
|
|
@@ -9638,94 +9636,382 @@ async function listThreadReplies(input) {
|
|
|
9638
9636
|
}
|
|
9639
9637
|
return replies.slice(0, targetLimit);
|
|
9640
9638
|
}
|
|
9641
|
-
|
|
9642
|
-
|
|
9643
|
-
|
|
9644
|
-
|
|
9645
|
-
|
|
9646
|
-
|
|
9647
|
-
|
|
9648
|
-
|
|
9649
|
-
|
|
9650
|
-
|
|
9651
|
-
|
|
9652
|
-
}
|
|
9653
|
-
function parseSlackTimestampParam(field, value) {
|
|
9654
|
-
if (!value) {
|
|
9655
|
-
return { ok: true, value: void 0 };
|
|
9656
|
-
}
|
|
9657
|
-
const timestamp = parseSlackMessageTs(String(value));
|
|
9658
|
-
if (timestamp) {
|
|
9659
|
-
return { ok: true, value: timestamp };
|
|
9639
|
+
async function getConversationInfo(channelId) {
|
|
9640
|
+
const client = getSlackClient();
|
|
9641
|
+
const response = await withSlackRetries(
|
|
9642
|
+
() => client.conversations.info({
|
|
9643
|
+
channel: channelId
|
|
9644
|
+
}),
|
|
9645
|
+
3,
|
|
9646
|
+
{ action: "conversations.info", idempotent: true }
|
|
9647
|
+
);
|
|
9648
|
+
const channel = response.channel;
|
|
9649
|
+
if (!channel || typeof channel !== "object") {
|
|
9650
|
+
throw new Error(`Slack conversations.info returned no channel for ${channelId}`);
|
|
9660
9651
|
}
|
|
9652
|
+
const record2 = channel;
|
|
9661
9653
|
return {
|
|
9662
|
-
|
|
9663
|
-
|
|
9654
|
+
id: channelId,
|
|
9655
|
+
...typeof record2.name === "string" && record2.name ? { name: record2.name } : {},
|
|
9656
|
+
isChannel: record2.is_channel === true,
|
|
9657
|
+
isPrivate: record2.is_private === true,
|
|
9658
|
+
isIm: record2.is_im === true,
|
|
9659
|
+
isMpim: record2.is_mpim === true,
|
|
9660
|
+
...typeof record2.is_member === "boolean" ? { isMember: record2.is_member } : {}
|
|
9664
9661
|
};
|
|
9665
9662
|
}
|
|
9666
|
-
function
|
|
9667
|
-
const
|
|
9668
|
-
|
|
9669
|
-
|
|
9663
|
+
async function joinPublicChannel(channelId) {
|
|
9664
|
+
const client = getSlackClient();
|
|
9665
|
+
await withSlackRetries(
|
|
9666
|
+
() => client.conversations.join({
|
|
9667
|
+
channel: channelId
|
|
9668
|
+
}),
|
|
9669
|
+
3,
|
|
9670
|
+
{ action: "conversations.join", idempotent: true }
|
|
9671
|
+
);
|
|
9672
|
+
}
|
|
9673
|
+
async function listPublicChannels(input = {}) {
|
|
9674
|
+
const client = getSlackClient();
|
|
9675
|
+
const targetLimit = Math.max(1, Math.min(input.limit ?? 1e3, 1e3));
|
|
9676
|
+
const maxPages = Math.max(1, Math.min(input.maxPages ?? 10, 20));
|
|
9677
|
+
const channels = [];
|
|
9678
|
+
let cursor;
|
|
9679
|
+
let pages = 0;
|
|
9680
|
+
while (channels.length < targetLimit && pages < maxPages) {
|
|
9681
|
+
pages += 1;
|
|
9682
|
+
const pageLimit = Math.max(1, Math.min(200, targetLimit - channels.length));
|
|
9683
|
+
const response = await withSlackRetries(
|
|
9684
|
+
() => client.conversations.list({
|
|
9685
|
+
types: "public_channel",
|
|
9686
|
+
exclude_archived: true,
|
|
9687
|
+
limit: pageLimit,
|
|
9688
|
+
cursor
|
|
9689
|
+
}),
|
|
9690
|
+
3,
|
|
9691
|
+
{ action: "conversations.list", idempotent: true }
|
|
9692
|
+
);
|
|
9693
|
+
const batch = response.channels ?? [];
|
|
9694
|
+
for (const item of batch) {
|
|
9695
|
+
if (typeof item.id !== "string" || !item.id) {
|
|
9696
|
+
continue;
|
|
9697
|
+
}
|
|
9698
|
+
if (item.is_private === true) {
|
|
9699
|
+
continue;
|
|
9700
|
+
}
|
|
9701
|
+
channels.push({
|
|
9702
|
+
id: item.id,
|
|
9703
|
+
...typeof item.name === "string" && item.name ? { name: item.name } : {},
|
|
9704
|
+
...typeof item.is_member === "boolean" ? { isMember: item.is_member } : {},
|
|
9705
|
+
...typeof item.is_archived === "boolean" ? { isArchived: item.is_archived } : {}
|
|
9706
|
+
});
|
|
9707
|
+
}
|
|
9708
|
+
cursor = response.response_metadata?.next_cursor || void 0;
|
|
9709
|
+
if (!cursor) {
|
|
9710
|
+
break;
|
|
9711
|
+
}
|
|
9670
9712
|
}
|
|
9671
|
-
return
|
|
9672
|
-
ok: false,
|
|
9673
|
-
error: `Invalid \`${field}\` Slack timestamp. Use a numeric Slack ts like \`1712345678.123456\`.`
|
|
9674
|
-
};
|
|
9713
|
+
return channels.slice(0, targetLimit);
|
|
9675
9714
|
}
|
|
9676
|
-
|
|
9677
|
-
|
|
9678
|
-
|
|
9679
|
-
|
|
9680
|
-
(value) => value === "true" ? true : value === "false" ? false : value,
|
|
9681
|
-
z36.boolean()
|
|
9682
|
-
).describe(description);
|
|
9683
|
-
function normalizeRangeTimestamp(field, value, targetChannelId) {
|
|
9684
|
-
if (value === void 0) {
|
|
9685
|
-
return { ok: true, value: void 0 };
|
|
9715
|
+
async function resolvePublicChannelByName(channelName) {
|
|
9716
|
+
const normalized = channelName.trim().replace(/^#/, "").toLowerCase();
|
|
9717
|
+
if (!normalized) {
|
|
9718
|
+
return void 0;
|
|
9686
9719
|
}
|
|
9687
|
-
const
|
|
9688
|
-
|
|
9689
|
-
|
|
9720
|
+
const channels = await listPublicChannels();
|
|
9721
|
+
return channels.find(
|
|
9722
|
+
(channel) => channel.name?.trim().toLowerCase() === normalized
|
|
9723
|
+
);
|
|
9724
|
+
}
|
|
9725
|
+
|
|
9726
|
+
// src/chat/slack/tool-support/channel-access.ts
|
|
9727
|
+
var DENIED_PRIVATE = "Cannot read this Slack conversation because it is private. Only the current conversation or public channels are readable.";
|
|
9728
|
+
var DENIED_NOT_FOUND = "Cannot read this Slack conversation because the channel was not found or the bot cannot see it.";
|
|
9729
|
+
var DENIED_NOT_IN_CHANNEL = "Cannot read this Slack conversation because the bot is not in the channel.";
|
|
9730
|
+
var DENIED_MISSING_SCOPE = "Cannot verify Slack channel access because this installation is missing channel read scopes.";
|
|
9731
|
+
function deny(reason, error) {
|
|
9732
|
+
return { allowed: false, reason, error };
|
|
9733
|
+
}
|
|
9734
|
+
async function checkSlackChannelReadAccess(args) {
|
|
9735
|
+
const currentChannels = args.currentChannelIds.filter(
|
|
9736
|
+
(channelId) => Boolean(channelId)
|
|
9737
|
+
);
|
|
9738
|
+
if (currentChannels.includes(args.targetChannelId)) {
|
|
9739
|
+
return { allowed: true, isMember: true };
|
|
9690
9740
|
}
|
|
9691
|
-
const
|
|
9692
|
-
|
|
9693
|
-
|
|
9741
|
+
const visibility = await getConversationStore().getDestinationVisibility({
|
|
9742
|
+
provider: "slack",
|
|
9743
|
+
providerTenantId: args.teamId,
|
|
9744
|
+
providerDestinationId: args.targetChannelId
|
|
9745
|
+
});
|
|
9746
|
+
if (visibility === "private") {
|
|
9747
|
+
return deny("private", DENIED_PRIVATE);
|
|
9694
9748
|
}
|
|
9695
|
-
|
|
9696
|
-
|
|
9697
|
-
|
|
9698
|
-
if (
|
|
9699
|
-
return
|
|
9749
|
+
try {
|
|
9750
|
+
const info = await getConversationInfo(args.targetChannelId);
|
|
9751
|
+
const isPublicChannel = info.isChannel && !info.isPrivate && !info.isIm && !info.isMpim;
|
|
9752
|
+
if (!isPublicChannel) {
|
|
9753
|
+
return deny("private", DENIED_PRIVATE);
|
|
9754
|
+
}
|
|
9755
|
+
return {
|
|
9756
|
+
allowed: true,
|
|
9757
|
+
isPublic: true,
|
|
9758
|
+
...info.name ? { channelName: info.name } : {},
|
|
9759
|
+
...typeof info.isMember === "boolean" ? { isMember: info.isMember } : {}
|
|
9760
|
+
};
|
|
9761
|
+
} catch (error) {
|
|
9762
|
+
if (error instanceof SlackActionError) {
|
|
9763
|
+
if (error.code === "not_found") {
|
|
9764
|
+
return deny("not_found", DENIED_NOT_FOUND);
|
|
9765
|
+
}
|
|
9766
|
+
if (error.code === "not_in_channel") {
|
|
9767
|
+
return deny("not_in_channel", DENIED_NOT_IN_CHANNEL);
|
|
9768
|
+
}
|
|
9769
|
+
if (error.code === "missing_scope") {
|
|
9770
|
+
return deny("missing_scope", DENIED_MISSING_SCOPE);
|
|
9771
|
+
}
|
|
9700
9772
|
}
|
|
9773
|
+
throw error;
|
|
9701
9774
|
}
|
|
9702
|
-
return timestamp;
|
|
9703
9775
|
}
|
|
9704
|
-
function
|
|
9705
|
-
|
|
9706
|
-
|
|
9707
|
-
|
|
9708
|
-
|
|
9709
|
-
|
|
9710
|
-
|
|
9711
|
-
|
|
9712
|
-
|
|
9713
|
-
|
|
9714
|
-
|
|
9715
|
-
|
|
9716
|
-
|
|
9717
|
-
|
|
9718
|
-
|
|
9719
|
-
|
|
9720
|
-
|
|
9721
|
-
|
|
9722
|
-
|
|
9723
|
-
|
|
9724
|
-
|
|
9725
|
-
|
|
9726
|
-
|
|
9727
|
-
|
|
9776
|
+
async function joinPublicChannelForRead(args) {
|
|
9777
|
+
try {
|
|
9778
|
+
await joinPublicChannel(args.targetChannelId);
|
|
9779
|
+
return {
|
|
9780
|
+
ok: true,
|
|
9781
|
+
...args.channelName ? { channelName: args.channelName } : {}
|
|
9782
|
+
};
|
|
9783
|
+
} catch (error) {
|
|
9784
|
+
if (error instanceof SlackActionError) {
|
|
9785
|
+
if (error.code === "missing_scope") {
|
|
9786
|
+
return {
|
|
9787
|
+
ok: false,
|
|
9788
|
+
reason: "missing_scope",
|
|
9789
|
+
error: "Cannot join this public Slack channel because this installation is missing the `channels:join` scope."
|
|
9790
|
+
};
|
|
9791
|
+
}
|
|
9792
|
+
if (error.code === "not_found") {
|
|
9793
|
+
return {
|
|
9794
|
+
ok: false,
|
|
9795
|
+
reason: "not_found",
|
|
9796
|
+
error: DENIED_NOT_FOUND
|
|
9797
|
+
};
|
|
9798
|
+
}
|
|
9799
|
+
if (error.apiError === "method_not_supported_for_channel_type" || error.apiError === "is_archived" || error.apiError === "cant_invite_self") {
|
|
9800
|
+
return {
|
|
9801
|
+
ok: false,
|
|
9802
|
+
reason: "private",
|
|
9803
|
+
error: DENIED_PRIVATE
|
|
9804
|
+
};
|
|
9805
|
+
}
|
|
9806
|
+
return {
|
|
9807
|
+
ok: false,
|
|
9808
|
+
reason: "not_in_channel",
|
|
9809
|
+
error: "Could not join this public Slack channel. Ask an admin to add the bot, then retry."
|
|
9810
|
+
};
|
|
9811
|
+
}
|
|
9812
|
+
throw error;
|
|
9813
|
+
}
|
|
9814
|
+
}
|
|
9815
|
+
|
|
9816
|
+
// src/chat/slack/tool-support/channel-target.ts
|
|
9817
|
+
import { z as z35 } from "zod";
|
|
9818
|
+
var slackChannelRefParam = z35.string().trim().min(1).max(80).describe("Slack channel ID or public channel name.");
|
|
9819
|
+
async function resolveSlackChannelRef(input) {
|
|
9820
|
+
const trimmed = input.value.trim();
|
|
9821
|
+
if (!trimmed) {
|
|
9822
|
+
throw new ToolInputError(
|
|
9823
|
+
`Invalid \`${input.field}\`. Provide a Slack channel id like \`C123\` or a public channel name like \`#proj-foo\`.`
|
|
9824
|
+
);
|
|
9825
|
+
}
|
|
9826
|
+
const channelId = parseSlackChannelId(trimmed);
|
|
9827
|
+
if (channelId) {
|
|
9828
|
+
return {
|
|
9829
|
+
channelId,
|
|
9830
|
+
resolvedFromName: false
|
|
9831
|
+
};
|
|
9832
|
+
}
|
|
9833
|
+
const match = await resolvePublicChannelByName(trimmed);
|
|
9834
|
+
if (!match) {
|
|
9835
|
+
throw new ToolInputError(
|
|
9836
|
+
`No public Slack channel named \`${trimmed}\` was found. Use an exact public channel name or a channel id.`
|
|
9837
|
+
);
|
|
9838
|
+
}
|
|
9839
|
+
return {
|
|
9840
|
+
channelId: match.id,
|
|
9841
|
+
...match.name ? { channelName: match.name } : {},
|
|
9842
|
+
resolvedFromName: true
|
|
9843
|
+
};
|
|
9844
|
+
}
|
|
9845
|
+
async function resolveOptionalSlackChannelRef(input) {
|
|
9846
|
+
if (input.value !== void 0) {
|
|
9847
|
+
return resolveSlackChannelRef({
|
|
9848
|
+
field: input.field ?? "channel_id",
|
|
9849
|
+
value: input.value
|
|
9850
|
+
});
|
|
9851
|
+
}
|
|
9852
|
+
if (input.defaultChannelId) {
|
|
9853
|
+
return {
|
|
9854
|
+
channelId: input.defaultChannelId,
|
|
9855
|
+
resolvedFromName: false
|
|
9856
|
+
};
|
|
9857
|
+
}
|
|
9858
|
+
throw new ToolInputError(
|
|
9859
|
+
"Provide `channel_id`, or use this tool in an active Slack channel context."
|
|
9860
|
+
);
|
|
9861
|
+
}
|
|
9862
|
+
|
|
9863
|
+
// src/chat/slack/tools/channel-join.ts
|
|
9864
|
+
import { z as z36 } from "zod";
|
|
9865
|
+
function createSlackChannelJoinTool(context) {
|
|
9866
|
+
return zodTool({
|
|
9867
|
+
description: "Join a public Slack channel.",
|
|
9868
|
+
annotations: {
|
|
9869
|
+
destructiveHint: false,
|
|
9870
|
+
idempotentHint: false,
|
|
9871
|
+
openWorldHint: true,
|
|
9872
|
+
readOnlyHint: false
|
|
9873
|
+
},
|
|
9874
|
+
inputSchema: z36.object({
|
|
9875
|
+
channel_id: slackChannelRefParam
|
|
9876
|
+
}),
|
|
9877
|
+
outputSchema: juniorToolOutputSchema,
|
|
9878
|
+
execute: async ({ channel_id }) => {
|
|
9879
|
+
const target = await resolveSlackChannelRef({
|
|
9880
|
+
field: "channel_id",
|
|
9881
|
+
value: channel_id
|
|
9882
|
+
});
|
|
9883
|
+
const access = await checkSlackChannelReadAccess({
|
|
9884
|
+
currentChannelIds: [
|
|
9885
|
+
context.destinationChannelId,
|
|
9886
|
+
context.sourceChannelId
|
|
9887
|
+
],
|
|
9888
|
+
targetChannelId: target.channelId,
|
|
9889
|
+
teamId: context.teamId
|
|
9890
|
+
});
|
|
9891
|
+
if (!access.allowed) {
|
|
9892
|
+
throw new ToolInputError(access.error);
|
|
9893
|
+
}
|
|
9894
|
+
if (access.isMember === true) {
|
|
9895
|
+
return {
|
|
9896
|
+
channel_id: target.channelId,
|
|
9897
|
+
...access.channelName || target.channelName ? { channel_name: access.channelName ?? target.channelName } : {},
|
|
9898
|
+
joined: false,
|
|
9899
|
+
already_member: true
|
|
9900
|
+
};
|
|
9901
|
+
}
|
|
9902
|
+
try {
|
|
9903
|
+
await joinPublicChannel(target.channelId);
|
|
9904
|
+
} catch (error) {
|
|
9905
|
+
if (error instanceof SlackActionError) {
|
|
9906
|
+
if (error.code === "missing_scope") {
|
|
9907
|
+
throw new ToolInputError(
|
|
9908
|
+
"Cannot join this public Slack channel because this installation is missing the `channels:join` scope.",
|
|
9909
|
+
{ cause: error }
|
|
9910
|
+
);
|
|
9911
|
+
}
|
|
9912
|
+
throw new ToolInputError(
|
|
9913
|
+
"Could not join this public Slack channel. Confirm it is public and retry, or ask an admin to add the bot.",
|
|
9914
|
+
{ cause: error }
|
|
9915
|
+
);
|
|
9916
|
+
}
|
|
9917
|
+
throw error;
|
|
9918
|
+
}
|
|
9919
|
+
return {
|
|
9920
|
+
channel_id: target.channelId,
|
|
9921
|
+
...access.channelName || target.channelName ? { channel_name: access.channelName ?? target.channelName } : {},
|
|
9922
|
+
joined: true,
|
|
9923
|
+
already_member: false
|
|
9924
|
+
};
|
|
9925
|
+
}
|
|
9926
|
+
});
|
|
9927
|
+
}
|
|
9928
|
+
|
|
9929
|
+
// src/chat/slack/timestamp-param.ts
|
|
9930
|
+
import { z as z37 } from "zod";
|
|
9931
|
+
function slackTimestampParam(description) {
|
|
9932
|
+
return z37.preprocess(
|
|
9933
|
+
(value) => typeof value === "number" && Number.isFinite(value) ? String(value) : value,
|
|
9934
|
+
z37.string().min(1)
|
|
9935
|
+
).describe(description);
|
|
9936
|
+
}
|
|
9937
|
+
function parseSlackTimestampParam(field, value) {
|
|
9938
|
+
if (!value) {
|
|
9939
|
+
return { ok: true, value: void 0 };
|
|
9940
|
+
}
|
|
9941
|
+
const timestamp = parseSlackMessageTs(String(value));
|
|
9942
|
+
if (timestamp) {
|
|
9943
|
+
return { ok: true, value: timestamp };
|
|
9944
|
+
}
|
|
9945
|
+
return {
|
|
9946
|
+
ok: false,
|
|
9947
|
+
error: `Invalid \`${field}\` Slack timestamp. Use a numeric Slack ts like \`1712345678.123456\`.`
|
|
9948
|
+
};
|
|
9949
|
+
}
|
|
9950
|
+
function parseRequiredSlackTimestampParam(field, value) {
|
|
9951
|
+
const timestamp = parseSlackMessageTs(String(value));
|
|
9952
|
+
if (timestamp) {
|
|
9953
|
+
return { ok: true, value: timestamp };
|
|
9954
|
+
}
|
|
9955
|
+
return {
|
|
9956
|
+
ok: false,
|
|
9957
|
+
error: `Invalid \`${field}\` Slack timestamp. Use a numeric Slack ts like \`1712345678.123456\`.`
|
|
9958
|
+
};
|
|
9959
|
+
}
|
|
9960
|
+
|
|
9961
|
+
// src/chat/slack/tools/channel-list-messages.ts
|
|
9962
|
+
import { z as z38 } from "zod";
|
|
9963
|
+
var booleanInput2 = (description) => z38.preprocess(
|
|
9964
|
+
(value) => value === "true" ? true : value === "false" ? false : value,
|
|
9965
|
+
z38.boolean()
|
|
9966
|
+
).describe(description);
|
|
9967
|
+
function normalizeRangeTimestamp(field, value, targetChannelId) {
|
|
9968
|
+
if (value === void 0) {
|
|
9969
|
+
return { ok: true, value: void 0 };
|
|
9970
|
+
}
|
|
9971
|
+
const trimmed = String(value).trim();
|
|
9972
|
+
if (!trimmed) {
|
|
9973
|
+
return parseSlackTimestampParam(field, value);
|
|
9974
|
+
}
|
|
9975
|
+
const timestamp = parseSlackTimestampParam(field, trimmed);
|
|
9976
|
+
if (timestamp.ok && timestamp.value) {
|
|
9977
|
+
return timestamp;
|
|
9978
|
+
}
|
|
9979
|
+
const threadId = parseSlackThreadId(trimmed);
|
|
9980
|
+
const threadTimestamp = threadId ? parseSlackTimestampParam(field, threadId.threadTs) : void 0;
|
|
9981
|
+
if (threadId && threadTimestamp?.ok && threadTimestamp.value) {
|
|
9982
|
+
if (threadId.channelId === targetChannelId) {
|
|
9983
|
+
return threadTimestamp;
|
|
9984
|
+
}
|
|
9985
|
+
}
|
|
9986
|
+
return timestamp;
|
|
9987
|
+
}
|
|
9988
|
+
function createSlackChannelListMessagesTool(context) {
|
|
9989
|
+
return zodTool({
|
|
9990
|
+
description: "List messages from Slack channel history. Defaults to the active channel. Pass `channel_id` to read another public channel.",
|
|
9991
|
+
annotations: {
|
|
9992
|
+
destructiveHint: false,
|
|
9993
|
+
idempotentHint: true,
|
|
9994
|
+
openWorldHint: true,
|
|
9995
|
+
readOnlyHint: true
|
|
9996
|
+
},
|
|
9997
|
+
inputSchema: z38.object({
|
|
9998
|
+
channel_id: slackChannelRefParam.optional(),
|
|
9999
|
+
limit: z38.coerce.number().int().min(1).max(1e3).describe("Maximum number of messages to return across pages.").optional(),
|
|
10000
|
+
cursor: z38.string().min(1).describe("Optional cursor to continue from a prior call.").optional(),
|
|
10001
|
+
oldest: slackTimestampParam(
|
|
10002
|
+
"Oldest message timestamp (Slack ts) for range filtering."
|
|
10003
|
+
).optional(),
|
|
10004
|
+
latest: slackTimestampParam(
|
|
10005
|
+
"Latest message timestamp (Slack ts) for range filtering."
|
|
10006
|
+
).optional(),
|
|
10007
|
+
inclusive: booleanInput2(
|
|
10008
|
+
"Whether oldest/latest bounds should be inclusive."
|
|
10009
|
+
).optional(),
|
|
10010
|
+
max_pages: z38.coerce.number().int().min(1).max(10).describe("Maximum number of API pages to traverse in a single call.").optional()
|
|
10011
|
+
}),
|
|
10012
|
+
outputSchema: juniorToolOutputSchema,
|
|
9728
10013
|
execute: async ({
|
|
10014
|
+
channel_id,
|
|
9729
10015
|
limit,
|
|
9730
10016
|
cursor,
|
|
9731
10017
|
oldest,
|
|
@@ -9733,9 +10019,22 @@ function createSlackChannelListMessagesTool(context) {
|
|
|
9733
10019
|
inclusive,
|
|
9734
10020
|
max_pages
|
|
9735
10021
|
}) => {
|
|
9736
|
-
const
|
|
9737
|
-
|
|
9738
|
-
|
|
10022
|
+
const target = await resolveOptionalSlackChannelRef({
|
|
10023
|
+
field: "channel_id",
|
|
10024
|
+
value: channel_id,
|
|
10025
|
+
defaultChannelId: context.destinationChannelId
|
|
10026
|
+
});
|
|
10027
|
+
const targetChannelId = target.channelId;
|
|
10028
|
+
const access = await checkSlackChannelReadAccess({
|
|
10029
|
+
currentChannelIds: [
|
|
10030
|
+
context.destinationChannelId,
|
|
10031
|
+
context.sourceChannelId
|
|
10032
|
+
],
|
|
10033
|
+
targetChannelId,
|
|
10034
|
+
teamId: context.teamId
|
|
10035
|
+
});
|
|
10036
|
+
if (!access.allowed) {
|
|
10037
|
+
throw new ToolInputError(access.error);
|
|
9739
10038
|
}
|
|
9740
10039
|
const normalizedOldest = normalizeRangeTimestamp(
|
|
9741
10040
|
"oldest",
|
|
@@ -9753,39 +10052,84 @@ function createSlackChannelListMessagesTool(context) {
|
|
|
9753
10052
|
if (!normalizedLatest.ok) {
|
|
9754
10053
|
throw new ToolInputError(normalizedLatest.error);
|
|
9755
10054
|
}
|
|
10055
|
+
const readHistory = async () => listChannelMessages({
|
|
10056
|
+
channelId: targetChannelId,
|
|
10057
|
+
limit: limit ?? 100,
|
|
10058
|
+
cursor,
|
|
10059
|
+
oldest: normalizedOldest.value,
|
|
10060
|
+
latest: normalizedLatest.value,
|
|
10061
|
+
inclusive,
|
|
10062
|
+
maxPages: max_pages
|
|
10063
|
+
});
|
|
9756
10064
|
let result;
|
|
10065
|
+
let joined = false;
|
|
10066
|
+
let channelName = access.channelName ?? target.channelName;
|
|
10067
|
+
let readError;
|
|
9757
10068
|
try {
|
|
9758
|
-
result = await
|
|
9759
|
-
channelId: targetChannelId,
|
|
9760
|
-
limit: limit ?? 100,
|
|
9761
|
-
cursor,
|
|
9762
|
-
oldest: normalizedOldest.value,
|
|
9763
|
-
latest: normalizedLatest.value,
|
|
9764
|
-
inclusive,
|
|
9765
|
-
maxPages: max_pages
|
|
9766
|
-
});
|
|
10069
|
+
result = await readHistory();
|
|
9767
10070
|
} catch (error) {
|
|
10071
|
+
readError = error;
|
|
10072
|
+
const canJoin = error instanceof SlackActionError && error.code === "not_in_channel" && access.isMember !== true;
|
|
10073
|
+
if (canJoin) {
|
|
10074
|
+
const joinResult = await joinPublicChannelForRead({
|
|
10075
|
+
channelName,
|
|
10076
|
+
targetChannelId
|
|
10077
|
+
});
|
|
10078
|
+
if (!joinResult.ok) {
|
|
10079
|
+
throw new ToolInputError(joinResult.error);
|
|
10080
|
+
}
|
|
10081
|
+
joined = true;
|
|
10082
|
+
channelName = joinResult.channelName ?? channelName;
|
|
10083
|
+
try {
|
|
10084
|
+
result = await readHistory();
|
|
10085
|
+
readError = void 0;
|
|
10086
|
+
} catch (retryError) {
|
|
10087
|
+
readError = retryError;
|
|
10088
|
+
}
|
|
10089
|
+
}
|
|
10090
|
+
}
|
|
10091
|
+
if (!result) {
|
|
10092
|
+
const error = readError;
|
|
9768
10093
|
if (error instanceof SlackActionError && error.apiError === "invalid_cursor") {
|
|
9769
10094
|
throw new ToolInputError(
|
|
9770
10095
|
"The supplied Slack history cursor is no longer valid. Retry the lookup without `cursor` to start from the newest page again.",
|
|
9771
10096
|
{ cause: error }
|
|
9772
10097
|
);
|
|
9773
10098
|
}
|
|
10099
|
+
if (error instanceof SlackActionError) {
|
|
10100
|
+
if (error.code === "not_in_channel") {
|
|
10101
|
+
throw new ToolInputError(
|
|
10102
|
+
"Could not read this Slack channel history because the bot is not in the channel.",
|
|
10103
|
+
{ cause: error }
|
|
10104
|
+
);
|
|
10105
|
+
}
|
|
10106
|
+
if (error.code === "missing_scope") {
|
|
10107
|
+
throw new ToolInputError(
|
|
10108
|
+
"Could not read this Slack channel history because this installation is missing history scopes.",
|
|
10109
|
+
{ cause: error }
|
|
10110
|
+
);
|
|
10111
|
+
}
|
|
10112
|
+
throw new ToolInputError(
|
|
10113
|
+
"Could not read this Slack channel history.",
|
|
10114
|
+
{ cause: error }
|
|
10115
|
+
);
|
|
10116
|
+
}
|
|
9774
10117
|
throw error;
|
|
9775
10118
|
}
|
|
9776
|
-
|
|
10119
|
+
return {
|
|
9777
10120
|
channel_id: targetChannelId,
|
|
10121
|
+
...channelName ? { channel_name: channelName } : {},
|
|
10122
|
+
...joined ? { joined_channel: true } : {},
|
|
9778
10123
|
count: result.messages.length,
|
|
9779
10124
|
messages: result.messages,
|
|
9780
10125
|
...result.nextCursor ? { next_cursor: result.nextCursor } : {}
|
|
9781
10126
|
};
|
|
9782
|
-
return summary;
|
|
9783
10127
|
}
|
|
9784
10128
|
});
|
|
9785
10129
|
}
|
|
9786
10130
|
|
|
9787
10131
|
// src/chat/slack/tools/conversation-message-search.ts
|
|
9788
|
-
import { z as
|
|
10132
|
+
import { z as z39 } from "zod";
|
|
9789
10133
|
|
|
9790
10134
|
// src/chat/conversations/tool-source.ts
|
|
9791
10135
|
var CONVERSATIONS_TOOL_SOURCE = {
|
|
@@ -9796,35 +10140,32 @@ var CONVERSATIONS_TOOL_SOURCE = {
|
|
|
9796
10140
|
// src/chat/slack/tools/conversation-message-search.ts
|
|
9797
10141
|
var DEFAULT_LIMIT = 5;
|
|
9798
10142
|
var conversationMessageSearchOutputSchema = juniorToolOutputSchema.extend({
|
|
9799
|
-
channel_id:
|
|
9800
|
-
count:
|
|
9801
|
-
query:
|
|
9802
|
-
matches:
|
|
9803
|
-
|
|
9804
|
-
channel_id:
|
|
9805
|
-
channel_name:
|
|
9806
|
-
conversation_id:
|
|
9807
|
-
excerpt:
|
|
9808
|
-
message_id:
|
|
9809
|
-
message_role:
|
|
9810
|
-
message_timestamp:
|
|
9811
|
-
permalink:
|
|
9812
|
-
thread_ts:
|
|
10143
|
+
channel_id: z39.string().min(1).optional(),
|
|
10144
|
+
count: z39.number().int().nonnegative(),
|
|
10145
|
+
query: z39.string().optional(),
|
|
10146
|
+
matches: z39.array(
|
|
10147
|
+
z39.object({
|
|
10148
|
+
channel_id: z39.string().min(1),
|
|
10149
|
+
channel_name: z39.string().min(1).optional(),
|
|
10150
|
+
conversation_id: z39.string().min(1),
|
|
10151
|
+
excerpt: z39.string(),
|
|
10152
|
+
message_id: z39.string().min(1),
|
|
10153
|
+
message_role: z39.enum(["assistant", "user"]),
|
|
10154
|
+
message_timestamp: z39.string().datetime(),
|
|
10155
|
+
permalink: z39.string().url().optional(),
|
|
10156
|
+
thread_ts: z39.string().min(1)
|
|
9813
10157
|
}).strict()
|
|
9814
10158
|
)
|
|
9815
10159
|
});
|
|
9816
|
-
function resolveSearchFilters(input) {
|
|
10160
|
+
async function resolveSearchFilters(input) {
|
|
9817
10161
|
const query = input.query?.trim() || void 0;
|
|
9818
10162
|
let channelId;
|
|
9819
|
-
if (input.channel_id != null) {
|
|
9820
|
-
const
|
|
9821
|
-
"channel_id",
|
|
9822
|
-
input.channel_id
|
|
9823
|
-
);
|
|
9824
|
-
|
|
9825
|
-
throw new ToolInputError(parsed.error);
|
|
9826
|
-
}
|
|
9827
|
-
channelId = parsed.value;
|
|
10163
|
+
if (input.channel_id != null && input.channel_id.trim() !== "") {
|
|
10164
|
+
const target = await resolveSlackChannelRef({
|
|
10165
|
+
field: "channel_id",
|
|
10166
|
+
value: input.channel_id
|
|
10167
|
+
});
|
|
10168
|
+
channelId = target.channelId;
|
|
9828
10169
|
}
|
|
9829
10170
|
if (!query && !channelId) {
|
|
9830
10171
|
throw new ToolInputError(
|
|
@@ -9836,9 +10177,9 @@ function resolveSearchFilters(input) {
|
|
|
9836
10177
|
...query ? { query } : {}
|
|
9837
10178
|
};
|
|
9838
10179
|
}
|
|
9839
|
-
function createSlackConversationMessageSearchTool(scope, currentConversationId
|
|
10180
|
+
function createSlackConversationMessageSearchTool(scope, currentConversationId) {
|
|
9840
10181
|
return zodTool({
|
|
9841
|
-
description: "Search retained user and assistant messages
|
|
10182
|
+
description: "Search retained user and assistant messages from public conversations in this Slack workspace. Excludes the current conversation. Not live Slack workspace search.",
|
|
9842
10183
|
exposure: "deferred",
|
|
9843
10184
|
source: CONVERSATIONS_TOOL_SOURCE,
|
|
9844
10185
|
annotations: {
|
|
@@ -9847,24 +10188,21 @@ function createSlackConversationMessageSearchTool(scope, currentConversationId,
|
|
|
9847
10188
|
openWorldHint: false,
|
|
9848
10189
|
readOnlyHint: true
|
|
9849
10190
|
},
|
|
9850
|
-
inputSchema:
|
|
9851
|
-
channel_id:
|
|
9852
|
-
|
|
9853
|
-
).nullable().optional()
|
|
9854
|
-
query: z37.string().trim().min(1).max(200).nullable().describe("Words or phrase to match in message text.").optional(),
|
|
9855
|
-
limit: z37.number().int().min(1).max(10).describe(`Maximum matches. Default ${DEFAULT_LIMIT}; max 10.`).nullable().optional()
|
|
10191
|
+
inputSchema: z39.object({
|
|
10192
|
+
channel_id: slackChannelRefParam.nullable().optional(),
|
|
10193
|
+
query: z39.string().trim().min(1).max(200).nullable().describe("Words or phrase to match in message text.").optional(),
|
|
10194
|
+
limit: z39.number().int().min(1).max(10).describe(`Maximum matches. Default ${DEFAULT_LIMIT}; max 10.`).nullable().optional()
|
|
9856
10195
|
}).strict(),
|
|
9857
10196
|
outputSchema: conversationMessageSearchOutputSchema,
|
|
9858
10197
|
execute: async (input) => {
|
|
9859
|
-
const filters = resolveSearchFilters(input);
|
|
9860
|
-
const store =
|
|
10198
|
+
const filters = await resolveSearchFilters(input);
|
|
10199
|
+
const store = getConversationMessageSearchStore();
|
|
9861
10200
|
const matches = await store.search({
|
|
9862
10201
|
currentConversationId,
|
|
9863
10202
|
filters,
|
|
9864
10203
|
limit: input.limit ?? DEFAULT_LIMIT,
|
|
9865
10204
|
scope
|
|
9866
10205
|
});
|
|
9867
|
-
const getPermalink = deps.getPermalink ?? getSlackMessagePermalink;
|
|
9868
10206
|
const matchesOutput = await Promise.all(
|
|
9869
10207
|
matches.map(async (match) => {
|
|
9870
10208
|
const reference = parseSlackThreadId(match.conversationId);
|
|
@@ -9873,7 +10211,7 @@ function createSlackConversationMessageSearchTool(scope, currentConversationId,
|
|
|
9873
10211
|
"Stored Slack conversation search returned an invalid destination"
|
|
9874
10212
|
);
|
|
9875
10213
|
}
|
|
9876
|
-
const permalink = await
|
|
10214
|
+
const permalink = await getSlackMessagePermalink({
|
|
9877
10215
|
channelId: reference.channelId,
|
|
9878
10216
|
messageTs: reference.threadTs
|
|
9879
10217
|
});
|
|
@@ -9901,35 +10239,238 @@ function createSlackConversationMessageSearchTool(scope, currentConversationId,
|
|
|
9901
10239
|
}
|
|
9902
10240
|
|
|
9903
10241
|
// src/chat/slack/tools/public-search.ts
|
|
9904
|
-
import { z as
|
|
10242
|
+
import { z as z40 } from "zod";
|
|
9905
10243
|
var DEFAULT_LIMIT2 = 10;
|
|
9906
|
-
var
|
|
9907
|
-
|
|
9908
|
-
|
|
9909
|
-
)
|
|
9910
|
-
|
|
9911
|
-
|
|
9912
|
-
|
|
9913
|
-
|
|
9914
|
-
|
|
9915
|
-
|
|
9916
|
-
|
|
9917
|
-
|
|
9918
|
-
|
|
10244
|
+
var DEFAULT_CONTENT_TYPES = ["messages"];
|
|
10245
|
+
var CONTENT_TYPES = ["messages", "files", "channels", "users"];
|
|
10246
|
+
var unixTimestampParam = z40.coerce.number().int().nonnegative();
|
|
10247
|
+
function optionalUnixTimestampParam(description) {
|
|
10248
|
+
return z40.preprocess(
|
|
10249
|
+
(value) => typeof value === "string" && value.trim() === "" ? void 0 : value,
|
|
10250
|
+
unixTimestampParam.optional()
|
|
10251
|
+
).describe(description);
|
|
10252
|
+
}
|
|
10253
|
+
function normalizeOptionalUnixTimestamp(value) {
|
|
10254
|
+
if (value === void 0 || value === null) {
|
|
10255
|
+
return void 0;
|
|
10256
|
+
}
|
|
10257
|
+
if (typeof value === "string" && value.trim() === "") {
|
|
10258
|
+
return void 0;
|
|
10259
|
+
}
|
|
10260
|
+
return unixTimestampParam.parse(value);
|
|
10261
|
+
}
|
|
10262
|
+
var searchMessageSchema = z40.object({
|
|
10263
|
+
author_name: z40.string().min(1).optional().describe("Author display name."),
|
|
10264
|
+
author_user_id: z40.string().min(1).optional().describe("Author user ID."),
|
|
10265
|
+
channel_id: z40.string().min(1).describe("Channel ID."),
|
|
10266
|
+
channel_name: z40.string().min(1).optional().describe("Channel name."),
|
|
10267
|
+
message_ts: z40.string().min(1).describe("Message timestamp."),
|
|
10268
|
+
content: z40.string().describe("Message text."),
|
|
10269
|
+
is_author_bot: z40.boolean().optional().describe("Whether the author is a bot."),
|
|
10270
|
+
permalink: z40.string().url().describe("Message permalink.")
|
|
10271
|
+
});
|
|
10272
|
+
var searchFileSchema = z40.object({
|
|
10273
|
+
file_id: z40.string().min(1).describe("File ID."),
|
|
10274
|
+
title: z40.string().min(1).optional().describe("File title."),
|
|
10275
|
+
name: z40.string().min(1).optional().describe("File name."),
|
|
10276
|
+
filetype: z40.string().min(1).optional().describe("File type."),
|
|
10277
|
+
user_id: z40.string().min(1).optional().describe("Uploader user ID."),
|
|
10278
|
+
user_name: z40.string().min(1).optional().describe("Uploader user name."),
|
|
10279
|
+
channel_id: z40.string().min(1).optional().describe("Channel ID."),
|
|
10280
|
+
channel_name: z40.string().min(1).optional().describe("Channel name."),
|
|
10281
|
+
permalink: z40.string().url().optional().describe("File permalink."),
|
|
10282
|
+
content: z40.string().min(1).optional().describe("File preview or content snippet.")
|
|
10283
|
+
});
|
|
10284
|
+
var searchChannelSchema = z40.object({
|
|
10285
|
+
channel_id: z40.string().min(1).describe("Channel ID."),
|
|
10286
|
+
channel_name: z40.string().min(1).optional().describe("Channel name."),
|
|
10287
|
+
is_private: z40.boolean().optional().describe("Whether the channel is private."),
|
|
10288
|
+
is_member: z40.boolean().optional().describe("Whether the bot is a member."),
|
|
10289
|
+
topic: z40.string().min(1).optional().describe("Channel topic."),
|
|
10290
|
+
purpose: z40.string().min(1).optional().describe("Channel purpose."),
|
|
10291
|
+
permalink: z40.string().url().optional().describe("Channel permalink.")
|
|
10292
|
+
});
|
|
10293
|
+
var searchUserSchema = z40.object({
|
|
10294
|
+
user_id: z40.string().min(1).describe("User ID."),
|
|
10295
|
+
user_name: z40.string().min(1).optional().describe("Username."),
|
|
10296
|
+
real_name: z40.string().min(1).optional().describe("Real name."),
|
|
10297
|
+
display_name: z40.string().min(1).optional().describe("Display name."),
|
|
10298
|
+
title: z40.string().min(1).optional().describe("Profile title."),
|
|
10299
|
+
permalink: z40.string().url().optional().describe("Profile permalink.")
|
|
9919
10300
|
});
|
|
9920
10301
|
var publicSearchOutputSchema = juniorToolOutputSchema.extend({
|
|
9921
|
-
query:
|
|
9922
|
-
|
|
9923
|
-
|
|
9924
|
-
|
|
10302
|
+
query: z40.string().describe("Search query."),
|
|
10303
|
+
content_types: z40.array(z40.enum(CONTENT_TYPES)).describe("Content types included in the search."),
|
|
10304
|
+
count: z40.number().int().nonnegative().describe("Total matched results."),
|
|
10305
|
+
messages: z40.array(searchMessageSchema).describe("Matched messages."),
|
|
10306
|
+
files: z40.array(searchFileSchema).describe("Matched files."),
|
|
10307
|
+
channels: z40.array(searchChannelSchema).describe("Matched channels."),
|
|
10308
|
+
users: z40.array(searchUserSchema).describe("Matched users."),
|
|
10309
|
+
next_cursor: z40.string().min(1).optional().describe("Cursor for the next result page.")
|
|
9925
10310
|
});
|
|
9926
|
-
|
|
9927
|
-
|
|
9928
|
-
|
|
10311
|
+
var nonEmptyString = z40.string().trim().min(1);
|
|
10312
|
+
var optionalWireString = z40.preprocess((value) => {
|
|
10313
|
+
if (typeof value !== "string") {
|
|
10314
|
+
return void 0;
|
|
10315
|
+
}
|
|
10316
|
+
const trimmed = value.trim();
|
|
10317
|
+
return trimmed === "" ? void 0 : trimmed;
|
|
10318
|
+
}, nonEmptyString.optional());
|
|
10319
|
+
var optionalWireUrl = z40.preprocess((value) => {
|
|
10320
|
+
if (typeof value !== "string") {
|
|
10321
|
+
return void 0;
|
|
10322
|
+
}
|
|
10323
|
+
const trimmed = value.trim();
|
|
10324
|
+
if (!trimmed) {
|
|
10325
|
+
return void 0;
|
|
10326
|
+
}
|
|
10327
|
+
try {
|
|
10328
|
+
new URL(trimmed);
|
|
10329
|
+
return trimmed;
|
|
10330
|
+
} catch {
|
|
10331
|
+
return void 0;
|
|
10332
|
+
}
|
|
10333
|
+
}, z40.string().url().optional());
|
|
10334
|
+
var optionalWireBoolean = z40.preprocess(
|
|
10335
|
+
(value) => typeof value === "boolean" ? value : void 0,
|
|
10336
|
+
z40.boolean().optional()
|
|
10337
|
+
);
|
|
10338
|
+
var slackSearchMessageWireSchema = z40.object({
|
|
10339
|
+
author_name: optionalWireString,
|
|
10340
|
+
author_user_id: optionalWireString,
|
|
10341
|
+
channel_id: nonEmptyString,
|
|
10342
|
+
channel_name: optionalWireString,
|
|
10343
|
+
message_ts: nonEmptyString,
|
|
10344
|
+
content: z40.string(),
|
|
10345
|
+
is_author_bot: optionalWireBoolean,
|
|
10346
|
+
permalink: z40.string().url()
|
|
10347
|
+
}).transform(
|
|
10348
|
+
(value) => ({
|
|
10349
|
+
channel_id: value.channel_id,
|
|
10350
|
+
message_ts: value.message_ts,
|
|
10351
|
+
content: value.content,
|
|
10352
|
+
permalink: value.permalink,
|
|
10353
|
+
...value.author_name ? { author_name: value.author_name } : {},
|
|
10354
|
+
...value.author_user_id ? { author_user_id: value.author_user_id } : {},
|
|
10355
|
+
...value.channel_name ? { channel_name: value.channel_name } : {},
|
|
10356
|
+
...value.is_author_bot !== void 0 ? { is_author_bot: value.is_author_bot } : {}
|
|
10357
|
+
})
|
|
10358
|
+
);
|
|
10359
|
+
var slackSearchFileWireSchema = z40.object({
|
|
10360
|
+
id: optionalWireString,
|
|
10361
|
+
file_id: optionalWireString,
|
|
10362
|
+
title: optionalWireString,
|
|
10363
|
+
name: optionalWireString,
|
|
10364
|
+
filetype: optionalWireString,
|
|
10365
|
+
file_type: optionalWireString,
|
|
10366
|
+
user: optionalWireString,
|
|
10367
|
+
user_id: optionalWireString,
|
|
10368
|
+
username: optionalWireString,
|
|
10369
|
+
user_name: optionalWireString,
|
|
10370
|
+
channel_id: optionalWireString,
|
|
10371
|
+
channel_name: optionalWireString,
|
|
10372
|
+
permalink: optionalWireUrl,
|
|
10373
|
+
content: optionalWireString,
|
|
10374
|
+
preview: optionalWireString
|
|
10375
|
+
}).transform((value) => {
|
|
10376
|
+
const fileId = value.file_id ?? value.id;
|
|
10377
|
+
if (!fileId) {
|
|
10378
|
+
return void 0;
|
|
10379
|
+
}
|
|
10380
|
+
return {
|
|
10381
|
+
file_id: fileId,
|
|
10382
|
+
...value.title ? { title: value.title } : {},
|
|
10383
|
+
...value.name ? { name: value.name } : {},
|
|
10384
|
+
...value.filetype ?? value.file_type ? { filetype: value.filetype ?? value.file_type } : {},
|
|
10385
|
+
...value.user_id ?? value.user ? { user_id: value.user_id ?? value.user } : {},
|
|
10386
|
+
...value.user_name ?? value.username ? { user_name: value.user_name ?? value.username } : {},
|
|
10387
|
+
...value.channel_id ? { channel_id: value.channel_id } : {},
|
|
10388
|
+
...value.channel_name ? { channel_name: value.channel_name } : {},
|
|
10389
|
+
...value.permalink ? { permalink: value.permalink } : {},
|
|
10390
|
+
...value.content ?? value.preview ? { content: value.content ?? value.preview } : {}
|
|
10391
|
+
};
|
|
10392
|
+
});
|
|
10393
|
+
var slackSearchChannelWireSchema = z40.object({
|
|
10394
|
+
id: optionalWireString,
|
|
10395
|
+
channel_id: optionalWireString,
|
|
10396
|
+
name: optionalWireString,
|
|
10397
|
+
channel_name: optionalWireString,
|
|
10398
|
+
is_private: optionalWireBoolean,
|
|
10399
|
+
is_member: optionalWireBoolean,
|
|
10400
|
+
topic: optionalWireString,
|
|
10401
|
+
purpose: optionalWireString,
|
|
10402
|
+
permalink: optionalWireUrl
|
|
10403
|
+
}).transform((value) => {
|
|
10404
|
+
const channelId = value.channel_id ?? value.id;
|
|
10405
|
+
if (!channelId) {
|
|
10406
|
+
return void 0;
|
|
10407
|
+
}
|
|
10408
|
+
return {
|
|
10409
|
+
channel_id: channelId,
|
|
10410
|
+
...value.channel_name ?? value.name ? { channel_name: value.channel_name ?? value.name } : {},
|
|
10411
|
+
...value.is_private !== void 0 ? { is_private: value.is_private } : {},
|
|
10412
|
+
...value.is_member !== void 0 ? { is_member: value.is_member } : {},
|
|
10413
|
+
...value.topic ? { topic: value.topic } : {},
|
|
10414
|
+
...value.purpose ? { purpose: value.purpose } : {},
|
|
10415
|
+
...value.permalink ? { permalink: value.permalink } : {}
|
|
10416
|
+
};
|
|
10417
|
+
});
|
|
10418
|
+
var slackSearchUserWireSchema = z40.object({
|
|
10419
|
+
id: optionalWireString,
|
|
10420
|
+
user_id: optionalWireString,
|
|
10421
|
+
name: optionalWireString,
|
|
10422
|
+
username: optionalWireString,
|
|
10423
|
+
user_name: optionalWireString,
|
|
10424
|
+
real_name: optionalWireString,
|
|
10425
|
+
display_name: optionalWireString,
|
|
10426
|
+
title: optionalWireString,
|
|
10427
|
+
permalink: optionalWireUrl
|
|
10428
|
+
}).transform((value) => {
|
|
10429
|
+
const userId = value.user_id ?? value.id;
|
|
10430
|
+
if (!userId) {
|
|
10431
|
+
return void 0;
|
|
10432
|
+
}
|
|
10433
|
+
return {
|
|
10434
|
+
user_id: userId,
|
|
10435
|
+
...value.user_name ?? value.name ?? value.username ? { user_name: value.user_name ?? value.name ?? value.username } : {},
|
|
10436
|
+
...value.real_name ? { real_name: value.real_name } : {},
|
|
10437
|
+
...value.display_name ? { display_name: value.display_name } : {},
|
|
10438
|
+
...value.title ? { title: value.title } : {},
|
|
10439
|
+
...value.permalink ? { permalink: value.permalink } : {}
|
|
10440
|
+
};
|
|
10441
|
+
});
|
|
10442
|
+
var slackSearchResponseSchema = z40.object({
|
|
10443
|
+
results: z40.object({
|
|
10444
|
+
messages: z40.array(z40.unknown()).default([]),
|
|
10445
|
+
files: z40.array(z40.unknown()).default([]),
|
|
10446
|
+
channels: z40.array(z40.unknown()).default([]),
|
|
10447
|
+
users: z40.array(z40.unknown()).default([]),
|
|
10448
|
+
// Slack often returns "" on the final page; omit rather than fail the parse.
|
|
10449
|
+
next_cursor: optionalWireString
|
|
10450
|
+
}).default({
|
|
10451
|
+
messages: [],
|
|
10452
|
+
files: [],
|
|
10453
|
+
channels: [],
|
|
10454
|
+
users: []
|
|
10455
|
+
})
|
|
10456
|
+
});
|
|
10457
|
+
function parseItems(values, schema) {
|
|
10458
|
+
const items = [];
|
|
10459
|
+
for (const value of values) {
|
|
10460
|
+
const parsed = schema.safeParse(value);
|
|
10461
|
+
if (parsed.success && parsed.data !== void 0) {
|
|
10462
|
+
items.push(parsed.data);
|
|
10463
|
+
}
|
|
10464
|
+
}
|
|
10465
|
+
return items;
|
|
9929
10466
|
}
|
|
9930
10467
|
function explicitSearchError(error) {
|
|
9931
10468
|
if (error.code === "missing_scope") {
|
|
9932
|
-
|
|
10469
|
+
const needed = error.needed?.trim();
|
|
10470
|
+
if (needed) {
|
|
10471
|
+
return `Public Slack search is unavailable because this installation is missing the \`${needed}\` scope.`;
|
|
10472
|
+
}
|
|
10473
|
+
return "Public Slack search is unavailable because this installation is missing a required search scope (`search:read.public`, and `search:read.files` / `search:read.users` when those content types are requested).";
|
|
9933
10474
|
}
|
|
9934
10475
|
if (error.code === "feature_unavailable") {
|
|
9935
10476
|
return "Public Slack search is not available for this Slack workspace or app installation.";
|
|
@@ -9939,33 +10480,33 @@ function explicitSearchError(error) {
|
|
|
9939
10480
|
}
|
|
9940
10481
|
return void 0;
|
|
9941
10482
|
}
|
|
10483
|
+
function normalizeContentTypes(contentTypes) {
|
|
10484
|
+
const selected = contentTypes?.length ? contentTypes : [...DEFAULT_CONTENT_TYPES];
|
|
10485
|
+
return [...new Set(selected)];
|
|
10486
|
+
}
|
|
9942
10487
|
function createSlackPublicSearchTool(actionToken) {
|
|
9943
10488
|
return zodTool({
|
|
9944
|
-
description: "Search public Slack
|
|
10489
|
+
description: "Search live public Slack content across the workspace. Defaults to messages; optionally include files, channels, or users. Private channels and DMs are never searched.",
|
|
9945
10490
|
annotations: {
|
|
9946
10491
|
destructiveHint: false,
|
|
9947
10492
|
idempotentHint: true,
|
|
9948
10493
|
openWorldHint: true,
|
|
9949
10494
|
readOnlyHint: true
|
|
9950
10495
|
},
|
|
9951
|
-
inputSchema:
|
|
9952
|
-
query:
|
|
9953
|
-
|
|
9954
|
-
),
|
|
9955
|
-
|
|
9956
|
-
|
|
9957
|
-
),
|
|
9958
|
-
|
|
9959
|
-
|
|
9960
|
-
),
|
|
9961
|
-
cursor: z38.string().min(1).describe("Cursor for the next result page.").optional(),
|
|
9962
|
-
limit: z38.coerce.number().int().min(1).max(20).describe("Maximum results to return; Slack allows at most 20.").optional(),
|
|
9963
|
-
sort: z38.enum(["score", "timestamp"]).describe("Rank by relevance or timestamp.").optional(),
|
|
9964
|
-
sort_dir: z38.enum(["asc", "desc"]).describe("Sort direction.").optional()
|
|
10496
|
+
inputSchema: z40.object({
|
|
10497
|
+
query: z40.string().trim().min(1).max(500).describe("Slack search query."),
|
|
10498
|
+
content_types: z40.array(z40.enum(CONTENT_TYPES)).min(1).max(4).describe("Content types to include. Defaults to messages.").optional(),
|
|
10499
|
+
after: optionalUnixTimestampParam("Unix timestamp lower bound."),
|
|
10500
|
+
before: optionalUnixTimestampParam("Unix timestamp upper bound."),
|
|
10501
|
+
cursor: z40.string().min(1).describe("Cursor for the next result page.").optional(),
|
|
10502
|
+
limit: z40.coerce.number().int().min(1).max(20).describe("Maximum results to return; Slack allows at most 20.").optional(),
|
|
10503
|
+
sort: z40.enum(["score", "timestamp"]).describe("Rank by relevance or timestamp.").optional(),
|
|
10504
|
+
sort_dir: z40.enum(["asc", "desc"]).describe("Sort direction.").optional()
|
|
9965
10505
|
}),
|
|
9966
10506
|
outputSchema: publicSearchOutputSchema,
|
|
9967
10507
|
execute: async ({
|
|
9968
10508
|
query,
|
|
10509
|
+
content_types,
|
|
9969
10510
|
after,
|
|
9970
10511
|
before,
|
|
9971
10512
|
cursor,
|
|
@@ -9973,36 +10514,63 @@ function createSlackPublicSearchTool(actionToken) {
|
|
|
9973
10514
|
sort,
|
|
9974
10515
|
sort_dir
|
|
9975
10516
|
}) => {
|
|
10517
|
+
if (!actionToken) {
|
|
10518
|
+
throw new ToolInputError(
|
|
10519
|
+
"Public Slack search needs a fresh interactive mention or DM. Slack only issues the short-lived action token on those turns, so resumes and scheduled runs cannot search the workspace. Ask again in a new message, or use channel history / thread read when you already know the channel."
|
|
10520
|
+
);
|
|
10521
|
+
}
|
|
9976
10522
|
try {
|
|
9977
|
-
const
|
|
9978
|
-
const
|
|
9979
|
-
const
|
|
9980
|
-
|
|
9981
|
-
|
|
9982
|
-
|
|
9983
|
-
|
|
9984
|
-
|
|
9985
|
-
|
|
9986
|
-
|
|
9987
|
-
|
|
9988
|
-
|
|
9989
|
-
|
|
9990
|
-
|
|
9991
|
-
|
|
9992
|
-
|
|
9993
|
-
|
|
9994
|
-
|
|
9995
|
-
|
|
9996
|
-
|
|
9997
|
-
|
|
10523
|
+
const normalizedContentTypes = normalizeContentTypes(content_types);
|
|
10524
|
+
const normalizedAfter = normalizeOptionalUnixTimestamp(after);
|
|
10525
|
+
const normalizedBefore = normalizeOptionalUnixTimestamp(before);
|
|
10526
|
+
const response = slackSearchResponseSchema.parse(
|
|
10527
|
+
await withSlackRetries(
|
|
10528
|
+
() => getSlackClient().apiCall("assistant.search.context", {
|
|
10529
|
+
action_token: actionToken,
|
|
10530
|
+
query,
|
|
10531
|
+
channel_types: ["public_channel"],
|
|
10532
|
+
content_types: normalizedContentTypes,
|
|
10533
|
+
include_bots: true,
|
|
10534
|
+
limit: limit ?? DEFAULT_LIMIT2,
|
|
10535
|
+
...normalizedAfter !== void 0 ? { after: normalizedAfter } : {},
|
|
10536
|
+
...normalizedBefore !== void 0 ? { before: normalizedBefore } : {},
|
|
10537
|
+
...cursor ? { cursor } : {},
|
|
10538
|
+
...sort ? { sort } : {},
|
|
10539
|
+
...sort_dir ? { sort_dir } : {}
|
|
10540
|
+
}),
|
|
10541
|
+
3,
|
|
10542
|
+
{
|
|
10543
|
+
action: "assistant.search.context",
|
|
10544
|
+
idempotent: true
|
|
10545
|
+
}
|
|
10546
|
+
)
|
|
10547
|
+
);
|
|
10548
|
+
const messages = parseItems(
|
|
10549
|
+
response.results.messages,
|
|
10550
|
+
slackSearchMessageWireSchema
|
|
10551
|
+
);
|
|
10552
|
+
const files = parseItems(
|
|
10553
|
+
response.results.files,
|
|
10554
|
+
slackSearchFileWireSchema
|
|
9998
10555
|
);
|
|
9999
|
-
const
|
|
10000
|
-
|
|
10556
|
+
const channels = parseItems(
|
|
10557
|
+
response.results.channels,
|
|
10558
|
+
slackSearchChannelWireSchema
|
|
10559
|
+
);
|
|
10560
|
+
const users = parseItems(
|
|
10561
|
+
response.results.users,
|
|
10562
|
+
slackSearchUserWireSchema
|
|
10563
|
+
);
|
|
10564
|
+
const count = messages.length + files.length + channels.length + users.length;
|
|
10001
10565
|
return {
|
|
10002
10566
|
query,
|
|
10003
|
-
|
|
10567
|
+
content_types: normalizedContentTypes,
|
|
10568
|
+
count,
|
|
10004
10569
|
messages,
|
|
10005
|
-
|
|
10570
|
+
files,
|
|
10571
|
+
channels,
|
|
10572
|
+
users,
|
|
10573
|
+
...response.results.next_cursor ? { next_cursor: response.results.next_cursor } : {}
|
|
10006
10574
|
};
|
|
10007
10575
|
} catch (error) {
|
|
10008
10576
|
if (error instanceof SlackActionError) {
|
|
@@ -10018,7 +10586,7 @@ function createSlackPublicSearchTool(actionToken) {
|
|
|
10018
10586
|
}
|
|
10019
10587
|
|
|
10020
10588
|
// src/chat/slack/tools/message-add-reaction.ts
|
|
10021
|
-
import { z as
|
|
10589
|
+
import { z as z41 } from "zod";
|
|
10022
10590
|
|
|
10023
10591
|
// src/chat/tools/idempotency.ts
|
|
10024
10592
|
function stableSerialize(value) {
|
|
@@ -10048,9 +10616,9 @@ function createSlackMessageAddReactionTool(context, state) {
|
|
|
10048
10616
|
openWorldHint: true,
|
|
10049
10617
|
readOnlyHint: false
|
|
10050
10618
|
},
|
|
10051
|
-
description: "Add an emoji reaction to the current inbound Slack message.
|
|
10052
|
-
inputSchema:
|
|
10053
|
-
emoji:
|
|
10619
|
+
description: "Add an emoji reaction to the current inbound Slack message.",
|
|
10620
|
+
inputSchema: z41.object({
|
|
10621
|
+
emoji: z41.string().min(1).max(64).describe(
|
|
10054
10622
|
"Slack emoji alias name to react with (for example `thumbsup`, `white_check_mark`, or `thumbsup::skin-tone-6`). Optional surrounding colons are allowed."
|
|
10055
10623
|
)
|
|
10056
10624
|
}),
|
|
@@ -10099,14 +10667,14 @@ function createSlackMessageAddReactionTool(context, state) {
|
|
|
10099
10667
|
|
|
10100
10668
|
// src/chat/slack/tools/send-files.ts
|
|
10101
10669
|
import { createHash as createHash4 } from "crypto";
|
|
10102
|
-
import { z as
|
|
10670
|
+
import { z as z42 } from "zod";
|
|
10103
10671
|
var sendFilesResultSchema = juniorToolOutputSchema.extend({
|
|
10104
|
-
target:
|
|
10105
|
-
channel_id:
|
|
10106
|
-
deduplicated:
|
|
10107
|
-
file_count:
|
|
10108
|
-
file_ids:
|
|
10109
|
-
thread_ts:
|
|
10672
|
+
target: z42.string().min(1),
|
|
10673
|
+
channel_id: z42.string().min(1),
|
|
10674
|
+
deduplicated: z42.boolean().optional(),
|
|
10675
|
+
file_count: z42.number().int().nonnegative(),
|
|
10676
|
+
file_ids: z42.array(z42.string().min(1)).optional(),
|
|
10677
|
+
thread_ts: z42.string().min(1)
|
|
10110
10678
|
});
|
|
10111
10679
|
function normalizeFiles(files) {
|
|
10112
10680
|
return files.map((file) => ({
|
|
@@ -10135,9 +10703,9 @@ function createSendFilesTool(context, state, materializeFile) {
|
|
|
10135
10703
|
openWorldHint: true,
|
|
10136
10704
|
readOnlyHint: false
|
|
10137
10705
|
},
|
|
10138
|
-
description: "Send one or more sandbox files into the active Slack conversation.
|
|
10139
|
-
inputSchema:
|
|
10140
|
-
files:
|
|
10706
|
+
description: "Send one or more sandbox files into the active Slack conversation.",
|
|
10707
|
+
inputSchema: z42.object({
|
|
10708
|
+
files: z42.array(sandboxFileReferenceSchema).min(1).describe(
|
|
10141
10709
|
"One or more existing sandbox files. Objects returned by imageGenerate or webFetch can be passed unchanged."
|
|
10142
10710
|
)
|
|
10143
10711
|
}),
|
|
@@ -10223,7 +10791,7 @@ function extractCanvasId(input) {
|
|
|
10223
10791
|
}
|
|
10224
10792
|
}
|
|
10225
10793
|
|
|
10226
|
-
// src/chat/slack/
|
|
10794
|
+
// src/chat/slack/tool-support/canvas/markdown.ts
|
|
10227
10795
|
function getListType(marker) {
|
|
10228
10796
|
return /^\d/.test(marker) ? "numbered" : "bullet";
|
|
10229
10797
|
}
|
|
@@ -10372,7 +10940,7 @@ function normalizeCanvasMarkdown(markdown) {
|
|
|
10372
10940
|
};
|
|
10373
10941
|
}
|
|
10374
10942
|
|
|
10375
|
-
// src/chat/slack/
|
|
10943
|
+
// src/chat/slack/tool-support/canvas/api.ts
|
|
10376
10944
|
async function createCanvas(input) {
|
|
10377
10945
|
const client = getSlackClient();
|
|
10378
10946
|
const normalizedChannelId = normalizeSlackConversationId(input.channelId);
|
|
@@ -10530,7 +11098,7 @@ async function readCanvas(canvasIdOrUrl) {
|
|
|
10530
11098
|
}
|
|
10531
11099
|
|
|
10532
11100
|
// src/chat/slack/tools/canvas/create.ts
|
|
10533
|
-
import { z as
|
|
11101
|
+
import { z as z43 } from "zod";
|
|
10534
11102
|
function createSlackCanvasCreateTool(context, state) {
|
|
10535
11103
|
return zodTool({
|
|
10536
11104
|
annotations: {
|
|
@@ -10539,10 +11107,10 @@ function createSlackCanvasCreateTool(context, state) {
|
|
|
10539
11107
|
openWorldHint: true,
|
|
10540
11108
|
readOnlyHint: false
|
|
10541
11109
|
},
|
|
10542
|
-
description: "Create a Slack canvas
|
|
10543
|
-
inputSchema:
|
|
10544
|
-
title:
|
|
10545
|
-
markdown:
|
|
11110
|
+
description: "Create a Slack canvas in the active channel.",
|
|
11111
|
+
inputSchema: z43.object({
|
|
11112
|
+
title: z43.string().min(1).max(160).describe("Canvas title."),
|
|
11113
|
+
markdown: z43.string().min(1).describe("Canvas markdown body content.")
|
|
10546
11114
|
}),
|
|
10547
11115
|
outputSchema: juniorToolOutputSchema,
|
|
10548
11116
|
execute: async ({ title, markdown }) => {
|
|
@@ -10585,7 +11153,9 @@ function createSlackCanvasCreateTool(context, state) {
|
|
|
10585
11153
|
});
|
|
10586
11154
|
}
|
|
10587
11155
|
|
|
10588
|
-
// src/chat/slack/
|
|
11156
|
+
// src/chat/slack/tool-support/canvas/context.ts
|
|
11157
|
+
import { z as z44 } from "zod";
|
|
11158
|
+
var slackCanvasRefParam = z44.string().min(1).describe("Slack canvas/file ID or canvas/docs URL.");
|
|
10589
11159
|
function resolveCanvasTarget(canvas) {
|
|
10590
11160
|
const canvasId = extractCanvasId(canvas);
|
|
10591
11161
|
if (!canvasId) {
|
|
@@ -10598,26 +11168,26 @@ function resolveCanvasTarget(canvas) {
|
|
|
10598
11168
|
}
|
|
10599
11169
|
|
|
10600
11170
|
// src/chat/slack/tools/canvas/edit.ts
|
|
10601
|
-
import { z as
|
|
11171
|
+
import { z as z45 } from "zod";
|
|
10602
11172
|
function prepareCanvasEditArguments(input) {
|
|
10603
11173
|
return prepareTextReplacementArguments(input);
|
|
10604
11174
|
}
|
|
10605
|
-
var editReplacementSchema2 =
|
|
10606
|
-
oldText:
|
|
11175
|
+
var editReplacementSchema2 = z45.object({
|
|
11176
|
+
oldText: z45.string().min(1).describe(
|
|
10607
11177
|
"Exact Canvas markdown to replace. It must be unique in the current Canvas body and must not overlap another edit."
|
|
10608
11178
|
),
|
|
10609
|
-
newText:
|
|
11179
|
+
newText: z45.string().describe("Replacement Canvas markdown for this edit.")
|
|
10610
11180
|
});
|
|
10611
11181
|
var slackCanvasEditOutputSchema = juniorToolOutputSchema.extend({
|
|
10612
|
-
canvas_id:
|
|
10613
|
-
title:
|
|
10614
|
-
permalink:
|
|
10615
|
-
diff:
|
|
10616
|
-
first_changed_line:
|
|
10617
|
-
replacements:
|
|
10618
|
-
normalized_heading_count:
|
|
10619
|
-
summary:
|
|
10620
|
-
deduplicated:
|
|
11182
|
+
canvas_id: z45.string().optional(),
|
|
11183
|
+
title: z45.string().optional(),
|
|
11184
|
+
permalink: z45.string().optional(),
|
|
11185
|
+
diff: z45.string().optional(),
|
|
11186
|
+
first_changed_line: z45.number().int().positive().optional(),
|
|
11187
|
+
replacements: z45.number().int().nonnegative().optional(),
|
|
11188
|
+
normalized_heading_count: z45.number().int().nonnegative().optional(),
|
|
11189
|
+
summary: z45.string().optional(),
|
|
11190
|
+
deduplicated: z45.boolean().optional()
|
|
10621
11191
|
}).strict();
|
|
10622
11192
|
function createSlackCanvasEditTool(state) {
|
|
10623
11193
|
return zodTool({
|
|
@@ -10627,12 +11197,12 @@ function createSlackCanvasEditTool(state) {
|
|
|
10627
11197
|
openWorldHint: true,
|
|
10628
11198
|
readOnlyHint: false
|
|
10629
11199
|
},
|
|
10630
|
-
description: "Edit
|
|
11200
|
+
description: "Edit a Slack canvas with exact markdown replacements. Returns a diff.",
|
|
10631
11201
|
prepareArguments: prepareCanvasEditArguments,
|
|
10632
11202
|
executionMode: "sequential",
|
|
10633
|
-
inputSchema:
|
|
10634
|
-
canvas:
|
|
10635
|
-
edits:
|
|
11203
|
+
inputSchema: z45.object({
|
|
11204
|
+
canvas: slackCanvasRefParam,
|
|
11205
|
+
edits: z45.array(editReplacementSchema2).min(1).describe(
|
|
10636
11206
|
"Exact replacements matched against the current Canvas body, not incrementally."
|
|
10637
11207
|
)
|
|
10638
11208
|
}),
|
|
@@ -10685,34 +11255,32 @@ function createSlackCanvasEditTool(state) {
|
|
|
10685
11255
|
}
|
|
10686
11256
|
|
|
10687
11257
|
// src/chat/slack/tools/canvas/read.ts
|
|
10688
|
-
import { z as
|
|
11258
|
+
import { z as z46 } from "zod";
|
|
10689
11259
|
var slackCanvasReadOutputSchema = juniorToolOutputSchema.extend({
|
|
10690
|
-
canvas_id:
|
|
10691
|
-
title:
|
|
10692
|
-
permalink:
|
|
10693
|
-
mimetype:
|
|
10694
|
-
filetype:
|
|
10695
|
-
original_byte_length:
|
|
10696
|
-
content:
|
|
10697
|
-
start_line:
|
|
10698
|
-
end_line:
|
|
10699
|
-
total_lines:
|
|
11260
|
+
canvas_id: z46.string().optional(),
|
|
11261
|
+
title: z46.string().optional(),
|
|
11262
|
+
permalink: z46.string().optional(),
|
|
11263
|
+
mimetype: z46.string().optional(),
|
|
11264
|
+
filetype: z46.string().optional(),
|
|
11265
|
+
original_byte_length: z46.number().int().nonnegative().optional(),
|
|
11266
|
+
content: z46.string().optional(),
|
|
11267
|
+
start_line: z46.number().int().positive().optional(),
|
|
11268
|
+
end_line: z46.number().int().nonnegative().optional(),
|
|
11269
|
+
total_lines: z46.number().int().nonnegative().optional()
|
|
10700
11270
|
}).strict();
|
|
10701
11271
|
function createSlackCanvasReadTool() {
|
|
10702
11272
|
return zodTool({
|
|
10703
|
-
description: "Read a bounded line range from a Slack canvas as markdown.
|
|
11273
|
+
description: "Read a bounded line range from a Slack canvas as markdown.",
|
|
10704
11274
|
annotations: {
|
|
10705
11275
|
destructiveHint: false,
|
|
10706
11276
|
idempotentHint: true,
|
|
10707
11277
|
openWorldHint: true,
|
|
10708
11278
|
readOnlyHint: true
|
|
10709
11279
|
},
|
|
10710
|
-
inputSchema:
|
|
10711
|
-
canvas:
|
|
10712
|
-
|
|
10713
|
-
)
|
|
10714
|
-
offset: z43.coerce.number().int().min(1).describe("1-indexed line number to start reading from.").optional(),
|
|
10715
|
-
limit: z43.coerce.number().int().min(1).describe("Maximum number of lines to read. Defaults to 1000.").optional()
|
|
11280
|
+
inputSchema: z46.object({
|
|
11281
|
+
canvas: slackCanvasRefParam,
|
|
11282
|
+
offset: z46.coerce.number().int().min(1).describe("1-indexed line number to start reading from.").optional(),
|
|
11283
|
+
limit: z46.coerce.number().int().min(1).describe("Maximum number of lines to read. Defaults to 1000.").optional()
|
|
10716
11284
|
}),
|
|
10717
11285
|
outputSchema: slackCanvasReadOutputSchema,
|
|
10718
11286
|
execute: async ({ canvas, offset, limit }) => {
|
|
@@ -10748,7 +11316,7 @@ function createSlackCanvasReadTool() {
|
|
|
10748
11316
|
}
|
|
10749
11317
|
|
|
10750
11318
|
// src/chat/slack/tools/canvas/write.ts
|
|
10751
|
-
import { z as
|
|
11319
|
+
import { z as z47 } from "zod";
|
|
10752
11320
|
function createSlackCanvasWriteTool(state) {
|
|
10753
11321
|
return zodTool({
|
|
10754
11322
|
annotations: {
|
|
@@ -10757,11 +11325,11 @@ function createSlackCanvasWriteTool(state) {
|
|
|
10757
11325
|
openWorldHint: true,
|
|
10758
11326
|
readOnlyHint: false
|
|
10759
11327
|
},
|
|
10760
|
-
description: "
|
|
11328
|
+
description: "Replace the full markdown body of a Slack canvas.",
|
|
10761
11329
|
executionMode: "sequential",
|
|
10762
|
-
inputSchema:
|
|
10763
|
-
canvas:
|
|
10764
|
-
content:
|
|
11330
|
+
inputSchema: z47.object({
|
|
11331
|
+
canvas: slackCanvasRefParam,
|
|
11332
|
+
content: z47.string().describe("UTF-8 markdown content to write.")
|
|
10765
11333
|
}),
|
|
10766
11334
|
outputSchema: juniorToolOutputSchema,
|
|
10767
11335
|
execute: async ({ canvas, content }) => {
|
|
@@ -10795,7 +11363,7 @@ function createSlackCanvasWriteTool(state) {
|
|
|
10795
11363
|
});
|
|
10796
11364
|
}
|
|
10797
11365
|
|
|
10798
|
-
// src/chat/slack/
|
|
11366
|
+
// src/chat/slack/tool-support/list/api.ts
|
|
10799
11367
|
function normalizeKey(value) {
|
|
10800
11368
|
return value.toLowerCase().replace(/[^a-z0-9]+/g, "_");
|
|
10801
11369
|
}
|
|
@@ -10982,8 +11550,13 @@ async function updateListItem(input) {
|
|
|
10982
11550
|
);
|
|
10983
11551
|
}
|
|
10984
11552
|
|
|
11553
|
+
// src/chat/slack/tool-support/list/params.ts
|
|
11554
|
+
import { z as z48 } from "zod";
|
|
11555
|
+
var slackListIdParam = z48.string().min(1).describe("Slack list ID.");
|
|
11556
|
+
var slackListItemIdParam = z48.string().min(1).describe("Slack list item ID.");
|
|
11557
|
+
|
|
10985
11558
|
// src/chat/slack/tools/list/add-items.ts
|
|
10986
|
-
import { z as
|
|
11559
|
+
import { z as z49 } from "zod";
|
|
10987
11560
|
function createSlackListAddItemsTool(state) {
|
|
10988
11561
|
return zodTool({
|
|
10989
11562
|
annotations: {
|
|
@@ -10992,14 +11565,14 @@ function createSlackListAddItemsTool(state) {
|
|
|
10992
11565
|
openWorldHint: true,
|
|
10993
11566
|
readOnlyHint: false
|
|
10994
11567
|
},
|
|
10995
|
-
description: "Add tasks to a Slack list.
|
|
10996
|
-
inputSchema:
|
|
10997
|
-
list_id:
|
|
10998
|
-
items:
|
|
11568
|
+
description: "Add tasks to a Slack list.",
|
|
11569
|
+
inputSchema: z49.object({
|
|
11570
|
+
list_id: slackListIdParam,
|
|
11571
|
+
items: z49.array(z49.string().min(1)).min(1).max(25).describe("List item titles to create."),
|
|
10999
11572
|
assignee_user_id: slackUserIdParam(
|
|
11000
11573
|
"Optional Slack user ID assigned to all created items."
|
|
11001
11574
|
).optional(),
|
|
11002
|
-
due_date:
|
|
11575
|
+
due_date: z49.string().regex(/^\d{4}-\d{2}-\d{2}$/).describe("Optional due date in YYYY-MM-DD format.").optional()
|
|
11003
11576
|
}),
|
|
11004
11577
|
outputSchema: juniorToolOutputSchema,
|
|
11005
11578
|
execute: async ({ list_id, items, assignee_user_id, due_date }) => {
|
|
@@ -11038,7 +11611,7 @@ function createSlackListAddItemsTool(state) {
|
|
|
11038
11611
|
}
|
|
11039
11612
|
|
|
11040
11613
|
// src/chat/slack/tools/list/create.ts
|
|
11041
|
-
import { z as
|
|
11614
|
+
import { z as z50 } from "zod";
|
|
11042
11615
|
function createSlackListCreateTool(state) {
|
|
11043
11616
|
return zodTool({
|
|
11044
11617
|
annotations: {
|
|
@@ -11047,9 +11620,9 @@ function createSlackListCreateTool(state) {
|
|
|
11047
11620
|
openWorldHint: true,
|
|
11048
11621
|
readOnlyHint: false
|
|
11049
11622
|
},
|
|
11050
|
-
description: "Create a Slack todo list
|
|
11051
|
-
inputSchema:
|
|
11052
|
-
name:
|
|
11623
|
+
description: "Create a Slack todo list.",
|
|
11624
|
+
inputSchema: z50.object({
|
|
11625
|
+
name: z50.string().min(1).max(160).describe("Name for the new Slack list.")
|
|
11053
11626
|
}),
|
|
11054
11627
|
outputSchema: juniorToolOutputSchema,
|
|
11055
11628
|
execute: async ({ name }) => {
|
|
@@ -11074,19 +11647,19 @@ function createSlackListCreateTool(state) {
|
|
|
11074
11647
|
}
|
|
11075
11648
|
|
|
11076
11649
|
// src/chat/slack/tools/list/get-items.ts
|
|
11077
|
-
import { z as
|
|
11650
|
+
import { z as z51 } from "zod";
|
|
11078
11651
|
function createSlackListGetItemsTool() {
|
|
11079
11652
|
return zodTool({
|
|
11080
|
-
description: "Read items from a Slack list.
|
|
11653
|
+
description: "Read items from a Slack list.",
|
|
11081
11654
|
annotations: {
|
|
11082
11655
|
destructiveHint: false,
|
|
11083
11656
|
idempotentHint: true,
|
|
11084
11657
|
openWorldHint: true,
|
|
11085
11658
|
readOnlyHint: true
|
|
11086
11659
|
},
|
|
11087
|
-
inputSchema:
|
|
11088
|
-
list_id:
|
|
11089
|
-
limit:
|
|
11660
|
+
inputSchema: z51.object({
|
|
11661
|
+
list_id: slackListIdParam,
|
|
11662
|
+
limit: z51.coerce.number().int().min(1).max(200).describe("Maximum number of list items to return.").optional()
|
|
11090
11663
|
}),
|
|
11091
11664
|
outputSchema: juniorToolOutputSchema,
|
|
11092
11665
|
execute: async ({ list_id, limit }) => {
|
|
@@ -11101,23 +11674,23 @@ function createSlackListGetItemsTool() {
|
|
|
11101
11674
|
}
|
|
11102
11675
|
|
|
11103
11676
|
// src/chat/slack/tools/list/update-item.ts
|
|
11104
|
-
import { z as
|
|
11105
|
-
var booleanInput3 = (description) =>
|
|
11677
|
+
import { z as z52 } from "zod";
|
|
11678
|
+
var booleanInput3 = (description) => z52.preprocess(
|
|
11106
11679
|
(value) => value === "true" ? true : value === "false" ? false : value,
|
|
11107
|
-
|
|
11680
|
+
z52.boolean()
|
|
11108
11681
|
).describe(description);
|
|
11109
|
-
var updateListItemInputSchema =
|
|
11110
|
-
|
|
11111
|
-
list_id:
|
|
11112
|
-
item_id:
|
|
11682
|
+
var updateListItemInputSchema = z52.union([
|
|
11683
|
+
z52.object({
|
|
11684
|
+
list_id: slackListIdParam,
|
|
11685
|
+
item_id: slackListItemIdParam,
|
|
11113
11686
|
completed: booleanInput3("Optional completion status update."),
|
|
11114
|
-
title:
|
|
11687
|
+
title: z52.string().min(1).describe("Optional new item title.").optional()
|
|
11115
11688
|
}),
|
|
11116
|
-
|
|
11117
|
-
list_id:
|
|
11118
|
-
item_id:
|
|
11689
|
+
z52.object({
|
|
11690
|
+
list_id: slackListIdParam,
|
|
11691
|
+
item_id: slackListItemIdParam,
|
|
11119
11692
|
completed: booleanInput3("Optional completion status update.").optional(),
|
|
11120
|
-
title:
|
|
11693
|
+
title: z52.string().min(1).describe("Optional new item title.")
|
|
11121
11694
|
})
|
|
11122
11695
|
]);
|
|
11123
11696
|
function createSlackListUpdateItemTool(state) {
|
|
@@ -11128,7 +11701,7 @@ function createSlackListUpdateItemTool(state) {
|
|
|
11128
11701
|
openWorldHint: true,
|
|
11129
11702
|
readOnlyHint: false
|
|
11130
11703
|
},
|
|
11131
|
-
description: "Update an item in a Slack list.
|
|
11704
|
+
description: "Update an item in a Slack list.",
|
|
11132
11705
|
inputSchema: updateListItemInputSchema,
|
|
11133
11706
|
outputSchema: juniorToolOutputSchema,
|
|
11134
11707
|
execute: async ({ list_id, item_id, completed, title }) => {
|
|
@@ -11164,33 +11737,10 @@ function createSlackListUpdateItemTool(state) {
|
|
|
11164
11737
|
});
|
|
11165
11738
|
}
|
|
11166
11739
|
|
|
11167
|
-
// src/chat/slack/tools/channel-access.ts
|
|
11168
|
-
async function checkSlackChannelReadAccess(args) {
|
|
11169
|
-
const currentChannels = args.currentChannelIds.filter(
|
|
11170
|
-
(channelId) => Boolean(channelId)
|
|
11171
|
-
);
|
|
11172
|
-
if (currentChannels.includes(args.targetChannelId)) {
|
|
11173
|
-
return { allowed: true };
|
|
11174
|
-
}
|
|
11175
|
-
const store = args.store ?? getConversationStore();
|
|
11176
|
-
const visibility = await store.getDestinationVisibility({
|
|
11177
|
-
provider: "slack",
|
|
11178
|
-
providerTenantId: args.teamId,
|
|
11179
|
-
providerDestinationId: args.targetChannelId
|
|
11180
|
-
});
|
|
11181
|
-
if (visibility === "public") {
|
|
11182
|
-
return { allowed: true };
|
|
11183
|
-
}
|
|
11184
|
-
return {
|
|
11185
|
-
allowed: false,
|
|
11186
|
-
error: "Cannot read this Slack conversation: only the current conversation or public channels Junior has seen in this workspace are readable."
|
|
11187
|
-
};
|
|
11188
|
-
}
|
|
11189
|
-
|
|
11190
11740
|
// src/chat/slack/tools/thread-read.ts
|
|
11191
|
-
import { z as
|
|
11741
|
+
import { z as z53 } from "zod";
|
|
11192
11742
|
|
|
11193
|
-
// src/chat/slack/
|
|
11743
|
+
// src/chat/slack/tool-support/slack-message-url.ts
|
|
11194
11744
|
var SLACK_HOST_PATTERN = /^[a-z0-9-]+\.slack(?:-gov)?\.com$/;
|
|
11195
11745
|
var ARCHIVE_PATH_PATTERN = /^\/archives\/([CDG][A-Z0-9]+)\/p(\d{10})(\d{6})$/;
|
|
11196
11746
|
function pTimestampToTs(seconds, micros) {
|
|
@@ -11445,27 +11995,23 @@ function truncateMessages(messages, maxChars) {
|
|
|
11445
11995
|
}
|
|
11446
11996
|
return { messages: kept, omitted: messages.length - kept.length };
|
|
11447
11997
|
}
|
|
11448
|
-
function createSlackThreadReadTool(context
|
|
11998
|
+
function createSlackThreadReadTool(context) {
|
|
11449
11999
|
return zodTool({
|
|
11450
|
-
description: "Read a Slack thread from a shared
|
|
12000
|
+
description: "Read a Slack thread from a shared archive URL or explicit channel + timestamp. Works for the current conversation and public channels.",
|
|
11451
12001
|
annotations: {
|
|
11452
12002
|
destructiveHint: false,
|
|
11453
12003
|
idempotentHint: true,
|
|
11454
12004
|
openWorldHint: true,
|
|
11455
12005
|
readOnlyHint: true
|
|
11456
12006
|
},
|
|
11457
|
-
inputSchema:
|
|
11458
|
-
url:
|
|
11459
|
-
|
|
11460
|
-
).optional(),
|
|
11461
|
-
channel_id: slackChannelIdParam(
|
|
11462
|
-
"Slack channel/conversation ID (e.g. C123). Use with `ts` as an alternative to `url`."
|
|
11463
|
-
).optional(),
|
|
12007
|
+
inputSchema: z53.object({
|
|
12008
|
+
url: z53.string().min(1).describe("Slack message archive URL.").optional(),
|
|
12009
|
+
channel_id: slackChannelRefParam.optional(),
|
|
11464
12010
|
ts: slackTimestampParam(
|
|
11465
|
-
"Slack message timestamp
|
|
12011
|
+
"Slack message timestamp. May be the thread root or any message in the thread."
|
|
11466
12012
|
).optional(),
|
|
11467
|
-
limit:
|
|
11468
|
-
max_pages:
|
|
12013
|
+
limit: z53.coerce.number().int().min(1).max(1e3).describe("Maximum number of thread messages to fetch.").optional(),
|
|
12014
|
+
max_pages: z53.coerce.number().int().min(1).max(10).describe("Maximum number of Slack API pages to traverse.").optional()
|
|
11469
12015
|
}),
|
|
11470
12016
|
outputSchema: juniorToolOutputSchema,
|
|
11471
12017
|
execute: async ({ url, channel_id, ts, limit, max_pages }) => {
|
|
@@ -11485,14 +12031,11 @@ function createSlackThreadReadTool(context, deps = {}) {
|
|
|
11485
12031
|
if (!parsedTs.ok) {
|
|
11486
12032
|
throw new ToolInputError(parsedTs.error);
|
|
11487
12033
|
}
|
|
11488
|
-
const
|
|
11489
|
-
"channel_id",
|
|
11490
|
-
channel_id
|
|
11491
|
-
);
|
|
11492
|
-
|
|
11493
|
-
throw new ToolInputError(parsedChannelId.error);
|
|
11494
|
-
}
|
|
11495
|
-
channelId = parsedChannelId.value;
|
|
12034
|
+
const target = await resolveSlackChannelRef({
|
|
12035
|
+
field: "channel_id",
|
|
12036
|
+
value: channel_id
|
|
12037
|
+
});
|
|
12038
|
+
channelId = target.channelId;
|
|
11496
12039
|
messageTs = parsedTs.value;
|
|
11497
12040
|
} else {
|
|
11498
12041
|
throw new ToolInputError(
|
|
@@ -11504,7 +12047,6 @@ function createSlackThreadReadTool(context, deps = {}) {
|
|
|
11504
12047
|
context.destinationChannelId,
|
|
11505
12048
|
context.sourceChannelId
|
|
11506
12049
|
],
|
|
11507
|
-
store: deps.visibilityStore,
|
|
11508
12050
|
targetChannelId: channelId,
|
|
11509
12051
|
teamId: context.teamId
|
|
11510
12052
|
});
|
|
@@ -11512,20 +12054,57 @@ function createSlackThreadReadTool(context, deps = {}) {
|
|
|
11512
12054
|
throw new ToolInputError(access.error);
|
|
11513
12055
|
}
|
|
11514
12056
|
const lookupTs = threadTs ?? messageTs;
|
|
12057
|
+
const readReplies = async () => listThreadReplies({
|
|
12058
|
+
channelId,
|
|
12059
|
+
threadTs: lookupTs,
|
|
12060
|
+
limit: limit ?? 1e3,
|
|
12061
|
+
maxPages: max_pages
|
|
12062
|
+
});
|
|
11515
12063
|
let replies;
|
|
12064
|
+
let joined = false;
|
|
12065
|
+
let channelName = access.channelName;
|
|
12066
|
+
let readError;
|
|
11516
12067
|
try {
|
|
11517
|
-
replies = await
|
|
11518
|
-
channelId,
|
|
11519
|
-
threadTs: lookupTs,
|
|
11520
|
-
limit: limit ?? 1e3,
|
|
11521
|
-
maxPages: max_pages
|
|
11522
|
-
});
|
|
12068
|
+
replies = await readReplies();
|
|
11523
12069
|
} catch (error) {
|
|
12070
|
+
readError = error;
|
|
12071
|
+
const canJoin = error instanceof SlackActionError && error.code === "not_in_channel" && access.isMember !== true;
|
|
12072
|
+
if (canJoin) {
|
|
12073
|
+
const joinResult = await joinPublicChannelForRead({
|
|
12074
|
+
channelName,
|
|
12075
|
+
targetChannelId: channelId
|
|
12076
|
+
});
|
|
12077
|
+
if (!joinResult.ok) {
|
|
12078
|
+
throw new ToolInputError(joinResult.error);
|
|
12079
|
+
}
|
|
12080
|
+
joined = true;
|
|
12081
|
+
channelName = joinResult.channelName ?? channelName;
|
|
12082
|
+
try {
|
|
12083
|
+
replies = await readReplies();
|
|
12084
|
+
readError = void 0;
|
|
12085
|
+
} catch (retryError) {
|
|
12086
|
+
readError = retryError;
|
|
12087
|
+
}
|
|
12088
|
+
}
|
|
12089
|
+
}
|
|
12090
|
+
if (!replies) {
|
|
12091
|
+
const error = readError;
|
|
11524
12092
|
if (error instanceof SlackActionError) {
|
|
11525
|
-
|
|
11526
|
-
|
|
11527
|
-
|
|
11528
|
-
|
|
12093
|
+
if (error.code === "not_in_channel") {
|
|
12094
|
+
throw new ToolInputError(
|
|
12095
|
+
"Could not read this Slack thread because the bot is not in the channel.",
|
|
12096
|
+
{ cause: error }
|
|
12097
|
+
);
|
|
12098
|
+
}
|
|
12099
|
+
if (error.code === "missing_scope") {
|
|
12100
|
+
throw new ToolInputError(
|
|
12101
|
+
"Could not read this Slack thread because this installation is missing history scopes.",
|
|
12102
|
+
{ cause: error }
|
|
12103
|
+
);
|
|
12104
|
+
}
|
|
12105
|
+
throw new ToolInputError("Could not read this Slack thread.", {
|
|
12106
|
+
cause: error
|
|
12107
|
+
});
|
|
11529
12108
|
}
|
|
11530
12109
|
throw error;
|
|
11531
12110
|
}
|
|
@@ -11541,6 +12120,8 @@ function createSlackThreadReadTool(context, deps = {}) {
|
|
|
11541
12120
|
);
|
|
11542
12121
|
return {
|
|
11543
12122
|
channel_id: channelId,
|
|
12123
|
+
...channelName ? { channel_name: channelName } : {},
|
|
12124
|
+
...joined ? { joined_channel: true } : {},
|
|
11544
12125
|
target_message_ts: messageTs,
|
|
11545
12126
|
thread_ts: resolvedThreadTs,
|
|
11546
12127
|
count: messages.length,
|
|
@@ -11556,7 +12137,7 @@ function createSlackThreadReadTool(context, deps = {}) {
|
|
|
11556
12137
|
// src/chat/tools/user-lookup.ts
|
|
11557
12138
|
import { and, eq, or, sql } from "drizzle-orm";
|
|
11558
12139
|
import { alias } from "drizzle-orm/pg-core";
|
|
11559
|
-
import { z as
|
|
12140
|
+
import { z as z54 } from "zod";
|
|
11560
12141
|
var linkedSlackIdentity = alias(juniorIdentities, "user_lookup_slack_identity");
|
|
11561
12142
|
function explicitUserLookupError(error) {
|
|
11562
12143
|
if (error.apiError === "user_not_found" || error.code === "not_found") {
|
|
@@ -11705,9 +12286,9 @@ function createUserLookupTool(teamId, providers) {
|
|
|
11705
12286
|
openWorldHint: true,
|
|
11706
12287
|
readOnlyHint: true
|
|
11707
12288
|
},
|
|
11708
|
-
inputSchema:
|
|
11709
|
-
provider:
|
|
11710
|
-
query:
|
|
12289
|
+
inputSchema: z54.object({
|
|
12290
|
+
provider: z54.enum(providers).describe("Enabled identity provider to query."),
|
|
12291
|
+
query: z54.string().trim().min(1).describe("Provider subject ID, handle, Slack email, or Slack name.")
|
|
11711
12292
|
}).strict(),
|
|
11712
12293
|
outputSchema: juniorToolOutputSchema,
|
|
11713
12294
|
execute: async ({ provider, query }) => {
|
|
@@ -11727,18 +12308,18 @@ function createUserLookupTool(teamId, providers) {
|
|
|
11727
12308
|
}
|
|
11728
12309
|
|
|
11729
12310
|
// src/chat/tools/system-time.ts
|
|
11730
|
-
import { z as
|
|
11731
|
-
var systemTimeInputSchema =
|
|
11732
|
-
timezone:
|
|
12311
|
+
import { z as z55 } from "zod";
|
|
12312
|
+
var systemTimeInputSchema = z55.object({
|
|
12313
|
+
timezone: z55.string().trim().min(1).optional().describe(
|
|
11733
12314
|
"Optional IANA timezone, for example America/Los_Angeles. When set, iso_local and timezone_offset_minutes are for that zone."
|
|
11734
12315
|
)
|
|
11735
12316
|
});
|
|
11736
12317
|
var systemTimeOutputSchema = juniorToolOutputSchema.extend({
|
|
11737
|
-
unix_ms:
|
|
11738
|
-
iso_utc:
|
|
11739
|
-
iso_local:
|
|
11740
|
-
timezone:
|
|
11741
|
-
timezone_offset_minutes:
|
|
12318
|
+
unix_ms: z55.number(),
|
|
12319
|
+
iso_utc: z55.string(),
|
|
12320
|
+
iso_local: z55.string(),
|
|
12321
|
+
timezone: z55.string().nullable(),
|
|
12322
|
+
timezone_offset_minutes: z55.number()
|
|
11742
12323
|
});
|
|
11743
12324
|
function createSystemTimeTool() {
|
|
11744
12325
|
return zodTool({
|
|
@@ -11818,27 +12399,27 @@ function getTimeZoneOffsetMinutes(timestampMs, timezone) {
|
|
|
11818
12399
|
}
|
|
11819
12400
|
|
|
11820
12401
|
// src/chat/tools/search-conversation-events.ts
|
|
11821
|
-
import { z as
|
|
12402
|
+
import { z as z56 } from "zod";
|
|
11822
12403
|
var DEFAULT_LIMIT3 = 25;
|
|
11823
12404
|
var MAX_LIMIT = 100;
|
|
11824
12405
|
var MAX_EVENT_DATA_BYTES = 4e3;
|
|
11825
12406
|
var MAX_EVENTS_JSON_BYTES = 2e4;
|
|
11826
12407
|
var MAX_IDENTITY_CHARS = 256;
|
|
11827
12408
|
var textEncoder = new TextEncoder();
|
|
11828
|
-
var knownEventTypeSchema =
|
|
11829
|
-
var projectedEventSchema =
|
|
11830
|
-
seq:
|
|
11831
|
-
history_version:
|
|
11832
|
-
created_at:
|
|
11833
|
-
idempotency_key:
|
|
11834
|
-
data:
|
|
12409
|
+
var knownEventTypeSchema = z56.enum(KNOWN_CONVERSATION_EVENT_TYPES);
|
|
12410
|
+
var projectedEventSchema = z56.object({
|
|
12411
|
+
seq: z56.number().int().nonnegative().describe("Stable event position for pagination."),
|
|
12412
|
+
history_version: z56.number().int().nonnegative().describe("Agent history generation after replacement."),
|
|
12413
|
+
created_at: z56.iso.datetime().describe("When the event was recorded."),
|
|
12414
|
+
idempotency_key: z56.string().min(1).optional().describe("Retry-stable event identity, when assigned."),
|
|
12415
|
+
data: z56.record(z56.string(), z56.unknown()).describe("Bounded event data.")
|
|
11835
12416
|
}).strict();
|
|
11836
12417
|
var searchConversationEventsOutputSchema = juniorToolOutputSchema.extend({
|
|
11837
|
-
conversation_id:
|
|
11838
|
-
events:
|
|
11839
|
-
has_older:
|
|
11840
|
-
has_newer:
|
|
11841
|
-
omitted_event_count:
|
|
12418
|
+
conversation_id: z56.string().min(1),
|
|
12419
|
+
events: z56.array(projectedEventSchema),
|
|
12420
|
+
has_older: z56.boolean().describe("Whether matching older events exist."),
|
|
12421
|
+
has_newer: z56.boolean().describe("Whether matching newer events exist."),
|
|
12422
|
+
omitted_event_count: z56.number().int().nonnegative().optional().describe("Events omitted by the response byte limit.")
|
|
11842
12423
|
});
|
|
11843
12424
|
function createSearchConversationEventsTool(context) {
|
|
11844
12425
|
return zodTool({
|
|
@@ -11851,16 +12432,16 @@ function createSearchConversationEventsTool(context) {
|
|
|
11851
12432
|
openWorldHint: false,
|
|
11852
12433
|
readOnlyHint: true
|
|
11853
12434
|
},
|
|
11854
|
-
inputSchema:
|
|
11855
|
-
conversation_id:
|
|
12435
|
+
inputSchema: z56.object({
|
|
12436
|
+
conversation_id: z56.string().trim().min(1).nullable().describe(
|
|
11856
12437
|
"Conversation ID to search. Omit or null for the current conversation."
|
|
11857
12438
|
).optional(),
|
|
11858
|
-
after_seq:
|
|
11859
|
-
before_seq:
|
|
11860
|
-
limit:
|
|
12439
|
+
after_seq: z56.number().int().nonnegative().nullable().describe("Exclusive event sequence lower bound; returns ascending.").optional(),
|
|
12440
|
+
before_seq: z56.number().int().nonnegative().nullable().describe("Exclusive event sequence upper bound.").optional(),
|
|
12441
|
+
limit: z56.number().int().min(1).max(MAX_LIMIT).nullable().describe(
|
|
11861
12442
|
`Maximum events. Default ${DEFAULT_LIMIT3}; max ${MAX_LIMIT}.`
|
|
11862
12443
|
).optional(),
|
|
11863
|
-
types:
|
|
12444
|
+
types: z56.array(knownEventTypeSchema).min(1).nullable().describe("Event types to include; omit for all types.").optional()
|
|
11864
12445
|
}).strict(),
|
|
11865
12446
|
outputSchema: searchConversationEventsOutputSchema,
|
|
11866
12447
|
execute: async (input) => {
|
|
@@ -12106,10 +12687,10 @@ function stripReplacementHistoryField(value) {
|
|
|
12106
12687
|
}
|
|
12107
12688
|
|
|
12108
12689
|
// src/chat/tools/handoff/tool.ts
|
|
12109
|
-
import { z as
|
|
12690
|
+
import { z as z57 } from "zod";
|
|
12110
12691
|
var HANDOFF_TOOL_NAME = "handoff";
|
|
12111
12692
|
function createHandoffTool(handoff) {
|
|
12112
|
-
const profileSchema =
|
|
12693
|
+
const profileSchema = z57.enum(handoff.profiles);
|
|
12113
12694
|
const handoffResultSchema = juniorToolOutputSchema.extend({
|
|
12114
12695
|
model_profile: modelProfileSchema
|
|
12115
12696
|
});
|
|
@@ -12123,7 +12704,7 @@ function createHandoffTool(handoff) {
|
|
|
12123
12704
|
},
|
|
12124
12705
|
description: `Switch to another execution profile and continue the same task. Profiles: ${profileNames}. Call this as the only tool.`,
|
|
12125
12706
|
executionMode: "sequential",
|
|
12126
|
-
inputSchema:
|
|
12707
|
+
inputSchema: z57.object({
|
|
12127
12708
|
profile: profileSchema.describe("Target execution profile")
|
|
12128
12709
|
}).strict(),
|
|
12129
12710
|
outputSchema: handoffResultSchema,
|
|
@@ -12144,7 +12725,7 @@ function createHandoffTool(handoff) {
|
|
|
12144
12725
|
}
|
|
12145
12726
|
|
|
12146
12727
|
// src/chat/tools/web/fetch-tool.ts
|
|
12147
|
-
import { z as
|
|
12728
|
+
import { z as z58 } from "zod";
|
|
12148
12729
|
|
|
12149
12730
|
// src/chat/tools/web/constants.ts
|
|
12150
12731
|
var USER_AGENT = "junior-bot/0.1";
|
|
@@ -12587,9 +13168,9 @@ function createWebFetchTool(hooks, options = {}) {
|
|
|
12587
13168
|
openWorldHint: true,
|
|
12588
13169
|
readOnlyHint: true
|
|
12589
13170
|
},
|
|
12590
|
-
inputSchema:
|
|
12591
|
-
url:
|
|
12592
|
-
max_chars:
|
|
13171
|
+
inputSchema: z58.object({
|
|
13172
|
+
url: z58.string().min(1).describe("HTTP(S) URL to fetch."),
|
|
13173
|
+
max_chars: z58.coerce.number().int().min(500).max(MAX_FETCH_CHARS).describe("Optional maximum number of extracted characters to return.").optional()
|
|
12593
13174
|
}),
|
|
12594
13175
|
outputSchema: juniorToolOutputSchema,
|
|
12595
13176
|
execute: async ({ url, max_chars }) => {
|
|
@@ -12634,7 +13215,7 @@ function createWebFetchTool(hooks, options = {}) {
|
|
|
12634
13215
|
}
|
|
12635
13216
|
|
|
12636
13217
|
// src/chat/tools/web/search.ts
|
|
12637
|
-
import { z as
|
|
13218
|
+
import { z as z59 } from "zod";
|
|
12638
13219
|
import { generateText } from "ai";
|
|
12639
13220
|
import { createGatewayProvider } from "@ai-sdk/gateway";
|
|
12640
13221
|
var SEARCH_TIMEOUT_MS = 6e4;
|
|
@@ -12676,9 +13257,9 @@ function createWebSearchTool(modelId, override) {
|
|
|
12676
13257
|
openWorldHint: true,
|
|
12677
13258
|
readOnlyHint: true
|
|
12678
13259
|
},
|
|
12679
|
-
inputSchema:
|
|
12680
|
-
query:
|
|
12681
|
-
max_results:
|
|
13260
|
+
inputSchema: z59.object({
|
|
13261
|
+
query: z59.string().min(1).max(500).describe("Search query."),
|
|
13262
|
+
max_results: z59.coerce.number().int().min(1).max(MAX_RESULTS2).describe("Max results to return.").optional()
|
|
12682
13263
|
}),
|
|
12683
13264
|
outputSchema: juniorToolOutputSchema,
|
|
12684
13265
|
execute: async ({ query, max_results }) => {
|
|
@@ -12720,7 +13301,7 @@ function createWebSearchTool(modelId, override) {
|
|
|
12720
13301
|
}
|
|
12721
13302
|
|
|
12722
13303
|
// src/chat/tools/sandbox/write-file.ts
|
|
12723
|
-
import { z as
|
|
13304
|
+
import { z as z60 } from "zod";
|
|
12724
13305
|
function createWriteFileTool() {
|
|
12725
13306
|
return zodTool({
|
|
12726
13307
|
annotations: {
|
|
@@ -12731,9 +13312,9 @@ function createWriteFileTool() {
|
|
|
12731
13312
|
},
|
|
12732
13313
|
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.",
|
|
12733
13314
|
executionMode: "sequential",
|
|
12734
|
-
inputSchema:
|
|
12735
|
-
path:
|
|
12736
|
-
content:
|
|
13315
|
+
inputSchema: z60.object({
|
|
13316
|
+
path: z60.string().min(1).describe("Path to write in the sandbox workspace."),
|
|
13317
|
+
content: z60.string().describe("UTF-8 file content to write.")
|
|
12737
13318
|
}),
|
|
12738
13319
|
outputSchema: juniorToolOutputSchema,
|
|
12739
13320
|
execute: async () => {
|
|
@@ -12825,6 +13406,7 @@ function createTools(availableSkills, hooks = {}, context, options = {}) {
|
|
|
12825
13406
|
tools.slackCanvasEdit = createSlackCanvasEditTool(state);
|
|
12826
13407
|
tools.slackCanvasWrite = createSlackCanvasWriteTool(state);
|
|
12827
13408
|
tools.slackThreadRead = createSlackThreadReadTool(slackContext);
|
|
13409
|
+
tools.slackChannelJoin = createSlackChannelJoinTool(slackContext);
|
|
12828
13410
|
if (context.conversationId && slackContext.source.visibility === "public") {
|
|
12829
13411
|
tools.searchConversationMessages = createSlackConversationMessageSearchTool(
|
|
12830
13412
|
{
|
|
@@ -12835,7 +13417,7 @@ function createTools(availableSkills, hooks = {}, context, options = {}) {
|
|
|
12835
13417
|
context.conversationId
|
|
12836
13418
|
);
|
|
12837
13419
|
}
|
|
12838
|
-
if (context.source.platform === "slack"
|
|
13420
|
+
if (context.source.platform === "slack") {
|
|
12839
13421
|
tools.slackPublicSearch = createSlackPublicSearchTool(
|
|
12840
13422
|
context.slackActionToken
|
|
12841
13423
|
);
|
|
@@ -12870,9 +13452,7 @@ function createTools(availableSkills, hooks = {}, context, options = {}) {
|
|
|
12870
13452
|
(input) => readSandboxFileUpload(context.workspace, input)
|
|
12871
13453
|
);
|
|
12872
13454
|
}
|
|
12873
|
-
|
|
12874
|
-
tools.slackChannelListMessages = createSlackChannelListMessagesTool(slackContext);
|
|
12875
|
-
}
|
|
13455
|
+
tools.slackChannelListMessages = createSlackChannelListMessagesTool(slackContext);
|
|
12876
13456
|
if (rawChannelCapabilities.canAddReactions) {
|
|
12877
13457
|
tools.addReaction = createSlackMessageAddReactionTool(
|
|
12878
13458
|
slackContext,
|
|
@@ -13431,7 +14011,7 @@ function handleToolExecutionError(error, toolName, toolCallId, shouldTrace, conv
|
|
|
13431
14011
|
}
|
|
13432
14012
|
|
|
13433
14013
|
// src/chat/tools/execute-tool.ts
|
|
13434
|
-
import { z as
|
|
14014
|
+
import { z as z61 } from "zod";
|
|
13435
14015
|
var EXECUTE_TOOL_NAME = "executeTool";
|
|
13436
14016
|
function createExecuteToolTool() {
|
|
13437
14017
|
return zodTool({
|
|
@@ -13443,11 +14023,11 @@ function createExecuteToolTool() {
|
|
|
13443
14023
|
},
|
|
13444
14024
|
description: "Execute any catalog tool by exact tool_name from searchTools or a tool-result execution hint. Put tool-specific parameters inside arguments.",
|
|
13445
14025
|
executionMode: "sequential",
|
|
13446
|
-
inputSchema:
|
|
13447
|
-
tool_name:
|
|
14026
|
+
inputSchema: z61.object({
|
|
14027
|
+
tool_name: z61.string().min(1).describe(
|
|
13448
14028
|
"Exact catalog tool_name returned by searchTools or a tool-result execution hint."
|
|
13449
14029
|
),
|
|
13450
|
-
arguments:
|
|
14030
|
+
arguments: z61.record(z61.string(), z61.unknown()).describe(
|
|
13451
14031
|
'Arguments matching the selected catalog tool schema, for example { "query": "..." }.'
|
|
13452
14032
|
).optional()
|
|
13453
14033
|
}).strict(),
|
|
@@ -13487,7 +14067,7 @@ function planToolExposure(tools) {
|
|
|
13487
14067
|
}
|
|
13488
14068
|
|
|
13489
14069
|
// src/chat/tools/search-tools.ts
|
|
13490
|
-
import { z as
|
|
14070
|
+
import { z as z62 } from "zod";
|
|
13491
14071
|
var SEARCH_TOOLS_NAME = "searchTools";
|
|
13492
14072
|
var DEFAULT_MAX_RESULTS2 = 5;
|
|
13493
14073
|
var MAX_RESULTS3 = 20;
|
|
@@ -13532,29 +14112,29 @@ var SEARCH_STOP_WORDS = /* @__PURE__ */ new Set([
|
|
|
13532
14112
|
"you",
|
|
13533
14113
|
"your"
|
|
13534
14114
|
]);
|
|
13535
|
-
var searchToolsSourceSchema =
|
|
13536
|
-
id:
|
|
13537
|
-
description:
|
|
14115
|
+
var searchToolsSourceSchema = z62.object({
|
|
14116
|
+
id: z62.string(),
|
|
14117
|
+
description: z62.string()
|
|
13538
14118
|
}).strict();
|
|
13539
|
-
var searchToolsToolSchema =
|
|
13540
|
-
tool_name:
|
|
13541
|
-
description:
|
|
13542
|
-
exposure:
|
|
13543
|
-
source:
|
|
13544
|
-
input_schema:
|
|
13545
|
-
call_notes:
|
|
13546
|
-
annotations:
|
|
14119
|
+
var searchToolsToolSchema = z62.object({
|
|
14120
|
+
tool_name: z62.string(),
|
|
14121
|
+
description: z62.string(),
|
|
14122
|
+
exposure: z62.enum(["direct", "deferred", "modelOnly", "hidden"]),
|
|
14123
|
+
source: z62.string().optional(),
|
|
14124
|
+
input_schema: z62.unknown(),
|
|
14125
|
+
call_notes: z62.array(z62.string()),
|
|
14126
|
+
annotations: z62.record(z62.string(), z62.unknown())
|
|
13547
14127
|
}).strict();
|
|
13548
14128
|
var searchToolsOutputSchema = juniorToolOutputSchema.extend({
|
|
13549
|
-
query:
|
|
13550
|
-
source:
|
|
13551
|
-
sources:
|
|
13552
|
-
total_catalog_tools:
|
|
13553
|
-
total_eligible_tools:
|
|
13554
|
-
total_matches:
|
|
13555
|
-
returned_tools:
|
|
13556
|
-
execution_tool:
|
|
13557
|
-
tools:
|
|
14129
|
+
query: z62.string().nullable(),
|
|
14130
|
+
source: z62.string().nullable(),
|
|
14131
|
+
sources: z62.array(searchToolsSourceSchema),
|
|
14132
|
+
total_catalog_tools: z62.number().int().nonnegative(),
|
|
14133
|
+
total_eligible_tools: z62.number().int().nonnegative(),
|
|
14134
|
+
total_matches: z62.number().int().nonnegative(),
|
|
14135
|
+
returned_tools: z62.number().int().nonnegative(),
|
|
14136
|
+
execution_tool: z62.literal("executeTool"),
|
|
14137
|
+
tools: z62.array(searchToolsToolSchema)
|
|
13558
14138
|
}).strict();
|
|
13559
14139
|
function terms(value) {
|
|
13560
14140
|
const chunks = value.match(/[\p{L}\p{N}]+/gu) ?? [];
|
|
@@ -13765,14 +14345,14 @@ function createSearchToolsTool(catalogTools) {
|
|
|
13765
14345
|
openWorldHint: false,
|
|
13766
14346
|
readOnlyHint: true
|
|
13767
14347
|
},
|
|
13768
|
-
inputSchema:
|
|
13769
|
-
query:
|
|
14348
|
+
inputSchema: z62.object({
|
|
14349
|
+
query: z62.string().nullable().describe(
|
|
13770
14350
|
"Optional search terms describing the tool, owner, action, or arguments needed. Empty string lists catalog tools."
|
|
13771
14351
|
).optional(),
|
|
13772
|
-
source:
|
|
14352
|
+
source: z62.string().nullable().describe(
|
|
13773
14353
|
"Optional source id to search within, such as a plugin source returned in sources."
|
|
13774
14354
|
).optional(),
|
|
13775
|
-
max_results:
|
|
14355
|
+
max_results: z62.number().int().min(1).max(MAX_RESULTS3).nullable().describe("Maximum matching catalog tool descriptors to return.").optional()
|
|
13776
14356
|
}).strict(),
|
|
13777
14357
|
outputSchema: searchToolsOutputSchema,
|
|
13778
14358
|
privateTraceResult: (result) => ({
|
|
@@ -15014,7 +15594,7 @@ function createPluginEgress(deps) {
|
|
|
15014
15594
|
}
|
|
15015
15595
|
|
|
15016
15596
|
// src/chat/services/guardian-action-review.ts
|
|
15017
|
-
import { z as
|
|
15597
|
+
import { z as z63 } from "zod";
|
|
15018
15598
|
|
|
15019
15599
|
// src/chat/services/guardian-action-policy.ts
|
|
15020
15600
|
var GUARDIAN_ACTION_POLICY = `You are judging one planned Junior agent action.
|
|
@@ -15082,17 +15662,17 @@ Assess the exact action's intrinsic risk and whether the user's intent authorize
|
|
|
15082
15662
|
- 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.`;
|
|
15083
15663
|
|
|
15084
15664
|
// src/chat/services/guardian-action-review.ts
|
|
15085
|
-
var guardianDecisionSchema =
|
|
15086
|
-
decision:
|
|
15087
|
-
reason:
|
|
15088
|
-
riskLevel:
|
|
15089
|
-
userAuthorization:
|
|
15665
|
+
var guardianDecisionSchema = z63.object({
|
|
15666
|
+
decision: z63.enum(["allow", "ask", "deny"]),
|
|
15667
|
+
reason: z63.string().trim().min(1).max(500),
|
|
15668
|
+
riskLevel: z63.enum(["low", "medium", "high", "critical"]),
|
|
15669
|
+
userAuthorization: z63.enum(["high", "medium", "low", "unknown"])
|
|
15090
15670
|
}).strict();
|
|
15091
15671
|
var GUARDIAN_REVIEW_TIMEOUT_MS = 6e4;
|
|
15092
15672
|
var GUARDIAN_REVIEW_MAX_TOKENS = 2e3;
|
|
15093
15673
|
var MAX_PROPOSAL_CHARS = 192e3;
|
|
15094
15674
|
function guardianPrompt(proposal) {
|
|
15095
|
-
const proposalJson = JSON.stringify(
|
|
15675
|
+
const proposalJson = JSON.stringify(z63.json().parse(proposal), null, 2);
|
|
15096
15676
|
if (proposalJson.length > MAX_PROPOSAL_CHARS) {
|
|
15097
15677
|
throw new Error(
|
|
15098
15678
|
`Guardian action proposal exceeds ${MAX_PROPOSAL_CHARS} characters.`
|
|
@@ -15337,6 +15917,38 @@ async function tryRecordSkillLoadStat(skill) {
|
|
|
15337
15917
|
});
|
|
15338
15918
|
}
|
|
15339
15919
|
}
|
|
15920
|
+
function resolveToolRuntimeRoute(args) {
|
|
15921
|
+
const destination = toolInvocationDestination(args.routing);
|
|
15922
|
+
switch (args.routing.source.platform) {
|
|
15923
|
+
case "slack": {
|
|
15924
|
+
if (destination.platform !== "slack") {
|
|
15925
|
+
throw new TypeError("Slack tool runtime requires a Slack destination");
|
|
15926
|
+
}
|
|
15927
|
+
return {
|
|
15928
|
+
destination,
|
|
15929
|
+
actor: args.actor?.platform === "slack" ? args.actor : void 0,
|
|
15930
|
+
source: args.routing.source,
|
|
15931
|
+
slackActionToken: args.routing.slackActionToken
|
|
15932
|
+
};
|
|
15933
|
+
}
|
|
15934
|
+
case "local": {
|
|
15935
|
+
if (destination.platform !== "local") {
|
|
15936
|
+
throw new TypeError("Local tool runtime requires a local destination");
|
|
15937
|
+
}
|
|
15938
|
+
return {
|
|
15939
|
+
destination,
|
|
15940
|
+
actor: args.actor?.platform === "local" ? args.actor : void 0,
|
|
15941
|
+
source: args.routing.source
|
|
15942
|
+
};
|
|
15943
|
+
}
|
|
15944
|
+
case "web":
|
|
15945
|
+
return {
|
|
15946
|
+
destination,
|
|
15947
|
+
actor: args.actor?.platform === "web" ? args.actor : void 0,
|
|
15948
|
+
source: args.routing.source
|
|
15949
|
+
};
|
|
15950
|
+
}
|
|
15951
|
+
}
|
|
15340
15952
|
async function wireAgentTools(args) {
|
|
15341
15953
|
const runSource = args.routing.source;
|
|
15342
15954
|
const credentialUserId = args.routing.credentialContext ? credentialUserSubjectId(args.routing.credentialContext) : void 0;
|
|
@@ -15453,36 +16065,20 @@ async function wireAgentTools(args) {
|
|
|
15453
16065
|
...args.durability.spawnAgent ? { spawnAgent: args.durability.spawnAgent } : {},
|
|
15454
16066
|
...args.requestHandoff ? { handoff: args.requestHandoff } : {}
|
|
15455
16067
|
};
|
|
15456
|
-
const
|
|
15457
|
-
|
|
15458
|
-
|
|
15459
|
-
|
|
15460
|
-
|
|
15461
|
-
|
|
15462
|
-
|
|
15463
|
-
|
|
15464
|
-
destination: toolDestination,
|
|
15465
|
-
actor: args.currentActor?.platform === "slack" ? args.currentActor : void 0,
|
|
15466
|
-
source: runSource,
|
|
15467
|
-
slackActionToken: args.routing.slackActionToken
|
|
15468
|
-
};
|
|
15469
|
-
} else {
|
|
15470
|
-
if (toolDestination.platform !== "local") {
|
|
15471
|
-
throw new TypeError("Local tool runtime requires a local destination");
|
|
15472
|
-
}
|
|
15473
|
-
toolRuntimeContext = {
|
|
15474
|
-
...commonToolRuntimeContext,
|
|
15475
|
-
destination: toolDestination,
|
|
15476
|
-
actor: args.currentActor?.platform === "local" ? args.currentActor : void 0,
|
|
15477
|
-
source: runSource
|
|
15478
|
-
};
|
|
15479
|
-
}
|
|
16068
|
+
const toolRoute = resolveToolRuntimeRoute({
|
|
16069
|
+
actor: args.currentActor,
|
|
16070
|
+
routing: args.routing
|
|
16071
|
+
});
|
|
16072
|
+
const toolRuntimeContext = {
|
|
16073
|
+
...commonToolRuntimeContext,
|
|
16074
|
+
...toolRoute
|
|
16075
|
+
};
|
|
15480
16076
|
const actionReview = createToolActionReview({
|
|
15481
16077
|
context: {
|
|
15482
16078
|
actor: args.currentActor,
|
|
15483
16079
|
conversationId: args.conversationId,
|
|
15484
16080
|
credentialContext: args.routing.credentialContext,
|
|
15485
|
-
destination:
|
|
16081
|
+
destination: toolRoute.destination,
|
|
15486
16082
|
source: runSource,
|
|
15487
16083
|
userIntent: args.currentUserIntent,
|
|
15488
16084
|
evidence: () => buildToolActionEvidence(args.currentAgentMessages())
|
|
@@ -15688,6 +16284,7 @@ function createResumeState(args) {
|
|
|
15688
16284
|
destination: args.destination,
|
|
15689
16285
|
destinationVisibility: args.destinationVisibility,
|
|
15690
16286
|
dispatchId: args.dispatchId,
|
|
16287
|
+
publishExternally: args.publishExternally,
|
|
15691
16288
|
source: args.runSource,
|
|
15692
16289
|
actor: args.actor,
|
|
15693
16290
|
surface: args.surface
|
|
@@ -16496,6 +17093,12 @@ async function executeAgentRunInPrivacyContext(request, conversationPrivacy, run
|
|
|
16496
17093
|
let connectedMcpProviders = /* @__PURE__ */ new Set();
|
|
16497
17094
|
let turnUsage;
|
|
16498
17095
|
let priorPhaseUsage;
|
|
17096
|
+
let agent;
|
|
17097
|
+
let acceptedToolFreeAssistant = false;
|
|
17098
|
+
const generatedFiles = [];
|
|
17099
|
+
const toolCalls = [];
|
|
17100
|
+
let shouldTrace = false;
|
|
17101
|
+
let getSandboxRef;
|
|
16499
17102
|
const configuredReasoningLevel = policy.reasoningLevel ?? botConfig.reasoningLevel;
|
|
16500
17103
|
let turnRoute = configuredReasoningLevel ? configuredTurnRoute(
|
|
16501
17104
|
STANDARD_MODEL_PROFILE,
|
|
@@ -16534,7 +17137,7 @@ async function executeAgentRunInPrivacyContext(request, conversationPrivacy, run
|
|
|
16534
17137
|
activeModelProfile = projection.modelProfile;
|
|
16535
17138
|
activeModelId = modelIdForProfile(botConfig, activeModelProfile);
|
|
16536
17139
|
let durableModelProfile = projection.modelProfile;
|
|
16537
|
-
|
|
17140
|
+
shouldTrace = shouldEmitDevAgentTrace();
|
|
16538
17141
|
const spanContext = { modelId: activeModelId };
|
|
16539
17142
|
const availableSkills = await discoverRunSkills({
|
|
16540
17143
|
skillDirs: policy.skillDirs
|
|
@@ -16591,6 +17194,7 @@ async function executeAgentRunInPrivacyContext(request, conversationPrivacy, run
|
|
|
16591
17194
|
...routing.dispatch?.id ? { dispatchId: routing.dispatch.id } : {},
|
|
16592
17195
|
durability,
|
|
16593
17196
|
recordActiveMcpProviders,
|
|
17197
|
+
publishExternally: checkpoint.record?.publishExternally ?? routing.publishExternally ?? false,
|
|
16594
17198
|
actor,
|
|
16595
17199
|
runSource,
|
|
16596
17200
|
conversationId,
|
|
@@ -16716,9 +17320,6 @@ async function executeAgentRunInPrivacyContext(request, conversationPrivacy, run
|
|
|
16716
17320
|
}
|
|
16717
17321
|
activeModelProfile = routedModelProfile;
|
|
16718
17322
|
activeModelId = routedModelId;
|
|
16719
|
-
const generatedFiles = [];
|
|
16720
|
-
const toolCalls = [];
|
|
16721
|
-
let agent;
|
|
16722
17323
|
let pendingPiHookError;
|
|
16723
17324
|
let pendingHandoff;
|
|
16724
17325
|
const currentAgentMessages = () => agent ? [...agent.state.messages] : [];
|
|
@@ -16857,6 +17458,7 @@ async function executeAgentRunInPrivacyContext(request, conversationPrivacy, run
|
|
|
16857
17458
|
});
|
|
16858
17459
|
mcpToolManager = wiring.mcpToolManager;
|
|
16859
17460
|
closeTools = wiring.close;
|
|
17461
|
+
getSandboxRef = () => wiring.getSandboxRef();
|
|
16860
17462
|
const initialRepositoryInstructions = wiring.getSandboxRef() ? await wiring.captureRepositoryInstructions() : void 0;
|
|
16861
17463
|
const recordAgentsTransition = async (instructions) => {
|
|
16862
17464
|
try {
|
|
@@ -17038,6 +17640,7 @@ async function executeAgentRunInPrivacyContext(request, conversationPrivacy, run
|
|
|
17038
17640
|
}
|
|
17039
17641
|
try {
|
|
17040
17642
|
await delivery(message);
|
|
17643
|
+
acceptedToolFreeAssistant = true;
|
|
17041
17644
|
} catch (error) {
|
|
17042
17645
|
assistantMessageDeliveryError = new AssistantMessageDeliveryError(
|
|
17043
17646
|
error
|
|
@@ -17521,6 +18124,27 @@ async function executeAgentRunInPrivacyContext(request, conversationPrivacy, run
|
|
|
17521
18124
|
if (resume && runError instanceof AuthorizationPauseError) {
|
|
17522
18125
|
return await resume.parkForAuth(runError, turnUsage);
|
|
17523
18126
|
}
|
|
18127
|
+
if (resume?.timedOut && acceptedToolFreeAssistant && agent && turnRoute) {
|
|
18128
|
+
await recordActiveMcpProviders();
|
|
18129
|
+
const piMessages = [...agent.state.messages];
|
|
18130
|
+
return {
|
|
18131
|
+
status: "completed",
|
|
18132
|
+
result: buildTurnResult({
|
|
18133
|
+
newMessages: piMessages.slice(resume.beforeMessageCount),
|
|
18134
|
+
userInput,
|
|
18135
|
+
toolCalls,
|
|
18136
|
+
sandboxRef: getSandboxRef?.() ?? lastKnownSandboxRef,
|
|
18137
|
+
piMessages,
|
|
18138
|
+
durationMs: Date.now() - replyStartedAtMs,
|
|
18139
|
+
generatedFileCount: generatedFiles.length,
|
|
18140
|
+
shouldTrace,
|
|
18141
|
+
usage: turnUsage,
|
|
18142
|
+
executionProfile: turnRoute,
|
|
18143
|
+
assistantUserName: botConfig.userName,
|
|
18144
|
+
modelId: activeModelId
|
|
18145
|
+
})
|
|
18146
|
+
};
|
|
18147
|
+
}
|
|
17524
18148
|
if (resume) {
|
|
17525
18149
|
const outcome = await resume.translateSuspension({
|
|
17526
18150
|
currentUsage: turnUsage,
|