@sentry/junior 0.146.0 → 0.147.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-SLJADYE5.js → agent-hooks-HS6VGUPM.js} +10 -10
- package/dist/api/conversations/detail.d.ts +1 -0
- package/dist/api/conversations/event-list.d.ts +1 -0
- package/dist/api/schema/conversation.d.ts +4 -0
- package/dist/api/schema.js +1 -1
- package/dist/api.js +26 -22
- package/dist/app.js +220 -238
- package/dist/{catalog-runtime-RQIMSDPR.js → catalog-runtime-M6ZTPYRV.js} +5 -5
- package/dist/chat/agent/prompt.d.ts +0 -2
- package/dist/chat/agent/request.d.ts +2 -5
- package/dist/chat/agent/sandbox.d.ts +2 -2
- package/dist/chat/agent/tools.d.ts +0 -2
- package/dist/chat/agent-dispatch/types.d.ts +2 -2
- package/dist/chat/capabilities/jr-rpc-command.d.ts +2 -2
- package/dist/chat/configuration/service.d.ts +5 -2
- package/dist/chat/configuration/sql.d.ts +9 -0
- package/dist/chat/configuration/types.d.ts +17 -13
- package/dist/chat/conversations/history.d.ts +3 -0
- package/dist/chat/conversations/projection.d.ts +10 -0
- package/dist/chat/credentials/unlink-provider.d.ts +2 -1
- package/dist/chat/credentials/user-token-store.d.ts +2 -0
- package/dist/chat/event-tasks/tool-support.d.ts +2 -0
- package/dist/chat/identities/sql.d.ts +8 -0
- package/dist/chat/logging.d.ts +2 -0
- package/dist/chat/mcp/auth-store.d.ts +0 -2
- package/dist/chat/mcp/oauth.d.ts +0 -2
- package/dist/chat/oauth-flow.d.ts +3 -1
- package/dist/chat/pi/client.d.ts +2 -0
- package/dist/chat/plugins/credential-hooks.d.ts +2 -0
- package/dist/chat/prompt.d.ts +0 -2
- package/dist/chat/resource-events/notification.d.ts +2 -1
- package/dist/chat/runtime/delivered-turn-state.d.ts +1 -4
- package/dist/chat/runtime/thread-state.d.ts +8 -11
- package/dist/chat/runtime/turn-input.d.ts +4 -2
- package/dist/chat/runtime/turn-preparation.d.ts +2 -4
- package/dist/chat/sandbox/command-result.d.ts +2 -0
- package/dist/chat/sandbox/egress/schemas.d.ts +6 -0
- package/dist/chat/scheduled-tasks/tool-support.d.ts +2 -0
- package/dist/chat/scheduled-tasks/tools/create.d.ts +2 -0
- package/dist/chat/scheduled-tasks/tools/delete.d.ts +2 -0
- package/dist/chat/scheduled-tasks/tools/list.d.ts +2 -0
- package/dist/chat/scheduled-tasks/tools/run-now.d.ts +2 -0
- package/dist/chat/scheduled-tasks/tools/update.d.ts +2 -0
- package/dist/chat/services/mcp-auth-orchestration.d.ts +0 -3
- package/dist/chat/services/plugin-auth-orchestration.d.ts +2 -1
- package/dist/chat/services/provider-default-config.d.ts +2 -2
- package/dist/chat/services/subscribed-decision.d.ts +3 -0
- package/dist/chat/services/subscribed-reply-policy.d.ts +1 -0
- package/dist/chat/services/turn-result.d.ts +0 -3
- package/dist/chat/services/turn-router.d.ts +3 -0
- package/dist/chat/slack/assistant-thread/lifecycle.d.ts +0 -1
- package/dist/chat/slack/assistant-thread/title.d.ts +0 -3
- package/dist/chat/slack/dispatch-turn.d.ts +1 -1
- package/dist/chat/slack/tools/canvas/context.d.ts +0 -10
- package/dist/chat/slack/tools/canvas/create.d.ts +2 -0
- package/dist/chat/slack/tools/canvas/edit.d.ts +2 -0
- package/dist/chat/slack/tools/canvas/read.d.ts +2 -0
- package/dist/chat/slack/tools/canvas/write.d.ts +2 -0
- package/dist/chat/slack/tools/channel-list-messages.d.ts +2 -0
- package/dist/chat/slack/tools/conversation-message-search.d.ts +2 -0
- package/dist/chat/slack/tools/list/add-items.d.ts +4 -1
- package/dist/chat/slack/tools/list/api.d.ts +8 -1
- package/dist/chat/slack/tools/list/create.d.ts +2 -0
- package/dist/chat/slack/tools/list/get-items.d.ts +5 -3
- package/dist/chat/slack/tools/list/update-item.d.ts +5 -1
- package/dist/chat/slack/tools/message-add-reaction.d.ts +2 -0
- package/dist/chat/slack/tools/public-search.d.ts +2 -0
- package/dist/chat/slack/tools/send-files.d.ts +2 -0
- package/dist/chat/slack/tools/thread-read.d.ts +2 -0
- package/dist/chat/slack/vision-cache.d.ts +5 -0
- package/dist/chat/state/conversation.d.ts +4 -5
- package/dist/chat/tool-support/structured-result.d.ts +1 -0
- package/dist/chat/tool-support/timed-out-tool-result.d.ts +11 -0
- package/dist/chat/tools/create-event-task.d.ts +2 -0
- package/dist/chat/tools/delete-event-task.d.ts +2 -0
- package/dist/chat/tools/handoff/tool.d.ts +2 -0
- package/dist/chat/tools/list-event-tasks.d.ts +2 -0
- package/dist/chat/tools/list-resource-event-subscriptions.d.ts +2 -0
- package/dist/chat/tools/runtime/report-progress.d.ts +2 -0
- package/dist/chat/tools/runtime/spawn-agent.d.ts +2 -0
- package/dist/chat/tools/search-conversation-events.d.ts +2 -0
- package/dist/chat/tools/search-resource-event-types.d.ts +2 -0
- package/dist/chat/tools/search-tools.d.ts +2 -0
- package/dist/chat/tools/skill/load-skill.d.ts +2 -0
- package/dist/chat/tools/skill/search-mcp-tools.d.ts +2 -0
- package/dist/chat/tools/stop-watching-resources.d.ts +2 -0
- package/dist/chat/tools/system-time.d.ts +2 -0
- package/dist/chat/tools/types.d.ts +0 -6
- package/dist/chat/tools/update-event-task.d.ts +2 -0
- package/dist/chat/tools/user-lookup.d.ts +29 -0
- package/dist/chat/tools/watch-resource-events.d.ts +2 -0
- package/dist/chat/tools/web/fetch-tool.d.ts +2 -0
- package/dist/chat/tools/web/image-generate.d.ts +2 -0
- package/dist/chat/tools/web/search.d.ts +2 -0
- package/dist/{chunk-LVW7BLLT.js → chunk-34GS7B6L.js} +2 -2
- package/dist/{chunk-B63BF443.js → chunk-4LJO56OJ.js} +9 -1
- package/dist/{chunk-H6U2U3EP.js → chunk-6H5SZR24.js} +16 -20
- package/dist/{chunk-M6ZWP4RI.js → chunk-745QJ3ZA.js} +1 -1
- package/dist/{chunk-BLETMLRX.js → chunk-7A4M7PCV.js} +231 -472
- package/dist/{chunk-MKRIZ4VG.js → chunk-7NVJVJID.js} +4 -2
- package/dist/{chunk-ZDGHGY74.js → chunk-7UQIVT6G.js} +13 -6
- package/dist/{chunk-GDQEU4I7.js → chunk-AIOK6LAG.js} +28 -489
- package/dist/{chunk-QSXZ42KX.js → chunk-AVOCH2Z5.js} +3 -3
- package/dist/{chunk-FXDDDSPL.js → chunk-AVZDSUFB.js} +4 -4
- package/dist/{chunk-OFPYOC3M.js → chunk-AYU72WO7.js} +102 -72
- package/dist/chunk-AZ7EAOBE.js +566 -0
- package/dist/{chunk-PH4Q3A6W.js → chunk-CSZINQJ2.js} +1 -1
- package/dist/{chunk-X2WMBTS3.js → chunk-CWP5RHVX.js} +4 -4
- package/dist/{chunk-HQE6EJS5.js → chunk-DLDRQHG5.js} +1 -1
- package/dist/{chunk-MCFIXAV5.js → chunk-DU74WPIC.js} +55 -37
- package/dist/{chunk-X22KCSCO.js → chunk-EFLJ2WJH.js} +6 -4
- package/dist/{chunk-37JJDS4H.js → chunk-GGB4WL5A.js} +1 -1
- package/dist/{chunk-F7REGDKO.js → chunk-IIOOO4FQ.js} +1 -1
- package/dist/{chunk-PB222GIA.js → chunk-JUUKWRBE.js} +1 -1
- package/dist/{chunk-T5GXFFLA.js → chunk-K4SZAP3K.js} +1 -1
- package/dist/{chunk-GYEKOX7N.js → chunk-ORO3PWKQ.js} +1 -1
- package/dist/{chunk-AISNSNDV.js → chunk-PVNG6UMU.js} +3 -3
- package/dist/{chunk-47OSH2ZO.js → chunk-Q4R73I43.js} +365 -206
- package/dist/{chunk-QG7OOKIN.js → chunk-RXBVB2JM.js} +1 -1
- package/dist/{chunk-V6SRLKUB.js → chunk-SGZO7UWH.js} +2 -2
- package/dist/{chunk-JLMVCNXL.js → chunk-SVHUEHUL.js} +1 -0
- package/dist/{chunk-FEKQHPVA.js → chunk-X5UY34KT.js} +6 -5
- package/dist/{chunk-FGHADGIC.js → chunk-YBVXBNSV.js} +2 -2
- package/dist/{chunk-JUA6VU2Z.js → chunk-YEO3VX72.js} +10 -23
- package/dist/{chunk-SCGVWUZX.js → chunk-YHDERDRO.js} +7 -6
- package/dist/{chunk-TCEJ7XXM.js → chunk-YNTTROJT.js} +1 -1
- package/dist/{chunk-37EVZP66.js → chunk-YSB2N563.js} +49 -8
- package/dist/{chunk-W65V465O.js → chunk-Z4YU7Z4L.js} +3 -2
- 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/schema/location-configurations.d.ts +127 -0
- package/dist/db/schema.d.ts +128 -1
- package/dist/{db-WWOMXWTT.js → db-CSEW4RII.js} +7 -7
- package/dist/instrumentation.js +4 -4
- package/dist/nitro.js +2 -2
- package/dist/{oauth-callback-server-A6ZZX74U.js → oauth-callback-server-FUEV5HNG.js} +24 -24
- package/dist/{runner-KSGB2UAV.js → runner-U3XHSKSH.js} +21 -39
- package/dist/{skills-26QPWKVS.js → skills-AKE6W3WI.js} +6 -6
- package/dist/spawn-B6GDTWJ4.js +39 -0
- package/dist/{validation-OPSRGFGH.js → validation-WDTAULUF.js} +6 -6
- package/dist/version.js +1 -1
- package/dist/{work-VMSW7STJ.js → work-C3HAO2BG.js} +17 -17
- package/dist/{worker-2JNFB7C7.js → worker-LNP4YKBM.js} +10 -10
- package/migrations/0024_misty_typhoid_mary.sql +12 -0
- package/migrations/meta/0024_snapshot.json +2275 -0
- package/migrations/meta/_journal.json +7 -0
- package/package.json +5 -5
- package/dist/chat/slack/tools/user-lookup.d.ts +0 -27
- package/dist/chat/state/artifacts.d.ts +0 -30
- package/dist/chat/tool-support/turn-deadline-result.d.ts +0 -3
- package/dist/chunk-Q6QZTTLS.js +0 -55
- package/dist/spawn-5LAJXZ2P.js +0 -39
|
@@ -1,30 +1,34 @@
|
|
|
1
1
|
import {
|
|
2
2
|
resolveBaseUrl
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-7UQIVT6G.js";
|
|
4
4
|
import {
|
|
5
5
|
createPluginLogger,
|
|
6
6
|
getPlugins
|
|
7
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-YHDERDRO.js";
|
|
8
|
+
import {
|
|
9
|
+
getSlackClient,
|
|
10
|
+
withSlackRetries
|
|
11
|
+
} from "./chunk-SGZO7UWH.js";
|
|
8
12
|
import {
|
|
9
13
|
getDb,
|
|
10
14
|
parseDestination
|
|
11
|
-
} from "./chunk-
|
|
15
|
+
} from "./chunk-YSB2N563.js";
|
|
12
16
|
import {
|
|
13
17
|
sleep
|
|
14
18
|
} from "./chunk-EM225ITJ.js";
|
|
15
19
|
import {
|
|
16
20
|
acquireActiveLock,
|
|
17
21
|
getStateAdapter
|
|
18
|
-
} from "./chunk-
|
|
22
|
+
} from "./chunk-ORO3PWKQ.js";
|
|
19
23
|
import {
|
|
20
24
|
pluginCatalogRuntime
|
|
21
|
-
} from "./chunk-
|
|
25
|
+
} from "./chunk-JUUKWRBE.js";
|
|
22
26
|
import {
|
|
23
27
|
fetchWithBoundedOAuthErrorBodies
|
|
24
|
-
} from "./chunk-
|
|
28
|
+
} from "./chunk-GGB4WL5A.js";
|
|
25
29
|
import {
|
|
26
30
|
isRecord
|
|
27
|
-
} from "./chunk-
|
|
31
|
+
} from "./chunk-4LJO56OJ.js";
|
|
28
32
|
|
|
29
33
|
// src/chat/capabilities/router.ts
|
|
30
34
|
var ProviderCredentialRouter = class {
|
|
@@ -209,6 +213,349 @@ function getMcpAwareTelemetryMessage(error, _privacy) {
|
|
|
209
213
|
return getMcpAwareErrorMessage(error);
|
|
210
214
|
}
|
|
211
215
|
|
|
216
|
+
// src/chat/slack/users.ts
|
|
217
|
+
function normalizeUser(raw) {
|
|
218
|
+
const rawFields = raw.profile?.fields;
|
|
219
|
+
const profileFields = [];
|
|
220
|
+
if (rawFields && typeof rawFields === "object") {
|
|
221
|
+
for (const [id, field] of Object.entries(rawFields)) {
|
|
222
|
+
if (!field) continue;
|
|
223
|
+
profileFields.push({
|
|
224
|
+
id,
|
|
225
|
+
label: field.label || void 0,
|
|
226
|
+
value: field.value || void 0,
|
|
227
|
+
alt: field.alt || void 0
|
|
228
|
+
});
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
return {
|
|
232
|
+
id: raw.id ?? "",
|
|
233
|
+
team_id: raw.team_id || void 0,
|
|
234
|
+
name: raw.name || void 0,
|
|
235
|
+
real_name: raw.real_name || raw.profile?.real_name || void 0,
|
|
236
|
+
display_name: raw.profile?.display_name || void 0,
|
|
237
|
+
title: raw.profile?.title || void 0,
|
|
238
|
+
email: raw.profile?.email || void 0,
|
|
239
|
+
status_text: raw.profile?.status_text ?? void 0,
|
|
240
|
+
status_emoji: raw.profile?.status_emoji ?? void 0,
|
|
241
|
+
is_bot: raw.is_bot ?? false,
|
|
242
|
+
is_deleted: raw.deleted ?? false,
|
|
243
|
+
timezone: raw.tz || void 0,
|
|
244
|
+
...profileFields.length > 0 ? { profile_fields: profileFields } : {}
|
|
245
|
+
};
|
|
246
|
+
}
|
|
247
|
+
async function lookupSlackUserProfile(userId) {
|
|
248
|
+
const client = getSlackClient();
|
|
249
|
+
const result = await withSlackRetries(
|
|
250
|
+
() => client.users.info({ user: userId }),
|
|
251
|
+
3,
|
|
252
|
+
{ action: "users.info" }
|
|
253
|
+
);
|
|
254
|
+
const user = result.user;
|
|
255
|
+
if (!user) {
|
|
256
|
+
throw new Error(`Slack users.info returned no user for ${userId}`);
|
|
257
|
+
}
|
|
258
|
+
return normalizeUser(user);
|
|
259
|
+
}
|
|
260
|
+
async function lookupSlackUserByEmail(email) {
|
|
261
|
+
const client = getSlackClient();
|
|
262
|
+
let result;
|
|
263
|
+
try {
|
|
264
|
+
result = await withSlackRetries(
|
|
265
|
+
() => client.users.lookupByEmail({ email }),
|
|
266
|
+
3,
|
|
267
|
+
{ action: "users.lookupByEmail" }
|
|
268
|
+
);
|
|
269
|
+
} catch (error) {
|
|
270
|
+
const apiError = error.apiError;
|
|
271
|
+
if (apiError === "users_not_found") {
|
|
272
|
+
return null;
|
|
273
|
+
}
|
|
274
|
+
throw error;
|
|
275
|
+
}
|
|
276
|
+
const user = result.user;
|
|
277
|
+
if (!user) {
|
|
278
|
+
return null;
|
|
279
|
+
}
|
|
280
|
+
return normalizeUser(user);
|
|
281
|
+
}
|
|
282
|
+
function scoreMatch(user, queryLower) {
|
|
283
|
+
const name = (user.name ?? "").toLowerCase();
|
|
284
|
+
const realName = (user.real_name ?? user.profile?.real_name ?? "").toLowerCase();
|
|
285
|
+
const displayName = (user.profile?.display_name ?? "").toLowerCase();
|
|
286
|
+
if (name === queryLower || displayName === queryLower) return 100;
|
|
287
|
+
if (realName === queryLower) return 90;
|
|
288
|
+
if (name.startsWith(queryLower) || displayName.startsWith(queryLower))
|
|
289
|
+
return 70;
|
|
290
|
+
if (realName.startsWith(queryLower)) return 60;
|
|
291
|
+
const realNameWords = realName.split(/\s+/);
|
|
292
|
+
if (realNameWords.some((w) => w === queryLower)) return 55;
|
|
293
|
+
if (realNameWords.some((w) => w.startsWith(queryLower))) return 50;
|
|
294
|
+
if (name.includes(queryLower) || displayName.includes(queryLower)) return 30;
|
|
295
|
+
if (realName.includes(queryLower)) return 20;
|
|
296
|
+
return 0;
|
|
297
|
+
}
|
|
298
|
+
async function listWorkspaceUsers(options) {
|
|
299
|
+
const client = getSlackClient();
|
|
300
|
+
const matches = [];
|
|
301
|
+
let cursor;
|
|
302
|
+
let pages = 0;
|
|
303
|
+
let totalScanned = 0;
|
|
304
|
+
while (pages < options.maxPages) {
|
|
305
|
+
pages++;
|
|
306
|
+
const result = await withSlackRetries(
|
|
307
|
+
() => client.users.list({
|
|
308
|
+
limit: 200,
|
|
309
|
+
...cursor ? { cursor } : {}
|
|
310
|
+
}),
|
|
311
|
+
3,
|
|
312
|
+
{ action: "users.list" }
|
|
313
|
+
);
|
|
314
|
+
const members = result.members ?? [];
|
|
315
|
+
totalScanned += members.length;
|
|
316
|
+
for (const member of members) {
|
|
317
|
+
if (!options.includeDeleted && member.deleted) continue;
|
|
318
|
+
if (!options.includeBots && member.is_bot) continue;
|
|
319
|
+
if (member.id === "USLACKBOT") continue;
|
|
320
|
+
const score = options.score(member);
|
|
321
|
+
if (score <= 0) continue;
|
|
322
|
+
matches.push({ user: member, score });
|
|
323
|
+
}
|
|
324
|
+
const nextCursor = result.response_metadata?.next_cursor;
|
|
325
|
+
if (!nextCursor) {
|
|
326
|
+
cursor = void 0;
|
|
327
|
+
break;
|
|
328
|
+
}
|
|
329
|
+
cursor = nextCursor;
|
|
330
|
+
}
|
|
331
|
+
return {
|
|
332
|
+
matches,
|
|
333
|
+
searched_pages: pages,
|
|
334
|
+
searched_user_count: totalScanned,
|
|
335
|
+
// True only when we hit the page cap with more data remaining.
|
|
336
|
+
truncated: pages >= options.maxPages && Boolean(cursor)
|
|
337
|
+
};
|
|
338
|
+
}
|
|
339
|
+
async function searchSlackUsers(options) {
|
|
340
|
+
const {
|
|
341
|
+
query,
|
|
342
|
+
limit = 10,
|
|
343
|
+
maxPages = 3,
|
|
344
|
+
includeDeleted = false,
|
|
345
|
+
includeBots = false
|
|
346
|
+
} = options;
|
|
347
|
+
const queryLower = query.toLowerCase().trim();
|
|
348
|
+
const listed = await listWorkspaceUsers({
|
|
349
|
+
maxPages,
|
|
350
|
+
includeDeleted,
|
|
351
|
+
includeBots,
|
|
352
|
+
score: (member) => scoreMatch(member, queryLower)
|
|
353
|
+
});
|
|
354
|
+
listed.matches.sort((a, b) => {
|
|
355
|
+
if (b.score !== a.score) return b.score - a.score;
|
|
356
|
+
return (a.user.name ?? "").localeCompare(b.user.name ?? "");
|
|
357
|
+
});
|
|
358
|
+
return {
|
|
359
|
+
users: listed.matches.slice(0, limit).map((m) => normalizeUser(m.user)),
|
|
360
|
+
searched_pages: listed.searched_pages,
|
|
361
|
+
searched_user_count: listed.searched_user_count,
|
|
362
|
+
truncated: listed.truncated
|
|
363
|
+
};
|
|
364
|
+
}
|
|
365
|
+
|
|
366
|
+
// src/chat/plugins/credential-hooks.ts
|
|
367
|
+
import {
|
|
368
|
+
pluginAuthorizationSchema,
|
|
369
|
+
pluginCredentialResultSchema,
|
|
370
|
+
pluginGrantSchema,
|
|
371
|
+
pluginProviderAccountSchema
|
|
372
|
+
} from "@sentry/junior-plugin-api";
|
|
373
|
+
function parseSchema(schema, value, message) {
|
|
374
|
+
const result = schema.safeParse(value);
|
|
375
|
+
if (!result.success) {
|
|
376
|
+
throw new Error(message);
|
|
377
|
+
}
|
|
378
|
+
return result.data;
|
|
379
|
+
}
|
|
380
|
+
function parseAuthorization(value, pluginName) {
|
|
381
|
+
if (value === void 0) {
|
|
382
|
+
return void 0;
|
|
383
|
+
}
|
|
384
|
+
const authorization = parseSchema(
|
|
385
|
+
pluginAuthorizationSchema,
|
|
386
|
+
value,
|
|
387
|
+
`Plugin "${pluginName}" grant authorization is invalid`
|
|
388
|
+
);
|
|
389
|
+
if (authorization.provider !== pluginName) {
|
|
390
|
+
throw new Error(
|
|
391
|
+
`Plugin "${pluginName}" grant authorization provider must match the issuing plugin`
|
|
392
|
+
);
|
|
393
|
+
}
|
|
394
|
+
return authorization;
|
|
395
|
+
}
|
|
396
|
+
function parseGrant(value, pluginName) {
|
|
397
|
+
return parseSchema(
|
|
398
|
+
pluginGrantSchema,
|
|
399
|
+
value,
|
|
400
|
+
`Plugin "${pluginName}" grantForEgress returned an invalid grant`
|
|
401
|
+
);
|
|
402
|
+
}
|
|
403
|
+
function pluginFor(provider) {
|
|
404
|
+
return getPlugins().find((candidate) => candidate.manifest.name === provider);
|
|
405
|
+
}
|
|
406
|
+
function basePluginContext(plugin) {
|
|
407
|
+
const pluginName = plugin.manifest.name;
|
|
408
|
+
return {
|
|
409
|
+
plugin: { name: pluginName },
|
|
410
|
+
log: createPluginLogger(pluginName),
|
|
411
|
+
db: getDb()
|
|
412
|
+
};
|
|
413
|
+
}
|
|
414
|
+
function parseCredentialResult(value, pluginName) {
|
|
415
|
+
const result = parseSchema(
|
|
416
|
+
pluginCredentialResultSchema,
|
|
417
|
+
value,
|
|
418
|
+
`Plugin "${pluginName}" issueCredential result is invalid`
|
|
419
|
+
);
|
|
420
|
+
if (result.type === "lease") {
|
|
421
|
+
parseAuthorization(result.lease.authorization, pluginName);
|
|
422
|
+
return result;
|
|
423
|
+
}
|
|
424
|
+
if (result.type === "unavailable") {
|
|
425
|
+
return result;
|
|
426
|
+
}
|
|
427
|
+
parseAuthorization(result.authorization, pluginName);
|
|
428
|
+
return result;
|
|
429
|
+
}
|
|
430
|
+
async function selectPluginGrant(input) {
|
|
431
|
+
const plugin = pluginFor(input.provider);
|
|
432
|
+
const hook = plugin?.hooks?.grantForEgress;
|
|
433
|
+
if (!plugin || !hook) {
|
|
434
|
+
return void 0;
|
|
435
|
+
}
|
|
436
|
+
const result = await hook({
|
|
437
|
+
...basePluginContext(plugin),
|
|
438
|
+
request: {
|
|
439
|
+
...input.bodyText !== void 0 ? { bodyText: input.bodyText } : {},
|
|
440
|
+
method: input.method,
|
|
441
|
+
...input.operation ? { operation: input.operation } : {},
|
|
442
|
+
url: input.upstreamUrl.toString()
|
|
443
|
+
}
|
|
444
|
+
});
|
|
445
|
+
return result === void 0 ? void 0 : parseGrant(result, plugin.manifest.name);
|
|
446
|
+
}
|
|
447
|
+
async function onPluginEgressResponse(input) {
|
|
448
|
+
const plugin = pluginFor(input.provider);
|
|
449
|
+
const hook = plugin?.hooks?.onEgressResponse;
|
|
450
|
+
if (!plugin || !hook) {
|
|
451
|
+
return {};
|
|
452
|
+
}
|
|
453
|
+
let permissionDenied;
|
|
454
|
+
await hook({
|
|
455
|
+
...basePluginContext(plugin),
|
|
456
|
+
grant: input.grant,
|
|
457
|
+
permissionDenied(message) {
|
|
458
|
+
const trimmed = message.trim();
|
|
459
|
+
if (!trimmed) {
|
|
460
|
+
throw new Error(
|
|
461
|
+
`Plugin "${plugin.manifest.name}" onEgressResponse permissionDenied message is empty`
|
|
462
|
+
);
|
|
463
|
+
}
|
|
464
|
+
permissionDenied = { message: trimmed };
|
|
465
|
+
},
|
|
466
|
+
request: {
|
|
467
|
+
method: input.method,
|
|
468
|
+
...input.operation ? { operation: input.operation } : {},
|
|
469
|
+
url: input.upstreamUrl.toString()
|
|
470
|
+
},
|
|
471
|
+
response: input.response
|
|
472
|
+
});
|
|
473
|
+
return permissionDenied ? { permissionDenied } : {};
|
|
474
|
+
}
|
|
475
|
+
function hasEgressCredentialHooks(provider) {
|
|
476
|
+
const hooks = pluginFor(provider)?.hooks;
|
|
477
|
+
return Boolean(hooks?.grantForEgress || hooks?.issueCredential);
|
|
478
|
+
}
|
|
479
|
+
function getOAuthAccountProviders() {
|
|
480
|
+
return getPlugins().filter((plugin) => Boolean(plugin.hooks?.resolveOAuthAccount)).map((plugin) => plugin.manifest.name);
|
|
481
|
+
}
|
|
482
|
+
async function resolvePluginOAuthAccount(input) {
|
|
483
|
+
const plugin = pluginFor(input.provider);
|
|
484
|
+
const hook = plugin?.hooks?.resolveOAuthAccount;
|
|
485
|
+
if (!plugin || !hook) {
|
|
486
|
+
return void 0;
|
|
487
|
+
}
|
|
488
|
+
const account = await hook({
|
|
489
|
+
...basePluginContext(plugin),
|
|
490
|
+
tokens: input.tokens
|
|
491
|
+
});
|
|
492
|
+
return account === void 0 ? void 0 : parseSchema(
|
|
493
|
+
pluginProviderAccountSchema,
|
|
494
|
+
account,
|
|
495
|
+
`Plugin "${plugin.manifest.name}" resolveOAuthAccount returned an invalid account`
|
|
496
|
+
);
|
|
497
|
+
}
|
|
498
|
+
async function issuePluginCredential(input) {
|
|
499
|
+
const plugin = pluginFor(input.provider);
|
|
500
|
+
const hook = plugin?.hooks?.issueCredential;
|
|
501
|
+
if (!plugin || !hook) {
|
|
502
|
+
throw new Error(`Plugin "${input.provider}" has no issueCredential hook`);
|
|
503
|
+
}
|
|
504
|
+
const currentUserId = "type" in input.actor ? input.actor.userId : void 0;
|
|
505
|
+
const credentialSubjectUserId = input.credentialSubject?.userId;
|
|
506
|
+
const result = await hook({
|
|
507
|
+
...basePluginContext(plugin),
|
|
508
|
+
actor: input.actor,
|
|
509
|
+
grant: input.grant,
|
|
510
|
+
...input.credentialSubject ? { credentialSubject: input.credentialSubject } : {},
|
|
511
|
+
tokens: {
|
|
512
|
+
...currentUserId ? {
|
|
513
|
+
currentUser: {
|
|
514
|
+
userId: currentUserId,
|
|
515
|
+
get: async () => await input.userTokenStore.get(
|
|
516
|
+
currentUserId,
|
|
517
|
+
plugin.manifest.name
|
|
518
|
+
),
|
|
519
|
+
set: async (tokens) => {
|
|
520
|
+
await input.userTokenStore.set(
|
|
521
|
+
currentUserId,
|
|
522
|
+
plugin.manifest.name,
|
|
523
|
+
tokens
|
|
524
|
+
);
|
|
525
|
+
},
|
|
526
|
+
withRefresh: async (callback) => await input.userTokenStore.withRefresh(
|
|
527
|
+
currentUserId,
|
|
528
|
+
plugin.manifest.name,
|
|
529
|
+
callback
|
|
530
|
+
)
|
|
531
|
+
}
|
|
532
|
+
} : {},
|
|
533
|
+
...credentialSubjectUserId ? {
|
|
534
|
+
credentialSubject: {
|
|
535
|
+
userId: credentialSubjectUserId,
|
|
536
|
+
get: async () => await input.userTokenStore.get(
|
|
537
|
+
credentialSubjectUserId,
|
|
538
|
+
plugin.manifest.name
|
|
539
|
+
),
|
|
540
|
+
set: async (tokens) => {
|
|
541
|
+
await input.userTokenStore.set(
|
|
542
|
+
credentialSubjectUserId,
|
|
543
|
+
plugin.manifest.name,
|
|
544
|
+
tokens
|
|
545
|
+
);
|
|
546
|
+
},
|
|
547
|
+
withRefresh: async (callback) => await input.userTokenStore.withRefresh(
|
|
548
|
+
credentialSubjectUserId,
|
|
549
|
+
plugin.manifest.name,
|
|
550
|
+
callback
|
|
551
|
+
)
|
|
552
|
+
}
|
|
553
|
+
} : {}
|
|
554
|
+
}
|
|
555
|
+
});
|
|
556
|
+
return parseCredentialResult(result, plugin.manifest.name);
|
|
557
|
+
}
|
|
558
|
+
|
|
212
559
|
// src/chat/mcp/auth-store.ts
|
|
213
560
|
import {
|
|
214
561
|
sourceSchema
|
|
@@ -284,7 +631,6 @@ function parseMcpAuthSession(value) {
|
|
|
284
631
|
...typeof parsed.threadTs === "string" ? { threadTs: parsed.threadTs } : {},
|
|
285
632
|
...typeof parsed.toolChannelId === "string" ? { toolChannelId: parsed.toolChannelId } : {},
|
|
286
633
|
...isRecord(parsed.configuration) ? { configuration: parsed.configuration } : {},
|
|
287
|
-
...isRecord(parsed.artifactState) ? { artifactState: parsed.artifactState } : {},
|
|
288
634
|
...typeof parsed.authorizationUrl === "string" ? { authorizationUrl: parsed.authorizationUrl } : {},
|
|
289
635
|
...typeof parsed.codeVerifier === "string" ? { codeVerifier: parsed.codeVerifier } : {}
|
|
290
636
|
};
|
|
@@ -683,8 +1029,7 @@ async function createMcpOAuthClientProvider(input) {
|
|
|
683
1029
|
...input.channelId ? { channelId: input.channelId } : {},
|
|
684
1030
|
...input.threadTs ? { threadTs: input.threadTs } : {},
|
|
685
1031
|
...input.toolChannelId ? { toolChannelId: input.toolChannelId } : {},
|
|
686
|
-
...input.configuration ? { configuration: input.configuration } : {}
|
|
687
|
-
...input.artifactState ? { artifactState: input.artifactState } : {}
|
|
1032
|
+
...input.configuration ? { configuration: input.configuration } : {}
|
|
688
1033
|
}
|
|
689
1034
|
);
|
|
690
1035
|
}
|
|
@@ -758,196 +1103,6 @@ async function finalizeMcpAuthorization(provider, authSessionId, authorizationCo
|
|
|
758
1103
|
return nextSession;
|
|
759
1104
|
}
|
|
760
1105
|
|
|
761
|
-
// src/chat/plugins/credential-hooks.ts
|
|
762
|
-
import {
|
|
763
|
-
pluginAuthorizationSchema,
|
|
764
|
-
pluginCredentialResultSchema,
|
|
765
|
-
pluginGrantSchema,
|
|
766
|
-
pluginProviderAccountSchema
|
|
767
|
-
} from "@sentry/junior-plugin-api";
|
|
768
|
-
function parseSchema(schema, value, message) {
|
|
769
|
-
const result = schema.safeParse(value);
|
|
770
|
-
if (!result.success) {
|
|
771
|
-
throw new Error(message);
|
|
772
|
-
}
|
|
773
|
-
return result.data;
|
|
774
|
-
}
|
|
775
|
-
function parseAuthorization(value, pluginName) {
|
|
776
|
-
if (value === void 0) {
|
|
777
|
-
return void 0;
|
|
778
|
-
}
|
|
779
|
-
const authorization = parseSchema(
|
|
780
|
-
pluginAuthorizationSchema,
|
|
781
|
-
value,
|
|
782
|
-
`Plugin "${pluginName}" grant authorization is invalid`
|
|
783
|
-
);
|
|
784
|
-
if (authorization.provider !== pluginName) {
|
|
785
|
-
throw new Error(
|
|
786
|
-
`Plugin "${pluginName}" grant authorization provider must match the issuing plugin`
|
|
787
|
-
);
|
|
788
|
-
}
|
|
789
|
-
return authorization;
|
|
790
|
-
}
|
|
791
|
-
function parseGrant(value, pluginName) {
|
|
792
|
-
return parseSchema(
|
|
793
|
-
pluginGrantSchema,
|
|
794
|
-
value,
|
|
795
|
-
`Plugin "${pluginName}" grantForEgress returned an invalid grant`
|
|
796
|
-
);
|
|
797
|
-
}
|
|
798
|
-
function pluginFor(provider) {
|
|
799
|
-
return getPlugins().find((candidate) => candidate.manifest.name === provider);
|
|
800
|
-
}
|
|
801
|
-
function basePluginContext(plugin) {
|
|
802
|
-
const pluginName = plugin.manifest.name;
|
|
803
|
-
return {
|
|
804
|
-
plugin: { name: pluginName },
|
|
805
|
-
log: createPluginLogger(pluginName),
|
|
806
|
-
db: getDb()
|
|
807
|
-
};
|
|
808
|
-
}
|
|
809
|
-
function parseCredentialResult(value, pluginName) {
|
|
810
|
-
const result = parseSchema(
|
|
811
|
-
pluginCredentialResultSchema,
|
|
812
|
-
value,
|
|
813
|
-
`Plugin "${pluginName}" issueCredential result is invalid`
|
|
814
|
-
);
|
|
815
|
-
if (result.type === "lease") {
|
|
816
|
-
parseAuthorization(result.lease.authorization, pluginName);
|
|
817
|
-
return result;
|
|
818
|
-
}
|
|
819
|
-
if (result.type === "unavailable") {
|
|
820
|
-
return result;
|
|
821
|
-
}
|
|
822
|
-
parseAuthorization(result.authorization, pluginName);
|
|
823
|
-
return result;
|
|
824
|
-
}
|
|
825
|
-
async function selectPluginGrant(input) {
|
|
826
|
-
const plugin = pluginFor(input.provider);
|
|
827
|
-
const hook = plugin?.hooks?.grantForEgress;
|
|
828
|
-
if (!plugin || !hook) {
|
|
829
|
-
return void 0;
|
|
830
|
-
}
|
|
831
|
-
const result = await hook({
|
|
832
|
-
...basePluginContext(plugin),
|
|
833
|
-
request: {
|
|
834
|
-
...input.bodyText !== void 0 ? { bodyText: input.bodyText } : {},
|
|
835
|
-
method: input.method,
|
|
836
|
-
...input.operation ? { operation: input.operation } : {},
|
|
837
|
-
url: input.upstreamUrl.toString()
|
|
838
|
-
}
|
|
839
|
-
});
|
|
840
|
-
return result === void 0 ? void 0 : parseGrant(result, plugin.manifest.name);
|
|
841
|
-
}
|
|
842
|
-
async function onPluginEgressResponse(input) {
|
|
843
|
-
const plugin = pluginFor(input.provider);
|
|
844
|
-
const hook = plugin?.hooks?.onEgressResponse;
|
|
845
|
-
if (!plugin || !hook) {
|
|
846
|
-
return {};
|
|
847
|
-
}
|
|
848
|
-
let permissionDenied;
|
|
849
|
-
await hook({
|
|
850
|
-
...basePluginContext(plugin),
|
|
851
|
-
grant: input.grant,
|
|
852
|
-
permissionDenied(message) {
|
|
853
|
-
const trimmed = message.trim();
|
|
854
|
-
if (!trimmed) {
|
|
855
|
-
throw new Error(
|
|
856
|
-
`Plugin "${plugin.manifest.name}" onEgressResponse permissionDenied message is empty`
|
|
857
|
-
);
|
|
858
|
-
}
|
|
859
|
-
permissionDenied = { message: trimmed };
|
|
860
|
-
},
|
|
861
|
-
request: {
|
|
862
|
-
method: input.method,
|
|
863
|
-
...input.operation ? { operation: input.operation } : {},
|
|
864
|
-
url: input.upstreamUrl.toString()
|
|
865
|
-
},
|
|
866
|
-
response: input.response
|
|
867
|
-
});
|
|
868
|
-
return permissionDenied ? { permissionDenied } : {};
|
|
869
|
-
}
|
|
870
|
-
function hasEgressCredentialHooks(provider) {
|
|
871
|
-
const hooks = pluginFor(provider)?.hooks;
|
|
872
|
-
return Boolean(hooks?.grantForEgress || hooks?.issueCredential);
|
|
873
|
-
}
|
|
874
|
-
async function resolvePluginOAuthAccount(input) {
|
|
875
|
-
const plugin = pluginFor(input.provider);
|
|
876
|
-
const hook = plugin?.hooks?.resolveOAuthAccount;
|
|
877
|
-
if (!plugin || !hook) {
|
|
878
|
-
return void 0;
|
|
879
|
-
}
|
|
880
|
-
const account = await hook({
|
|
881
|
-
...basePluginContext(plugin),
|
|
882
|
-
tokens: input.tokens
|
|
883
|
-
});
|
|
884
|
-
return account === void 0 ? void 0 : parseSchema(
|
|
885
|
-
pluginProviderAccountSchema,
|
|
886
|
-
account,
|
|
887
|
-
`Plugin "${plugin.manifest.name}" resolveOAuthAccount returned an invalid account`
|
|
888
|
-
);
|
|
889
|
-
}
|
|
890
|
-
async function issuePluginCredential(input) {
|
|
891
|
-
const plugin = pluginFor(input.provider);
|
|
892
|
-
const hook = plugin?.hooks?.issueCredential;
|
|
893
|
-
if (!plugin || !hook) {
|
|
894
|
-
throw new Error(`Plugin "${input.provider}" has no issueCredential hook`);
|
|
895
|
-
}
|
|
896
|
-
const currentUserId = "type" in input.actor ? input.actor.userId : void 0;
|
|
897
|
-
const credentialSubjectUserId = input.credentialSubject?.userId;
|
|
898
|
-
const result = await hook({
|
|
899
|
-
...basePluginContext(plugin),
|
|
900
|
-
actor: input.actor,
|
|
901
|
-
grant: input.grant,
|
|
902
|
-
...input.credentialSubject ? { credentialSubject: input.credentialSubject } : {},
|
|
903
|
-
tokens: {
|
|
904
|
-
...currentUserId ? {
|
|
905
|
-
currentUser: {
|
|
906
|
-
userId: currentUserId,
|
|
907
|
-
get: async () => await input.userTokenStore.get(
|
|
908
|
-
currentUserId,
|
|
909
|
-
plugin.manifest.name
|
|
910
|
-
),
|
|
911
|
-
set: async (tokens) => {
|
|
912
|
-
await input.userTokenStore.set(
|
|
913
|
-
currentUserId,
|
|
914
|
-
plugin.manifest.name,
|
|
915
|
-
tokens
|
|
916
|
-
);
|
|
917
|
-
},
|
|
918
|
-
withRefresh: async (callback) => await input.userTokenStore.withRefresh(
|
|
919
|
-
currentUserId,
|
|
920
|
-
plugin.manifest.name,
|
|
921
|
-
callback
|
|
922
|
-
)
|
|
923
|
-
}
|
|
924
|
-
} : {},
|
|
925
|
-
...credentialSubjectUserId ? {
|
|
926
|
-
credentialSubject: {
|
|
927
|
-
userId: credentialSubjectUserId,
|
|
928
|
-
get: async () => await input.userTokenStore.get(
|
|
929
|
-
credentialSubjectUserId,
|
|
930
|
-
plugin.manifest.name
|
|
931
|
-
),
|
|
932
|
-
set: async (tokens) => {
|
|
933
|
-
await input.userTokenStore.set(
|
|
934
|
-
credentialSubjectUserId,
|
|
935
|
-
plugin.manifest.name,
|
|
936
|
-
tokens
|
|
937
|
-
);
|
|
938
|
-
},
|
|
939
|
-
withRefresh: async (callback) => await input.userTokenStore.withRefresh(
|
|
940
|
-
credentialSubjectUserId,
|
|
941
|
-
plugin.manifest.name,
|
|
942
|
-
callback
|
|
943
|
-
)
|
|
944
|
-
}
|
|
945
|
-
} : {}
|
|
946
|
-
}
|
|
947
|
-
});
|
|
948
|
-
return parseCredentialResult(result, plugin.manifest.name);
|
|
949
|
-
}
|
|
950
|
-
|
|
951
1106
|
export {
|
|
952
1107
|
createUserTokenStore,
|
|
953
1108
|
issueProviderCredentialLease,
|
|
@@ -957,6 +1112,15 @@ export {
|
|
|
957
1112
|
McpToolError,
|
|
958
1113
|
getMcpAwareErrorType,
|
|
959
1114
|
getMcpAwareTelemetryMessage,
|
|
1115
|
+
lookupSlackUserProfile,
|
|
1116
|
+
lookupSlackUserByEmail,
|
|
1117
|
+
searchSlackUsers,
|
|
1118
|
+
selectPluginGrant,
|
|
1119
|
+
onPluginEgressResponse,
|
|
1120
|
+
hasEgressCredentialHooks,
|
|
1121
|
+
getOAuthAccountProviders,
|
|
1122
|
+
resolvePluginOAuthAccount,
|
|
1123
|
+
issuePluginCredential,
|
|
960
1124
|
getMcpAuthSession,
|
|
961
1125
|
patchMcpAuthSession,
|
|
962
1126
|
deleteMcpAuthSession,
|
|
@@ -965,10 +1129,5 @@ export {
|
|
|
965
1129
|
deleteMcpStoredOAuthCredentials,
|
|
966
1130
|
deleteMcpServerSessionId,
|
|
967
1131
|
createMcpOAuthClientProvider,
|
|
968
|
-
finalizeMcpAuthorization
|
|
969
|
-
selectPluginGrant,
|
|
970
|
-
onPluginEgressResponse,
|
|
971
|
-
hasEgressCredentialHooks,
|
|
972
|
-
resolvePluginOAuthAccount,
|
|
973
|
-
issuePluginCredential
|
|
1132
|
+
finalizeMcpAuthorization
|
|
974
1133
|
};
|
|
@@ -3,7 +3,7 @@ import {
|
|
|
3
3
|
} from "./chunk-EM225ITJ.js";
|
|
4
4
|
import {
|
|
5
5
|
getSlackBotToken
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-7NVJVJID.js";
|
|
7
7
|
import {
|
|
8
8
|
parseSlackChannelReferenceId
|
|
9
9
|
} from "./chunk-F3B2YJ76.js";
|
|
@@ -12,7 +12,7 @@ import {
|
|
|
12
12
|
setSpanAttributes,
|
|
13
13
|
setSpanStatus,
|
|
14
14
|
withSpan
|
|
15
|
-
} from "./chunk-
|
|
15
|
+
} from "./chunk-4LJO56OJ.js";
|
|
16
16
|
|
|
17
17
|
// src/chat/slack/client.ts
|
|
18
18
|
import { AsyncLocalStorage as AsyncLocalStorage2 } from "async_hooks";
|
|
@@ -242,6 +242,7 @@ var conversationReportTurnRoutedEventDataSchema = z2.object({
|
|
|
242
242
|
turnId: z2.string().min(1),
|
|
243
243
|
modelProfile: z2.string().min(1),
|
|
244
244
|
modelId: z2.string().min(1),
|
|
245
|
+
costUsd: z2.number().finite().nonnegative().optional(),
|
|
245
246
|
reasoningLevel: z2.string().min(1),
|
|
246
247
|
confidence: z2.number().min(0).max(1).optional(),
|
|
247
248
|
source: z2.enum(["configured", "inherited", "router"])
|
|
@@ -4,24 +4,24 @@ import {
|
|
|
4
4
|
import {
|
|
5
5
|
formatProviderLabel,
|
|
6
6
|
startOAuthFlow
|
|
7
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-7UQIVT6G.js";
|
|
8
8
|
import {
|
|
9
9
|
abandonReplacedPendingAuth,
|
|
10
10
|
canReusePendingAuthLink,
|
|
11
11
|
recordAuthorizationRequested
|
|
12
|
-
} from "./chunk-
|
|
12
|
+
} from "./chunk-AIOK6LAG.js";
|
|
13
13
|
import {
|
|
14
14
|
parseSandboxEgressAuthRequiredSignal
|
|
15
15
|
} from "./chunk-HUO3UTAQ.js";
|
|
16
16
|
import {
|
|
17
17
|
AGENT_INVOCATION_MAILBOX_STATUSES
|
|
18
|
-
} from "./chunk-
|
|
18
|
+
} from "./chunk-DU74WPIC.js";
|
|
19
19
|
import {
|
|
20
20
|
TURN_REASONING_LEVELS
|
|
21
|
-
} from "./chunk-
|
|
21
|
+
} from "./chunk-7NVJVJID.js";
|
|
22
22
|
import {
|
|
23
23
|
pluginCatalogRuntime
|
|
24
|
-
} from "./chunk-
|
|
24
|
+
} from "./chunk-JUUKWRBE.js";
|
|
25
25
|
import {
|
|
26
26
|
credentialContextSchema
|
|
27
27
|
} from "./chunk-RUIXF3YQ.js";
|
|
@@ -128,6 +128,7 @@ function createPluginAuthOrchestration(input) {
|
|
|
128
128
|
if (!reusingPendingLink) {
|
|
129
129
|
const oauthResult = await startOAuthFlow(provider, {
|
|
130
130
|
actorId: input.actorId,
|
|
131
|
+
...input.actor ? { actor: input.actor } : {},
|
|
131
132
|
channelId: input.channelId,
|
|
132
133
|
destination: input.destination,
|
|
133
134
|
source: input.source,
|