@sentry/junior 0.99.0 → 0.101.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/README.md +0 -1
- package/dist/{agent-hooks-OSW6C3CJ.js → agent-hooks-V6KU7PQN.js} +6 -5
- package/dist/api/activity.d.ts +14 -0
- package/dist/api/conversations/aggregate.d.ts +16 -0
- package/dist/api/conversations/detail-projection.d.ts +1 -0
- package/dist/api/conversations/list.query.d.ts +3 -0
- package/dist/api/conversations/projection.d.ts +1 -0
- package/dist/api/conversations/reporting.d.ts +42 -0
- package/dist/api/conversations/schema.d.ts +9 -9
- package/dist/api/conversations/stats.query.d.ts +1 -1
- package/dist/api/locations/detail.d.ts +81 -0
- package/dist/api/locations/list.d.ts +30 -0
- package/dist/api/locations/query.d.ts +5 -0
- package/dist/api/locations/schema.d.ts +175 -0
- package/dist/api/people/list.query.d.ts +1 -1
- package/dist/api/people/profile.query.d.ts +1 -1
- package/dist/api/people/schema.d.ts +10 -14
- package/dist/api/people/shared.d.ts +38 -78
- package/dist/api/schema.d.ts +8 -0
- package/dist/api/schema.js +14 -3
- package/dist/api.js +24 -11
- package/dist/app.js +126 -70
- package/dist/chat/agent/request.d.ts +4 -1
- package/dist/chat/config.d.ts +2 -0
- package/dist/chat/conversations/store.d.ts +1 -1
- package/dist/chat/mcp/auth-store.d.ts +1 -0
- package/dist/chat/mcp/client.d.ts +2 -0
- package/dist/chat/mcp/oauth-provider.d.ts +4 -1
- package/dist/chat/mcp/oauth.d.ts +3 -1
- package/dist/chat/mcp/tool-manager.d.ts +2 -0
- package/dist/chat/reasoning-level.d.ts +4 -0
- package/dist/chat/services/mcp-auth-orchestration.d.ts +1 -1
- package/dist/chat/services/pending-auth.d.ts +17 -9
- package/dist/chat/services/{turn-thinking-level.d.ts → turn-reasoning-level.d.ts} +11 -10
- package/dist/chat/services/turn-result.d.ts +3 -3
- package/dist/chat/state/conversation.d.ts +7 -3
- package/dist/chat/tools/search-tools.d.ts +2 -2
- package/dist/{chunk-T55RBE4Z.js → chunk-2RNOB32R.js} +3 -1
- package/dist/{chunk-ZZUBLPXD.js → chunk-5VGJJSSV.js} +9 -7
- package/dist/{chunk-EEZCY5WX.js → chunk-A7X2FDUO.js} +18 -2
- package/dist/{chunk-CRQVIHDI.js → chunk-DBPLXSBK.js} +2 -8
- package/dist/{chunk-NJEDJFK4.js → chunk-EBFJOOUE.js} +2 -2
- package/dist/{chunk-WTYEKPXU.js → chunk-FP5N5OWZ.js} +1 -1
- package/dist/chunk-FXFQNHRU.js +48 -0
- package/dist/chunk-GEUUJRQF.js +102 -0
- package/dist/chunk-HNIT4HXU.js +75 -0
- package/dist/{chunk-EUZ44ROE.js → chunk-HYDQULR2.js} +2 -4
- package/dist/{chunk-DHHU2WSG.js → chunk-IQIBZXGB.js} +2 -2
- package/dist/{chunk-OL6XQ23W.js → chunk-IVXL57YF.js} +3 -3
- package/dist/{chunk-IO65E4ZD.js → chunk-JPQISMMJ.js} +3 -3
- package/dist/{chunk-KFUSLFLL.js → chunk-JSAANELJ.js} +11 -4
- package/dist/{chunk-ER45IV77.js → chunk-L2JIOAA2.js} +10 -10
- package/dist/chunk-PGGEOCQY.js +77 -0
- package/dist/{chunk-EOWXRY5E.js → chunk-PWC24W5F.js} +1 -1
- package/dist/chunk-QOZOJNSE.js +96 -0
- package/dist/{chunk-FTTFV6DC.js → chunk-TPTJEHUE.js} +4 -4
- package/dist/{chunk-PYK7R5A7.js → chunk-UWGTSF5O.js} +285 -174
- package/dist/chunk-VFBFK6EY.js +275 -0
- package/dist/{chunk-OGHXZ4KQ.js → chunk-VHRM6GNH.js} +88 -122
- package/dist/{chunk-NG2AV7IB.js → chunk-VVIXK2BX.js} +1 -1
- package/dist/{chunk-6DTVCPLO.js → chunk-XIMUQ4IU.js} +4 -3
- package/dist/{chunk-H66UCBPW.js → chunk-XJA7BPHS.js} +1 -1
- package/dist/{chunk-WJ7STXT6.js → chunk-XVR4O24H.js} +8 -10
- package/dist/cli/chat.js +16 -15
- package/dist/cli/plugins.js +6 -5
- package/dist/cli/snapshot-warmup.js +2 -2
- package/dist/cli/upgrade.js +126 -8
- package/dist/db/schema/conversations.d.ts +17 -0
- package/dist/db/schema/destinations.d.ts +12 -3
- package/dist/db/schema.d.ts +19 -2
- package/dist/{db-GFSCDAHS.js → db-RCZB7KNM.js} +3 -2
- package/dist/{detail-Q4IVDNGS.js → detail-4EPUMSDU.js} +11 -10
- package/dist/detail-CD4SPJ4K.js +29 -0
- package/dist/{legacy-import-6WWXMALY.js → legacy-import-VCYLWT2V.js} +4 -3
- package/dist/list-7L5LY2WU.js +30 -0
- package/dist/list-DA2ATOM4.js +80 -0
- package/dist/{list-A3F5JDYV.js → list-J6ROVH56.js} +7 -6
- package/dist/{plugin-conversations-PDCQWU3O.js → plugin-conversations-JANXC4GA.js} +6 -5
- package/dist/profile-6NRWEKMZ.js +212 -0
- package/dist/{runner-267ZRLZD.js → runner-CZIKSWGC.js} +13 -12
- package/dist/stats-Q5FRUXLY.js +174 -0
- package/dist/{subagent-UN3MP6LV.js → subagent-YIINCFAS.js} +10 -9
- package/migrations/0003_peaceful_scalphunter.sql +4 -0
- package/migrations/meta/0003_snapshot.json +1035 -0
- package/migrations/meta/_journal.json +8 -1
- package/package.json +6 -6
- package/dist/api-reference.d.ts +0 -14
- package/dist/chunk-CV22LUIV.js +0 -261
- package/dist/list-M5BRWW3D.js +0 -92
- package/dist/profile-UEIRSVT3.js +0 -146
- package/dist/stats-L62E4O4U.js +0 -207
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import {
|
|
2
2
|
CooperativeTurnYieldError,
|
|
3
3
|
TurnInputCommitLostError,
|
|
4
|
+
abandonReplacedPendingAuth,
|
|
4
5
|
canReusePendingAuthLink,
|
|
5
6
|
getInterruptionMarker,
|
|
6
7
|
isTurnInputCommitLostError,
|
|
@@ -10,14 +11,14 @@ import {
|
|
|
10
11
|
persistRunningSessionRecord,
|
|
11
12
|
persistTimeoutSessionRecord,
|
|
12
13
|
persistYieldSessionRecord
|
|
13
|
-
} from "./chunk-
|
|
14
|
+
} from "./chunk-XVR4O24H.js";
|
|
14
15
|
import {
|
|
15
16
|
JUNIOR_THREAD_STATE_TTL_MS
|
|
16
|
-
} from "./chunk-
|
|
17
|
+
} from "./chunk-XIMUQ4IU.js";
|
|
17
18
|
import {
|
|
18
19
|
addAgentTurnUsage,
|
|
19
20
|
hasAgentTurnUsage
|
|
20
|
-
} from "./chunk-
|
|
21
|
+
} from "./chunk-IVXL57YF.js";
|
|
21
22
|
import {
|
|
22
23
|
loadConnectedMcpProviders,
|
|
23
24
|
loadConversationProjection,
|
|
@@ -25,12 +26,12 @@ import {
|
|
|
25
26
|
recordAuthorizationRequested,
|
|
26
27
|
recordMcpProviderConnected,
|
|
27
28
|
recordToolExecutionStarted
|
|
28
|
-
} from "./chunk-
|
|
29
|
+
} from "./chunk-IQIBZXGB.js";
|
|
29
30
|
import {
|
|
30
31
|
estimateTextTokens,
|
|
31
32
|
getAgentContextCompactionTriggerTokens,
|
|
32
33
|
updateConversationStats
|
|
33
|
-
} from "./chunk-
|
|
34
|
+
} from "./chunk-JPQISMMJ.js";
|
|
34
35
|
import {
|
|
35
36
|
buildNonInteractiveShellScript,
|
|
36
37
|
createSandboxInstance,
|
|
@@ -40,7 +41,7 @@ import {
|
|
|
40
41
|
isSnapshotMissingError,
|
|
41
42
|
resolveRuntimeDependencySnapshot,
|
|
42
43
|
runNonInteractiveCommand
|
|
43
|
-
} from "./chunk-
|
|
44
|
+
} from "./chunk-XJA7BPHS.js";
|
|
44
45
|
import {
|
|
45
46
|
privateTraceResultAttributes
|
|
46
47
|
} from "./chunk-CM5EZD5F.js";
|
|
@@ -52,7 +53,7 @@ import {
|
|
|
52
53
|
getPlugins,
|
|
53
54
|
getSlackToolContext,
|
|
54
55
|
resolveChannelCapabilities
|
|
55
|
-
} from "./chunk-
|
|
56
|
+
} from "./chunk-TPTJEHUE.js";
|
|
56
57
|
import {
|
|
57
58
|
SlackActionError,
|
|
58
59
|
downloadPrivateSlackFile,
|
|
@@ -62,10 +63,10 @@ import {
|
|
|
62
63
|
isDmChannel,
|
|
63
64
|
normalizeSlackConversationId,
|
|
64
65
|
withSlackRetries
|
|
65
|
-
} from "./chunk-
|
|
66
|
+
} from "./chunk-FP5N5OWZ.js";
|
|
66
67
|
import {
|
|
67
68
|
createPluginLogger
|
|
68
|
-
} from "./chunk-
|
|
69
|
+
} from "./chunk-PWC24W5F.js";
|
|
69
70
|
import {
|
|
70
71
|
contextProvenance,
|
|
71
72
|
getAgentStepStore,
|
|
@@ -74,7 +75,7 @@ import {
|
|
|
74
75
|
getDb,
|
|
75
76
|
instructionActors,
|
|
76
77
|
instructionProvenanceFor
|
|
77
|
-
} from "./chunk-
|
|
78
|
+
} from "./chunk-VHRM6GNH.js";
|
|
78
79
|
import {
|
|
79
80
|
SANDBOX_DATA_ROOT,
|
|
80
81
|
SANDBOX_SKILLS_ROOT,
|
|
@@ -94,6 +95,7 @@ import {
|
|
|
94
95
|
ModelProfileNotConfiguredError,
|
|
95
96
|
STANDARD_MODEL_PROFILE,
|
|
96
97
|
TURN_CONTEXT_TAG,
|
|
98
|
+
TURN_REASONING_LEVELS,
|
|
97
99
|
acquireActiveLock,
|
|
98
100
|
botConfig,
|
|
99
101
|
completeObject,
|
|
@@ -119,7 +121,7 @@ import {
|
|
|
119
121
|
stripRuntimeTurnContext,
|
|
120
122
|
trimTrailingAssistantMessages,
|
|
121
123
|
unwrapCurrentInstruction
|
|
122
|
-
} from "./chunk-
|
|
124
|
+
} from "./chunk-A7X2FDUO.js";
|
|
123
125
|
import {
|
|
124
126
|
parseSlackThreadId,
|
|
125
127
|
resolveConversationPrivacy,
|
|
@@ -687,7 +689,7 @@ function buildTurnResult(input) {
|
|
|
687
689
|
shouldTrace,
|
|
688
690
|
spanContext,
|
|
689
691
|
usage,
|
|
690
|
-
|
|
692
|
+
reasoningSelection,
|
|
691
693
|
correlation,
|
|
692
694
|
assistantUserName,
|
|
693
695
|
modelId
|
|
@@ -817,7 +819,7 @@ function buildTurnResult(input) {
|
|
|
817
819
|
outcome: resolvedOutcome,
|
|
818
820
|
modelId,
|
|
819
821
|
assistantMessageCount: assistantMessages.length,
|
|
820
|
-
|
|
822
|
+
reasoningLevel: reasoningSelection.reasoningLevel,
|
|
821
823
|
toolCalls,
|
|
822
824
|
toolResultCount: toolResults.length,
|
|
823
825
|
toolErrorCount,
|
|
@@ -840,20 +842,13 @@ function buildTurnResult(input) {
|
|
|
840
842
|
};
|
|
841
843
|
}
|
|
842
844
|
|
|
843
|
-
// src/chat/services/turn-
|
|
845
|
+
// src/chat/services/turn-reasoning-level.ts
|
|
844
846
|
import { z } from "zod";
|
|
845
847
|
var CLASSIFIER_CONFIDENCE_THRESHOLD = 0.75;
|
|
846
848
|
var MAX_ROUTER_CONTEXT_CHARS = 8e3;
|
|
847
849
|
var ROUTER_CONTEXT_HEAD_CHARS = 3e3;
|
|
848
850
|
var ROUTER_CONTEXT_TAIL_CHARS = 5e3;
|
|
849
851
|
var TRUNCATION_MARKER = "\n\u2026[truncated]\u2026\n";
|
|
850
|
-
var TURN_THINKING_LEVELS = [
|
|
851
|
-
"none",
|
|
852
|
-
"low",
|
|
853
|
-
"medium",
|
|
854
|
-
"high",
|
|
855
|
-
"xhigh"
|
|
856
|
-
];
|
|
857
852
|
var CONFIDENCE_LABELS = {
|
|
858
853
|
low: 0.5,
|
|
859
854
|
medium: CLASSIFIER_CONFIDENCE_THRESHOLD,
|
|
@@ -874,15 +869,15 @@ function coerceClassifierConfidence(value) {
|
|
|
874
869
|
return CONFIDENCE_LABELS[trimmed] ?? value;
|
|
875
870
|
}
|
|
876
871
|
var turnExecutionProfileSchema = z.object({
|
|
877
|
-
|
|
872
|
+
reasoning_level: z.enum(TURN_REASONING_LEVELS),
|
|
878
873
|
confidence: z.preprocess(
|
|
879
874
|
coerceClassifierConfidence,
|
|
880
875
|
z.number().min(0).max(1)
|
|
881
876
|
),
|
|
882
877
|
reason: z.string().min(1)
|
|
883
878
|
});
|
|
884
|
-
var
|
|
885
|
-
var
|
|
879
|
+
var CLASSIFIER_FALLBACK_REASONING_LEVEL = "medium";
|
|
880
|
+
var REASONING_LEVEL_RANK = {
|
|
886
881
|
none: 0,
|
|
887
882
|
low: 1,
|
|
888
883
|
medium: 2,
|
|
@@ -911,7 +906,7 @@ function trimContextForRouter(text) {
|
|
|
911
906
|
}
|
|
912
907
|
function buildClassifierSystemPrompt() {
|
|
913
908
|
return [
|
|
914
|
-
"You route assistant turns to the
|
|
909
|
+
"You route assistant turns to the reasoning level most likely to produce a complete, source-grounded answer.",
|
|
915
910
|
"Choose exactly one bucket: none, low, medium, high, or xhigh.",
|
|
916
911
|
"",
|
|
917
912
|
"Use none only for greetings, acknowledgments, and turns that need no substantive assistant work.",
|
|
@@ -923,7 +918,7 @@ function buildClassifierSystemPrompt() {
|
|
|
923
918
|
"",
|
|
924
919
|
"Classify based on the substance of the task, not the length of the current message. When the current instruction is a short affirmation (for example: 'go', 'do it', 'yes please', 'proceed') and prior thread context contains a pending task, classify the pending task \u2014 not the affirmation.",
|
|
925
920
|
"",
|
|
926
|
-
"Return JSON only with
|
|
921
|
+
"Return JSON only with reasoning_level, confidence, and reason.",
|
|
927
922
|
"confidence must be a number from 0 to 1, not a word label."
|
|
928
923
|
].join("\n");
|
|
929
924
|
}
|
|
@@ -952,7 +947,13 @@ function buildClassifierPrompt(args) {
|
|
|
952
947
|
}
|
|
953
948
|
return sections.join("\n");
|
|
954
949
|
}
|
|
955
|
-
|
|
950
|
+
function configuredTurnReasoningLevel(reasoningLevel, source) {
|
|
951
|
+
return {
|
|
952
|
+
reasoningLevel,
|
|
953
|
+
reason: `configured:${source}`
|
|
954
|
+
};
|
|
955
|
+
}
|
|
956
|
+
async function selectTurnReasoningLevel(args) {
|
|
956
957
|
const trimmedContext = trimContextForRouter(args.conversationContext);
|
|
957
958
|
const instructionLength = args.messageText.trim().length;
|
|
958
959
|
const turnBlockCount = (args.currentTurnBlocks ?? []).filter(
|
|
@@ -971,8 +972,8 @@ async function selectTurnThinkingLevel(args) {
|
|
|
971
972
|
modelId: args.fastModelId
|
|
972
973
|
};
|
|
973
974
|
return withSpan(
|
|
974
|
-
"chat.
|
|
975
|
-
"chat.
|
|
975
|
+
"chat.route_reasoning",
|
|
976
|
+
"chat.route_reasoning",
|
|
976
977
|
logContext,
|
|
977
978
|
async () => {
|
|
978
979
|
setSpanAttributes({
|
|
@@ -994,29 +995,29 @@ async function selectTurnThinkingLevel(args) {
|
|
|
994
995
|
},
|
|
995
996
|
prompt
|
|
996
997
|
});
|
|
997
|
-
const normalizedSelection =
|
|
998
|
+
const normalizedSelection = applyReasoningFloor(selection, {
|
|
998
999
|
minimum: trimmedContext || turnBlockCount > 0 ? "medium" : void 0
|
|
999
1000
|
});
|
|
1000
1001
|
setSpanAttributes({
|
|
1001
|
-
"app.ai.
|
|
1002
|
-
"app.ai.
|
|
1002
|
+
"app.ai.reasoning_level": normalizedSelection.reasoningLevel,
|
|
1003
|
+
"app.ai.reasoning_level_reason": normalizedSelection.reason,
|
|
1003
1004
|
...normalizedSelection.confidence !== void 0 ? {
|
|
1004
|
-
"app.ai.
|
|
1005
|
+
"app.ai.reasoning_level_confidence": normalizedSelection.confidence
|
|
1005
1006
|
} : {}
|
|
1006
1007
|
});
|
|
1007
1008
|
return normalizedSelection;
|
|
1008
1009
|
}
|
|
1009
1010
|
);
|
|
1010
1011
|
}
|
|
1011
|
-
function
|
|
1012
|
+
function applyReasoningFloor(selection, args) {
|
|
1012
1013
|
const minimum = args.minimum;
|
|
1013
|
-
if (!minimum || selection.
|
|
1014
|
+
if (!minimum || selection.reasoningLevel === "none" || REASONING_LEVEL_RANK[selection.reasoningLevel] >= REASONING_LEVEL_RANK[minimum]) {
|
|
1014
1015
|
return selection;
|
|
1015
1016
|
}
|
|
1016
1017
|
return {
|
|
1017
1018
|
...selection,
|
|
1018
|
-
|
|
1019
|
-
reason: `
|
|
1019
|
+
reasoningLevel: minimum,
|
|
1020
|
+
reason: `reasoning_floor:${minimum}:${selection.reason}`
|
|
1020
1021
|
};
|
|
1021
1022
|
}
|
|
1022
1023
|
async function classifyTurn(args) {
|
|
@@ -1036,23 +1037,23 @@ async function classifyTurn(args) {
|
|
|
1036
1037
|
if (parsed.confidence < CLASSIFIER_CONFIDENCE_THRESHOLD) {
|
|
1037
1038
|
return {
|
|
1038
1039
|
confidence: parsed.confidence,
|
|
1039
|
-
|
|
1040
|
+
reasoningLevel: CLASSIFIER_FALLBACK_REASONING_LEVEL,
|
|
1040
1041
|
reason: `low_confidence_medium_default:${reason}`
|
|
1041
1042
|
};
|
|
1042
1043
|
}
|
|
1043
1044
|
return {
|
|
1044
1045
|
confidence: parsed.confidence,
|
|
1045
|
-
|
|
1046
|
+
reasoningLevel: parsed.reasoning_level,
|
|
1046
1047
|
reason
|
|
1047
1048
|
};
|
|
1048
1049
|
} catch {
|
|
1049
1050
|
return {
|
|
1050
|
-
|
|
1051
|
+
reasoningLevel: CLASSIFIER_FALLBACK_REASONING_LEVEL,
|
|
1051
1052
|
reason: "classifier_error_default"
|
|
1052
1053
|
};
|
|
1053
1054
|
}
|
|
1054
1055
|
}
|
|
1055
|
-
function
|
|
1056
|
+
function toPiReasoningLevel(level) {
|
|
1056
1057
|
switch (level) {
|
|
1057
1058
|
case "none":
|
|
1058
1059
|
return "off";
|
|
@@ -3151,6 +3152,7 @@ var PluginMcpClient = class {
|
|
|
3151
3152
|
plugin;
|
|
3152
3153
|
options;
|
|
3153
3154
|
client;
|
|
3155
|
+
clientPromise;
|
|
3154
3156
|
lastAttemptedTransportSessionId;
|
|
3155
3157
|
transport;
|
|
3156
3158
|
listedTools;
|
|
@@ -3227,6 +3229,20 @@ var PluginMcpClient = class {
|
|
|
3227
3229
|
if (this.client) {
|
|
3228
3230
|
return this.client;
|
|
3229
3231
|
}
|
|
3232
|
+
if (this.clientPromise) {
|
|
3233
|
+
return await this.clientPromise;
|
|
3234
|
+
}
|
|
3235
|
+
const clientPromise = this.connectClient();
|
|
3236
|
+
this.clientPromise = clientPromise;
|
|
3237
|
+
try {
|
|
3238
|
+
return await clientPromise;
|
|
3239
|
+
} finally {
|
|
3240
|
+
if (this.clientPromise === clientPromise) {
|
|
3241
|
+
this.clientPromise = void 0;
|
|
3242
|
+
}
|
|
3243
|
+
}
|
|
3244
|
+
}
|
|
3245
|
+
async connectClient() {
|
|
3230
3246
|
const mcp = this.plugin.manifest.mcp;
|
|
3231
3247
|
if (!mcp) {
|
|
3232
3248
|
throw new Error(
|
|
@@ -3289,6 +3305,7 @@ var PluginMcpClient = class {
|
|
|
3289
3305
|
this.listedTools = void 0;
|
|
3290
3306
|
this.transport = void 0;
|
|
3291
3307
|
this.client = void 0;
|
|
3308
|
+
this.clientPromise = void 0;
|
|
3292
3309
|
if (transport) {
|
|
3293
3310
|
await transport.close();
|
|
3294
3311
|
}
|
|
@@ -3337,6 +3354,9 @@ function getMcpAwareTelemetryMessage(error, privacy) {
|
|
|
3337
3354
|
}
|
|
3338
3355
|
|
|
3339
3356
|
// src/chat/mcp/tool-manager.ts
|
|
3357
|
+
var MAX_TOOL_RESULT_TOKENS = 1e4;
|
|
3358
|
+
var MAX_TOOL_RESULT_BYTES = 32 * 1024;
|
|
3359
|
+
var CHARS_PER_ESTIMATED_TOKEN = 4;
|
|
3340
3360
|
function normalizeMcpToolName(provider, toolName) {
|
|
3341
3361
|
return `mcp__${provider}__${toolName}`;
|
|
3342
3362
|
}
|
|
@@ -3407,16 +3427,80 @@ function toAgentToolContent(result) {
|
|
|
3407
3427
|
}
|
|
3408
3428
|
return [{ type: "text", text: "ok" }];
|
|
3409
3429
|
}
|
|
3430
|
+
function utf8Bytes(value) {
|
|
3431
|
+
return Buffer.byteLength(value, "utf8");
|
|
3432
|
+
}
|
|
3433
|
+
function prefixWithin(value, maxChars, maxBytes) {
|
|
3434
|
+
let low = 0;
|
|
3435
|
+
let high = Math.min(value.length, maxChars);
|
|
3436
|
+
while (low < high) {
|
|
3437
|
+
const middle = Math.ceil((low + high) / 2);
|
|
3438
|
+
if (utf8Bytes(value.slice(0, middle)) <= maxBytes) {
|
|
3439
|
+
low = middle;
|
|
3440
|
+
} else {
|
|
3441
|
+
high = middle - 1;
|
|
3442
|
+
}
|
|
3443
|
+
}
|
|
3444
|
+
if (low > 0 && /[\uD800-\uDBFF]/.test(value[low - 1])) {
|
|
3445
|
+
low -= 1;
|
|
3446
|
+
}
|
|
3447
|
+
return value.slice(0, low);
|
|
3448
|
+
}
|
|
3449
|
+
function suffixWithin(value, maxChars, maxBytes) {
|
|
3450
|
+
let low = Math.max(0, value.length - maxChars);
|
|
3451
|
+
let high = value.length;
|
|
3452
|
+
while (low < high) {
|
|
3453
|
+
const middle = Math.floor((low + high) / 2);
|
|
3454
|
+
if (utf8Bytes(value.slice(middle)) <= maxBytes) {
|
|
3455
|
+
high = middle;
|
|
3456
|
+
} else {
|
|
3457
|
+
low = middle + 1;
|
|
3458
|
+
}
|
|
3459
|
+
}
|
|
3460
|
+
if (low < value.length && /[\uDC00-\uDFFF]/.test(value[low])) {
|
|
3461
|
+
low += 1;
|
|
3462
|
+
}
|
|
3463
|
+
return value.slice(low);
|
|
3464
|
+
}
|
|
3465
|
+
function boundMcpContent(content) {
|
|
3466
|
+
const text = content.filter((part) => part.type === "text").map((part) => part.text).join("\n\n");
|
|
3467
|
+
const originalBytes = utf8Bytes(text);
|
|
3468
|
+
const originalTokens = Math.ceil(text.length / CHARS_PER_ESTIMATED_TOKEN);
|
|
3469
|
+
if (originalTokens <= MAX_TOOL_RESULT_TOKENS && originalBytes <= MAX_TOOL_RESULT_BYTES) {
|
|
3470
|
+
return content;
|
|
3471
|
+
}
|
|
3472
|
+
const warning = `
|
|
3473
|
+
|
|
3474
|
+
Warning: truncated output (original token count: ${originalTokens}; original bytes: ${originalBytes})
|
|
3475
|
+
|
|
3476
|
+
`;
|
|
3477
|
+
const remainingChars = MAX_TOOL_RESULT_TOKENS * CHARS_PER_ESTIMATED_TOKEN - warning.length;
|
|
3478
|
+
const remainingBytes = MAX_TOOL_RESULT_BYTES - utf8Bytes(warning);
|
|
3479
|
+
const head = prefixWithin(
|
|
3480
|
+
text,
|
|
3481
|
+
Math.ceil(remainingChars / 2),
|
|
3482
|
+
Math.ceil(remainingBytes / 2)
|
|
3483
|
+
);
|
|
3484
|
+
const tail = suffixWithin(
|
|
3485
|
+
text.slice(head.length),
|
|
3486
|
+
remainingChars - head.length,
|
|
3487
|
+
remainingBytes - utf8Bytes(head)
|
|
3488
|
+
);
|
|
3489
|
+
return [
|
|
3490
|
+
{ type: "text", text: `${head}${warning}${tail}` },
|
|
3491
|
+
...content.filter((part) => part.type === "image")
|
|
3492
|
+
];
|
|
3493
|
+
}
|
|
3410
3494
|
function toModelVisibleMcpContent(result) {
|
|
3411
3495
|
const content = toAgentToolContent(result);
|
|
3412
3496
|
if (content.some((part) => part.type === "image")) {
|
|
3413
|
-
return content;
|
|
3497
|
+
return boundMcpContent(content);
|
|
3414
3498
|
}
|
|
3415
3499
|
const structured = summarizeStructuredContent(result.structuredContent);
|
|
3416
3500
|
if (structured) {
|
|
3417
|
-
return [{ type: "text", text: structured }];
|
|
3501
|
+
return boundMcpContent([{ type: "text", text: structured }]);
|
|
3418
3502
|
}
|
|
3419
|
-
return content;
|
|
3503
|
+
return boundMcpContent(content);
|
|
3420
3504
|
}
|
|
3421
3505
|
function describeMcpTool(provider, tool) {
|
|
3422
3506
|
const prefix = `[${provider}]`;
|
|
@@ -3453,6 +3537,7 @@ var McpToolManager = class {
|
|
|
3453
3537
|
activeProviders = /* @__PURE__ */ new Set();
|
|
3454
3538
|
authorizationPendingProviders = /* @__PURE__ */ new Set();
|
|
3455
3539
|
clientsByProvider = /* @__PURE__ */ new Map();
|
|
3540
|
+
clientPromisesByProvider = /* @__PURE__ */ new Map();
|
|
3456
3541
|
toolsByProvider = /* @__PURE__ */ new Map();
|
|
3457
3542
|
getActiveProviders() {
|
|
3458
3543
|
return [...this.activeProviders].sort(
|
|
@@ -3545,6 +3630,21 @@ var McpToolManager = class {
|
|
|
3545
3630
|
if (existing) {
|
|
3546
3631
|
return existing;
|
|
3547
3632
|
}
|
|
3633
|
+
const pending = this.clientPromisesByProvider.get(plugin.manifest.name);
|
|
3634
|
+
if (pending) {
|
|
3635
|
+
return await pending;
|
|
3636
|
+
}
|
|
3637
|
+
const clientPromise = this.createClient(plugin);
|
|
3638
|
+
this.clientPromisesByProvider.set(plugin.manifest.name, clientPromise);
|
|
3639
|
+
try {
|
|
3640
|
+
return await clientPromise;
|
|
3641
|
+
} finally {
|
|
3642
|
+
if (this.clientPromisesByProvider.get(plugin.manifest.name) === clientPromise) {
|
|
3643
|
+
this.clientPromisesByProvider.delete(plugin.manifest.name);
|
|
3644
|
+
}
|
|
3645
|
+
}
|
|
3646
|
+
}
|
|
3647
|
+
async createClient(plugin) {
|
|
3548
3648
|
const authProvider = this.options.authProviderFactory ? await this.options.authProviderFactory(plugin) : void 0;
|
|
3549
3649
|
const client = new PluginMcpClient(plugin, {
|
|
3550
3650
|
...authProvider ? { authProvider } : {},
|
|
@@ -6680,7 +6780,9 @@ function stableSerialize(value) {
|
|
|
6680
6780
|
return `[${value.map((entry) => stableSerialize(entry)).join(",")}]`;
|
|
6681
6781
|
}
|
|
6682
6782
|
if (value && typeof value === "object") {
|
|
6683
|
-
const entries = Object.entries(value).sort(
|
|
6783
|
+
const entries = Object.entries(value).sort(
|
|
6784
|
+
(a, b) => a[0].localeCompare(b[0])
|
|
6785
|
+
);
|
|
6684
6786
|
return `{${entries.map(([key, entry]) => `${JSON.stringify(key)}:${stableSerialize(entry)}`).join(",")}}`;
|
|
6685
6787
|
}
|
|
6686
6788
|
const serialized = JSON.stringify(value);
|
|
@@ -10004,13 +10106,19 @@ function createPluginAuthOrchestration(input) {
|
|
|
10004
10106
|
}
|
|
10005
10107
|
}
|
|
10006
10108
|
if (input.sessionId && recordPendingAuth) {
|
|
10007
|
-
|
|
10109
|
+
const nextPendingAuth = {
|
|
10008
10110
|
kind: "plugin",
|
|
10009
10111
|
provider,
|
|
10010
10112
|
actorId: input.actorId,
|
|
10011
10113
|
...options?.scope ? { scope: options.scope } : {},
|
|
10012
10114
|
sessionId: input.sessionId,
|
|
10013
10115
|
linkSentAtMs: reusingPendingLink ? input.pendingAuth.linkSentAtMs : Date.now()
|
|
10116
|
+
};
|
|
10117
|
+
await recordPendingAuth(nextPendingAuth);
|
|
10118
|
+
await abandonReplacedPendingAuth({
|
|
10119
|
+
conversationId: input.conversationId,
|
|
10120
|
+
previousPendingAuth: input.pendingAuth,
|
|
10121
|
+
nextPendingAuth
|
|
10014
10122
|
});
|
|
10015
10123
|
}
|
|
10016
10124
|
if (input.conversationId && input.sessionId) {
|
|
@@ -12578,9 +12686,9 @@ import { StreamableHTTPClientTransport as StreamableHTTPClientTransport2 } from
|
|
|
12578
12686
|
import {
|
|
12579
12687
|
sourceSchema as sourceSchema2
|
|
12580
12688
|
} from "@sentry/junior-plugin-api";
|
|
12581
|
-
var MCP_AUTH_SESSION_PREFIX = "junior:
|
|
12689
|
+
var MCP_AUTH_SESSION_PREFIX = "junior:mcp_oauth_attempt:v2";
|
|
12582
12690
|
var MCP_AUTH_CREDENTIALS_PREFIX = "junior:mcp_auth_credentials";
|
|
12583
|
-
var MCP_AUTH_SESSION_INDEX_PREFIX = "junior:
|
|
12691
|
+
var MCP_AUTH_SESSION_INDEX_PREFIX = "junior:mcp_oauth_attempt_index:v2";
|
|
12584
12692
|
var MCP_SERVER_SESSION_PREFIX = "junior:mcp_server_session";
|
|
12585
12693
|
var MCP_AUTH_SESSION_TTL_MS = 24 * 60 * 60 * 1e3;
|
|
12586
12694
|
var MCP_AUTH_CREDENTIALS_TTL_MS = 30 * 24 * 60 * 60 * 1e3;
|
|
@@ -12622,7 +12730,7 @@ function parseMcpAuthSession(value) {
|
|
|
12622
12730
|
if (!isRecord(parsed)) {
|
|
12623
12731
|
return void 0;
|
|
12624
12732
|
}
|
|
12625
|
-
if (typeof parsed.authSessionId !== "string" || typeof parsed.provider !== "string" || typeof parsed.userId !== "string" || typeof parsed.conversationId !== "string" || typeof parsed.sessionId !== "string" || typeof parsed.userMessage !== "string" || typeof parsed.createdAtMs !== "number" || typeof parsed.updatedAtMs !== "number") {
|
|
12733
|
+
if (parsed.schemaVersion !== 2 || typeof parsed.authSessionId !== "string" || typeof parsed.provider !== "string" || typeof parsed.userId !== "string" || typeof parsed.conversationId !== "string" || typeof parsed.sessionId !== "string" || typeof parsed.userMessage !== "string" || typeof parsed.createdAtMs !== "number" || typeof parsed.updatedAtMs !== "number") {
|
|
12626
12734
|
return void 0;
|
|
12627
12735
|
}
|
|
12628
12736
|
const destination = parsed.destination === void 0 ? void 0 : parseDestination(parsed.destination);
|
|
@@ -12634,6 +12742,7 @@ function parseMcpAuthSession(value) {
|
|
|
12634
12742
|
return void 0;
|
|
12635
12743
|
}
|
|
12636
12744
|
return {
|
|
12745
|
+
schemaVersion: 2,
|
|
12637
12746
|
authSessionId: parsed.authSessionId,
|
|
12638
12747
|
provider: parsed.provider,
|
|
12639
12748
|
userId: parsed.userId,
|
|
@@ -12731,6 +12840,7 @@ async function patchMcpAuthSession(authSessionId, patch) {
|
|
|
12731
12840
|
const next = {
|
|
12732
12841
|
...current,
|
|
12733
12842
|
...patch,
|
|
12843
|
+
schemaVersion: 2,
|
|
12734
12844
|
authSessionId: current.authSessionId,
|
|
12735
12845
|
provider: current.provider,
|
|
12736
12846
|
userId: current.userId,
|
|
@@ -12775,25 +12885,6 @@ async function deleteMcpAuthSessionsForUserProvider(userId, provider) {
|
|
|
12775
12885
|
}
|
|
12776
12886
|
await stateAdapter.delete(indexKey);
|
|
12777
12887
|
}
|
|
12778
|
-
async function getLatestMcpAuthSessionForUserProvider(userId, provider) {
|
|
12779
|
-
const stateAdapter = await getConnectedStateAdapter();
|
|
12780
|
-
const authSessionIds = parseSessionIndex(
|
|
12781
|
-
await stateAdapter.get(sessionIndexKey(userId, provider))
|
|
12782
|
-
);
|
|
12783
|
-
let latestSession;
|
|
12784
|
-
for (const authSessionId of authSessionIds) {
|
|
12785
|
-
const session = parseMcpAuthSession(
|
|
12786
|
-
await stateAdapter.get(sessionKey(authSessionId))
|
|
12787
|
-
);
|
|
12788
|
-
if (!session) {
|
|
12789
|
-
continue;
|
|
12790
|
-
}
|
|
12791
|
-
if (!latestSession || session.updatedAtMs > latestSession.updatedAtMs) {
|
|
12792
|
-
latestSession = session;
|
|
12793
|
-
}
|
|
12794
|
-
}
|
|
12795
|
-
return latestSession;
|
|
12796
|
-
}
|
|
12797
12888
|
async function getMcpStoredOAuthCredentials(userId, provider) {
|
|
12798
12889
|
const stateAdapter = await getConnectedStateAdapter();
|
|
12799
12890
|
return parseStoredCredentials(
|
|
@@ -12852,15 +12943,17 @@ function clientAllowsRedirectUri(clientInformation, callbackUrl) {
|
|
|
12852
12943
|
return redirectUris.includes(callbackUrl);
|
|
12853
12944
|
}
|
|
12854
12945
|
var StateBackedMcpOAuthClientProvider = class {
|
|
12855
|
-
constructor(authSessionId, callbackUrl, sessionContext) {
|
|
12946
|
+
constructor(authSessionId, callbackUrl, sessionContext, runCredentialMutation) {
|
|
12856
12947
|
this.authSessionId = authSessionId;
|
|
12857
12948
|
this.callbackUrl = callbackUrl;
|
|
12858
12949
|
this.sessionContext = sessionContext;
|
|
12950
|
+
this.runCredentialMutation = runCredentialMutation;
|
|
12859
12951
|
this.clientMetadata = createClientMetadata(callbackUrl);
|
|
12860
12952
|
}
|
|
12861
12953
|
authSessionId;
|
|
12862
12954
|
callbackUrl;
|
|
12863
12955
|
sessionContext;
|
|
12956
|
+
runCredentialMutation;
|
|
12864
12957
|
clientMetadata;
|
|
12865
12958
|
get redirectUrl() {
|
|
12866
12959
|
return this.callbackUrl;
|
|
@@ -12884,11 +12977,16 @@ var StateBackedMcpOAuthClientProvider = class {
|
|
|
12884
12977
|
return void 0;
|
|
12885
12978
|
}
|
|
12886
12979
|
async saveClientInformation(clientInformation) {
|
|
12887
|
-
|
|
12888
|
-
|
|
12889
|
-
|
|
12890
|
-
|
|
12891
|
-
|
|
12980
|
+
await this.mutateCredentials(async () => {
|
|
12981
|
+
const session = await this.getCredentialContext();
|
|
12982
|
+
const credentials = await getMcpStoredOAuthCredentials(
|
|
12983
|
+
session.userId,
|
|
12984
|
+
session.provider
|
|
12985
|
+
) ?? {};
|
|
12986
|
+
await putMcpStoredOAuthCredentials(session.userId, session.provider, {
|
|
12987
|
+
...credentials,
|
|
12988
|
+
clientInformation
|
|
12989
|
+
});
|
|
12892
12990
|
});
|
|
12893
12991
|
}
|
|
12894
12992
|
async tokens() {
|
|
@@ -12900,19 +12998,32 @@ var StateBackedMcpOAuthClientProvider = class {
|
|
|
12900
12998
|
return credentials?.tokens;
|
|
12901
12999
|
}
|
|
12902
13000
|
async saveTokens(tokens) {
|
|
12903
|
-
|
|
12904
|
-
|
|
12905
|
-
|
|
12906
|
-
|
|
12907
|
-
|
|
13001
|
+
await this.mutateCredentials(async () => {
|
|
13002
|
+
const session = await this.getCredentialContext();
|
|
13003
|
+
const credentials = await getMcpStoredOAuthCredentials(
|
|
13004
|
+
session.userId,
|
|
13005
|
+
session.provider
|
|
13006
|
+
) ?? {};
|
|
13007
|
+
await putMcpStoredOAuthCredentials(session.userId, session.provider, {
|
|
13008
|
+
...credentials,
|
|
13009
|
+
tokens
|
|
13010
|
+
});
|
|
12908
13011
|
});
|
|
12909
13012
|
}
|
|
12910
13013
|
async redirectToAuthorization(authorizationUrl) {
|
|
13014
|
+
const existing = await getMcpAuthSession(this.authSessionId);
|
|
13015
|
+
if (existing?.authorizationUrl && existing.authorizationUrl !== authorizationUrl.toString()) {
|
|
13016
|
+
throw new Error("MCP OAuth authorization attempt is already initialized");
|
|
13017
|
+
}
|
|
12911
13018
|
await this.ensureSession({
|
|
12912
13019
|
authorizationUrl: authorizationUrl.toString()
|
|
12913
13020
|
});
|
|
12914
13021
|
}
|
|
12915
13022
|
async saveCodeVerifier(codeVerifier) {
|
|
13023
|
+
const existing = await getMcpAuthSession(this.authSessionId);
|
|
13024
|
+
if (existing?.codeVerifier && existing.codeVerifier !== codeVerifier) {
|
|
13025
|
+
throw new Error("MCP OAuth authorization attempt is already initialized");
|
|
13026
|
+
}
|
|
12916
13027
|
await this.ensureSession({ codeVerifier });
|
|
12917
13028
|
}
|
|
12918
13029
|
async codeVerifier() {
|
|
@@ -12923,11 +13034,16 @@ var StateBackedMcpOAuthClientProvider = class {
|
|
|
12923
13034
|
return session.codeVerifier;
|
|
12924
13035
|
}
|
|
12925
13036
|
async saveDiscoveryState(state) {
|
|
12926
|
-
|
|
12927
|
-
|
|
12928
|
-
|
|
12929
|
-
|
|
12930
|
-
|
|
13037
|
+
await this.mutateCredentials(async () => {
|
|
13038
|
+
const session = await this.getCredentialContext();
|
|
13039
|
+
const credentials = await getMcpStoredOAuthCredentials(
|
|
13040
|
+
session.userId,
|
|
13041
|
+
session.provider
|
|
13042
|
+
) ?? {};
|
|
13043
|
+
await putMcpStoredOAuthCredentials(session.userId, session.provider, {
|
|
13044
|
+
...credentials,
|
|
13045
|
+
discoveryState: state
|
|
13046
|
+
});
|
|
12931
13047
|
});
|
|
12932
13048
|
}
|
|
12933
13049
|
async discoveryState() {
|
|
@@ -12939,34 +13055,36 @@ var StateBackedMcpOAuthClientProvider = class {
|
|
|
12939
13055
|
return credentials?.discoveryState;
|
|
12940
13056
|
}
|
|
12941
13057
|
async invalidateCredentials(scope) {
|
|
12942
|
-
|
|
12943
|
-
|
|
12944
|
-
|
|
12945
|
-
|
|
12946
|
-
|
|
12947
|
-
|
|
13058
|
+
await this.mutateCredentials(async () => {
|
|
13059
|
+
const session = await this.getCredentialContext();
|
|
13060
|
+
const credentials = await getMcpStoredOAuthCredentials(
|
|
13061
|
+
session.userId,
|
|
13062
|
+
session.provider
|
|
13063
|
+
) ?? {};
|
|
13064
|
+
await putMcpStoredOAuthCredentials(session.userId, session.provider, {
|
|
13065
|
+
...scope === "tokens" || scope === "all" ? {} : credentials.tokens ? { tokens: credentials.tokens } : {},
|
|
13066
|
+
...scope === "client" || scope === "all" ? {} : credentials.clientInformation ? { clientInformation: credentials.clientInformation } : {},
|
|
13067
|
+
...scope === "discovery" || scope === "all" ? {} : credentials.discoveryState ? { discoveryState: credentials.discoveryState } : {}
|
|
13068
|
+
});
|
|
12948
13069
|
});
|
|
12949
|
-
if (scope === "verifier" || scope === "all") {
|
|
12950
|
-
const authSession = await getMcpAuthSession(this.authSessionId);
|
|
12951
|
-
if (authSession) {
|
|
12952
|
-
await patchMcpAuthSession(this.authSessionId, {
|
|
12953
|
-
codeVerifier: void 0,
|
|
12954
|
-
...scope === "all" ? { authorizationUrl: void 0 } : {}
|
|
12955
|
-
});
|
|
12956
|
-
}
|
|
12957
|
-
}
|
|
12958
13070
|
}
|
|
12959
13071
|
async getMcpServerSessionId() {
|
|
12960
13072
|
const session = await this.getCredentialContext();
|
|
12961
13073
|
return await getMcpServerSessionId(session.userId, session.provider);
|
|
12962
13074
|
}
|
|
12963
13075
|
async saveMcpServerSessionId(sessionId) {
|
|
12964
|
-
|
|
12965
|
-
|
|
12966
|
-
|
|
12967
|
-
|
|
12968
|
-
|
|
12969
|
-
|
|
13076
|
+
await this.mutateCredentials(async () => {
|
|
13077
|
+
const session = await this.getCredentialContext();
|
|
13078
|
+
if (!sessionId) {
|
|
13079
|
+
await deleteMcpServerSessionId(session.userId, session.provider);
|
|
13080
|
+
return;
|
|
13081
|
+
}
|
|
13082
|
+
await putMcpServerSessionId(session.userId, session.provider, sessionId);
|
|
13083
|
+
});
|
|
13084
|
+
}
|
|
13085
|
+
/** Route shared credential writes through callback-owned freshness control. */
|
|
13086
|
+
async mutateCredentials(mutation) {
|
|
13087
|
+
return this.runCredentialMutation ? await this.runCredentialMutation(mutation) : await mutation();
|
|
12970
13088
|
}
|
|
12971
13089
|
async getCredentialContext() {
|
|
12972
13090
|
return this.sessionContext ?? await this.requireSession();
|
|
@@ -12981,6 +13099,7 @@ var StateBackedMcpOAuthClientProvider = class {
|
|
|
12981
13099
|
}
|
|
12982
13100
|
const now = Date.now();
|
|
12983
13101
|
const nextSession = {
|
|
13102
|
+
schemaVersion: 2,
|
|
12984
13103
|
authSessionId: this.authSessionId,
|
|
12985
13104
|
...this.sessionContext,
|
|
12986
13105
|
...patch,
|
|
@@ -13018,32 +13137,7 @@ async function createMcpOAuthClientProvider(input) {
|
|
|
13018
13137
|
"Cannot determine base URL (set JUNIOR_BASE_URL or deploy to Vercel)"
|
|
13019
13138
|
);
|
|
13020
13139
|
}
|
|
13021
|
-
const
|
|
13022
|
-
input.userId,
|
|
13023
|
-
input.provider
|
|
13024
|
-
);
|
|
13025
|
-
const reusableSession = existingSession && existingSession.conversationId === input.conversationId && existingSession.sessionId === input.sessionId ? existingSession : void 0;
|
|
13026
|
-
const now = Date.now();
|
|
13027
|
-
const authSessionId = reusableSession?.authSessionId ?? randomUUID3();
|
|
13028
|
-
await putMcpAuthSession({
|
|
13029
|
-
authSessionId,
|
|
13030
|
-
provider: input.provider,
|
|
13031
|
-
userId: input.userId,
|
|
13032
|
-
conversationId: input.conversationId,
|
|
13033
|
-
...input.destination ? { destination: input.destination } : {},
|
|
13034
|
-
...input.source ? { source: input.source } : {},
|
|
13035
|
-
sessionId: input.sessionId,
|
|
13036
|
-
userMessage: input.userMessage,
|
|
13037
|
-
...input.channelId ? { channelId: input.channelId } : {},
|
|
13038
|
-
...input.threadTs ? { threadTs: input.threadTs } : {},
|
|
13039
|
-
...input.toolChannelId ? { toolChannelId: input.toolChannelId } : {},
|
|
13040
|
-
...input.configuration ? { configuration: input.configuration } : {},
|
|
13041
|
-
...input.artifactState ? { artifactState: input.artifactState } : {},
|
|
13042
|
-
...reusableSession?.authorizationUrl ? { authorizationUrl: reusableSession.authorizationUrl } : {},
|
|
13043
|
-
...reusableSession?.codeVerifier ? { codeVerifier: reusableSession.codeVerifier } : {},
|
|
13044
|
-
createdAtMs: reusableSession?.createdAtMs ?? now,
|
|
13045
|
-
updatedAtMs: now
|
|
13046
|
-
});
|
|
13140
|
+
const authSessionId = randomUUID3();
|
|
13047
13141
|
return new StateBackedMcpOAuthClientProvider(
|
|
13048
13142
|
authSessionId,
|
|
13049
13143
|
`${baseUrl}${getMcpOAuthCallbackPath(input.provider)}`,
|
|
@@ -13052,6 +13146,7 @@ async function createMcpOAuthClientProvider(input) {
|
|
|
13052
13146
|
userId: input.userId,
|
|
13053
13147
|
conversationId: input.conversationId,
|
|
13054
13148
|
...input.destination ? { destination: input.destination } : {},
|
|
13149
|
+
...input.source ? { source: input.source } : {},
|
|
13055
13150
|
sessionId: input.sessionId,
|
|
13056
13151
|
userMessage: input.userMessage,
|
|
13057
13152
|
...input.channelId ? { channelId: input.channelId } : {},
|
|
@@ -13062,7 +13157,7 @@ async function createMcpOAuthClientProvider(input) {
|
|
|
13062
13157
|
}
|
|
13063
13158
|
);
|
|
13064
13159
|
}
|
|
13065
|
-
async function finalizeMcpAuthorization(provider, authSessionId, authorizationCode) {
|
|
13160
|
+
async function finalizeMcpAuthorization(provider, authSessionId, authorizationCode, runCredentialMutation) {
|
|
13066
13161
|
const plugin = requirePluginWithMcp(provider);
|
|
13067
13162
|
const mcp = plugin.manifest.mcp;
|
|
13068
13163
|
if (!mcp) {
|
|
@@ -13086,7 +13181,9 @@ async function finalizeMcpAuthorization(provider, authSessionId, authorizationCo
|
|
|
13086
13181
|
const callbackUrl = `${baseUrl}${getMcpOAuthCallbackPath(provider)}`;
|
|
13087
13182
|
const authProvider = new StateBackedMcpOAuthClientProvider(
|
|
13088
13183
|
authSessionId,
|
|
13089
|
-
callbackUrl
|
|
13184
|
+
callbackUrl,
|
|
13185
|
+
void 0,
|
|
13186
|
+
runCredentialMutation
|
|
13090
13187
|
);
|
|
13091
13188
|
const requestInit = {};
|
|
13092
13189
|
if (mcp.headers && Object.keys(mcp.headers).length > 0) {
|
|
@@ -13169,16 +13266,6 @@ function createMcpAuthOrchestration(input) {
|
|
|
13169
13266
|
`Missing pending auth recorder for MCP authorization pause "${provider}"`
|
|
13170
13267
|
);
|
|
13171
13268
|
}
|
|
13172
|
-
const latestArtifactState = input.getMergedArtifactState();
|
|
13173
|
-
await patchMcpAuthSession(authSessionId, {
|
|
13174
|
-
configuration: { ...input.getConfiguration() },
|
|
13175
|
-
artifactState: latestArtifactState,
|
|
13176
|
-
toolChannelId: input.toolChannelId ?? latestArtifactState.assistantContextChannelId ?? input.channelId
|
|
13177
|
-
});
|
|
13178
|
-
const authSession = await getMcpAuthSession(authSessionId);
|
|
13179
|
-
if (!authSession?.authorizationUrl) {
|
|
13180
|
-
throw new Error(`Missing MCP authorization URL for plugin "${provider}"`);
|
|
13181
|
-
}
|
|
13182
13269
|
const reusingPendingLink = canReusePendingAuthLink({
|
|
13183
13270
|
pendingAuth: input.pendingAuth,
|
|
13184
13271
|
kind: "mcp",
|
|
@@ -13186,8 +13273,31 @@ function createMcpAuthOrchestration(input) {
|
|
|
13186
13273
|
actorId,
|
|
13187
13274
|
sessionId
|
|
13188
13275
|
});
|
|
13276
|
+
const reusedAuthSessionId = reusingPendingLink && input.pendingAuth?.kind === "mcp" ? input.pendingAuth.authSessionId : void 0;
|
|
13277
|
+
const activeAuthSessionId = reusedAuthSessionId ?? authSessionId;
|
|
13278
|
+
const latestArtifactState = input.getMergedArtifactState();
|
|
13279
|
+
await patchMcpAuthSession(activeAuthSessionId, {
|
|
13280
|
+
configuration: { ...input.getConfiguration() },
|
|
13281
|
+
artifactState: latestArtifactState,
|
|
13282
|
+
toolChannelId: input.toolChannelId ?? latestArtifactState.assistantContextChannelId ?? input.channelId
|
|
13283
|
+
});
|
|
13189
13284
|
const providerLabel = formatProviderLabel(provider);
|
|
13285
|
+
const nextPendingAuth = {
|
|
13286
|
+
authSessionId: activeAuthSessionId,
|
|
13287
|
+
kind: "mcp",
|
|
13288
|
+
provider,
|
|
13289
|
+
actorId,
|
|
13290
|
+
sessionId,
|
|
13291
|
+
linkSentAtMs: reusingPendingLink ? input.pendingAuth.linkSentAtMs : Date.now()
|
|
13292
|
+
};
|
|
13190
13293
|
if (!reusingPendingLink) {
|
|
13294
|
+
const authSession = await getMcpAuthSession(authSessionId);
|
|
13295
|
+
if (!authSession?.authorizationUrl) {
|
|
13296
|
+
throw new Error(
|
|
13297
|
+
`Missing MCP authorization URL for plugin "${provider}"`
|
|
13298
|
+
);
|
|
13299
|
+
}
|
|
13300
|
+
await recordPendingAuth(nextPendingAuth);
|
|
13191
13301
|
const delivery = await deliverPrivateMessage({
|
|
13192
13302
|
channelId: authSession.channelId,
|
|
13193
13303
|
threadTs: authSession.threadTs,
|
|
@@ -13199,20 +13309,21 @@ function createMcpAuthOrchestration(input) {
|
|
|
13199
13309
|
})
|
|
13200
13310
|
});
|
|
13201
13311
|
if (!delivery) {
|
|
13312
|
+
await deleteMcpAuthSession(authSessionId);
|
|
13313
|
+
await recordPendingAuth(input.pendingAuth);
|
|
13202
13314
|
throw new Error(
|
|
13203
13315
|
`Unable to deliver MCP authorization link for plugin "${provider}"`
|
|
13204
13316
|
);
|
|
13205
13317
|
}
|
|
13318
|
+
await abandonReplacedPendingAuth({
|
|
13319
|
+
conversationId,
|
|
13320
|
+
previousPendingAuth: input.pendingAuth,
|
|
13321
|
+
nextPendingAuth
|
|
13322
|
+
});
|
|
13206
13323
|
} else {
|
|
13207
13324
|
await deleteMcpAuthSession(authSessionId);
|
|
13325
|
+
await recordPendingAuth(nextPendingAuth);
|
|
13208
13326
|
}
|
|
13209
|
-
await recordPendingAuth({
|
|
13210
|
-
kind: "mcp",
|
|
13211
|
-
provider,
|
|
13212
|
-
actorId,
|
|
13213
|
-
sessionId,
|
|
13214
|
-
linkSentAtMs: reusingPendingLink ? input.pendingAuth.linkSentAtMs : Date.now()
|
|
13215
|
-
});
|
|
13216
13327
|
await recordAuthorizationRequested({
|
|
13217
13328
|
conversationId,
|
|
13218
13329
|
kind: "mcp",
|
|
@@ -15223,7 +15334,11 @@ async function executeAgentRunInPrivacyContext(request, conversationPrivacy) {
|
|
|
15223
15334
|
let canRecordMcpProviders = false;
|
|
15224
15335
|
let turnUsage;
|
|
15225
15336
|
let handoffPhaseUsage;
|
|
15226
|
-
|
|
15337
|
+
const configuredReasoningLevel = policy.reasoningLevel ?? botConfig.reasoningLevel;
|
|
15338
|
+
let reasoningSelection = configuredReasoningLevel ? configuredTurnReasoningLevel(
|
|
15339
|
+
configuredReasoningLevel,
|
|
15340
|
+
policy.reasoningLevel ? "agent_config" : "default"
|
|
15341
|
+
) : void 0;
|
|
15227
15342
|
let activeModelProfile = STANDARD_MODEL_PROFILE;
|
|
15228
15343
|
let activeModelId = modelIdForProfile(botConfig, activeModelProfile);
|
|
15229
15344
|
const actor = actorFromRouting(routing);
|
|
@@ -15337,7 +15452,7 @@ async function executeAgentRunInPrivacyContext(request, conversationPrivacy) {
|
|
|
15337
15452
|
destination: routing.destination,
|
|
15338
15453
|
durability,
|
|
15339
15454
|
getLoadedSkillNames: () => loadedSkillNamesForResume,
|
|
15340
|
-
getReasoningLevel: () =>
|
|
15455
|
+
getReasoningLevel: () => reasoningSelection?.reasoningLevel,
|
|
15341
15456
|
logContext: sessionRecordLogContext,
|
|
15342
15457
|
getModelId: () => activeModelId,
|
|
15343
15458
|
recordActiveMcpProviders,
|
|
@@ -15394,7 +15509,7 @@ async function executeAgentRunInPrivacyContext(request, conversationPrivacy) {
|
|
|
15394
15509
|
});
|
|
15395
15510
|
const { routerBlocks, userContentParts } = buildPromptInput(input);
|
|
15396
15511
|
const preAgentPromptMessages = () => existingSessionRecord?.piMessages ?? [...input.piMessages ?? []];
|
|
15397
|
-
|
|
15512
|
+
reasoningSelection ??= await selectTurnReasoningLevel({
|
|
15398
15513
|
completeObject,
|
|
15399
15514
|
conversationContext: input.conversationContext,
|
|
15400
15515
|
context: {
|
|
@@ -15409,10 +15524,10 @@ async function executeAgentRunInPrivacyContext(request, conversationPrivacy) {
|
|
|
15409
15524
|
});
|
|
15410
15525
|
setSpanAttributes({
|
|
15411
15526
|
"gen_ai.request.model": activeModelId,
|
|
15412
|
-
"gen_ai.request.reasoning.level":
|
|
15413
|
-
"app.ai.
|
|
15414
|
-
...
|
|
15415
|
-
"app.ai.
|
|
15527
|
+
"gen_ai.request.reasoning.level": reasoningSelection.reasoningLevel,
|
|
15528
|
+
"app.ai.reasoning_level_reason": reasoningSelection.reason,
|
|
15529
|
+
...reasoningSelection.confidence !== void 0 ? {
|
|
15530
|
+
"app.ai.reasoning_level_confidence": reasoningSelection.confidence
|
|
15416
15531
|
} : {}
|
|
15417
15532
|
});
|
|
15418
15533
|
const generatedFiles = [];
|
|
@@ -15439,8 +15554,8 @@ async function executeAgentRunInPrivacyContext(request, conversationPrivacy) {
|
|
|
15439
15554
|
modelProfile: profile
|
|
15440
15555
|
};
|
|
15441
15556
|
const handoffModel = resolveGatewayModel(target.modelId);
|
|
15442
|
-
const handoffThinkingLevel =
|
|
15443
|
-
|
|
15557
|
+
const handoffThinkingLevel = toPiReasoningLevel(
|
|
15558
|
+
reasoningSelection.reasoningLevel
|
|
15444
15559
|
);
|
|
15445
15560
|
void (async () => {
|
|
15446
15561
|
await observers.onStatus?.({ text: "Switching models" });
|
|
@@ -15673,7 +15788,7 @@ async function executeAgentRunInPrivacyContext(request, conversationPrivacy) {
|
|
|
15673
15788
|
runResume.adoptCommittedBoundary(replacement);
|
|
15674
15789
|
setSpanAttributes({
|
|
15675
15790
|
"gen_ai.request.model": activeModelId,
|
|
15676
|
-
"gen_ai.request.reasoning.level":
|
|
15791
|
+
"gen_ai.request.reasoning.level": reasoningSelection.reasoningLevel,
|
|
15677
15792
|
"app.ai.model_profile": activeModelProfile
|
|
15678
15793
|
});
|
|
15679
15794
|
update = {
|
|
@@ -15693,7 +15808,7 @@ async function executeAgentRunInPrivacyContext(request, conversationPrivacy) {
|
|
|
15693
15808
|
initialState: {
|
|
15694
15809
|
systemPrompt: baseInstructions,
|
|
15695
15810
|
model: resolveGatewayModel(activeModelId),
|
|
15696
|
-
thinkingLevel:
|
|
15811
|
+
thinkingLevel: toPiReasoningLevel(reasoningSelection.reasoningLevel),
|
|
15697
15812
|
tools: wiring.agentTools
|
|
15698
15813
|
}
|
|
15699
15814
|
});
|
|
@@ -15762,7 +15877,6 @@ async function executeAgentRunInPrivacyContext(request, conversationPrivacy) {
|
|
|
15762
15877
|
"gen_ai.invoke_agent",
|
|
15763
15878
|
spanContext,
|
|
15764
15879
|
async () => {
|
|
15765
|
-
let promptResult;
|
|
15766
15880
|
const freshPromptMessage = {
|
|
15767
15881
|
role: "user",
|
|
15768
15882
|
content: promptContentParts,
|
|
@@ -15824,8 +15938,8 @@ async function executeAgentRunInPrivacyContext(request, conversationPrivacy) {
|
|
|
15824
15938
|
"gen_ai.provider.name": GEN_AI_PROVIDER_NAME,
|
|
15825
15939
|
"gen_ai.operation.name": "invoke_agent",
|
|
15826
15940
|
"gen_ai.request.model": activeModelId,
|
|
15827
|
-
...
|
|
15828
|
-
"gen_ai.request.reasoning.level":
|
|
15941
|
+
...reasoningSelection ? {
|
|
15942
|
+
"gen_ai.request.reasoning.level": reasoningSelection.reasoningLevel
|
|
15829
15943
|
} : {},
|
|
15830
15944
|
"app.ai.turn_timeout_ms": turnTimeoutBudgetMs,
|
|
15831
15945
|
"app.ai.turn_deadline_remaining_ms": Math.max(
|
|
@@ -15870,7 +15984,7 @@ async function executeAgentRunInPrivacyContext(request, conversationPrivacy) {
|
|
|
15870
15984
|
let run = shouldPromptAgent ? agent.prompt(freshPromptMessage) : agent.continue();
|
|
15871
15985
|
let retryUsage;
|
|
15872
15986
|
for (let attempt = 0; ; attempt += 1) {
|
|
15873
|
-
|
|
15987
|
+
await runAgentStep(run);
|
|
15874
15988
|
signal?.throwIfAborted();
|
|
15875
15989
|
if (runResume.cooperativeYieldError) {
|
|
15876
15990
|
throw runResume.cooperativeYieldError;
|
|
@@ -15882,11 +15996,7 @@ async function executeAgentRunInPrivacyContext(request, conversationPrivacy) {
|
|
|
15882
15996
|
const outputMessagesAttribute = serializeGenAiAttribute(
|
|
15883
15997
|
conversationPrivacy !== "public" ? outputMessages.map(toGenAiMessageMetadata) : outputMessages.map(toCanonicalOutputMessage)
|
|
15884
15998
|
);
|
|
15885
|
-
const usageSummary = extractGenAiUsageSummary(
|
|
15886
|
-
promptResult,
|
|
15887
|
-
agent.state,
|
|
15888
|
-
...outputMessages
|
|
15889
|
-
);
|
|
15999
|
+
const usageSummary = extractGenAiUsageSummary(...outputMessages);
|
|
15890
16000
|
const currentUsage = hasAgentTurnUsage(usageSummary) ? usageSummary : void 0;
|
|
15891
16001
|
const currentPhaseUsage = addAgentTurnUsage(
|
|
15892
16002
|
retryUsage,
|
|
@@ -15941,7 +16051,7 @@ async function executeAgentRunInPrivacyContext(request, conversationPrivacy) {
|
|
|
15941
16051
|
...sessionConversationId ? { "app.ai.session.conversation_id": sessionConversationId } : {},
|
|
15942
16052
|
...sessionId ? { "app.ai.turn.session_id": sessionId } : {},
|
|
15943
16053
|
...currentSliceId ? { "app.ai.turn.slice_id": currentSliceId } : {},
|
|
15944
|
-
"gen_ai.request.reasoning.level":
|
|
16054
|
+
"gen_ai.request.reasoning.level": reasoningSelection.reasoningLevel,
|
|
15945
16055
|
...toGenAiMessagesTraceAttributes("app.ai.input", inputMessages),
|
|
15946
16056
|
...inputMessagesAttribute ? { "gen_ai.input.messages": inputMessagesAttribute } : {}
|
|
15947
16057
|
}
|
|
@@ -15967,7 +16077,7 @@ async function executeAgentRunInPrivacyContext(request, conversationPrivacy) {
|
|
|
15967
16077
|
shouldTrace,
|
|
15968
16078
|
spanContext,
|
|
15969
16079
|
usage: turnUsage,
|
|
15970
|
-
|
|
16080
|
+
reasoningSelection,
|
|
15971
16081
|
correlation: routing.correlation,
|
|
15972
16082
|
assistantUserName: botConfig.userName,
|
|
15973
16083
|
modelId: activeModelId
|
|
@@ -16023,8 +16133,8 @@ async function executeAgentRunInPrivacyContext(request, conversationPrivacy) {
|
|
|
16023
16133
|
outcome: "provider_error",
|
|
16024
16134
|
modelId: activeModelId,
|
|
16025
16135
|
assistantMessageCount: 0,
|
|
16026
|
-
...
|
|
16027
|
-
|
|
16136
|
+
...reasoningSelection ? {
|
|
16137
|
+
reasoningLevel: reasoningSelection.reasoningLevel
|
|
16028
16138
|
} : {},
|
|
16029
16139
|
toolCalls: [],
|
|
16030
16140
|
toolResultCount: 0,
|
|
@@ -16101,6 +16211,7 @@ export {
|
|
|
16101
16211
|
normalizeSandboxEgressTracePropagationDomains,
|
|
16102
16212
|
shouldPropagateSandboxEgressTrace,
|
|
16103
16213
|
resolveSandboxEgressProviderForHost,
|
|
16214
|
+
getMcpAuthSession,
|
|
16104
16215
|
deleteMcpAuthSession,
|
|
16105
16216
|
deleteMcpAuthSessionsForUserProvider,
|
|
16106
16217
|
getMcpStoredOAuthCredentials,
|