@sentry/junior 0.145.0 → 0.146.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-L7D2BDVV.js → agent-hooks-SLJADYE5.js} +10 -10
- package/dist/api.js +19 -19
- package/dist/app.js +97 -84
- package/dist/{catalog-runtime-QLAC4Q3W.js → catalog-runtime-RQIMSDPR.js} +5 -5
- package/dist/chat/agent/resume.d.ts +0 -3
- package/dist/chat/agent/skills.d.ts +0 -1
- package/dist/chat/agent/tools.d.ts +0 -1
- package/dist/chat/conversations/message-search.d.ts +32 -0
- package/dist/chat/conversations/sql/message-search.d.ts +4 -0
- package/dist/chat/conversations/tool-source.d.ts +5 -0
- package/dist/chat/db.d.ts +2 -2
- package/dist/chat/slack/message/attachments.d.ts +2 -0
- package/dist/chat/slack/message/blocks.d.ts +2 -0
- package/dist/chat/slack/message/content.d.ts +18 -0
- package/dist/chat/slack/message/identity.d.ts +7 -0
- package/dist/chat/slack/tools/{conversation-search.d.ts → conversation-message-search.d.ts} +21 -14
- package/dist/chat/slack/tools/user-lookup.d.ts +2 -1
- package/dist/chat/task-execution/checkpoint.d.ts +1 -3
- package/dist/chat/task-execution/turn-cursor.d.ts +0 -9
- package/dist/chat/tools/{query-conversation-events.d.ts → search-conversation-events.d.ts} +3 -3
- package/dist/{chunk-2UH3JI64.js → chunk-37EVZP66.js} +41 -29
- package/dist/{chunk-CD2XFGYQ.js → chunk-37JJDS4H.js} +1 -1
- package/dist/{chunk-I47UGQPJ.js → chunk-47OSH2ZO.js} +7 -7
- package/dist/{chunk-RUSS62EN.js → chunk-AISNSNDV.js} +3 -3
- package/dist/{chunk-2LWPFSB4.js → chunk-B63BF443.js} +1 -1
- package/dist/{chunk-64SBYW2O.js → chunk-BLETMLRX.js} +455 -162
- package/dist/{chunk-GDV5LXRA.js → chunk-F7REGDKO.js} +1 -1
- package/dist/{chunk-B46ZMVOV.js → chunk-FEKQHPVA.js} +5 -5
- package/dist/{chunk-5PNPQYTO.js → chunk-FGHADGIC.js} +2 -2
- package/dist/{chunk-GUWLDMGF.js → chunk-FXDDDSPL.js} +4 -4
- package/dist/{chunk-ZIAMN2UW.js → chunk-GDQEU4I7.js} +16 -28
- package/dist/{chunk-QUG4JSZK.js → chunk-GYEKOX7N.js} +1 -1
- package/dist/{chunk-QJBDABQA.js → chunk-H6U2U3EP.js} +10 -10
- package/dist/{chunk-DS3J6WGY.js → chunk-HQE6EJS5.js} +1 -1
- package/dist/{chunk-HISR3DTV.js → chunk-JUA6VU2Z.js} +5 -7
- package/dist/{chunk-PJ4NMVQB.js → chunk-LVW7BLLT.js} +2 -2
- package/dist/{chunk-LVVSIMBB.js → chunk-M6ZWP4RI.js} +1 -1
- package/dist/{chunk-27TEJTZO.js → chunk-MCFIXAV5.js} +1 -1
- package/dist/{chunk-XFKIRN3Q.js → chunk-MKRIZ4VG.js} +2 -3
- package/dist/{chunk-2XET6PKP.js → chunk-OFPYOC3M.js} +15 -16
- package/dist/{chunk-SIN3MXH6.js → chunk-PB222GIA.js} +1 -1
- package/dist/{chunk-DXEQAIUV.js → chunk-PH4Q3A6W.js} +1 -1
- package/dist/{chunk-JTGS3ZZE.js → chunk-QG7OOKIN.js} +1 -1
- package/dist/{chunk-EIX2LQ6L.js → chunk-QSXZ42KX.js} +3 -3
- package/dist/{chunk-ZIMRGFYL.js → chunk-SCGVWUZX.js} +6 -6
- package/dist/{chunk-VTDMB7XX.js → chunk-T5GXFFLA.js} +1 -1
- package/dist/{chunk-WF5HVH3M.js → chunk-TCEJ7XXM.js} +1 -1
- package/dist/{chunk-TZRXYWRE.js → chunk-V6SRLKUB.js} +2 -2
- package/dist/{chunk-ZYAJMESY.js → chunk-W65V465O.js} +2 -2
- package/dist/{chunk-YD54Q45G.js → chunk-X22KCSCO.js} +4 -4
- package/dist/{chunk-HLOUZC5C.js → chunk-X2WMBTS3.js} +4 -4
- package/dist/{chunk-FUBRJA5F.js → chunk-ZDGHGY74.js} +6 -6
- package/dist/cli/chat.js +32 -32
- 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-62PW6LM3.js → db-WWOMXWTT.js} +9 -9
- package/dist/instrumentation.js +4 -4
- package/dist/nitro.js +2 -2
- package/dist/{oauth-callback-server-6NZNHJAM.js → oauth-callback-server-A6ZZX74U.js} +23 -23
- package/dist/{runner-GCRPG3GQ.js → runner-KSGB2UAV.js} +15 -17
- package/dist/{skills-2S3MDFIQ.js → skills-26QPWKVS.js} +6 -6
- package/dist/{spawn-7WK37BTD.js → spawn-5LAJXZ2P.js} +17 -17
- package/dist/{validation-HAOLCJ5A.js → validation-OPSRGFGH.js} +6 -6
- package/dist/version.js +1 -1
- package/dist/{work-R4XYKMUW.js → work-VMSW7STJ.js} +16 -16
- package/dist/{worker-U2UCVR7M.js → worker-2JNFB7C7.js} +10 -10
- package/package.json +5 -5
- package/dist/chat/conversations/search.d.ts +0 -24
- package/dist/chat/conversations/sql/search.d.ts +0 -4
- package/dist/chat/slack/legacy-attachments.d.ts +0 -4
- package/dist/chat/slack/message.d.ts +0 -12
|
@@ -7,7 +7,7 @@ import {
|
|
|
7
7
|
PluginCredentialFailureError,
|
|
8
8
|
agentNameSchema,
|
|
9
9
|
createPluginAuthOrchestration
|
|
10
|
-
} from "./chunk-
|
|
10
|
+
} from "./chunk-FEKQHPVA.js";
|
|
11
11
|
import {
|
|
12
12
|
authorizationId
|
|
13
13
|
} from "./chunk-DIB4GX3G.js";
|
|
@@ -28,7 +28,7 @@ import {
|
|
|
28
28
|
patchMcpAuthSession,
|
|
29
29
|
selectPluginGrant,
|
|
30
30
|
toMcpProviderError
|
|
31
|
-
} from "./chunk-
|
|
31
|
+
} from "./chunk-47OSH2ZO.js";
|
|
32
32
|
import {
|
|
33
33
|
RetryableDeliveryError,
|
|
34
34
|
actorFromRouting,
|
|
@@ -44,12 +44,12 @@ import {
|
|
|
44
44
|
getSlackMessagePermalink,
|
|
45
45
|
resolveBaseUrl,
|
|
46
46
|
uploadFilesToConversation
|
|
47
|
-
} from "./chunk-
|
|
47
|
+
} from "./chunk-ZDGHGY74.js";
|
|
48
48
|
import {
|
|
49
49
|
estimateTextTokens,
|
|
50
50
|
getAgentContextCompactionTriggerTokens,
|
|
51
51
|
getAgentContextInputLimitTokens
|
|
52
|
-
} from "./chunk-
|
|
52
|
+
} from "./chunk-T5GXFFLA.js";
|
|
53
53
|
import {
|
|
54
54
|
AGENTS_REMOVAL_NOTICE,
|
|
55
55
|
AGENTS_REPLACEMENT_NOTICE,
|
|
@@ -111,7 +111,7 @@ import {
|
|
|
111
111
|
stripRuntimeTurnContext,
|
|
112
112
|
trimTrailingAssistantMessages,
|
|
113
113
|
truncateText
|
|
114
|
-
} from "./chunk-
|
|
114
|
+
} from "./chunk-GDQEU4I7.js";
|
|
115
115
|
import {
|
|
116
116
|
JUNIOR_THREAD_STATE_TTL_MS
|
|
117
117
|
} from "./chunk-3Y47VMHV.js";
|
|
@@ -143,7 +143,7 @@ import {
|
|
|
143
143
|
runNonInteractiveCommand,
|
|
144
144
|
throwSandboxOperationError,
|
|
145
145
|
wrapSandboxSetupError
|
|
146
|
-
} from "./chunk-
|
|
146
|
+
} from "./chunk-FXDDDSPL.js";
|
|
147
147
|
import {
|
|
148
148
|
SCHEDULED_TASK_SYSTEM_ACTOR,
|
|
149
149
|
compactEventTask,
|
|
@@ -175,15 +175,15 @@ import {
|
|
|
175
175
|
saveEventTask,
|
|
176
176
|
scheduledTaskAttributes,
|
|
177
177
|
writableEventTask
|
|
178
|
-
} from "./chunk-
|
|
178
|
+
} from "./chunk-X22KCSCO.js";
|
|
179
179
|
import {
|
|
180
180
|
parseSlackThreadId
|
|
181
|
-
} from "./chunk-
|
|
181
|
+
} from "./chunk-PH4Q3A6W.js";
|
|
182
182
|
import {
|
|
183
183
|
SHORT_TITLE_MAX_LENGTH,
|
|
184
184
|
generateShortTitle,
|
|
185
185
|
resolveTaskTitle
|
|
186
|
-
} from "./chunk-
|
|
186
|
+
} from "./chunk-W65V465O.js";
|
|
187
187
|
import {
|
|
188
188
|
ToolInputError,
|
|
189
189
|
addAgentTurnUsage,
|
|
@@ -201,7 +201,7 @@ import {
|
|
|
201
201
|
getSlackToolContext,
|
|
202
202
|
readActorIdentity,
|
|
203
203
|
resolveChannelCapabilities
|
|
204
|
-
} from "./chunk-
|
|
204
|
+
} from "./chunk-SCGVWUZX.js";
|
|
205
205
|
import {
|
|
206
206
|
SlackActionError,
|
|
207
207
|
downloadPrivateSlackFile,
|
|
@@ -210,18 +210,23 @@ import {
|
|
|
210
210
|
isConversationScopedChannel,
|
|
211
211
|
normalizeSlackConversationId,
|
|
212
212
|
withSlackRetries
|
|
213
|
-
} from "./chunk-
|
|
213
|
+
} from "./chunk-V6SRLKUB.js";
|
|
214
214
|
import {
|
|
215
215
|
KNOWN_CONVERSATION_EVENT_TYPES,
|
|
216
216
|
contextProvenance,
|
|
217
217
|
getConversationEventStore,
|
|
218
|
-
|
|
218
|
+
getConversationMessageSearchStore,
|
|
219
219
|
getConversationStore,
|
|
220
220
|
getDb,
|
|
221
|
+
getSqlExecutor,
|
|
221
222
|
instructionActors,
|
|
222
223
|
instructionProvenanceFor,
|
|
223
|
-
sameActorIdentity
|
|
224
|
-
|
|
224
|
+
sameActorIdentity,
|
|
225
|
+
upsertIdentity
|
|
226
|
+
} from "./chunk-37EVZP66.js";
|
|
227
|
+
import {
|
|
228
|
+
juniorIdentities
|
|
229
|
+
} from "./chunk-MCFIXAV5.js";
|
|
225
230
|
import {
|
|
226
231
|
SANDBOX_DATA_ROOT,
|
|
227
232
|
SANDBOX_SKILLS_ROOT,
|
|
@@ -233,7 +238,7 @@ import {
|
|
|
233
238
|
} from "./chunk-EM225ITJ.js";
|
|
234
239
|
import {
|
|
235
240
|
getStateAdapter
|
|
236
|
-
} from "./chunk-
|
|
241
|
+
} from "./chunk-GYEKOX7N.js";
|
|
237
242
|
import {
|
|
238
243
|
ACTIVE_TURN_COMPACTION_SUMMARY_PREFIX,
|
|
239
244
|
COMPACTION_SUMMARY_PREFIX,
|
|
@@ -261,13 +266,12 @@ import {
|
|
|
261
266
|
modelIdForProfile,
|
|
262
267
|
modelProfileSchema,
|
|
263
268
|
normalizeSlackEmojiName,
|
|
264
|
-
parseTurnReasoningLevel,
|
|
265
269
|
profileConfig,
|
|
266
270
|
renderCurrentInstruction,
|
|
267
271
|
resolveGatewayCredential,
|
|
268
272
|
resolveGatewayModel,
|
|
269
273
|
unwrapCurrentInstruction
|
|
270
|
-
} from "./chunk-
|
|
274
|
+
} from "./chunk-MKRIZ4VG.js";
|
|
271
275
|
import {
|
|
272
276
|
canExposeConversationPayload,
|
|
273
277
|
resolveConversationPrivacy,
|
|
@@ -277,16 +281,16 @@ import {
|
|
|
277
281
|
toGenAiMessagesTraceAttributes,
|
|
278
282
|
toGenAiPayloadMetadata,
|
|
279
283
|
toGenAiPayloadTraceAttributes
|
|
280
|
-
} from "./chunk-
|
|
284
|
+
} from "./chunk-QG7OOKIN.js";
|
|
281
285
|
import {
|
|
282
286
|
discoverSkills,
|
|
283
287
|
findSkillByName,
|
|
284
288
|
loadSkillsByName,
|
|
285
289
|
parseSkillInvocation
|
|
286
|
-
} from "./chunk-
|
|
290
|
+
} from "./chunk-FGHADGIC.js";
|
|
287
291
|
import {
|
|
288
292
|
pluginCatalogRuntime
|
|
289
|
-
} from "./chunk-
|
|
293
|
+
} from "./chunk-PB222GIA.js";
|
|
290
294
|
import {
|
|
291
295
|
CredentialUnavailableError,
|
|
292
296
|
OAuthProviderError,
|
|
@@ -294,7 +298,7 @@ import {
|
|
|
294
298
|
getOAuthProviderErrorAttributes,
|
|
295
299
|
resolveAuthTokenPlaceholder,
|
|
296
300
|
resolvePluginCommandEnv
|
|
297
|
-
} from "./chunk-
|
|
301
|
+
} from "./chunk-37JJDS4H.js";
|
|
298
302
|
import {
|
|
299
303
|
credentialUserSubjectId
|
|
300
304
|
} from "./chunk-RUIXF3YQ.js";
|
|
@@ -316,6 +320,7 @@ import {
|
|
|
316
320
|
logInfo,
|
|
317
321
|
logWarn,
|
|
318
322
|
normalizeGenAiFinishReason,
|
|
323
|
+
normalizeIdentityEmail,
|
|
319
324
|
serializeGenAiAttribute,
|
|
320
325
|
setSpanAttributes,
|
|
321
326
|
setSpanStatus,
|
|
@@ -323,7 +328,7 @@ import {
|
|
|
323
328
|
summarizeMessageText,
|
|
324
329
|
withLogContext,
|
|
325
330
|
withSpan
|
|
326
|
-
} from "./chunk-
|
|
331
|
+
} from "./chunk-B63BF443.js";
|
|
327
332
|
import {
|
|
328
333
|
startInactiveSpan,
|
|
329
334
|
withActiveSpan
|
|
@@ -1573,7 +1578,6 @@ async function restoreSkillRuntime(args) {
|
|
|
1573
1578
|
const restoredSkill = await args.skillSandbox.loadSkill(skillName);
|
|
1574
1579
|
if (restoredSkill) {
|
|
1575
1580
|
upsertActiveSkill(args.activeSkills, restoredSkill);
|
|
1576
|
-
args.syncLoadedSkillNamesForResume();
|
|
1577
1581
|
}
|
|
1578
1582
|
}
|
|
1579
1583
|
if (args.invokedSkill) {
|
|
@@ -1582,7 +1586,6 @@ async function restoreSkillRuntime(args) {
|
|
|
1582
1586
|
);
|
|
1583
1587
|
if (restoredSkill) {
|
|
1584
1588
|
upsertActiveSkill(args.activeSkills, restoredSkill);
|
|
1585
|
-
args.syncLoadedSkillNamesForResume();
|
|
1586
1589
|
}
|
|
1587
1590
|
}
|
|
1588
1591
|
}
|
|
@@ -8132,7 +8135,7 @@ function createSearchResourceEventTypesTool(catalog) {
|
|
|
8132
8135
|
outputSchema: outputSchema2,
|
|
8133
8136
|
async execute({ query, namespace, maxResults }) {
|
|
8134
8137
|
const normalizedQuery = normalizeSearchText(query ?? "");
|
|
8135
|
-
const
|
|
8138
|
+
const terms2 = normalizedQuery.split(/\s+/).filter(Boolean);
|
|
8136
8139
|
const matches = searchableResourceTypes(catalog).filter(
|
|
8137
8140
|
(resourceType) => {
|
|
8138
8141
|
if (namespace && resourceType.namespace !== namespace) return false;
|
|
@@ -8144,7 +8147,7 @@ function createSearchResourceEventTypesTool(catalog) {
|
|
|
8144
8147
|
...resourceType.suggestedEvents ?? []
|
|
8145
8148
|
].join(" ")
|
|
8146
8149
|
);
|
|
8147
|
-
return
|
|
8150
|
+
return terms2.every((term) => text.includes(term));
|
|
8148
8151
|
}
|
|
8149
8152
|
);
|
|
8150
8153
|
const resourceTypes = matches.slice(
|
|
@@ -9816,32 +9819,63 @@ function createSlackChannelListMessagesTool(context) {
|
|
|
9816
9819
|
});
|
|
9817
9820
|
}
|
|
9818
9821
|
|
|
9819
|
-
// src/chat/slack/tools/conversation-search.ts
|
|
9822
|
+
// src/chat/slack/tools/conversation-message-search.ts
|
|
9820
9823
|
import { z as z37 } from "zod";
|
|
9824
|
+
|
|
9825
|
+
// src/chat/conversations/tool-source.ts
|
|
9826
|
+
var CONVERSATIONS_TOOL_SOURCE = {
|
|
9827
|
+
id: "conversations",
|
|
9828
|
+
description: "Search messages and events in retained Junior conversations."
|
|
9829
|
+
};
|
|
9830
|
+
|
|
9831
|
+
// src/chat/slack/tools/conversation-message-search.ts
|
|
9821
9832
|
var DEFAULT_LIMIT = 5;
|
|
9822
|
-
var
|
|
9823
|
-
|
|
9833
|
+
var conversationMessageSearchOutputSchema = juniorToolOutputSchema.extend({
|
|
9834
|
+
channel_id: z37.string().min(1).optional(),
|
|
9824
9835
|
count: z37.number().int().nonnegative(),
|
|
9825
|
-
|
|
9836
|
+
query: z37.string().optional(),
|
|
9837
|
+
matches: z37.array(
|
|
9826
9838
|
z37.object({
|
|
9839
|
+
channel_id: z37.string().min(1),
|
|
9840
|
+
channel_name: z37.string().min(1).optional(),
|
|
9827
9841
|
conversation_id: z37.string().min(1),
|
|
9828
|
-
|
|
9842
|
+
excerpt: z37.string(),
|
|
9829
9843
|
message_id: z37.string().min(1),
|
|
9830
9844
|
message_role: z37.enum(["assistant", "user"]),
|
|
9831
9845
|
message_timestamp: z37.string().datetime(),
|
|
9832
|
-
|
|
9833
|
-
|
|
9846
|
+
permalink: z37.string().url().optional(),
|
|
9847
|
+
thread_ts: z37.string().min(1)
|
|
9834
9848
|
}).strict()
|
|
9835
9849
|
)
|
|
9836
9850
|
});
|
|
9837
|
-
function
|
|
9851
|
+
function resolveSearchFilters(input) {
|
|
9852
|
+
const query = input.query?.trim() || void 0;
|
|
9853
|
+
let channelId;
|
|
9854
|
+
if (input.channel_id != null) {
|
|
9855
|
+
const parsed = parseRequiredSlackChannelIdParam(
|
|
9856
|
+
"channel_id",
|
|
9857
|
+
input.channel_id
|
|
9858
|
+
);
|
|
9859
|
+
if (!parsed.ok) {
|
|
9860
|
+
throw new ToolInputError(parsed.error);
|
|
9861
|
+
}
|
|
9862
|
+
channelId = parsed.value;
|
|
9863
|
+
}
|
|
9864
|
+
if (!query && !channelId) {
|
|
9865
|
+
throw new ToolInputError(
|
|
9866
|
+
"Provide at least one of `query` or `channel_id`."
|
|
9867
|
+
);
|
|
9868
|
+
}
|
|
9869
|
+
return {
|
|
9870
|
+
...channelId ? { channelId } : {},
|
|
9871
|
+
...query ? { query } : {}
|
|
9872
|
+
};
|
|
9873
|
+
}
|
|
9874
|
+
function createSlackConversationMessageSearchTool(scope, currentConversationId, deps = {}) {
|
|
9838
9875
|
return zodTool({
|
|
9839
|
-
description: "Search
|
|
9876
|
+
description: "Search retained user and assistant messages in public Junior conversations across the current Slack workspace. Excludes the current conversation.",
|
|
9840
9877
|
exposure: "deferred",
|
|
9841
|
-
source:
|
|
9842
|
-
id: "conversation-history",
|
|
9843
|
-
description: "Search retained public Junior conversation threads in the current Slack workspace."
|
|
9844
|
-
},
|
|
9878
|
+
source: CONVERSATIONS_TOOL_SOURCE,
|
|
9845
9879
|
annotations: {
|
|
9846
9880
|
destructiveHint: false,
|
|
9847
9881
|
idempotentHint: true,
|
|
@@ -9849,20 +9883,24 @@ function createSlackConversationSearchTool(scope, currentConversationId, deps =
|
|
|
9849
9883
|
readOnlyHint: true
|
|
9850
9884
|
},
|
|
9851
9885
|
inputSchema: z37.object({
|
|
9852
|
-
|
|
9853
|
-
|
|
9854
|
-
|
|
9855
|
-
|
|
9856
|
-
|
|
9857
|
-
|
|
9886
|
+
channel_id: slackChannelIdParam(
|
|
9887
|
+
"Destination Slack channel ID; no active-channel default."
|
|
9888
|
+
).nullable().optional(),
|
|
9889
|
+
query: z37.string().trim().min(1).max(200).nullable().describe("Words or phrase to match in message text.").optional(),
|
|
9890
|
+
limit: z37.number().int().min(1).max(10).describe(`Maximum matches. Default ${DEFAULT_LIMIT}; max 10.`).nullable().optional()
|
|
9891
|
+
}).strict(),
|
|
9892
|
+
outputSchema: conversationMessageSearchOutputSchema,
|
|
9893
|
+
execute: async (input) => {
|
|
9894
|
+
const filters = resolveSearchFilters(input);
|
|
9895
|
+
const store = deps.store ?? getConversationMessageSearchStore();
|
|
9858
9896
|
const matches = await store.search({
|
|
9859
9897
|
currentConversationId,
|
|
9860
|
-
|
|
9861
|
-
|
|
9898
|
+
filters,
|
|
9899
|
+
limit: input.limit ?? DEFAULT_LIMIT,
|
|
9862
9900
|
scope
|
|
9863
9901
|
});
|
|
9864
9902
|
const getPermalink = deps.getPermalink ?? getSlackMessagePermalink;
|
|
9865
|
-
const
|
|
9903
|
+
const matchesOutput = await Promise.all(
|
|
9866
9904
|
matches.map(async (match) => {
|
|
9867
9905
|
const reference = parseSlackThreadId(match.conversationId);
|
|
9868
9906
|
if (!reference || reference.channelId !== match.providerDestinationId) {
|
|
@@ -9881,14 +9919,17 @@ function createSlackConversationSearchTool(scope, currentConversationId, deps =
|
|
|
9881
9919
|
message_role: match.role,
|
|
9882
9920
|
message_timestamp: new Date(match.messageCreatedAtMs).toISOString(),
|
|
9883
9921
|
excerpt: match.excerpt,
|
|
9922
|
+
channel_id: match.providerDestinationId,
|
|
9923
|
+
...match.channelName ? { channel_name: match.channelName } : {},
|
|
9884
9924
|
...permalink ? { permalink } : {}
|
|
9885
9925
|
};
|
|
9886
9926
|
})
|
|
9887
9927
|
);
|
|
9888
9928
|
return {
|
|
9889
|
-
query,
|
|
9890
|
-
|
|
9891
|
-
|
|
9929
|
+
...filters.query ? { query: filters.query } : {},
|
|
9930
|
+
...filters.channelId ? { channel_id: filters.channelId } : {},
|
|
9931
|
+
count: matchesOutput.length,
|
|
9932
|
+
matches: matchesOutput
|
|
9892
9933
|
};
|
|
9893
9934
|
}
|
|
9894
9935
|
});
|
|
@@ -11294,7 +11335,100 @@ function parseSlackMessageReference(input) {
|
|
|
11294
11335
|
};
|
|
11295
11336
|
}
|
|
11296
11337
|
|
|
11297
|
-
// src/chat/slack/
|
|
11338
|
+
// src/chat/slack/message/blocks.ts
|
|
11339
|
+
var MAX_BLOCKS = 50;
|
|
11340
|
+
var MAX_CHILDREN = 50;
|
|
11341
|
+
var MAX_DEPTH = 16;
|
|
11342
|
+
var MAX_NODES = 5e3;
|
|
11343
|
+
var CHILD_KEYS = [
|
|
11344
|
+
"blocks",
|
|
11345
|
+
"elements",
|
|
11346
|
+
"fields",
|
|
11347
|
+
"accessory",
|
|
11348
|
+
"element",
|
|
11349
|
+
"rows",
|
|
11350
|
+
"cells"
|
|
11351
|
+
];
|
|
11352
|
+
function toText(value) {
|
|
11353
|
+
return typeof value === "string" && value.length > 0 ? value : void 0;
|
|
11354
|
+
}
|
|
11355
|
+
function readText(value) {
|
|
11356
|
+
if (typeof value === "string") return toText(value);
|
|
11357
|
+
if (!value || typeof value !== "object") return void 0;
|
|
11358
|
+
return toText(value.text);
|
|
11359
|
+
}
|
|
11360
|
+
function parseChildren(value, budget, depth) {
|
|
11361
|
+
if (Array.isArray(value)) {
|
|
11362
|
+
return value.slice(0, MAX_CHILDREN).flatMap((child) => parseChildren(child, budget, depth));
|
|
11363
|
+
}
|
|
11364
|
+
return parseElement(value, budget, depth);
|
|
11365
|
+
}
|
|
11366
|
+
function parseElement(value, budget, depth) {
|
|
11367
|
+
if (!value || typeof value !== "object" || depth > MAX_DEPTH || budget.remainingNodes <= 0) {
|
|
11368
|
+
return [];
|
|
11369
|
+
}
|
|
11370
|
+
budget.remainingNodes -= 1;
|
|
11371
|
+
const element = value;
|
|
11372
|
+
const type = toText(element.type);
|
|
11373
|
+
const text = readText(element.text);
|
|
11374
|
+
if (type === "link") {
|
|
11375
|
+
const url = toText(element.url);
|
|
11376
|
+
return [
|
|
11377
|
+
text && url && text !== url ? `${text} (${url})` : text || url
|
|
11378
|
+
].filter((part) => Boolean(part));
|
|
11379
|
+
}
|
|
11380
|
+
if (type === "button") {
|
|
11381
|
+
const url = toText(element.url);
|
|
11382
|
+
return [text && url ? `${text} (${url})` : text].filter(
|
|
11383
|
+
(part) => Boolean(part)
|
|
11384
|
+
);
|
|
11385
|
+
}
|
|
11386
|
+
if (type === "emoji") {
|
|
11387
|
+
const name = toText(element.name);
|
|
11388
|
+
return name ? [`:${name}:`] : [];
|
|
11389
|
+
}
|
|
11390
|
+
if (type === "user") {
|
|
11391
|
+
const userId = toText(element.user_id);
|
|
11392
|
+
return userId ? [`<@${userId}>`] : [];
|
|
11393
|
+
}
|
|
11394
|
+
if (type === "channel") {
|
|
11395
|
+
const channelId = toText(element.channel_id);
|
|
11396
|
+
return channelId ? [`<#${channelId}>`] : [];
|
|
11397
|
+
}
|
|
11398
|
+
if (type === "usergroup") {
|
|
11399
|
+
const usergroupId = toText(element.usergroup_id);
|
|
11400
|
+
return usergroupId ? [`<!subteam^${usergroupId}>`] : [];
|
|
11401
|
+
}
|
|
11402
|
+
if (type === "broadcast") {
|
|
11403
|
+
const range = toText(element.range);
|
|
11404
|
+
return range ? [`<!${range}>`] : [];
|
|
11405
|
+
}
|
|
11406
|
+
const parts = [
|
|
11407
|
+
text,
|
|
11408
|
+
readText(element.title),
|
|
11409
|
+
readText(element.description),
|
|
11410
|
+
readText(element.label),
|
|
11411
|
+
readText(element.hint),
|
|
11412
|
+
readText(element.placeholder),
|
|
11413
|
+
toText(element.alt_text),
|
|
11414
|
+
toText(element.provider_name),
|
|
11415
|
+
toText(element.fallback)
|
|
11416
|
+
].filter((part) => Boolean(part));
|
|
11417
|
+
for (const key of CHILD_KEYS) {
|
|
11418
|
+
parts.push(...parseChildren(element[key], budget, depth + 1));
|
|
11419
|
+
}
|
|
11420
|
+
if (type === "checkboxes" || type === "radio_buttons") {
|
|
11421
|
+
parts.push(...parseChildren(element.options, budget, depth + 1));
|
|
11422
|
+
}
|
|
11423
|
+
return parts;
|
|
11424
|
+
}
|
|
11425
|
+
function renderBlockText(value) {
|
|
11426
|
+
if (!Array.isArray(value)) return "";
|
|
11427
|
+
const budget = { remainingNodes: MAX_NODES };
|
|
11428
|
+
return value.slice(0, MAX_BLOCKS).flatMap((block) => parseElement(block, budget, 0)).join("\n");
|
|
11429
|
+
}
|
|
11430
|
+
|
|
11431
|
+
// src/chat/slack/message/attachments.ts
|
|
11298
11432
|
var MAX_ATTACHMENTS = 10;
|
|
11299
11433
|
var MAX_FIELDS_PER_ATTACHMENT = 20;
|
|
11300
11434
|
var MAX_FIELD_CHARS = 1e3;
|
|
@@ -11332,6 +11466,7 @@ function renderAttachment(raw) {
|
|
|
11332
11466
|
const text = toStr(obj.text);
|
|
11333
11467
|
const footer = toStr(obj.footer);
|
|
11334
11468
|
const fields = Array.isArray(obj.fields) ? obj.fields : [];
|
|
11469
|
+
const blockText = renderBlockText(obj.blocks);
|
|
11335
11470
|
const add = (value) => {
|
|
11336
11471
|
if (!value) return;
|
|
11337
11472
|
const normalized = normalizeAttachmentText(value);
|
|
@@ -11339,7 +11474,7 @@ function renderAttachment(raw) {
|
|
|
11339
11474
|
seen.add(normalized);
|
|
11340
11475
|
parts.push(normalized);
|
|
11341
11476
|
};
|
|
11342
|
-
const hasRichContent = pretext || title || text;
|
|
11477
|
+
const hasRichContent = pretext || title || text || blockText;
|
|
11343
11478
|
if (!hasRichContent) {
|
|
11344
11479
|
add(fallback);
|
|
11345
11480
|
}
|
|
@@ -11355,28 +11490,19 @@ function renderAttachment(raw) {
|
|
|
11355
11490
|
for (const field of fields.slice(0, MAX_FIELDS_PER_ATTACHMENT)) {
|
|
11356
11491
|
add(renderField(field));
|
|
11357
11492
|
}
|
|
11493
|
+
add(blockText);
|
|
11358
11494
|
add(footer);
|
|
11359
11495
|
return parts.join("\n");
|
|
11360
11496
|
}
|
|
11361
|
-
function
|
|
11497
|
+
function renderAttachmentText(input) {
|
|
11362
11498
|
const rendered = getAttachmentPayload(input).slice(0, MAX_ATTACHMENTS).map(renderAttachment).filter((line) => line.length > 0).map((line) => `[attachment] ${line}`).join("\n");
|
|
11363
11499
|
return rendered.slice(0, MAX_ATTACHMENT_TEXT_CHARS);
|
|
11364
11500
|
}
|
|
11365
|
-
function appendSlackLegacyAttachmentText(baseText, rawMessageOrAttachments) {
|
|
11366
|
-
const base = baseText?.trim() ?? "";
|
|
11367
|
-
const attachmentText = renderSlackLegacyAttachmentText(
|
|
11368
|
-
rawMessageOrAttachments
|
|
11369
|
-
);
|
|
11370
|
-
if (!attachmentText) return base;
|
|
11371
|
-
if (!base) return attachmentText;
|
|
11372
|
-
return `${base}
|
|
11373
|
-
${attachmentText}`;
|
|
11374
|
-
}
|
|
11375
11501
|
|
|
11376
11502
|
// src/chat/slack/tools/thread-read.ts
|
|
11377
11503
|
var MAX_THREAD_READ_CHARS = 4e4;
|
|
11378
11504
|
function sanitizeMessage(msg) {
|
|
11379
|
-
const attachmentText =
|
|
11505
|
+
const attachmentText = renderAttachmentText(msg.attachments);
|
|
11380
11506
|
return {
|
|
11381
11507
|
ts: msg.ts,
|
|
11382
11508
|
user: msg.user,
|
|
@@ -11517,6 +11643,10 @@ function createSlackThreadReadTool(context, deps = {}) {
|
|
|
11517
11643
|
});
|
|
11518
11644
|
}
|
|
11519
11645
|
|
|
11646
|
+
// src/chat/slack/tools/user-lookup.ts
|
|
11647
|
+
import { and, eq } from "drizzle-orm";
|
|
11648
|
+
import { z as z50 } from "zod";
|
|
11649
|
+
|
|
11520
11650
|
// src/chat/slack/users.ts
|
|
11521
11651
|
function normalizeUser(raw) {
|
|
11522
11652
|
const rawFields = raw.profile?.fields;
|
|
@@ -11657,7 +11787,6 @@ async function searchSlackUsers(options) {
|
|
|
11657
11787
|
}
|
|
11658
11788
|
|
|
11659
11789
|
// src/chat/slack/tools/user-lookup.ts
|
|
11660
|
-
import { z as z50 } from "zod";
|
|
11661
11790
|
function explicitUserLookupError(error) {
|
|
11662
11791
|
if (error.apiError === "user_not_found") {
|
|
11663
11792
|
return "No Slack user found for the supplied user ID.";
|
|
@@ -11676,9 +11805,52 @@ function explicitUserLookupError(error) {
|
|
|
11676
11805
|
}
|
|
11677
11806
|
return void 0;
|
|
11678
11807
|
}
|
|
11679
|
-
function
|
|
11808
|
+
function slackMention(userId) {
|
|
11809
|
+
return `<@${userId}>`;
|
|
11810
|
+
}
|
|
11811
|
+
async function storeProfile(teamId, profile) {
|
|
11812
|
+
await upsertIdentity(getSqlExecutor(), {
|
|
11813
|
+
kind: profile.is_bot ? "service" : "user",
|
|
11814
|
+
provider: "slack",
|
|
11815
|
+
providerTenantId: teamId,
|
|
11816
|
+
providerSubjectId: profile.id,
|
|
11817
|
+
...profile.real_name || profile.display_name ? { displayName: profile.real_name || profile.display_name } : {},
|
|
11818
|
+
...profile.name ? { handle: profile.name } : {},
|
|
11819
|
+
...profile.email ? { email: profile.email, emailVerified: true } : {}
|
|
11820
|
+
});
|
|
11821
|
+
}
|
|
11822
|
+
async function storedUserByEmail(teamId, email) {
|
|
11823
|
+
const emailNormalized = normalizeIdentityEmail(email);
|
|
11824
|
+
if (!emailNormalized) return void 0;
|
|
11825
|
+
const identities = await getSqlExecutor().db().select().from(juniorIdentities).where(
|
|
11826
|
+
and(
|
|
11827
|
+
eq(juniorIdentities.provider, "slack"),
|
|
11828
|
+
eq(juniorIdentities.providerTenantId, teamId),
|
|
11829
|
+
eq(juniorIdentities.kind, "user"),
|
|
11830
|
+
eq(juniorIdentities.emailVerified, true),
|
|
11831
|
+
eq(juniorIdentities.emailNormalized, emailNormalized)
|
|
11832
|
+
)
|
|
11833
|
+
).limit(2);
|
|
11834
|
+
if (identities.length > 1) {
|
|
11835
|
+
throw new Error(
|
|
11836
|
+
`Multiple Slack users share verified email ${emailNormalized} in workspace ${teamId}`
|
|
11837
|
+
);
|
|
11838
|
+
}
|
|
11839
|
+
const identity = identities[0];
|
|
11840
|
+
if (!identity) return void 0;
|
|
11841
|
+
return {
|
|
11842
|
+
id: identity.providerSubjectId,
|
|
11843
|
+
...identity.handle ? { name: identity.handle } : {},
|
|
11844
|
+
...identity.displayName ? { real_name: identity.displayName } : {},
|
|
11845
|
+
...identity.displayName ? { display_name: identity.displayName } : {},
|
|
11846
|
+
...identity.email ? { email: identity.email } : {},
|
|
11847
|
+
is_bot: false,
|
|
11848
|
+
is_deleted: false
|
|
11849
|
+
};
|
|
11850
|
+
}
|
|
11851
|
+
function createSlackUserLookupTool(teamId) {
|
|
11680
11852
|
return zodTool({
|
|
11681
|
-
description: "Look up Slack user profiles by user ID, email, or name search.
|
|
11853
|
+
description: "Look up Slack user profiles by user ID, email, or name search. Returns Slack `mention` values (`<@U\u2026>`). Use a mention only when one person clearly matches; otherwise ask which person the user means.",
|
|
11682
11854
|
annotations: {
|
|
11683
11855
|
destructiveHint: false,
|
|
11684
11856
|
idempotentHint: true,
|
|
@@ -11701,20 +11873,33 @@ function createSlackUserLookupTool() {
|
|
|
11701
11873
|
if (!parsedUserId.ok) {
|
|
11702
11874
|
throw new ToolInputError(parsedUserId.error);
|
|
11703
11875
|
}
|
|
11876
|
+
const user = await lookupSlackUserProfile(parsedUserId.value);
|
|
11877
|
+
await storeProfile(teamId, user);
|
|
11704
11878
|
return {
|
|
11705
11879
|
mode: "user_id",
|
|
11706
|
-
|
|
11880
|
+
mention: slackMention(user.id),
|
|
11881
|
+
user
|
|
11707
11882
|
};
|
|
11708
11883
|
}
|
|
11709
11884
|
if (mode === "email") {
|
|
11885
|
+
const stored = await storedUserByEmail(teamId, value);
|
|
11886
|
+
if (stored) {
|
|
11887
|
+
return {
|
|
11888
|
+
mode: "email",
|
|
11889
|
+
mention: slackMention(stored.id),
|
|
11890
|
+
user: stored
|
|
11891
|
+
};
|
|
11892
|
+
}
|
|
11710
11893
|
const profile = await lookupSlackUserByEmail(value);
|
|
11711
11894
|
if (!profile) {
|
|
11712
11895
|
throw new ToolInputError(
|
|
11713
11896
|
`No Slack user found with email address ${value}.`
|
|
11714
11897
|
);
|
|
11715
11898
|
}
|
|
11899
|
+
await storeProfile(teamId, profile);
|
|
11716
11900
|
return {
|
|
11717
11901
|
mode: "email",
|
|
11902
|
+
mention: slackMention(profile.id),
|
|
11718
11903
|
user: profile
|
|
11719
11904
|
};
|
|
11720
11905
|
}
|
|
@@ -11724,6 +11909,9 @@ function createSlackUserLookupTool() {
|
|
|
11724
11909
|
maxPages: 3,
|
|
11725
11910
|
includeBots: false
|
|
11726
11911
|
});
|
|
11912
|
+
if (result.users.length === 1) {
|
|
11913
|
+
await storeProfile(teamId, result.users[0]);
|
|
11914
|
+
}
|
|
11727
11915
|
return {
|
|
11728
11916
|
mode: "query",
|
|
11729
11917
|
query: value,
|
|
@@ -11731,7 +11919,10 @@ function createSlackUserLookupTool() {
|
|
|
11731
11919
|
searched_pages: result.searched_pages,
|
|
11732
11920
|
searched_user_count: result.searched_user_count,
|
|
11733
11921
|
truncated: result.truncated,
|
|
11734
|
-
users: result.users
|
|
11922
|
+
users: result.users.map((user) => ({
|
|
11923
|
+
...user,
|
|
11924
|
+
mention: slackMention(user.id)
|
|
11925
|
+
}))
|
|
11735
11926
|
};
|
|
11736
11927
|
} catch (error) {
|
|
11737
11928
|
if (error instanceof SlackActionError) {
|
|
@@ -11837,7 +12028,7 @@ function getTimeZoneOffsetMinutes(timestampMs, timezone) {
|
|
|
11837
12028
|
return Math.round((timestampMs - asUtcMs) / 6e4);
|
|
11838
12029
|
}
|
|
11839
12030
|
|
|
11840
|
-
// src/chat/tools/
|
|
12031
|
+
// src/chat/tools/search-conversation-events.ts
|
|
11841
12032
|
import { z as z52 } from "zod";
|
|
11842
12033
|
var DEFAULT_LIMIT3 = 25;
|
|
11843
12034
|
var MAX_LIMIT = 100;
|
|
@@ -11845,40 +12036,26 @@ var MAX_EVENT_DATA_BYTES = 4e3;
|
|
|
11845
12036
|
var MAX_EVENTS_JSON_BYTES = 2e4;
|
|
11846
12037
|
var MAX_IDENTITY_CHARS = 256;
|
|
11847
12038
|
var textEncoder = new TextEncoder();
|
|
11848
|
-
var CONVERSATION_EVENTS_TOOL_SOURCE = {
|
|
11849
|
-
id: "conversation-events",
|
|
11850
|
-
description: "Inspect Junior's durable conversation event log for debugging runtime behavior."
|
|
11851
|
-
};
|
|
11852
12039
|
var knownEventTypeSchema = z52.enum(KNOWN_CONVERSATION_EVENT_TYPES);
|
|
11853
12040
|
var projectedEventSchema = z52.object({
|
|
11854
|
-
seq: z52.number().int().nonnegative().describe("Stable event position
|
|
11855
|
-
history_version: z52.number().int().nonnegative().describe(
|
|
11856
|
-
"Model-history generation. It increments when handoff or compaction replaces active model context."
|
|
11857
|
-
),
|
|
12041
|
+
seq: z52.number().int().nonnegative().describe("Stable event position for pagination."),
|
|
12042
|
+
history_version: z52.number().int().nonnegative().describe("Agent history generation after replacement."),
|
|
11858
12043
|
created_at: z52.iso.datetime().describe("When the event was recorded."),
|
|
11859
|
-
idempotency_key: z52.string().min(1).optional().describe("Retry-stable event identity, when
|
|
11860
|
-
data: z52.record(z52.string(), z52.unknown()).describe(
|
|
11861
|
-
"Event data. Oversized payloads are replaced by identifying fields, payload_omitted, and payload_json_bytes."
|
|
11862
|
-
)
|
|
12044
|
+
idempotency_key: z52.string().min(1).optional().describe("Retry-stable event identity, when assigned."),
|
|
12045
|
+
data: z52.record(z52.string(), z52.unknown()).describe("Bounded event data.")
|
|
11863
12046
|
}).strict();
|
|
11864
|
-
var
|
|
12047
|
+
var searchConversationEventsOutputSchema = juniorToolOutputSchema.extend({
|
|
11865
12048
|
conversation_id: z52.string().min(1),
|
|
11866
12049
|
events: z52.array(projectedEventSchema),
|
|
11867
|
-
has_older: z52.boolean().describe(
|
|
11868
|
-
|
|
11869
|
-
)
|
|
11870
|
-
has_newer: z52.boolean().describe(
|
|
11871
|
-
"Whether matching events exist after this page; request them with after_seq set to the last returned seq."
|
|
11872
|
-
),
|
|
11873
|
-
omitted_event_count: z52.number().int().nonnegative().optional().describe(
|
|
11874
|
-
"Fetched events omitted to keep this response bounded. Continue with the pagination cursor for the omitted direction."
|
|
11875
|
-
)
|
|
12050
|
+
has_older: z52.boolean().describe("Whether matching older events exist."),
|
|
12051
|
+
has_newer: z52.boolean().describe("Whether matching newer events exist."),
|
|
12052
|
+
omitted_event_count: z52.number().int().nonnegative().optional().describe("Events omitted by the response byte limit.")
|
|
11876
12053
|
});
|
|
11877
|
-
function
|
|
12054
|
+
function createSearchConversationEventsTool(context) {
|
|
11878
12055
|
return zodTool({
|
|
11879
|
-
description: "
|
|
12056
|
+
description: "Search the durable event log for one conversation, including messages, agent history, tool results, handoffs, and compactions. Defaults to the current conversation. Outside the current conversation tree, only retained public conversations in the current Slack workspace are accessible.",
|
|
11880
12057
|
exposure: "deferred",
|
|
11881
|
-
source:
|
|
12058
|
+
source: CONVERSATIONS_TOOL_SOURCE,
|
|
11882
12059
|
annotations: {
|
|
11883
12060
|
destructiveHint: false,
|
|
11884
12061
|
idempotentHint: true,
|
|
@@ -11886,31 +12063,25 @@ function createQueryConversationEventsTool(context) {
|
|
|
11886
12063
|
readOnlyHint: true
|
|
11887
12064
|
},
|
|
11888
12065
|
inputSchema: z52.object({
|
|
11889
|
-
conversation_id: z52.string().trim().min(1).describe(
|
|
11890
|
-
"Conversation ID to
|
|
11891
|
-
),
|
|
11892
|
-
after_seq: z52.number().int().nonnegative().nullable().describe(
|
|
11893
|
-
"Exclusive lower bound on event seq. When set, returns the next newer page in ascending order."
|
|
11894
|
-
).optional(),
|
|
11895
|
-
before_seq: z52.number().int().nonnegative().nullable().describe(
|
|
11896
|
-
"Exclusive upper bound on event seq. Combine with defaults or after_seq to page older or bounded ranges."
|
|
12066
|
+
conversation_id: z52.string().trim().min(1).nullable().describe(
|
|
12067
|
+
"Conversation ID to search. Omit or null for the current conversation."
|
|
11897
12068
|
).optional(),
|
|
12069
|
+
after_seq: z52.number().int().nonnegative().nullable().describe("Exclusive event sequence lower bound; returns ascending.").optional(),
|
|
12070
|
+
before_seq: z52.number().int().nonnegative().nullable().describe("Exclusive event sequence upper bound.").optional(),
|
|
11898
12071
|
limit: z52.number().int().min(1).max(MAX_LIMIT).nullable().describe(
|
|
11899
|
-
`Maximum events
|
|
12072
|
+
`Maximum events. Default ${DEFAULT_LIMIT3}; max ${MAX_LIMIT}.`
|
|
11900
12073
|
).optional(),
|
|
11901
|
-
types: z52.array(knownEventTypeSchema).min(1).nullable().describe(
|
|
11902
|
-
"Optional event-type filter. Omit to return every durable event type."
|
|
11903
|
-
).optional()
|
|
12074
|
+
types: z52.array(knownEventTypeSchema).min(1).nullable().describe("Event types to include; omit for all types.").optional()
|
|
11904
12075
|
}).strict(),
|
|
11905
|
-
outputSchema:
|
|
12076
|
+
outputSchema: searchConversationEventsOutputSchema,
|
|
11906
12077
|
execute: async (input) => {
|
|
11907
12078
|
const currentConversationId = context.conversationId?.trim();
|
|
11908
12079
|
if (!currentConversationId) {
|
|
11909
12080
|
throw new ToolInputError(
|
|
11910
|
-
"
|
|
12081
|
+
"searchConversationEvents requires an active conversation"
|
|
11911
12082
|
);
|
|
11912
12083
|
}
|
|
11913
|
-
const conversationId = input.conversation_id;
|
|
12084
|
+
const conversationId = input.conversation_id?.trim() || currentConversationId;
|
|
11914
12085
|
const afterSeq = input.after_seq ?? void 0;
|
|
11915
12086
|
const beforeSeq = input.before_seq ?? void 0;
|
|
11916
12087
|
const limit = input.limit ?? DEFAULT_LIMIT3;
|
|
@@ -11943,7 +12114,7 @@ function createQueryConversationEventsTool(context) {
|
|
|
11943
12114
|
const targetRoot = targetRootConversationId === conversationId ? target : await conversationStore.get({
|
|
11944
12115
|
conversationId: targetRootConversationId
|
|
11945
12116
|
});
|
|
11946
|
-
|
|
12117
|
+
assertCanSearchConversationEvents({
|
|
11947
12118
|
accessScope,
|
|
11948
12119
|
targetConversationId: conversationId,
|
|
11949
12120
|
targetRootConversationId,
|
|
@@ -12021,7 +12192,7 @@ async function resolveRootConversationId(conversationStore, conversationId, pare
|
|
|
12021
12192
|
}
|
|
12022
12193
|
return conversationId;
|
|
12023
12194
|
}
|
|
12024
|
-
function
|
|
12195
|
+
function assertCanSearchConversationEvents(args) {
|
|
12025
12196
|
const {
|
|
12026
12197
|
accessScope,
|
|
12027
12198
|
targetConversationId,
|
|
@@ -12848,7 +13019,7 @@ function createTools(availableSkills, hooks = {}, context, options = {}) {
|
|
|
12848
13019
|
...createScheduledTaskTools(context)
|
|
12849
13020
|
};
|
|
12850
13021
|
if (context.conversationId) {
|
|
12851
|
-
tools.
|
|
13022
|
+
tools.searchConversationEvents = createSearchConversationEventsTool(context);
|
|
12852
13023
|
}
|
|
12853
13024
|
if (context.supportsImageInput) {
|
|
12854
13025
|
tools.viewImage = createViewImageTool(
|
|
@@ -12885,7 +13056,7 @@ function createTools(availableSkills, hooks = {}, context, options = {}) {
|
|
|
12885
13056
|
tools.slackCanvasWrite = createSlackCanvasWriteTool(state);
|
|
12886
13057
|
tools.slackThreadRead = createSlackThreadReadTool(slackContext);
|
|
12887
13058
|
if (context.conversationId && slackContext.source.visibility === "public") {
|
|
12888
|
-
tools.
|
|
13059
|
+
tools.searchConversationMessages = createSlackConversationMessageSearchTool(
|
|
12889
13060
|
{
|
|
12890
13061
|
kind: "public_provider_tenant",
|
|
12891
13062
|
provider: "slack",
|
|
@@ -12899,7 +13070,7 @@ function createTools(availableSkills, hooks = {}, context, options = {}) {
|
|
|
12899
13070
|
context.slackActionToken
|
|
12900
13071
|
);
|
|
12901
13072
|
}
|
|
12902
|
-
tools.slackUserLookup = createSlackUserLookupTool();
|
|
13073
|
+
tools.slackUserLookup = createSlackUserLookupTool(slackContext.teamId);
|
|
12903
13074
|
tools.slackListCreate = createSlackListCreateTool(state);
|
|
12904
13075
|
tools.slackListAddItems = createSlackListAddItemsTool(state);
|
|
12905
13076
|
tools.slackListGetItems = createSlackListGetItemsTool(state);
|
|
@@ -13544,6 +13715,46 @@ var SEARCH_TOOLS_NAME = "searchTools";
|
|
|
13544
13715
|
var DEFAULT_MAX_RESULTS2 = 5;
|
|
13545
13716
|
var MAX_RESULTS3 = 20;
|
|
13546
13717
|
var MODEL_VISIBLE_DESCRIPTION_CAP = 180;
|
|
13718
|
+
var SEARCH_FIELD_WEIGHTS = [8, 4, 1];
|
|
13719
|
+
var BM25_K1 = 1.2;
|
|
13720
|
+
var BM25_B = 0.75;
|
|
13721
|
+
var SEARCH_STOP_WORDS = /* @__PURE__ */ new Set([
|
|
13722
|
+
"a",
|
|
13723
|
+
"an",
|
|
13724
|
+
"and",
|
|
13725
|
+
"are",
|
|
13726
|
+
"as",
|
|
13727
|
+
"at",
|
|
13728
|
+
"be",
|
|
13729
|
+
"by",
|
|
13730
|
+
"do",
|
|
13731
|
+
"for",
|
|
13732
|
+
"from",
|
|
13733
|
+
"how",
|
|
13734
|
+
"i",
|
|
13735
|
+
"in",
|
|
13736
|
+
"is",
|
|
13737
|
+
"it",
|
|
13738
|
+
"me",
|
|
13739
|
+
"my",
|
|
13740
|
+
"of",
|
|
13741
|
+
"on",
|
|
13742
|
+
"or",
|
|
13743
|
+
"please",
|
|
13744
|
+
"that",
|
|
13745
|
+
"the",
|
|
13746
|
+
"this",
|
|
13747
|
+
"to",
|
|
13748
|
+
"use",
|
|
13749
|
+
"we",
|
|
13750
|
+
"what",
|
|
13751
|
+
"when",
|
|
13752
|
+
"where",
|
|
13753
|
+
"which",
|
|
13754
|
+
"with",
|
|
13755
|
+
"you",
|
|
13756
|
+
"your"
|
|
13757
|
+
]);
|
|
13547
13758
|
var searchToolsSourceSchema = z58.object({
|
|
13548
13759
|
id: z58.string(),
|
|
13549
13760
|
description: z58.string()
|
|
@@ -13568,8 +13779,26 @@ var searchToolsOutputSchema = juniorToolOutputSchema.extend({
|
|
|
13568
13779
|
execution_tool: z58.literal("executeTool"),
|
|
13569
13780
|
tools: z58.array(searchToolsToolSchema)
|
|
13570
13781
|
}).strict();
|
|
13571
|
-
function
|
|
13572
|
-
|
|
13782
|
+
function terms(value) {
|
|
13783
|
+
const chunks = value.match(/[\p{L}\p{N}]+/gu) ?? [];
|
|
13784
|
+
const result = [];
|
|
13785
|
+
for (const chunk of chunks) {
|
|
13786
|
+
result.push(chunk.toLowerCase());
|
|
13787
|
+
const expanded = chunk.replace(/([a-z\d])([A-Z])/g, "$1 $2").replace(/([A-Z]+)([A-Z][a-z])/g, "$1 $2").toLowerCase().split(/\s+/);
|
|
13788
|
+
if (expanded.length > 1) {
|
|
13789
|
+
result.push(...expanded);
|
|
13790
|
+
}
|
|
13791
|
+
}
|
|
13792
|
+
return result;
|
|
13793
|
+
}
|
|
13794
|
+
function queryTerms(query) {
|
|
13795
|
+
return [
|
|
13796
|
+
...new Set(
|
|
13797
|
+
terms(query).filter(
|
|
13798
|
+
(term) => term.length >= 2 && !SEARCH_STOP_WORDS.has(term)
|
|
13799
|
+
)
|
|
13800
|
+
)
|
|
13801
|
+
];
|
|
13573
13802
|
}
|
|
13574
13803
|
function summarizeModelVisibleDescription(description) {
|
|
13575
13804
|
const paragraph = description.split(/\n\s*\n/).map((part) => part.trim()).find(Boolean) ?? "";
|
|
@@ -13586,36 +13815,114 @@ function schemaText(schema) {
|
|
|
13586
13815
|
return "";
|
|
13587
13816
|
}
|
|
13588
13817
|
}
|
|
13589
|
-
function
|
|
13590
|
-
return
|
|
13591
|
-
|
|
13592
|
-
|
|
13593
|
-
|
|
13594
|
-
|
|
13595
|
-
|
|
13596
|
-
|
|
13597
|
-
|
|
13598
|
-
|
|
13599
|
-
|
|
13600
|
-
|
|
13601
|
-
|
|
13602
|
-
|
|
13603
|
-
|
|
13818
|
+
function searchableToolFields(name, definition) {
|
|
13819
|
+
return [
|
|
13820
|
+
terms(
|
|
13821
|
+
[
|
|
13822
|
+
name,
|
|
13823
|
+
definition.identity?.id,
|
|
13824
|
+
definition.identity?.name,
|
|
13825
|
+
definition.identity?.plugin
|
|
13826
|
+
].filter(Boolean).join(" ")
|
|
13827
|
+
),
|
|
13828
|
+
terms(
|
|
13829
|
+
[
|
|
13830
|
+
definition.description,
|
|
13831
|
+
definition.promptSnippet,
|
|
13832
|
+
...definition.promptGuidelines ?? []
|
|
13833
|
+
].filter(Boolean).join(" ")
|
|
13834
|
+
),
|
|
13835
|
+
terms(
|
|
13836
|
+
[
|
|
13837
|
+
definition.source?.id,
|
|
13838
|
+
definition.source?.description,
|
|
13839
|
+
schemaText(definition.inputSchema),
|
|
13840
|
+
schemaText(definition.annotations ?? {})
|
|
13841
|
+
].filter(Boolean).join(" ")
|
|
13842
|
+
)
|
|
13843
|
+
];
|
|
13844
|
+
}
|
|
13845
|
+
function prepareSearchDocuments(tools, source) {
|
|
13846
|
+
return Object.entries(tools).filter(
|
|
13847
|
+
([, definition]) => source ? definition.source?.id === source : true
|
|
13848
|
+
).map(([name, definition]) => ({
|
|
13849
|
+
name,
|
|
13850
|
+
fields: searchableToolFields(name, definition)
|
|
13851
|
+
}));
|
|
13852
|
+
}
|
|
13853
|
+
function averageFieldLengths(documents) {
|
|
13854
|
+
if (documents.length === 0) {
|
|
13855
|
+
return SEARCH_FIELD_WEIGHTS.map(() => 0);
|
|
13856
|
+
}
|
|
13857
|
+
return SEARCH_FIELD_WEIGHTS.map(
|
|
13858
|
+
(_, fieldIndex) => documents.reduce(
|
|
13859
|
+
(total, document) => total + document.fields[fieldIndex].length,
|
|
13860
|
+
0
|
|
13861
|
+
) / documents.length
|
|
13604
13862
|
);
|
|
13605
13863
|
}
|
|
13864
|
+
function documentFrequencies(documents) {
|
|
13865
|
+
const frequencies = /* @__PURE__ */ new Map();
|
|
13866
|
+
for (const document of documents) {
|
|
13867
|
+
const uniqueTerms = new Set(document.fields.flat());
|
|
13868
|
+
for (const term of uniqueTerms) {
|
|
13869
|
+
frequencies.set(term, (frequencies.get(term) ?? 0) + 1);
|
|
13870
|
+
}
|
|
13871
|
+
}
|
|
13872
|
+
return frequencies;
|
|
13873
|
+
}
|
|
13874
|
+
function scoreSearchDocument(document, query, frequencies, documentCount, averageLengths) {
|
|
13875
|
+
return query.reduce((score, term) => {
|
|
13876
|
+
const documentFrequency = frequencies.get(term) ?? 0;
|
|
13877
|
+
if (documentFrequency === 0) {
|
|
13878
|
+
return score;
|
|
13879
|
+
}
|
|
13880
|
+
const weightedTermFrequency = document.fields.reduce(
|
|
13881
|
+
(weighted, field, fieldIndex) => {
|
|
13882
|
+
const termFrequency = field.filter(
|
|
13883
|
+
(candidate) => candidate === term
|
|
13884
|
+
).length;
|
|
13885
|
+
if (termFrequency === 0) {
|
|
13886
|
+
return weighted;
|
|
13887
|
+
}
|
|
13888
|
+
const averageLength = averageLengths[fieldIndex] ?? 0;
|
|
13889
|
+
const lengthRatio = averageLength === 0 ? 1 : field.length / averageLength;
|
|
13890
|
+
return weighted + SEARCH_FIELD_WEIGHTS[fieldIndex] * (termFrequency / (1 - BM25_B + BM25_B * lengthRatio));
|
|
13891
|
+
},
|
|
13892
|
+
0
|
|
13893
|
+
);
|
|
13894
|
+
if (weightedTermFrequency === 0) {
|
|
13895
|
+
return score;
|
|
13896
|
+
}
|
|
13897
|
+
const inverseDocumentFrequency = Math.log(
|
|
13898
|
+
1 + (documentCount - documentFrequency + 0.5) / (documentFrequency + 0.5)
|
|
13899
|
+
);
|
|
13900
|
+
return score + inverseDocumentFrequency * weightedTermFrequency * (BM25_K1 + 1) / (weightedTermFrequency + BM25_K1);
|
|
13901
|
+
}, 0);
|
|
13902
|
+
}
|
|
13606
13903
|
function searchCatalogTools(tools, query, source) {
|
|
13607
|
-
const
|
|
13608
|
-
|
|
13609
|
-
|
|
13610
|
-
|
|
13611
|
-
|
|
13612
|
-
|
|
13904
|
+
const documents = prepareSearchDocuments(tools, source);
|
|
13905
|
+
if (!query.trim()) {
|
|
13906
|
+
return documents.map(({ name }) => name).sort((left, right) => left.localeCompare(right));
|
|
13907
|
+
}
|
|
13908
|
+
const searchTerms = queryTerms(query);
|
|
13909
|
+
if (searchTerms.length === 0) {
|
|
13910
|
+
return [];
|
|
13613
13911
|
}
|
|
13614
|
-
const
|
|
13615
|
-
|
|
13616
|
-
|
|
13617
|
-
|
|
13618
|
-
|
|
13912
|
+
const averageLengths = averageFieldLengths(documents);
|
|
13913
|
+
const frequencies = documentFrequencies(documents);
|
|
13914
|
+
return documents.map((document) => ({
|
|
13915
|
+
name: document.name,
|
|
13916
|
+
score: scoreSearchDocument(
|
|
13917
|
+
document,
|
|
13918
|
+
searchTerms,
|
|
13919
|
+
frequencies,
|
|
13920
|
+
documents.length,
|
|
13921
|
+
averageLengths
|
|
13922
|
+
)
|
|
13923
|
+
})).filter(({ score }) => score > 0).sort(
|
|
13924
|
+
(left, right) => right.score - left.score || left.name.localeCompare(right.name)
|
|
13925
|
+
).map(({ name }) => name);
|
|
13619
13926
|
}
|
|
13620
13927
|
function callNotes(definition) {
|
|
13621
13928
|
return [
|
|
@@ -15451,7 +15758,6 @@ async function wireAgentTools(args) {
|
|
|
15451
15758
|
);
|
|
15452
15759
|
const effective = resolvedSkill ?? loadedSkill;
|
|
15453
15760
|
upsertActiveSkill(args.activeSkills, effective);
|
|
15454
|
-
args.syncLoadedSkillNamesForResume();
|
|
15455
15761
|
if (await mcpToolManager.activateForSkill(effective)) {
|
|
15456
15762
|
await args.recordConnectedMcpProvider(effective.pluginProvider);
|
|
15457
15763
|
}
|
|
@@ -15617,14 +15923,11 @@ function createResumeState(args) {
|
|
|
15617
15923
|
const writeBase = () => ({
|
|
15618
15924
|
conversationId: args.conversationId,
|
|
15619
15925
|
turnId: args.turnId,
|
|
15620
|
-
modelId: args.getModelId(),
|
|
15621
15926
|
channelName: args.channelName,
|
|
15622
15927
|
destination: args.destination,
|
|
15623
15928
|
destinationVisibility: args.destinationVisibility,
|
|
15624
15929
|
dispatchId: args.dispatchId,
|
|
15625
15930
|
source: args.runSource,
|
|
15626
|
-
loadedSkillNames: args.getLoadedSkillNames(),
|
|
15627
|
-
reasoningLevel: args.getReasoningLevel(),
|
|
15628
15931
|
actor: args.actor,
|
|
15629
15932
|
surface: args.surface
|
|
15630
15933
|
});
|
|
@@ -16491,10 +16794,6 @@ async function executeAgentRunInPrivacyContext(request, conversationPrivacy, run
|
|
|
16491
16794
|
const skillInvocation = parseSkillInvocation(userInput, availableSkills);
|
|
16492
16795
|
const invokedSkill = skillInvocation ? findSkillByName(skillInvocation.skillName, availableSkills) : null;
|
|
16493
16796
|
const activeSkills = [];
|
|
16494
|
-
let loadedSkillNamesForResume = [];
|
|
16495
|
-
const syncLoadedSkillNamesForResume = () => {
|
|
16496
|
-
loadedSkillNamesForResume = activeSkills.map((skill) => skill.name);
|
|
16497
|
-
};
|
|
16498
16797
|
const skillSandbox = new SkillSandbox(availableSkills, activeSkills);
|
|
16499
16798
|
const checkpoint = await loadTurnCheckpoint({ conversationId, turnId });
|
|
16500
16799
|
const resumedFromSessionRecord = checkpoint.resumed;
|
|
@@ -16529,9 +16828,6 @@ async function executeAgentRunInPrivacyContext(request, conversationPrivacy, run
|
|
|
16529
16828
|
...routing.destinationVisibility ? { destinationVisibility: routing.destinationVisibility } : {},
|
|
16530
16829
|
...routing.dispatch?.id ? { dispatchId: routing.dispatch.id } : {},
|
|
16531
16830
|
durability,
|
|
16532
|
-
getLoadedSkillNames: () => loadedSkillNamesForResume,
|
|
16533
|
-
getReasoningLevel: () => turnRoute?.reasoningLevel,
|
|
16534
|
-
getModelId: () => activeModelId,
|
|
16535
16831
|
recordActiveMcpProviders,
|
|
16536
16832
|
actor,
|
|
16537
16833
|
runSource,
|
|
@@ -16569,8 +16865,7 @@ async function executeAgentRunInPrivacyContext(request, conversationPrivacy, run
|
|
|
16569
16865
|
activeSkills,
|
|
16570
16866
|
invokedSkill,
|
|
16571
16867
|
priorPiMessages,
|
|
16572
|
-
skillSandbox
|
|
16573
|
-
syncLoadedSkillNamesForResume
|
|
16868
|
+
skillSandbox
|
|
16574
16869
|
});
|
|
16575
16870
|
const explicitSkill = invokedSkill ? activeSkills.find((skill) => skill.name === invokedSkill.name) ?? null : null;
|
|
16576
16871
|
const { contextContentParts, routerBlocks, userContentParts } = buildPromptInput(input);
|
|
@@ -16584,10 +16879,9 @@ async function executeAgentRunInPrivacyContext(request, conversationPrivacy, run
|
|
|
16584
16879
|
botConfig,
|
|
16585
16880
|
activeModelProfile
|
|
16586
16881
|
);
|
|
16587
|
-
const resumedReasoningLevel = existingSessionRecord?.reasoningLevel ? parseTurnReasoningLevel(existingSessionRecord.reasoningLevel) : void 0;
|
|
16588
16882
|
turnRoute = {
|
|
16589
16883
|
profile: activeModelProfile,
|
|
16590
|
-
reasoningLevel: activeProfileConfig.reasoningLevel ??
|
|
16884
|
+
reasoningLevel: activeProfileConfig.reasoningLevel ?? storedTurnRoute.reasoningLevel,
|
|
16591
16885
|
reason: `resumed_handoff:${storedTurnRoute.modelProfile}:${activeModelProfile}`
|
|
16592
16886
|
};
|
|
16593
16887
|
} else {
|
|
@@ -16797,7 +17091,6 @@ async function executeAgentRunInPrivacyContext(request, conversationPrivacy, run
|
|
|
16797
17091
|
state,
|
|
16798
17092
|
supportsImageInput: () => resolveGatewayModel(activeModelId).input.includes("image"),
|
|
16799
17093
|
surface,
|
|
16800
|
-
syncLoadedSkillNamesForResume,
|
|
16801
17094
|
toolCalls,
|
|
16802
17095
|
userInput
|
|
16803
17096
|
});
|
|
@@ -17577,8 +17870,8 @@ export {
|
|
|
17577
17870
|
deliverResourceEventSubscription,
|
|
17578
17871
|
sanitizeScheduledTaskPrincipal,
|
|
17579
17872
|
listThreadReplies,
|
|
17580
|
-
|
|
17581
|
-
|
|
17873
|
+
renderBlockText,
|
|
17874
|
+
renderAttachmentText,
|
|
17582
17875
|
latestReportedProgress,
|
|
17583
17876
|
executeCredentialedEgressRequest,
|
|
17584
17877
|
createContextCompactor,
|