@sentry/junior 0.90.0 → 0.92.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-MXAF7RQL.js → agent-hooks-BYSSWCNW.js} +7 -7
- package/dist/api/people/list.d.ts +3 -3
- package/dist/api/people/list.js +15 -15
- package/dist/api/people/list.query.d.ts +2 -2
- package/dist/api/people/profile.d.ts +3 -3
- package/dist/api/people/profile.js +12 -12
- package/dist/api/people/profile.query.d.ts +2 -2
- package/dist/api/people/shared.d.ts +13 -13
- package/dist/api/people/types.d.ts +12 -12
- package/dist/api-reference.d.ts +1 -1
- package/dist/app.js +406 -267
- package/dist/{catalog-runtime-DXE6NXHT.js → catalog-runtime-NZHMSMYC.js} +2 -2
- package/dist/chat/actor.d.ts +75 -0
- package/dist/chat/agent/prompt.d.ts +4 -4
- package/dist/chat/agent/request.d.ts +21 -13
- package/dist/chat/agent/resume.d.ts +5 -4
- package/dist/chat/agent/tools.d.ts +2 -2
- package/dist/chat/capabilities/jr-rpc-command.d.ts +1 -1
- package/dist/chat/conversation-privacy.d.ts +11 -0
- package/dist/chat/conversations/sql/migrations.d.ts +1 -1
- package/dist/chat/conversations/sql/schema/conversations.d.ts +2 -19
- package/dist/chat/conversations/sql/schema.d.ts +2 -19
- package/dist/chat/conversations/sql/store.d.ts +3 -3
- package/dist/chat/conversations/store.d.ts +4 -4
- package/dist/chat/credentials/context.d.ts +4 -4
- package/dist/chat/current-instruction.d.ts +5 -3
- package/dist/chat/logging.d.ts +2 -2
- package/dist/chat/no-reply.d.ts +1 -1
- package/dist/chat/oauth-authorization-message.d.ts +6 -0
- package/dist/chat/oauth-flow.d.ts +1 -1
- package/dist/chat/pi/messages.d.ts +2 -2
- package/dist/chat/pi/transcript.d.ts +15 -0
- package/dist/chat/plugins/agent-hooks.d.ts +3 -3
- package/dist/chat/plugins/credential-hooks.d.ts +2 -8
- package/dist/chat/prompt.d.ts +3 -6
- package/dist/chat/runtime/reply-executor.d.ts +1 -1
- package/dist/chat/runtime/turn-input.d.ts +1 -1
- package/dist/chat/sandbox/egress/schemas.d.ts +2 -2
- package/dist/chat/sandbox/egress/session.d.ts +1 -1
- package/dist/chat/services/context-compaction.d.ts +1 -1
- package/dist/chat/services/conversation-memory.d.ts +1 -1
- package/dist/chat/services/mcp-auth-orchestration.d.ts +1 -1
- package/dist/chat/services/message-actor-identity.d.ts +4 -4
- package/dist/chat/services/pending-auth.d.ts +2 -2
- package/dist/chat/services/plugin-auth-orchestration.d.ts +1 -1
- package/dist/chat/services/provider-default-config.d.ts +1 -1
- package/dist/chat/services/subscribed-decision.d.ts +1 -1
- package/dist/chat/services/turn-result.d.ts +1 -1
- package/dist/chat/services/turn-session-record.d.ts +11 -8
- package/dist/chat/services/turn-thinking-level.d.ts +1 -1
- package/dist/chat/slack/assistant-thread/title.d.ts +1 -1
- package/dist/chat/slack/mrkdwn.d.ts +6 -0
- package/dist/chat/slack/tools/canvas/create.d.ts +41 -1
- package/dist/chat/slack/tools/canvas/edit.d.ts +60 -1
- package/dist/chat/slack/tools/canvas/read.d.ts +60 -1
- package/dist/chat/slack/tools/canvas/write.d.ts +41 -1
- package/dist/chat/slack/tools/channel-list-messages.d.ts +45 -1
- package/dist/chat/slack/tools/context.d.ts +3 -3
- package/dist/chat/slack/tools/list/add-items.d.ts +42 -1
- package/dist/chat/slack/tools/list/create.d.ts +40 -1
- package/dist/chat/slack/tools/list/get-items.d.ts +40 -1
- package/dist/chat/slack/tools/list/update-item.d.ts +46 -1
- package/dist/chat/slack/tools/message-add-reaction.d.ts +40 -1
- package/dist/chat/slack/tools/send-message.d.ts +45 -1
- package/dist/chat/slack/tools/thread-read.d.ts +44 -1
- package/dist/chat/slack/tools/user-lookup.d.ts +45 -1
- package/dist/chat/slack/user.d.ts +3 -3
- package/dist/chat/slack/vision-context.d.ts +2 -2
- package/dist/chat/sql/schema.d.ts +2 -19
- package/dist/chat/state/conversation-details.d.ts +4 -4
- package/dist/chat/state/conversation.d.ts +1 -1
- package/dist/chat/state/session-log.d.ts +140 -26
- package/dist/chat/state/turn-session.d.ts +18 -5
- package/dist/chat/task-execution/slack-work.d.ts +2 -2
- package/dist/chat/task-execution/state.d.ts +4 -4
- package/dist/chat/tool-support/zod-tool.d.ts +16 -4
- package/dist/chat/tools/advisor/tool.d.ts +41 -1
- package/dist/chat/tools/definition.d.ts +10 -0
- package/dist/chat/tools/execute-tool.d.ts +41 -1
- package/dist/chat/tools/resource-events.d.ts +124 -3
- package/dist/chat/tools/runtime/report-progress.d.ts +40 -1
- package/dist/chat/tools/sandbox/bash.d.ts +41 -1
- package/dist/chat/tools/sandbox/edit-file.d.ts +44 -1
- package/dist/chat/tools/sandbox/find-files.d.ts +42 -1
- package/dist/chat/tools/sandbox/grep.d.ts +46 -1
- package/dist/chat/tools/sandbox/list-dir.d.ts +41 -1
- package/dist/chat/tools/sandbox/read-file.d.ts +42 -1
- package/dist/chat/tools/sandbox/write-file.d.ts +41 -1
- package/dist/chat/tools/search-tools.d.ts +102 -1
- package/dist/chat/tools/skill/call-mcp-tool.d.ts +10 -1
- package/dist/chat/tools/skill/load-skill.d.ts +40 -1
- package/dist/chat/tools/skill/search-mcp-tools.d.ts +100 -1
- package/dist/chat/tools/system-time.d.ts +38 -1
- package/dist/chat/tools/types.d.ts +4 -4
- package/dist/chat/tools/web/fetch-tool.d.ts +41 -1
- package/dist/chat/tools/web/image-generate.d.ts +62 -1
- package/dist/chat/tools/web/search.d.ts +41 -1
- package/dist/{chunk-HXL2ZV74.js → chunk-3F54A3YM.js} +82 -11
- package/dist/{chunk-BKSZL4QO.js → chunk-7DVIELX3.js} +670 -401
- package/dist/{chunk-GCWD2VHP.js → chunk-7FS3K243.js} +284 -124
- package/dist/{chunk-AOISHLSF.js → chunk-ACJENBVF.js} +143 -20
- package/dist/{chunk-IRRMABQD.js → chunk-APIVR44P.js} +10 -10
- package/dist/{chunk-PHZHJTCK.js → chunk-BMQ5DXHV.js} +30 -52
- package/dist/{chunk-XP7F4LYB.js → chunk-BTH37NCU.js} +4 -4
- package/dist/{chunk-5GBUZI6M.js → chunk-H7KUZAMZ.js} +4 -4
- package/dist/{chunk-TYUXD3FN.js → chunk-MC4ZZE4Q.js} +1 -1
- package/dist/{chunk-QCKGI74V.js → chunk-N25HRI6B.js} +10 -10
- package/dist/{chunk-2S7M37HY.js → chunk-NIFONS4W.js} +86 -47
- package/dist/{chunk-ONFOWI2D.js → chunk-OJP53WIU.js} +16 -15
- package/dist/{chunk-NW7AXDA5.js → chunk-OZJXGX4U.js} +2 -2
- package/dist/{chunk-KC42JAAQ.js → chunk-PFXC67GJ.js} +3 -3
- package/dist/{chunk-ZUK7BL63.js → chunk-S6QKIGRM.js} +66 -54
- package/dist/{chunk-IX76WFJV.js → chunk-TF5VLGA7.js} +10 -10
- package/dist/{chunk-DACFZ5CI.js → chunk-VY7TVOIK.js} +16 -12
- package/dist/{chunk-AN2437E3.js → chunk-YTNPU7I2.js} +2 -2
- package/dist/{chunk-3MPOMK3K.js → chunk-YYBX2BD5.js} +61 -3
- package/dist/{chunk-RS6ANWVT.js → chunk-ZATRYQLR.js} +1 -1
- package/dist/cli/chat.js +20 -20
- package/dist/cli/check.js +3 -3
- package/dist/cli/plugins.js +9 -9
- package/dist/cli/snapshot-warmup.js +6 -6
- package/dist/cli/upgrade.js +9 -9
- package/dist/{db-CXI7PR5U.js → db-GCK43OO3.js} +4 -4
- package/dist/instrumentation.js +1 -1
- package/dist/reporting/conversations.d.ts +3 -3
- package/dist/reporting.d.ts +1 -1
- package/dist/reporting.js +48 -50
- package/dist/{runner-FKL3RAHA.js → runner-XWTFA26U.js} +20 -18
- package/dist/{validation-I7GD2YWS.js → validation-KYAWETI4.js} +3 -3
- package/package.json +6 -6
- package/dist/chat/requester.d.ts +0 -68
|
@@ -11,10 +11,10 @@ import {
|
|
|
11
11
|
persistRunningSessionRecord,
|
|
12
12
|
persistTimeoutSessionRecord,
|
|
13
13
|
persistYieldSessionRecord
|
|
14
|
-
} from "./chunk-
|
|
14
|
+
} from "./chunk-OJP53WIU.js";
|
|
15
15
|
import {
|
|
16
16
|
JUNIOR_THREAD_STATE_TTL_MS
|
|
17
|
-
} from "./chunk-
|
|
17
|
+
} from "./chunk-PFXC67GJ.js";
|
|
18
18
|
import {
|
|
19
19
|
buildNonInteractiveShellScript,
|
|
20
20
|
createSandboxInstance,
|
|
@@ -23,27 +23,25 @@ import {
|
|
|
23
23
|
isSnapshotMissingError,
|
|
24
24
|
resolveRuntimeDependencySnapshot,
|
|
25
25
|
runNonInteractiveCommand
|
|
26
|
-
} from "./chunk-
|
|
26
|
+
} from "./chunk-H7KUZAMZ.js";
|
|
27
27
|
import {
|
|
28
28
|
JUNIOR_PERSONALITY,
|
|
29
29
|
buildPluginSystemPromptContributions,
|
|
30
30
|
buildSystemPrompt,
|
|
31
31
|
buildTurnContextPrompt,
|
|
32
32
|
containsNoReplyMarker,
|
|
33
|
-
|
|
33
|
+
formatSlackLink,
|
|
34
34
|
isNoReplyMarker,
|
|
35
|
-
renderCurrentInstruction,
|
|
36
35
|
stripNoReplyMarker
|
|
37
|
-
} from "./chunk-
|
|
36
|
+
} from "./chunk-BMQ5DXHV.js";
|
|
38
37
|
import {
|
|
39
|
-
escapeXml,
|
|
40
38
|
loadConnectedMcpProviders,
|
|
41
39
|
recordAuthorizationRequested,
|
|
42
40
|
recordMcpProviderConnected,
|
|
43
41
|
recordSubagentEnded,
|
|
44
42
|
recordSubagentStarted,
|
|
45
43
|
recordToolExecutionStarted
|
|
46
|
-
} from "./chunk-
|
|
44
|
+
} from "./chunk-7FS3K243.js";
|
|
47
45
|
import {
|
|
48
46
|
SlackActionError,
|
|
49
47
|
createPluginHookRunner,
|
|
@@ -60,10 +58,10 @@ import {
|
|
|
60
58
|
normalizeSlackConversationId,
|
|
61
59
|
resolveChannelCapabilities,
|
|
62
60
|
withSlackRetries
|
|
63
|
-
} from "./chunk-
|
|
61
|
+
} from "./chunk-VY7TVOIK.js";
|
|
64
62
|
import {
|
|
65
63
|
createPluginLogger
|
|
66
|
-
} from "./chunk-
|
|
64
|
+
} from "./chunk-OZJXGX4U.js";
|
|
67
65
|
import {
|
|
68
66
|
SANDBOX_DATA_ROOT,
|
|
69
67
|
SANDBOX_SKILLS_ROOT,
|
|
@@ -74,11 +72,11 @@ import {
|
|
|
74
72
|
import {
|
|
75
73
|
acquireActiveLock,
|
|
76
74
|
getStateAdapter
|
|
77
|
-
} from "./chunk-
|
|
75
|
+
} from "./chunk-ZATRYQLR.js";
|
|
78
76
|
import {
|
|
79
77
|
getConversationStore,
|
|
80
78
|
getDb
|
|
81
|
-
} from "./chunk-
|
|
79
|
+
} from "./chunk-NIFONS4W.js";
|
|
82
80
|
import {
|
|
83
81
|
GEN_AI_PROVIDER_NAME,
|
|
84
82
|
GEN_AI_SERVER_ADDRESS,
|
|
@@ -87,6 +85,7 @@ import {
|
|
|
87
85
|
botConfig,
|
|
88
86
|
completeObject,
|
|
89
87
|
completeText,
|
|
88
|
+
escapeXml,
|
|
90
89
|
extractAssistantText,
|
|
91
90
|
getGatewayApiKey,
|
|
92
91
|
getPiGatewayApiKey,
|
|
@@ -99,19 +98,22 @@ import {
|
|
|
99
98
|
nextProviderRetry,
|
|
100
99
|
normalizeSlackEmojiName,
|
|
101
100
|
normalizeToolNameFromResult,
|
|
101
|
+
renderCurrentInstruction,
|
|
102
102
|
resolveGatewayModel,
|
|
103
103
|
stripRuntimeTurnContext
|
|
104
|
-
} from "./chunk-
|
|
104
|
+
} from "./chunk-3F54A3YM.js";
|
|
105
105
|
import {
|
|
106
106
|
parseSlackThreadId,
|
|
107
107
|
resolveConversationPrivacy,
|
|
108
108
|
runWithConversationPrivacy,
|
|
109
|
+
toCanonicalInputMessage,
|
|
110
|
+
toCanonicalOutputMessage,
|
|
109
111
|
toGenAiMessageMetadata,
|
|
110
112
|
toGenAiMessagesTraceAttributes,
|
|
111
113
|
toGenAiPayloadMetadata,
|
|
112
114
|
toGenAiPayloadTraceAttributes,
|
|
113
115
|
toGenAiTextMetadata
|
|
114
|
-
} from "./chunk-
|
|
116
|
+
} from "./chunk-YYBX2BD5.js";
|
|
115
117
|
import {
|
|
116
118
|
parseDestination
|
|
117
119
|
} from "./chunk-GHGPTPBL.js";
|
|
@@ -120,20 +122,21 @@ import {
|
|
|
120
122
|
findSkillByName,
|
|
121
123
|
loadSkillsByName,
|
|
122
124
|
parseSkillInvocation
|
|
123
|
-
} from "./chunk-
|
|
125
|
+
} from "./chunk-YTNPU7I2.js";
|
|
124
126
|
import {
|
|
125
127
|
CredentialUnavailableError,
|
|
126
128
|
credentialContextSchema,
|
|
127
129
|
pluginCatalogRuntime,
|
|
128
130
|
resolveAuthTokenPlaceholder,
|
|
129
131
|
resolvePluginCommandEnv
|
|
130
|
-
} from "./chunk-
|
|
132
|
+
} from "./chunk-BTH37NCU.js";
|
|
131
133
|
import {
|
|
132
|
-
|
|
134
|
+
createActor,
|
|
133
135
|
extractGenAiUsageAttributes,
|
|
134
136
|
extractGenAiUsageSummary,
|
|
135
137
|
getLogContextAttributes,
|
|
136
138
|
getTracePropagationHeaders,
|
|
139
|
+
isUserActor,
|
|
137
140
|
logError,
|
|
138
141
|
logException,
|
|
139
142
|
logInfo,
|
|
@@ -145,7 +148,7 @@ import {
|
|
|
145
148
|
setTags,
|
|
146
149
|
summarizeMessageText,
|
|
147
150
|
withSpan
|
|
148
|
-
} from "./chunk-
|
|
151
|
+
} from "./chunk-S6QKIGRM.js";
|
|
149
152
|
import {
|
|
150
153
|
isRecord
|
|
151
154
|
} from "./chunk-OB42YVAE.js";
|
|
@@ -465,7 +468,7 @@ function buildChatStartAttributes(model, context, mode, conversationPrivacy) {
|
|
|
465
468
|
...toGenAiMessagesTraceAttributes("app.ai.input", context.messages)
|
|
466
469
|
};
|
|
467
470
|
const inputMessages = serializeGenAiAttribute(
|
|
468
|
-
mode === "metadata" ? context.messages.map(toGenAiMessageMetadata) : context.messages
|
|
471
|
+
mode === "metadata" ? context.messages.map(toGenAiMessageMetadata) : context.messages.map(toCanonicalInputMessage)
|
|
469
472
|
);
|
|
470
473
|
if (inputMessages) {
|
|
471
474
|
attributes["gen_ai.input.messages"] = inputMessages;
|
|
@@ -486,7 +489,7 @@ function buildChatEndAttributes(message, mode) {
|
|
|
486
489
|
...toGenAiMessagesTraceAttributes("app.ai.output", [message])
|
|
487
490
|
};
|
|
488
491
|
const outputMessages = serializeGenAiAttribute(
|
|
489
|
-
mode === "metadata" ? [toGenAiMessageMetadata(message)] : [message]
|
|
492
|
+
mode === "metadata" ? [toGenAiMessageMetadata(message)] : [toCanonicalOutputMessage(message)]
|
|
490
493
|
);
|
|
491
494
|
if (outputMessages) {
|
|
492
495
|
attributes["gen_ai.output.messages"] = outputMessages;
|
|
@@ -675,8 +678,7 @@ function buildTurnResult(input) {
|
|
|
675
678
|
);
|
|
676
679
|
const canvasCreated = successfulToolNames.has("slackCanvasCreate");
|
|
677
680
|
const reactionPerformed = successfulToolNames.has("addReaction");
|
|
678
|
-
const
|
|
679
|
-
const sideEffectOnlySuccess = markerSideEffectSuccess;
|
|
681
|
+
const silentCompletionSuccess = exactNoReplyMarker;
|
|
680
682
|
const baseDeliveryPlan = {
|
|
681
683
|
mode: "thread",
|
|
682
684
|
postThreadText: true
|
|
@@ -689,7 +691,7 @@ function buildTurnResult(input) {
|
|
|
689
691
|
const markerCategory = reactionPerformed ? "reaction" : "none";
|
|
690
692
|
const markerContext = {
|
|
691
693
|
slackThreadId: correlation?.threadId,
|
|
692
|
-
slackUserId: correlation?.
|
|
694
|
+
slackUserId: correlation?.actorId,
|
|
693
695
|
slackChannelId: correlation?.channelId,
|
|
694
696
|
runId: correlation?.runId,
|
|
695
697
|
assistantUserName,
|
|
@@ -698,29 +700,22 @@ function buildTurnResult(input) {
|
|
|
698
700
|
const markerAttributes = {
|
|
699
701
|
"app.ai.no_reply_marker": true,
|
|
700
702
|
"app.ai.no_reply_marker_category": markerCategory,
|
|
701
|
-
"app.ai.no_reply_marker_accepted":
|
|
703
|
+
"app.ai.no_reply_marker_accepted": !isProviderError
|
|
702
704
|
};
|
|
703
|
-
if (
|
|
705
|
+
if (!isProviderError) {
|
|
704
706
|
logInfo(
|
|
705
707
|
"ai_no_reply_marker_accepted",
|
|
706
708
|
markerContext,
|
|
707
709
|
markerAttributes,
|
|
708
710
|
"No-reply marker suppressed visible thread text"
|
|
709
711
|
);
|
|
710
|
-
} else if (!isProviderError) {
|
|
711
|
-
logWarn(
|
|
712
|
-
"ai_no_reply_marker_rejected",
|
|
713
|
-
markerContext,
|
|
714
|
-
markerAttributes,
|
|
715
|
-
"No-reply marker requires a successful visible side effect"
|
|
716
|
-
);
|
|
717
712
|
}
|
|
718
713
|
} else if (mixedNoReplyMarker) {
|
|
719
714
|
logWarn(
|
|
720
715
|
"ai_no_reply_marker_mixed_text",
|
|
721
716
|
{
|
|
722
717
|
slackThreadId: correlation?.threadId,
|
|
723
|
-
slackUserId: correlation?.
|
|
718
|
+
slackUserId: correlation?.actorId,
|
|
724
719
|
slackChannelId: correlation?.channelId,
|
|
725
720
|
runId: correlation?.runId,
|
|
726
721
|
assistantUserName,
|
|
@@ -733,12 +728,12 @@ function buildTurnResult(input) {
|
|
|
733
728
|
"No-reply marker appeared with visible assistant text"
|
|
734
729
|
);
|
|
735
730
|
}
|
|
736
|
-
if (!primaryText && !
|
|
731
|
+
if (!primaryText && !silentCompletionSuccess && !isProviderError) {
|
|
737
732
|
logWarn(
|
|
738
733
|
"ai_model_response_empty",
|
|
739
734
|
{
|
|
740
735
|
slackThreadId: correlation?.threadId,
|
|
741
|
-
slackUserId: correlation?.
|
|
736
|
+
slackUserId: correlation?.actorId,
|
|
742
737
|
slackChannelId: correlation?.channelId,
|
|
743
738
|
runId: correlation?.runId,
|
|
744
739
|
assistantUserName,
|
|
@@ -756,7 +751,7 @@ function buildTurnResult(input) {
|
|
|
756
751
|
let outcome;
|
|
757
752
|
if (isProviderError) {
|
|
758
753
|
outcome = "provider_error";
|
|
759
|
-
} else if (primaryText ||
|
|
754
|
+
} else if (primaryText || silentCompletionSuccess) {
|
|
760
755
|
outcome = "success";
|
|
761
756
|
} else {
|
|
762
757
|
outcome = "execution_failure";
|
|
@@ -766,7 +761,7 @@ function buildTurnResult(input) {
|
|
|
766
761
|
const escapedOrRawPayload = Boolean(primaryText) && (isExecutionEscapeResponse(primaryText) || isRawToolPayloadResponse(primaryText));
|
|
767
762
|
const resolvedText = escapedOrRawPayload ? "" : responseText;
|
|
768
763
|
const resolvedOutcome = escapedOrRawPayload ? "execution_failure" : outcome;
|
|
769
|
-
const deliveryPlan = resolvedOutcome === "success" && !resolvedText
|
|
764
|
+
const deliveryPlan = resolvedOutcome === "success" && !resolvedText ? {
|
|
770
765
|
...baseDeliveryPlan,
|
|
771
766
|
postThreadText: false
|
|
772
767
|
} : baseDeliveryPlan;
|
|
@@ -939,7 +934,7 @@ async function selectTurnThinkingLevel(args) {
|
|
|
939
934
|
const logContext = {
|
|
940
935
|
slackThreadId: args.context?.threadId,
|
|
941
936
|
slackChannelId: args.context?.channelId,
|
|
942
|
-
slackUserId: args.context?.
|
|
937
|
+
slackUserId: args.context?.actorId,
|
|
943
938
|
runId: args.context?.runId,
|
|
944
939
|
modelId: args.fastModelId
|
|
945
940
|
};
|
|
@@ -962,7 +957,7 @@ async function selectTurnThinkingLevel(args) {
|
|
|
962
957
|
modelId: args.fastModelId,
|
|
963
958
|
threadId: args.context?.threadId ?? "",
|
|
964
959
|
channelId: args.context?.channelId ?? "",
|
|
965
|
-
|
|
960
|
+
actorId: args.context?.actorId ?? "",
|
|
966
961
|
runId: args.context?.runId ?? ""
|
|
967
962
|
},
|
|
968
963
|
prompt
|
|
@@ -1077,25 +1072,38 @@ function getSessionIdentifiers(routing) {
|
|
|
1077
1072
|
sessionId: routing.correlation?.turnId
|
|
1078
1073
|
};
|
|
1079
1074
|
}
|
|
1080
|
-
function
|
|
1081
|
-
|
|
1082
|
-
|
|
1083
|
-
|
|
1084
|
-
|
|
1085
|
-
|
|
1075
|
+
function actorFromRouting(routing) {
|
|
1076
|
+
if (routing.dispatch?.actor) {
|
|
1077
|
+
return routing.dispatch.actor;
|
|
1078
|
+
}
|
|
1079
|
+
const userActor = createActor(
|
|
1080
|
+
isUserActor(routing.actor) ? routing.actor : void 0,
|
|
1081
|
+
{
|
|
1082
|
+
platform: (isUserActor(routing.actor) ? routing.actor.platform : void 0) ?? (routing.destination.platform === "slack" ? "slack" : void 0),
|
|
1083
|
+
teamId: (routing.destination.platform === "slack" ? routing.destination.teamId : void 0) ?? routing.correlation?.teamId ?? (routing.actor?.platform === "slack" ? routing.actor.teamId : void 0),
|
|
1084
|
+
userId: routing.correlation?.actorId
|
|
1085
|
+
}
|
|
1086
|
+
);
|
|
1087
|
+
if (userActor) {
|
|
1088
|
+
return userActor;
|
|
1089
|
+
}
|
|
1090
|
+
if (routing.credentialContext && !("type" in routing.credentialContext.actor)) {
|
|
1091
|
+
return routing.credentialContext.actor;
|
|
1092
|
+
}
|
|
1093
|
+
return void 0;
|
|
1086
1094
|
}
|
|
1087
|
-
function
|
|
1088
|
-
const { destination,
|
|
1089
|
-
if (!
|
|
1095
|
+
function assertActorDestinationMatch(routing) {
|
|
1096
|
+
const { destination, actor } = routing;
|
|
1097
|
+
if (!actor) {
|
|
1090
1098
|
return;
|
|
1091
1099
|
}
|
|
1092
|
-
if (
|
|
1100
|
+
if (actor.platform !== destination.platform) {
|
|
1093
1101
|
throw new TypeError(
|
|
1094
|
-
`
|
|
1102
|
+
`Actor platform "${actor.platform}" does not match destination platform "${destination.platform}"`
|
|
1095
1103
|
);
|
|
1096
1104
|
}
|
|
1097
|
-
if (
|
|
1098
|
-
throw new TypeError("Slack
|
|
1105
|
+
if (actor.platform === "slack" && destination.platform === "slack" && actor.teamId !== destination.teamId) {
|
|
1106
|
+
throw new TypeError("Slack actor team does not match destination team");
|
|
1099
1107
|
}
|
|
1100
1108
|
}
|
|
1101
1109
|
function assertCorrelationDestinationMatch(routing) {
|
|
@@ -1347,15 +1355,12 @@ async function restoreSkillRuntime(args) {
|
|
|
1347
1355
|
}
|
|
1348
1356
|
|
|
1349
1357
|
// src/chat/agent/prompt.ts
|
|
1350
|
-
import { z as z2 } from "zod";
|
|
1351
1358
|
var MAX_INLINE_ATTACHMENT_BASE64_CHARS = 12e4;
|
|
1352
1359
|
var MAX_ROUTER_ATTACHMENT_PREVIEW_CHARS = 2e3;
|
|
1353
|
-
var legacyStoredTextPartSchema = z2.object({
|
|
1354
|
-
text: z2.string(),
|
|
1355
|
-
type: z2.literal("text")
|
|
1356
|
-
}).strict();
|
|
1357
1360
|
function isStructuredThreadContext(context) {
|
|
1358
|
-
return /^<thread-(compactions|transcript)>/.test(
|
|
1361
|
+
return /^<(recent-thread-messages|thread-(compactions|transcript))>/.test(
|
|
1362
|
+
context
|
|
1363
|
+
);
|
|
1359
1364
|
}
|
|
1360
1365
|
function renderThreadContextForPrompt(context) {
|
|
1361
1366
|
if (isStructuredThreadContext(context)) {
|
|
@@ -1363,9 +1368,9 @@ function renderThreadContextForPrompt(context) {
|
|
|
1363
1368
|
}
|
|
1364
1369
|
return ["<thread-background>", context, "</thread-background>"].join("\n");
|
|
1365
1370
|
}
|
|
1366
|
-
function buildUserTurnText(userInput, conversationContext) {
|
|
1371
|
+
function buildUserTurnText(userInput, conversationContext, actor) {
|
|
1367
1372
|
const trimmedContext = conversationContext?.trim();
|
|
1368
|
-
const currentInstruction = renderCurrentInstruction(userInput);
|
|
1373
|
+
const currentInstruction = renderCurrentInstruction(userInput, actor);
|
|
1369
1374
|
if (!trimmedContext) {
|
|
1370
1375
|
return currentInstruction;
|
|
1371
1376
|
}
|
|
@@ -1498,10 +1503,11 @@ function buildUserTurnInput(args) {
|
|
|
1498
1503
|
return { routerBlocks, userContentParts };
|
|
1499
1504
|
}
|
|
1500
1505
|
function buildPromptInput(input) {
|
|
1501
|
-
const promptConversationContext = input.piMessages && input.piMessages.length > 0 ? void 0 : input.conversationContext;
|
|
1506
|
+
const promptConversationContext = input.piMessages && input.piMessages.length > 0 && !input.includeConversationContextWithPiMessages ? void 0 : input.conversationContext;
|
|
1502
1507
|
const userTurnText = buildUserTurnText(
|
|
1503
1508
|
input.messageText,
|
|
1504
|
-
promptConversationContext
|
|
1509
|
+
promptConversationContext,
|
|
1510
|
+
input.actor
|
|
1505
1511
|
);
|
|
1506
1512
|
return buildUserTurnInput({
|
|
1507
1513
|
omittedImageAttachmentCount: input.omittedImageAttachmentCount ?? 0,
|
|
@@ -1511,7 +1517,7 @@ function buildPromptInput(input) {
|
|
|
1511
1517
|
}
|
|
1512
1518
|
function buildSteeringPiMessage(message) {
|
|
1513
1519
|
const { userContentParts } = buildUserTurnInput({
|
|
1514
|
-
userTurnText: buildUserTurnText(message.text),
|
|
1520
|
+
userTurnText: buildUserTurnText(message.text, void 0, message.actor),
|
|
1515
1521
|
userAttachments: message.userAttachments,
|
|
1516
1522
|
omittedImageAttachmentCount: message.omittedImageAttachmentCount ?? 0
|
|
1517
1523
|
});
|
|
@@ -1538,35 +1544,7 @@ function withoutTrailingUncheckpointedUserPrompt(messages, userContentParts) {
|
|
|
1538
1544
|
return messages.slice(0, -1);
|
|
1539
1545
|
}
|
|
1540
1546
|
function userPromptContentMatches(storedContent, currentContent) {
|
|
1541
|
-
|
|
1542
|
-
return true;
|
|
1543
|
-
}
|
|
1544
|
-
if (!Array.isArray(storedContent)) {
|
|
1545
|
-
return false;
|
|
1546
|
-
}
|
|
1547
|
-
if (storedContent.length !== currentContent.length) {
|
|
1548
|
-
return false;
|
|
1549
|
-
}
|
|
1550
|
-
return storedContent.every((storedPart, index) => {
|
|
1551
|
-
const currentPart = currentContent[index];
|
|
1552
|
-
if (index === 0 && currentPart?.type === "text") {
|
|
1553
|
-
const legacyTextPart = legacyStoredTextPartSchema.safeParse(storedPart);
|
|
1554
|
-
if (legacyTextPart.success) {
|
|
1555
|
-
return legacyTextPartMatchesCurrentText(
|
|
1556
|
-
legacyTextPart.data.text,
|
|
1557
|
-
currentPart.text
|
|
1558
|
-
);
|
|
1559
|
-
}
|
|
1560
|
-
}
|
|
1561
|
-
return JSON.stringify(storedPart) === JSON.stringify(currentPart);
|
|
1562
|
-
});
|
|
1563
|
-
}
|
|
1564
|
-
function legacyTextPartMatchesCurrentText(storedText, currentText) {
|
|
1565
|
-
const storedInstructionBody = extractCurrentInstructionBody(storedText);
|
|
1566
|
-
if (storedInstructionBody !== void 0) {
|
|
1567
|
-
return renderCurrentInstruction(storedInstructionBody) === currentText;
|
|
1568
|
-
}
|
|
1569
|
-
return renderCurrentInstruction(storedText) === currentText;
|
|
1547
|
+
return JSON.stringify(storedContent) === JSON.stringify(currentContent);
|
|
1570
1548
|
}
|
|
1571
1549
|
async function assemblePrompt(args) {
|
|
1572
1550
|
const source = args.routing.source;
|
|
@@ -1601,7 +1579,7 @@ async function assemblePrompt(args) {
|
|
|
1601
1579
|
source
|
|
1602
1580
|
} : void 0,
|
|
1603
1581
|
invocation: args.invocation,
|
|
1604
|
-
|
|
1582
|
+
actor: isUserActor(args.currentActor) ? args.currentActor : void 0,
|
|
1605
1583
|
artifactState: args.artifactState,
|
|
1606
1584
|
configuration: args.configurationValues
|
|
1607
1585
|
}) : null;
|
|
@@ -1769,7 +1747,7 @@ ${usage}
|
|
|
1769
1747
|
const entry = await configuration.set({
|
|
1770
1748
|
key,
|
|
1771
1749
|
value,
|
|
1772
|
-
updatedBy: deps.
|
|
1750
|
+
updatedBy: deps.actorId,
|
|
1773
1751
|
source: "jr-rpc"
|
|
1774
1752
|
});
|
|
1775
1753
|
logInfo(
|
|
@@ -2698,30 +2676,30 @@ function serializeMcpPayload(payload, privacy) {
|
|
|
2698
2676
|
}
|
|
2699
2677
|
|
|
2700
2678
|
// src/chat/tools/sandbox/bash.ts
|
|
2701
|
-
import { z as
|
|
2679
|
+
import { z as z4 } from "zod";
|
|
2702
2680
|
|
|
2703
2681
|
// src/chat/tool-support/structured-result.ts
|
|
2704
|
-
import { z as
|
|
2705
|
-
var juniorToolContinuationSchema =
|
|
2706
|
-
arguments:
|
|
2707
|
-
reason:
|
|
2682
|
+
import { z as z2 } from "zod";
|
|
2683
|
+
var juniorToolContinuationSchema = z2.object({
|
|
2684
|
+
arguments: z2.record(z2.string(), z2.unknown()),
|
|
2685
|
+
reason: z2.string().min(1).optional()
|
|
2708
2686
|
}).strict();
|
|
2709
2687
|
var juniorToolBoundContinuationSchema = juniorToolContinuationSchema.extend({
|
|
2710
|
-
tool_name:
|
|
2688
|
+
tool_name: z2.string().min(1)
|
|
2711
2689
|
});
|
|
2712
|
-
var juniorToolErrorSchema =
|
|
2713
|
-
kind:
|
|
2714
|
-
message:
|
|
2715
|
-
retryable:
|
|
2690
|
+
var juniorToolErrorSchema = z2.object({
|
|
2691
|
+
kind: z2.string().min(1),
|
|
2692
|
+
message: z2.string().min(1),
|
|
2693
|
+
retryable: z2.boolean().optional()
|
|
2716
2694
|
}).strict();
|
|
2717
|
-
var juniorToolResultSchema =
|
|
2718
|
-
ok:
|
|
2719
|
-
status:
|
|
2720
|
-
target:
|
|
2721
|
-
data:
|
|
2722
|
-
truncated:
|
|
2695
|
+
var juniorToolResultSchema = z2.object({
|
|
2696
|
+
ok: z2.boolean(),
|
|
2697
|
+
status: z2.enum(["success", "error"]),
|
|
2698
|
+
target: z2.string().min(1).optional(),
|
|
2699
|
+
data: z2.unknown().optional(),
|
|
2700
|
+
truncated: z2.boolean().optional(),
|
|
2723
2701
|
continuation: juniorToolContinuationSchema.optional(),
|
|
2724
|
-
error:
|
|
2702
|
+
error: z2.union([juniorToolErrorSchema, z2.string()]).optional()
|
|
2725
2703
|
}).passthrough();
|
|
2726
2704
|
var juniorToolResultWithBoundContinuationSchema = juniorToolResultSchema.extend({
|
|
2727
2705
|
continuation: juniorToolBoundContinuationSchema.optional()
|
|
@@ -2768,7 +2746,7 @@ function makeStructuredToolResult(details, options = {}) {
|
|
|
2768
2746
|
}
|
|
2769
2747
|
|
|
2770
2748
|
// src/chat/tool-support/zod-tool.ts
|
|
2771
|
-
import { z as
|
|
2749
|
+
import { z as z3 } from "zod";
|
|
2772
2750
|
|
|
2773
2751
|
// src/chat/tools/execution/tool-input-error.ts
|
|
2774
2752
|
var ToolInputError = class extends Error {
|
|
@@ -2802,7 +2780,7 @@ function zodTool(definition) {
|
|
|
2802
2780
|
const { inputSchema, outputSchema, prepareArguments, execute, ...toolDef } = definition;
|
|
2803
2781
|
let modelInputSchema;
|
|
2804
2782
|
try {
|
|
2805
|
-
modelInputSchema =
|
|
2783
|
+
modelInputSchema = z3.toJSONSchema(inputSchema);
|
|
2806
2784
|
} catch (error) {
|
|
2807
2785
|
throw new TypeError(
|
|
2808
2786
|
"zodTool() inputSchema must be representable as JSON Schema.",
|
|
@@ -2812,7 +2790,7 @@ function zodTool(definition) {
|
|
|
2812
2790
|
let modelOutputSchema;
|
|
2813
2791
|
if (outputSchema) {
|
|
2814
2792
|
try {
|
|
2815
|
-
modelOutputSchema =
|
|
2793
|
+
modelOutputSchema = z3.toJSONSchema(outputSchema);
|
|
2816
2794
|
} catch (error) {
|
|
2817
2795
|
throw new TypeError(
|
|
2818
2796
|
"zodTool() outputSchema must be representable as JSON Schema.",
|
|
@@ -2854,9 +2832,9 @@ function zodTool(definition) {
|
|
|
2854
2832
|
function createBashTool() {
|
|
2855
2833
|
return zodTool({
|
|
2856
2834
|
description: "Run a bash command inside the isolated sandbox workspace. Use this for repository inspection/execution tasks that need shell access. Do not use for network-sensitive or destructive actions unless explicitly required.",
|
|
2857
|
-
inputSchema:
|
|
2858
|
-
command:
|
|
2859
|
-
timeoutMs:
|
|
2835
|
+
inputSchema: z4.object({
|
|
2836
|
+
command: z4.string().min(1).describe("Bash command to run inside the sandbox."),
|
|
2837
|
+
timeoutMs: z4.coerce.number().int().min(1e3).describe(
|
|
2860
2838
|
"Optional command timeout in milliseconds. Use for commands that may hang."
|
|
2861
2839
|
).optional()
|
|
2862
2840
|
}),
|
|
@@ -3230,7 +3208,7 @@ function validateAndApplyTextEdits(content, edits, targetName) {
|
|
|
3230
3208
|
}
|
|
3231
3209
|
|
|
3232
3210
|
// src/chat/tools/sandbox/edit-file.ts
|
|
3233
|
-
import { z as
|
|
3211
|
+
import { z as z5 } from "zod";
|
|
3234
3212
|
function prepareEditFileArguments(input) {
|
|
3235
3213
|
return prepareTextReplacementArguments(input);
|
|
3236
3214
|
}
|
|
@@ -3328,20 +3306,20 @@ async function editFile(params) {
|
|
|
3328
3306
|
replacements: params.edits.length
|
|
3329
3307
|
});
|
|
3330
3308
|
}
|
|
3331
|
-
var editReplacementSchema =
|
|
3332
|
-
oldText:
|
|
3309
|
+
var editReplacementSchema = z5.object({
|
|
3310
|
+
oldText: z5.string().min(1).describe(
|
|
3333
3311
|
"Exact text to replace. It must be unique in the original file and must not overlap another edit."
|
|
3334
3312
|
),
|
|
3335
|
-
newText:
|
|
3313
|
+
newText: z5.string().describe("Replacement text for this edit.")
|
|
3336
3314
|
});
|
|
3337
3315
|
function createEditFileTool() {
|
|
3338
3316
|
return zodTool({
|
|
3339
3317
|
description: "Edit one sandbox workspace file with exact text replacements. Use for precise changes to existing files; prefer this over writeFile for targeted changes. Each oldText must match exactly, be unique, and not overlap another edit. Returns a diff. Multiple changes to the same file: use one edits[] call.",
|
|
3340
3318
|
prepareArguments: prepareEditFileArguments,
|
|
3341
3319
|
executionMode: "sequential",
|
|
3342
|
-
inputSchema:
|
|
3343
|
-
path:
|
|
3344
|
-
edits:
|
|
3320
|
+
inputSchema: z5.object({
|
|
3321
|
+
path: z5.string().min(1).describe("Path to edit in the sandbox workspace."),
|
|
3322
|
+
edits: z5.array(editReplacementSchema).min(1).describe(
|
|
3345
3323
|
"Exact replacements matched against the original file, not incrementally."
|
|
3346
3324
|
)
|
|
3347
3325
|
}),
|
|
@@ -3356,7 +3334,7 @@ function createEditFileTool() {
|
|
|
3356
3334
|
|
|
3357
3335
|
// src/chat/tools/sandbox/find-files.ts
|
|
3358
3336
|
import path3 from "path";
|
|
3359
|
-
import { z as
|
|
3337
|
+
import { z as z6 } from "zod";
|
|
3360
3338
|
var DEFAULT_FIND_LIMIT = 1e3;
|
|
3361
3339
|
async function findFiles(params) {
|
|
3362
3340
|
if (!params.pattern.trim()) {
|
|
@@ -3416,14 +3394,14 @@ function createFindFilesTool() {
|
|
|
3416
3394
|
return zodTool({
|
|
3417
3395
|
description: "Find sandbox workspace files by glob pattern. Returns bounded paths relative to the search root and skips dependency/cache directories.",
|
|
3418
3396
|
annotations: { readOnlyHint: true, destructiveHint: false },
|
|
3419
|
-
inputSchema:
|
|
3420
|
-
pattern:
|
|
3397
|
+
inputSchema: z6.object({
|
|
3398
|
+
pattern: z6.string().min(1).describe(
|
|
3421
3399
|
"Glob pattern to match, for example '*.ts', '**/*.json', or 'src/**/*.test.ts'."
|
|
3422
3400
|
),
|
|
3423
|
-
path:
|
|
3401
|
+
path: z6.string().min(1).describe(
|
|
3424
3402
|
"Directory or file path in the sandbox workspace. Defaults to the workspace root."
|
|
3425
3403
|
).optional(),
|
|
3426
|
-
limit:
|
|
3404
|
+
limit: z6.coerce.number().int().min(1).describe("Maximum number of file paths to return. Defaults to 1000.").optional()
|
|
3427
3405
|
}),
|
|
3428
3406
|
outputSchema: juniorToolResultSchema,
|
|
3429
3407
|
execute: async () => {
|
|
@@ -3436,12 +3414,12 @@ function createFindFilesTool() {
|
|
|
3436
3414
|
|
|
3437
3415
|
// src/chat/tools/sandbox/grep.ts
|
|
3438
3416
|
import path4 from "path";
|
|
3439
|
-
import { z as
|
|
3417
|
+
import { z as z7 } from "zod";
|
|
3440
3418
|
var DEFAULT_GREP_LIMIT = 100;
|
|
3441
3419
|
var MAX_GREP_LINE_CHARS = 500;
|
|
3442
|
-
var booleanInput = (description) =>
|
|
3420
|
+
var booleanInput = (description) => z7.preprocess(
|
|
3443
3421
|
(value) => value === "true" ? true : value === "false" ? false : value,
|
|
3444
|
-
|
|
3422
|
+
z7.boolean()
|
|
3445
3423
|
).describe(description);
|
|
3446
3424
|
function truncateGrepLine(value) {
|
|
3447
3425
|
if (value.length <= MAX_GREP_LINE_CHARS) {
|
|
@@ -3590,20 +3568,20 @@ function createGrepTool() {
|
|
|
3590
3568
|
return zodTool({
|
|
3591
3569
|
description: "Search sandbox workspace file contents. Returns bounded matching lines with file paths and line numbers. Respects path/glob filters and includes truncation notices.",
|
|
3592
3570
|
annotations: { readOnlyHint: true, destructiveHint: false },
|
|
3593
|
-
inputSchema:
|
|
3594
|
-
pattern:
|
|
3595
|
-
path:
|
|
3571
|
+
inputSchema: z7.object({
|
|
3572
|
+
pattern: z7.string().min(1).describe("Regex pattern or literal text to search for."),
|
|
3573
|
+
path: z7.string().min(1).describe(
|
|
3596
3574
|
"Directory or file path in the sandbox workspace. Defaults to the workspace root."
|
|
3597
3575
|
).optional(),
|
|
3598
|
-
glob:
|
|
3576
|
+
glob: z7.string().min(1).describe("Optional glob filter such as '*.ts' or '**/*.test.ts'.").optional(),
|
|
3599
3577
|
ignoreCase: booleanInput(
|
|
3600
3578
|
"Whether matching should ignore case."
|
|
3601
3579
|
).optional(),
|
|
3602
3580
|
literal: booleanInput(
|
|
3603
3581
|
"Treat pattern as literal text instead of regex."
|
|
3604
3582
|
).optional(),
|
|
3605
|
-
context:
|
|
3606
|
-
limit:
|
|
3583
|
+
context: z7.coerce.number().int().min(0).describe("Number of surrounding context lines to include.").optional(),
|
|
3584
|
+
limit: z7.coerce.number().int().min(1).describe("Maximum matches to return. Defaults to 100.").optional()
|
|
3607
3585
|
}),
|
|
3608
3586
|
outputSchema: juniorToolResultSchema,
|
|
3609
3587
|
execute: async () => {
|
|
@@ -3721,7 +3699,7 @@ async function readSandboxFileUpload(sandbox, input) {
|
|
|
3721
3699
|
|
|
3722
3700
|
// src/chat/tools/sandbox/list-dir.ts
|
|
3723
3701
|
import path6 from "path";
|
|
3724
|
-
import { z as
|
|
3702
|
+
import { z as z8 } from "zod";
|
|
3725
3703
|
var DEFAULT_LIST_LIMIT = 500;
|
|
3726
3704
|
async function listDir(params) {
|
|
3727
3705
|
const dirPath = resolveWorkspacePath(params.path);
|
|
@@ -3802,11 +3780,11 @@ function createListDirTool() {
|
|
|
3802
3780
|
return zodTool({
|
|
3803
3781
|
description: "List a sandbox workspace directory. Returns sorted entries with '/' suffixes for directories and bounded truncation notices.",
|
|
3804
3782
|
annotations: { readOnlyHint: true, destructiveHint: false },
|
|
3805
|
-
inputSchema:
|
|
3806
|
-
path:
|
|
3783
|
+
inputSchema: z8.object({
|
|
3784
|
+
path: z8.string().min(1).describe(
|
|
3807
3785
|
"Directory path in the sandbox workspace. Defaults to the workspace root."
|
|
3808
3786
|
).optional(),
|
|
3809
|
-
limit:
|
|
3787
|
+
limit: z8.coerce.number().int().min(1).describe("Maximum entries to return. Defaults to 500.").optional()
|
|
3810
3788
|
}),
|
|
3811
3789
|
outputSchema: juniorToolResultSchema,
|
|
3812
3790
|
execute: async () => {
|
|
@@ -3818,8 +3796,24 @@ function createListDirTool() {
|
|
|
3818
3796
|
}
|
|
3819
3797
|
|
|
3820
3798
|
// src/chat/tools/web/image-generate.ts
|
|
3821
|
-
import { z as
|
|
3799
|
+
import { z as z9 } from "zod";
|
|
3822
3800
|
var DEFAULT_IMAGE_MODEL = "google/gemini-3-pro-image";
|
|
3801
|
+
var imageGenerateOutputSchema = juniorToolResultSchema.extend({
|
|
3802
|
+
model: z9.string(),
|
|
3803
|
+
prompt: z9.string(),
|
|
3804
|
+
enrichedPrompt: z9.string(),
|
|
3805
|
+
image_count: z9.number().int().nonnegative(),
|
|
3806
|
+
images: z9.array(
|
|
3807
|
+
z9.object({
|
|
3808
|
+
filename: z9.string(),
|
|
3809
|
+
path: z9.string(),
|
|
3810
|
+
attachment_path: z9.string(),
|
|
3811
|
+
media_type: z9.string().optional(),
|
|
3812
|
+
bytes: z9.number().int().nonnegative()
|
|
3813
|
+
}).strict()
|
|
3814
|
+
),
|
|
3815
|
+
delivery: z9.string()
|
|
3816
|
+
}).strict();
|
|
3823
3817
|
var ENRICHMENT_SYSTEM_PROMPT = `You are an image prompt enrichment agent. Your job is to rewrite image generation requests to reflect a specific visual identity and mood.
|
|
3824
3818
|
|
|
3825
3819
|
<personality>
|
|
@@ -3879,10 +3873,10 @@ function parseImageGenerationError(status, body, model) {
|
|
|
3879
3873
|
function createImageGenerateTool(hooks, options = {}, deps = {}) {
|
|
3880
3874
|
return zodTool({
|
|
3881
3875
|
description: "Generate images from a prompt. Use when the user wants to visually show or represent something \u2014 feelings, concepts, art, humor, or any visual idea. Also use for explicit image creation requests.",
|
|
3882
|
-
inputSchema:
|
|
3883
|
-
prompt:
|
|
3876
|
+
inputSchema: z9.object({
|
|
3877
|
+
prompt: z9.string().min(1).max(4e3).describe("Image generation prompt.")
|
|
3884
3878
|
}),
|
|
3885
|
-
outputSchema:
|
|
3879
|
+
outputSchema: imageGenerateOutputSchema,
|
|
3886
3880
|
execute: async ({ prompt }) => {
|
|
3887
3881
|
const fetchImpl = deps.fetch ?? fetch;
|
|
3888
3882
|
const apiKey = getGatewayApiKey();
|
|
@@ -3972,7 +3966,7 @@ function createImageGenerateTool(hooks, options = {}, deps = {}) {
|
|
|
3972
3966
|
}
|
|
3973
3967
|
|
|
3974
3968
|
// src/chat/tools/skill/call-mcp-tool.ts
|
|
3975
|
-
import { z as
|
|
3969
|
+
import { z as z10 } from "zod";
|
|
3976
3970
|
function resolveMcpArguments(input) {
|
|
3977
3971
|
const extraKeys = Object.keys(input).filter(
|
|
3978
3972
|
(key) => key !== "tool_name" && key !== "arguments"
|
|
@@ -4008,9 +4002,9 @@ function missingToolMessage(toolName, provider) {
|
|
|
4008
4002
|
function createCallMcpToolTool(mcpToolManager) {
|
|
4009
4003
|
return zodTool({
|
|
4010
4004
|
description: "Call an active MCP tool by exact tool_name. Use searchMcpTools to discover tool names and schemas; copy required provider fields into arguments. Do not call with only tool_name unless the discovered tool has no arguments. Authorization is handled by the runtime when required.",
|
|
4011
|
-
inputSchema:
|
|
4012
|
-
tool_name:
|
|
4013
|
-
arguments:
|
|
4005
|
+
inputSchema: z10.object({
|
|
4006
|
+
tool_name: z10.string().min(1).describe("Exact MCP tool_name from searchMcpTools."),
|
|
4007
|
+
arguments: z10.record(z10.string(), z10.unknown()).describe(
|
|
4014
4008
|
'Arguments matching the disclosed MCP tool schema, for example { "query": "..." } when searchMcpTools shows query is required.'
|
|
4015
4009
|
).optional()
|
|
4016
4010
|
}).passthrough(),
|
|
@@ -4051,7 +4045,7 @@ function createCallMcpToolTool(mcpToolManager) {
|
|
|
4051
4045
|
}
|
|
4052
4046
|
|
|
4053
4047
|
// src/chat/tools/skill/load-skill.ts
|
|
4054
|
-
import { z as
|
|
4048
|
+
import { z as z11 } from "zod";
|
|
4055
4049
|
function toLoadedSkill(result, availableSkills) {
|
|
4056
4050
|
if (result.ok !== true || typeof result.skill_name !== "string" || typeof result.description !== "string" || typeof result.skill_dir !== "string" || typeof result.instructions !== "string") {
|
|
4057
4051
|
return null;
|
|
@@ -4100,8 +4094,8 @@ async function loadSkillFromHost(availableSkills, skillName) {
|
|
|
4100
4094
|
function createLoadSkillTool(availableSkills, options) {
|
|
4101
4095
|
return zodTool({
|
|
4102
4096
|
description: "Load a skill by name for this turn. The result includes working_directory; resolve skill paths there and run skill-owned bash commands from there or with absolute paths. When the result includes mcp_provider, use searchMcpTools before callMcpTool. Use when a request clearly matches a known skill.",
|
|
4103
|
-
inputSchema:
|
|
4104
|
-
skill_name:
|
|
4097
|
+
inputSchema: z11.object({
|
|
4098
|
+
skill_name: z11.string().min(1).describe("Skill name to load, without the leading slash.")
|
|
4105
4099
|
}),
|
|
4106
4100
|
outputSchema: juniorToolResultSchema,
|
|
4107
4101
|
execute: async ({ skill_name }) => {
|
|
@@ -4119,7 +4113,7 @@ function createLoadSkillTool(availableSkills, options) {
|
|
|
4119
4113
|
}
|
|
4120
4114
|
|
|
4121
4115
|
// src/chat/tools/skill/search-mcp-tools.ts
|
|
4122
|
-
import { z as
|
|
4116
|
+
import { z as z12 } from "zod";
|
|
4123
4117
|
|
|
4124
4118
|
// src/chat/tool-support/schema-summary.ts
|
|
4125
4119
|
function getSchemaProperties(schema) {
|
|
@@ -4249,6 +4243,38 @@ function toActiveMcpCatalogSummaries(toolDefs) {
|
|
|
4249
4243
|
// src/chat/tools/skill/search-mcp-tools.ts
|
|
4250
4244
|
var DEFAULT_MAX_RESULTS = 5;
|
|
4251
4245
|
var MAX_RESULTS = 20;
|
|
4246
|
+
var providerSummarySchema = z12.object({
|
|
4247
|
+
provider: z12.string(),
|
|
4248
|
+
description: z12.string(),
|
|
4249
|
+
active: z12.boolean()
|
|
4250
|
+
}).strict();
|
|
4251
|
+
var mcpCallExampleSchema = z12.object({
|
|
4252
|
+
tool_name: z12.string(),
|
|
4253
|
+
arguments: z12.record(z12.string(), z12.string())
|
|
4254
|
+
}).strict();
|
|
4255
|
+
var exposedToolSummarySchema = z12.object({
|
|
4256
|
+
tool_name: z12.string(),
|
|
4257
|
+
mcp_tool_name: z12.string(),
|
|
4258
|
+
provider: z12.string(),
|
|
4259
|
+
title: z12.string().optional(),
|
|
4260
|
+
description: z12.string(),
|
|
4261
|
+
signature: z12.string(),
|
|
4262
|
+
call: mcpCallExampleSchema,
|
|
4263
|
+
input_schema: z12.record(z12.string(), z12.unknown()),
|
|
4264
|
+
input_schema_summary: z12.string(),
|
|
4265
|
+
output_schema: z12.record(z12.string(), z12.unknown()).optional(),
|
|
4266
|
+
annotations: z12.record(z12.string(), z12.unknown()).optional()
|
|
4267
|
+
}).strict();
|
|
4268
|
+
var searchMcpToolsOutputSchema = juniorToolResultSchema.extend({
|
|
4269
|
+
query: z12.string().nullable(),
|
|
4270
|
+
provider: z12.string().nullable(),
|
|
4271
|
+
total_active_tools: z12.number().int().nonnegative(),
|
|
4272
|
+
returned_tools: z12.number().int().nonnegative(),
|
|
4273
|
+
execution_tool: z12.literal("callMcpTool"),
|
|
4274
|
+
execution_example: mcpCallExampleSchema,
|
|
4275
|
+
available_providers: z12.array(providerSummarySchema),
|
|
4276
|
+
tools: z12.array(exposedToolSummarySchema)
|
|
4277
|
+
}).strict();
|
|
4252
4278
|
function normalize(value) {
|
|
4253
4279
|
return value.toLowerCase().replace(/[^a-z0-9_]+/g, " ").trim();
|
|
4254
4280
|
}
|
|
@@ -4367,16 +4393,16 @@ function searchProviderCatalog(providers, query) {
|
|
|
4367
4393
|
function createSearchMcpToolsTool(mcpToolManager) {
|
|
4368
4394
|
return zodTool({
|
|
4369
4395
|
description: "List or search MCP providers and active MCP tools. When provider is supplied and not yet active, Junior connects to it on demand and returns tool descriptors including schemas. Without provider, returns active tools plus matching configured providers without connecting. Use when choosing a provider tool or when callMcpTool arguments are unclear.",
|
|
4370
|
-
inputSchema:
|
|
4371
|
-
query:
|
|
4396
|
+
inputSchema: z12.object({
|
|
4397
|
+
query: z12.string().min(1).describe(
|
|
4372
4398
|
"Optional search terms describing the MCP tool or arguments needed."
|
|
4373
4399
|
).optional(),
|
|
4374
|
-
provider:
|
|
4400
|
+
provider: z12.string().min(1).describe(
|
|
4375
4401
|
"Optional provider name to list or search within. If configured but not yet connected, Junior activates it on demand."
|
|
4376
4402
|
).optional(),
|
|
4377
|
-
max_results:
|
|
4403
|
+
max_results: z12.number().int().min(1).max(MAX_RESULTS).describe("Maximum matching tool descriptors to return.").optional()
|
|
4378
4404
|
}).strict(),
|
|
4379
|
-
outputSchema:
|
|
4405
|
+
outputSchema: searchMcpToolsOutputSchema,
|
|
4380
4406
|
execute: async ({ query, provider, max_results }) => {
|
|
4381
4407
|
if (provider) {
|
|
4382
4408
|
await mcpToolManager.activateProvider(provider);
|
|
@@ -4398,6 +4424,13 @@ function createSearchMcpToolsTool(mcpToolManager) {
|
|
|
4398
4424
|
provider: provider ?? null,
|
|
4399
4425
|
total_active_tools: catalog.length,
|
|
4400
4426
|
returned_tools: matches.length,
|
|
4427
|
+
execution_tool: "callMcpTool",
|
|
4428
|
+
execution_example: {
|
|
4429
|
+
tool_name: "<returned tool_name>",
|
|
4430
|
+
arguments: {
|
|
4431
|
+
"<argument>": "<value from input_schema>"
|
|
4432
|
+
}
|
|
4433
|
+
},
|
|
4401
4434
|
available_providers: providers,
|
|
4402
4435
|
tools: matches.map(toExposedToolSummary)
|
|
4403
4436
|
};
|
|
@@ -4412,7 +4445,7 @@ function createSearchMcpToolsTool(mcpToolManager) {
|
|
|
4412
4445
|
}
|
|
4413
4446
|
|
|
4414
4447
|
// src/chat/tools/sandbox/read-file.ts
|
|
4415
|
-
import { z as
|
|
4448
|
+
import { z as z13 } from "zod";
|
|
4416
4449
|
|
|
4417
4450
|
// src/chat/tool-support/text-range-result.ts
|
|
4418
4451
|
var DEFAULT_READ_LIMIT = 1e3;
|
|
@@ -4487,10 +4520,10 @@ function createReadFileTool() {
|
|
|
4487
4520
|
return zodTool({
|
|
4488
4521
|
description: "Read a bounded line range from a file in the sandbox workspace. Use when you need exact file contents to verify facts or make edits safely. Prefer grep/findFiles/listDir for broad discovery.",
|
|
4489
4522
|
annotations: { readOnlyHint: true, destructiveHint: false },
|
|
4490
|
-
inputSchema:
|
|
4491
|
-
path:
|
|
4492
|
-
offset:
|
|
4493
|
-
limit:
|
|
4523
|
+
inputSchema: z13.object({
|
|
4524
|
+
path: z13.string().min(1).describe("Path to the file in the sandbox workspace."),
|
|
4525
|
+
offset: z13.coerce.number().int().min(1).describe("1-indexed line number to start reading from.").optional(),
|
|
4526
|
+
limit: z13.coerce.number().int().min(1).describe("Maximum number of lines to read. Defaults to 1000.").optional()
|
|
4494
4527
|
}),
|
|
4495
4528
|
outputSchema: juniorToolResultSchema,
|
|
4496
4529
|
execute: async () => {
|
|
@@ -4502,12 +4535,12 @@ function createReadFileTool() {
|
|
|
4502
4535
|
}
|
|
4503
4536
|
|
|
4504
4537
|
// src/chat/tools/runtime/report-progress.ts
|
|
4505
|
-
import { z as
|
|
4538
|
+
import { z as z14 } from "zod";
|
|
4506
4539
|
function createReportProgressTool() {
|
|
4507
4540
|
return zodTool({
|
|
4508
4541
|
description: "Update the user-visible assistant loading message with a short progress phase. For every non-trivial turn, call this early with the initial major work phase, then call it again only when the major phase meaningfully changes. Messages must be written in sentence case with a present-participle verb (e.g. 'Searching docs', 'Reviewing results', 'Running checks'). Skip trivial direct answers, generic filler, and minor substeps.",
|
|
4509
|
-
inputSchema:
|
|
4510
|
-
message:
|
|
4542
|
+
inputSchema: z14.object({
|
|
4543
|
+
message: z14.string().min(1).describe("Short user-facing progress message.")
|
|
4511
4544
|
}),
|
|
4512
4545
|
outputSchema: juniorToolResultSchema,
|
|
4513
4546
|
execute: async () => ({
|
|
@@ -4518,31 +4551,31 @@ function createReportProgressTool() {
|
|
|
4518
4551
|
}
|
|
4519
4552
|
|
|
4520
4553
|
// src/chat/tools/resource-events.ts
|
|
4521
|
-
import { z as
|
|
4554
|
+
import { z as z16 } from "zod";
|
|
4522
4555
|
|
|
4523
4556
|
// src/chat/resource-events/store.ts
|
|
4524
4557
|
import { createHash } from "crypto";
|
|
4525
4558
|
import { destinationSchema } from "@sentry/junior-plugin-api";
|
|
4526
|
-
import { z as
|
|
4559
|
+
import { z as z15 } from "zod";
|
|
4527
4560
|
var RESOURCE_EVENT_PREFIX = "junior:resource_event_subscription";
|
|
4528
4561
|
var INDEX_LOCK_TTL_MS = 1e4;
|
|
4529
4562
|
var SUBSCRIPTION_LOCK_TTL_MS = 1e4;
|
|
4530
|
-
var subscriptionStatusSchema =
|
|
4531
|
-
var subscriptionIdIndexSchema =
|
|
4532
|
-
var subscriptionSchema =
|
|
4533
|
-
conversationId:
|
|
4534
|
-
createdAtMs:
|
|
4563
|
+
var subscriptionStatusSchema = z15.enum(["active", "cancelled", "completed"]);
|
|
4564
|
+
var subscriptionIdIndexSchema = z15.array(z15.string().min(1));
|
|
4565
|
+
var subscriptionSchema = z15.object({
|
|
4566
|
+
conversationId: z15.string().min(1),
|
|
4567
|
+
createdAtMs: z15.number().finite(),
|
|
4535
4568
|
destination: destinationSchema,
|
|
4536
|
-
events:
|
|
4537
|
-
expiresAtMs:
|
|
4538
|
-
id:
|
|
4539
|
-
intent:
|
|
4540
|
-
label:
|
|
4541
|
-
provider:
|
|
4542
|
-
resourceRef:
|
|
4543
|
-
resourceType:
|
|
4569
|
+
events: z15.array(z15.string().min(1)).min(1),
|
|
4570
|
+
expiresAtMs: z15.number().finite(),
|
|
4571
|
+
id: z15.string().min(1),
|
|
4572
|
+
intent: z15.string().min(1),
|
|
4573
|
+
label: z15.string().min(1),
|
|
4574
|
+
provider: z15.string().min(1),
|
|
4575
|
+
resourceRef: z15.string().min(1),
|
|
4576
|
+
resourceType: z15.string().min(1),
|
|
4544
4577
|
status: subscriptionStatusSchema,
|
|
4545
|
-
updatedAtMs:
|
|
4578
|
+
updatedAtMs: z15.number().finite()
|
|
4546
4579
|
}).strict();
|
|
4547
4580
|
function digest(value) {
|
|
4548
4581
|
return createHash("sha256").update(value).digest("hex").slice(0, 32);
|
|
@@ -4832,23 +4865,23 @@ async function deliverResourceEventSubscription(input) {
|
|
|
4832
4865
|
// src/chat/tools/resource-events.ts
|
|
4833
4866
|
var DEFAULT_TTL_MS = 14 * 24 * 60 * 60 * 1e3;
|
|
4834
4867
|
var MAX_TTL_MS = 30 * 24 * 60 * 60 * 1e3;
|
|
4835
|
-
var subscribeInputSchema =
|
|
4836
|
-
resourceRef:
|
|
4837
|
-
provider:
|
|
4838
|
-
resourceType:
|
|
4839
|
-
label:
|
|
4840
|
-
events:
|
|
4868
|
+
var subscribeInputSchema = z16.object({
|
|
4869
|
+
resourceRef: z16.string().describe("Opaque resource ref copied from a subscribable tool result."),
|
|
4870
|
+
provider: z16.string().describe("Provider that owns the resource ref."),
|
|
4871
|
+
resourceType: z16.string().describe("Provider-defined resource type from the subscribable hint."),
|
|
4872
|
+
label: z16.string().describe("Human-readable resource label from the subscribable hint."),
|
|
4873
|
+
events: z16.array(z16.string()).min(1).describe(
|
|
4841
4874
|
"High-signal event names to deliver to this conversation when they occur."
|
|
4842
4875
|
),
|
|
4843
|
-
intent:
|
|
4876
|
+
intent: z16.string().describe(
|
|
4844
4877
|
"Concise reason this conversation wants these events, used when an event arrives."
|
|
4845
4878
|
),
|
|
4846
|
-
ttlMs:
|
|
4879
|
+
ttlMs: z16.coerce.number().describe(
|
|
4847
4880
|
"How long to keep the subscription active. Defaults to 14 days and is capped at 30 days."
|
|
4848
4881
|
).optional()
|
|
4849
4882
|
});
|
|
4850
|
-
var cancelInputSchema =
|
|
4851
|
-
subscriptionId:
|
|
4883
|
+
var cancelInputSchema = z16.object({
|
|
4884
|
+
subscriptionId: z16.string().describe(
|
|
4852
4885
|
"Subscription id returned by subscribeToResourceEvents or listResourceEventSubscriptions."
|
|
4853
4886
|
)
|
|
4854
4887
|
});
|
|
@@ -4932,7 +4965,7 @@ function createSubscribeToResourceEventsTool(context) {
|
|
|
4932
4965
|
function createListResourceEventSubscriptionsTool(context) {
|
|
4933
4966
|
return zodTool({
|
|
4934
4967
|
description: "List active resource event subscriptions for the current conversation.",
|
|
4935
|
-
inputSchema:
|
|
4968
|
+
inputSchema: z16.object({}),
|
|
4936
4969
|
outputSchema: juniorToolResultSchema,
|
|
4937
4970
|
async execute() {
|
|
4938
4971
|
const conversationId = requireConversationContext(context);
|
|
@@ -5067,11 +5100,11 @@ async function listThreadReplies(input) {
|
|
|
5067
5100
|
}
|
|
5068
5101
|
|
|
5069
5102
|
// src/chat/slack/timestamp-param.ts
|
|
5070
|
-
import { z as
|
|
5103
|
+
import { z as z17 } from "zod";
|
|
5071
5104
|
function slackTimestampParam(description) {
|
|
5072
|
-
return
|
|
5105
|
+
return z17.preprocess(
|
|
5073
5106
|
(value) => typeof value === "number" && Number.isFinite(value) ? String(value) : value,
|
|
5074
|
-
|
|
5107
|
+
z17.string().min(1)
|
|
5075
5108
|
).describe(description);
|
|
5076
5109
|
}
|
|
5077
5110
|
function optionalSlackTimestampParam(description) {
|
|
@@ -5102,10 +5135,10 @@ function parseRequiredSlackTimestampParam(field, value) {
|
|
|
5102
5135
|
}
|
|
5103
5136
|
|
|
5104
5137
|
// src/chat/slack/tools/channel-list-messages.ts
|
|
5105
|
-
import { z as
|
|
5106
|
-
var booleanInput2 = (description) =>
|
|
5138
|
+
import { z as z18 } from "zod";
|
|
5139
|
+
var booleanInput2 = (description) => z18.preprocess(
|
|
5107
5140
|
(value) => value === "true" ? true : value === "false" ? false : value,
|
|
5108
|
-
|
|
5141
|
+
z18.boolean()
|
|
5109
5142
|
).describe(description);
|
|
5110
5143
|
function normalizeRangeTimestamp(field, value, targetChannelId) {
|
|
5111
5144
|
if (value === void 0) {
|
|
@@ -5132,9 +5165,9 @@ function createSlackChannelListMessagesTool(context) {
|
|
|
5132
5165
|
return zodTool({
|
|
5133
5166
|
description: "List channel messages from Slack history in the active channel context. Use when the user asks for recent or historical channel context outside this thread. Do not use for live monitoring or when current thread context already answers the question.",
|
|
5134
5167
|
annotations: { readOnlyHint: true, destructiveHint: false },
|
|
5135
|
-
inputSchema:
|
|
5136
|
-
limit:
|
|
5137
|
-
cursor:
|
|
5168
|
+
inputSchema: z18.object({
|
|
5169
|
+
limit: z18.coerce.number().int().min(1).max(1e3).describe("Maximum number of messages to return across pages.").optional(),
|
|
5170
|
+
cursor: z18.string().min(1).describe("Optional cursor to continue from a prior call.").optional(),
|
|
5138
5171
|
oldest: optionalSlackTimestampParam(
|
|
5139
5172
|
"Optional oldest message timestamp (Slack ts) for range filtering."
|
|
5140
5173
|
),
|
|
@@ -5144,7 +5177,7 @@ function createSlackChannelListMessagesTool(context) {
|
|
|
5144
5177
|
inclusive: booleanInput2(
|
|
5145
5178
|
"Whether oldest/latest bounds should be inclusive."
|
|
5146
5179
|
).optional(),
|
|
5147
|
-
max_pages:
|
|
5180
|
+
max_pages: z18.coerce.number().int().min(1).max(10).describe("Maximum number of API pages to traverse in a single call.").optional()
|
|
5148
5181
|
}),
|
|
5149
5182
|
outputSchema: juniorToolResultSchema,
|
|
5150
5183
|
execute: async ({
|
|
@@ -5477,7 +5510,7 @@ async function removeReactionFromMessage(input) {
|
|
|
5477
5510
|
}
|
|
5478
5511
|
|
|
5479
5512
|
// src/chat/slack/tools/message-add-reaction.ts
|
|
5480
|
-
import { z as
|
|
5513
|
+
import { z as z19 } from "zod";
|
|
5481
5514
|
|
|
5482
5515
|
// src/chat/tools/idempotency.ts
|
|
5483
5516
|
function stableSerialize(value) {
|
|
@@ -5499,8 +5532,8 @@ function createOperationKey(toolName, input) {
|
|
|
5499
5532
|
function createSlackMessageAddReactionTool(context, state) {
|
|
5500
5533
|
return zodTool({
|
|
5501
5534
|
description: "Add an emoji reaction to the current inbound Slack message. Use when the user asks for a reaction on the current message without another target. Provide a Slack emoji alias name (for example `thumbsup`, `white_check_mark`, or `thumbsup::skin-tone-6`), not a unicode emoji glyph. The target message is injected by runtime context; do not use this for arbitrary historical messages.",
|
|
5502
|
-
inputSchema:
|
|
5503
|
-
emoji:
|
|
5535
|
+
inputSchema: z19.object({
|
|
5536
|
+
emoji: z19.string().min(1).max(64).describe(
|
|
5504
5537
|
"Slack emoji alias name to react with (for example `thumbsup`, `white_check_mark`, or `thumbsup::skin-tone-6`). Optional surrounding colons are allowed."
|
|
5505
5538
|
)
|
|
5506
5539
|
}),
|
|
@@ -5551,15 +5584,15 @@ function createSlackMessageAddReactionTool(context, state) {
|
|
|
5551
5584
|
|
|
5552
5585
|
// src/chat/slack/tools/send-message.ts
|
|
5553
5586
|
import { createHash as createHash2 } from "crypto";
|
|
5554
|
-
import { z as
|
|
5555
|
-
var fileInputSchema =
|
|
5556
|
-
path:
|
|
5587
|
+
import { z as z20 } from "zod";
|
|
5588
|
+
var fileInputSchema = z20.object({
|
|
5589
|
+
path: z20.string().min(1).describe(
|
|
5557
5590
|
"Sandbox file path to include in the message. Absolute paths and workspace-relative paths are supported."
|
|
5558
5591
|
),
|
|
5559
|
-
filename:
|
|
5592
|
+
filename: z20.string().min(1).nullable().optional().describe(
|
|
5560
5593
|
"Optional filename override shown in Slack. Null is treated as omitted."
|
|
5561
5594
|
),
|
|
5562
|
-
mimeType:
|
|
5595
|
+
mimeType: z20.string().min(1).nullable().optional().describe("Optional MIME type override. Null is treated as omitted.")
|
|
5563
5596
|
});
|
|
5564
5597
|
function hasText(text) {
|
|
5565
5598
|
return typeof text === "string" && text.trim().length > 0;
|
|
@@ -5586,9 +5619,9 @@ function fileOperationInput(files) {
|
|
|
5586
5619
|
function createSendMessageTool(context, state, materializeFile) {
|
|
5587
5620
|
return zodTool({
|
|
5588
5621
|
description: "Send a Slack message with optional files into the active Slack conversation. Use when the user asks to attach, send, or share files here, in this conversation, or in this thread. The message can contain text, files, or both; file-only messages are allowed. Do not use for top-level channel posts, other named channels, inline @mentions, or pinging mentioned users.",
|
|
5589
|
-
inputSchema:
|
|
5590
|
-
text:
|
|
5591
|
-
files:
|
|
5622
|
+
inputSchema: z20.object({
|
|
5623
|
+
text: z20.string().max(4e4).nullable().optional().describe("Slack mrkdwn text to send. Null is treated as omitted."),
|
|
5624
|
+
files: z20.array(fileInputSchema).min(1).nullable().optional().describe(
|
|
5592
5625
|
"Sandbox files to include in the message. Null is treated as omitted."
|
|
5593
5626
|
)
|
|
5594
5627
|
}),
|
|
@@ -5916,13 +5949,13 @@ function storedCanvasUrl(state, canvasId) {
|
|
|
5916
5949
|
}
|
|
5917
5950
|
|
|
5918
5951
|
// src/chat/slack/tools/canvas/create.ts
|
|
5919
|
-
import { z as
|
|
5952
|
+
import { z as z21 } from "zod";
|
|
5920
5953
|
function createSlackCanvasCreateTool(context, state) {
|
|
5921
5954
|
return zodTool({
|
|
5922
5955
|
description: "Create a Slack canvas for long-form output in the active assistant context channel. Use when the answer is better as a reusable document than a thread reply: long-form research, timelines, bios/profiles, structured notes, plans, comparisons, or anything likely to exceed one compact Slack reply. After creating it, reply with one or two short sentences plus the canvas link; do not recap the canvas contents. Do not use for short answers that fit cleanly in one normal thread reply.",
|
|
5923
|
-
inputSchema:
|
|
5924
|
-
title:
|
|
5925
|
-
markdown:
|
|
5956
|
+
inputSchema: z21.object({
|
|
5957
|
+
title: z21.string().min(1).max(160).describe("Canvas title."),
|
|
5958
|
+
markdown: z21.string().min(1).describe("Canvas markdown body content.")
|
|
5926
5959
|
}),
|
|
5927
5960
|
outputSchema: juniorToolResultSchema,
|
|
5928
5961
|
execute: async ({ title, markdown }) => {
|
|
@@ -5985,28 +6018,39 @@ function createSlackCanvasCreateTool(context, state) {
|
|
|
5985
6018
|
}
|
|
5986
6019
|
|
|
5987
6020
|
// src/chat/slack/tools/canvas/edit.ts
|
|
5988
|
-
import { z as
|
|
6021
|
+
import { z as z22 } from "zod";
|
|
5989
6022
|
function prepareCanvasEditArguments(input) {
|
|
5990
6023
|
return prepareTextReplacementArguments(input);
|
|
5991
6024
|
}
|
|
5992
|
-
var editReplacementSchema2 =
|
|
5993
|
-
oldText:
|
|
6025
|
+
var editReplacementSchema2 = z22.object({
|
|
6026
|
+
oldText: z22.string().min(1).describe(
|
|
5994
6027
|
"Exact Canvas markdown to replace. It must be unique in the current Canvas body and must not overlap another edit."
|
|
5995
6028
|
),
|
|
5996
|
-
newText:
|
|
6029
|
+
newText: z22.string().describe("Replacement Canvas markdown for this edit.")
|
|
5997
6030
|
});
|
|
6031
|
+
var slackCanvasEditOutputSchema = juniorToolResultSchema.extend({
|
|
6032
|
+
canvas_id: z22.string().optional(),
|
|
6033
|
+
title: z22.string().optional(),
|
|
6034
|
+
permalink: z22.string().optional(),
|
|
6035
|
+
diff: z22.string().optional(),
|
|
6036
|
+
first_changed_line: z22.number().int().positive().optional(),
|
|
6037
|
+
replacements: z22.number().int().nonnegative().optional(),
|
|
6038
|
+
normalized_heading_count: z22.number().int().nonnegative().optional(),
|
|
6039
|
+
summary: z22.string().optional(),
|
|
6040
|
+
deduplicated: z22.boolean().optional()
|
|
6041
|
+
}).strict();
|
|
5998
6042
|
function createSlackCanvasEditTool(state) {
|
|
5999
6043
|
return zodTool({
|
|
6000
6044
|
description: "Edit one Slack canvas with exact markdown replacements. Use for precise changes to existing Canvas content; prefer this over slackCanvasWrite for targeted changes. Each oldText must match exactly, be unique, and not overlap another edit. Returns a diff. Multiple changes to the same canvas: use one edits[] call.",
|
|
6001
6045
|
prepareArguments: prepareCanvasEditArguments,
|
|
6002
6046
|
executionMode: "sequential",
|
|
6003
|
-
inputSchema:
|
|
6004
|
-
canvas:
|
|
6005
|
-
edits:
|
|
6047
|
+
inputSchema: z22.object({
|
|
6048
|
+
canvas: z22.string().min(1).describe("Canvas/file ID (e.g. `F0ABCDEF`) or Slack canvas/docs URL."),
|
|
6049
|
+
edits: z22.array(editReplacementSchema2).min(1).describe(
|
|
6006
6050
|
"Exact replacements matched against the current Canvas body, not incrementally."
|
|
6007
6051
|
)
|
|
6008
6052
|
}),
|
|
6009
|
-
outputSchema:
|
|
6053
|
+
outputSchema: slackCanvasEditOutputSchema,
|
|
6010
6054
|
execute: async ({ canvas, edits }) => {
|
|
6011
6055
|
const target = resolveCanvasTarget(canvas);
|
|
6012
6056
|
if (!target.ok) {
|
|
@@ -6080,19 +6124,31 @@ function createSlackCanvasEditTool(state) {
|
|
|
6080
6124
|
}
|
|
6081
6125
|
|
|
6082
6126
|
// src/chat/slack/tools/canvas/read.ts
|
|
6083
|
-
import { z as
|
|
6127
|
+
import { z as z23 } from "zod";
|
|
6128
|
+
var slackCanvasReadOutputSchema = juniorToolResultSchema.extend({
|
|
6129
|
+
canvas_id: z23.string().optional(),
|
|
6130
|
+
title: z23.string().optional(),
|
|
6131
|
+
permalink: z23.string().optional(),
|
|
6132
|
+
mimetype: z23.string().optional(),
|
|
6133
|
+
filetype: z23.string().optional(),
|
|
6134
|
+
original_byte_length: z23.number().int().nonnegative().optional(),
|
|
6135
|
+
content: z23.string().optional(),
|
|
6136
|
+
start_line: z23.number().int().positive().optional(),
|
|
6137
|
+
end_line: z23.number().int().nonnegative().optional(),
|
|
6138
|
+
total_lines: z23.number().int().nonnegative().optional()
|
|
6139
|
+
}).strict();
|
|
6084
6140
|
function createSlackCanvasReadTool() {
|
|
6085
6141
|
return zodTool({
|
|
6086
6142
|
description: "Read a bounded line range from a Slack canvas as markdown. Use when you need exact Canvas contents to verify facts or make edits safely. Do not use for generic web pages \u2014 use webFetch for those.",
|
|
6087
6143
|
annotations: { readOnlyHint: true, destructiveHint: false },
|
|
6088
|
-
inputSchema:
|
|
6089
|
-
canvas:
|
|
6144
|
+
inputSchema: z23.object({
|
|
6145
|
+
canvas: z23.string().min(1).describe(
|
|
6090
6146
|
"Canvas/file ID (e.g. `F0ABCDEF`) or Slack canvas/docs URL (e.g. `https://team.slack.com/docs/T.../F...`)."
|
|
6091
6147
|
),
|
|
6092
|
-
offset:
|
|
6093
|
-
limit:
|
|
6148
|
+
offset: z23.coerce.number().int().min(1).describe("1-indexed line number to start reading from.").optional(),
|
|
6149
|
+
limit: z23.coerce.number().int().min(1).describe("Maximum number of lines to read. Defaults to 1000.").optional()
|
|
6094
6150
|
}),
|
|
6095
|
-
outputSchema:
|
|
6151
|
+
outputSchema: slackCanvasReadOutputSchema,
|
|
6096
6152
|
execute: async ({ canvas, offset, limit }) => {
|
|
6097
6153
|
const target = resolveCanvasTarget(canvas);
|
|
6098
6154
|
if (!target.ok) {
|
|
@@ -6147,14 +6203,14 @@ function createSlackCanvasReadTool() {
|
|
|
6147
6203
|
}
|
|
6148
6204
|
|
|
6149
6205
|
// src/chat/slack/tools/canvas/write.ts
|
|
6150
|
-
import { z as
|
|
6206
|
+
import { z as z24 } from "zod";
|
|
6151
6207
|
function createSlackCanvasWriteTool(state) {
|
|
6152
6208
|
return zodTool({
|
|
6153
6209
|
description: "Write UTF-8 markdown content to a Slack canvas. Use for deliberate full-Canvas replacement after validation; use slackCanvasEdit for targeted changes to existing canvas content.",
|
|
6154
6210
|
executionMode: "sequential",
|
|
6155
|
-
inputSchema:
|
|
6156
|
-
canvas:
|
|
6157
|
-
content:
|
|
6211
|
+
inputSchema: z24.object({
|
|
6212
|
+
canvas: z24.string().min(1).describe("Canvas/file ID (e.g. `F0ABCDEF`) or Slack canvas/docs URL."),
|
|
6213
|
+
content: z24.string().describe("UTF-8 markdown content to write.")
|
|
6158
6214
|
}),
|
|
6159
6215
|
outputSchema: juniorToolResultSchema,
|
|
6160
6216
|
execute: async ({ canvas, content }) => {
|
|
@@ -6390,12 +6446,12 @@ async function updateListItem(input) {
|
|
|
6390
6446
|
}
|
|
6391
6447
|
|
|
6392
6448
|
// src/chat/slack/id-param.ts
|
|
6393
|
-
import { z as
|
|
6449
|
+
import { z as z25 } from "zod";
|
|
6394
6450
|
function slackChannelIdParam(description) {
|
|
6395
|
-
return
|
|
6451
|
+
return z25.string().min(1).describe(description);
|
|
6396
6452
|
}
|
|
6397
6453
|
function slackUserIdParam(description) {
|
|
6398
|
-
return
|
|
6454
|
+
return z25.string().min(1).describe(description);
|
|
6399
6455
|
}
|
|
6400
6456
|
function parseRequiredSlackChannelIdParam(field, value) {
|
|
6401
6457
|
const channelId = parseSlackChannelId(value);
|
|
@@ -6419,16 +6475,16 @@ function parseRequiredSlackUserIdParam(field, value) {
|
|
|
6419
6475
|
}
|
|
6420
6476
|
|
|
6421
6477
|
// src/chat/slack/tools/list/add-items.ts
|
|
6422
|
-
import { z as
|
|
6478
|
+
import { z as z26 } from "zod";
|
|
6423
6479
|
function createSlackListAddItemsTool(state) {
|
|
6424
6480
|
return zodTool({
|
|
6425
6481
|
description: "Add tasks to the active Slack list tracked in artifact context. Use when the user wants actionable items recorded in the current thread list. Do not use when no list exists and list creation was not requested.",
|
|
6426
|
-
inputSchema:
|
|
6427
|
-
items:
|
|
6482
|
+
inputSchema: z26.object({
|
|
6483
|
+
items: z26.array(z26.string().min(1)).min(1).max(25).describe("List item titles to create."),
|
|
6428
6484
|
assignee_user_id: slackUserIdParam(
|
|
6429
6485
|
"Optional Slack user ID assigned to all created items."
|
|
6430
6486
|
).optional(),
|
|
6431
|
-
due_date:
|
|
6487
|
+
due_date: z26.string().regex(/^\d{4}-\d{2}-\d{2}$/).describe("Optional due date in YYYY-MM-DD format.").optional()
|
|
6432
6488
|
}),
|
|
6433
6489
|
outputSchema: juniorToolResultSchema,
|
|
6434
6490
|
execute: async ({ items, assignee_user_id, due_date }) => {
|
|
@@ -6482,12 +6538,12 @@ function createSlackListAddItemsTool(state) {
|
|
|
6482
6538
|
}
|
|
6483
6539
|
|
|
6484
6540
|
// src/chat/slack/tools/list/create.ts
|
|
6485
|
-
import { z as
|
|
6541
|
+
import { z as z27 } from "zod";
|
|
6486
6542
|
function createSlackListCreateTool(state) {
|
|
6487
6543
|
return zodTool({
|
|
6488
6544
|
description: "Create a Slack todo list for action tracking. Use when the user needs structured tasks with ownership/completion tracking. Do not use for one-off notes without task management needs.",
|
|
6489
|
-
inputSchema:
|
|
6490
|
-
name:
|
|
6545
|
+
inputSchema: z27.object({
|
|
6546
|
+
name: z27.string().min(1).max(160).describe("Name for the new Slack list.")
|
|
6491
6547
|
}),
|
|
6492
6548
|
outputSchema: juniorToolResultSchema,
|
|
6493
6549
|
execute: async ({ name }) => {
|
|
@@ -6519,13 +6575,13 @@ function createSlackListCreateTool(state) {
|
|
|
6519
6575
|
}
|
|
6520
6576
|
|
|
6521
6577
|
// src/chat/slack/tools/list/get-items.ts
|
|
6522
|
-
import { z as
|
|
6578
|
+
import { z as z28 } from "zod";
|
|
6523
6579
|
function createSlackListGetItemsTool(state) {
|
|
6524
6580
|
return zodTool({
|
|
6525
6581
|
description: "Read items from the active Slack list tracked in artifact context. Use when the user asks for task status, open items, or list contents. Do not use when list state is already known from the immediately prior result.",
|
|
6526
6582
|
annotations: { readOnlyHint: true, destructiveHint: false },
|
|
6527
|
-
inputSchema:
|
|
6528
|
-
limit:
|
|
6583
|
+
inputSchema: z28.object({
|
|
6584
|
+
limit: z28.coerce.number().int().min(1).max(200).describe("Maximum number of list items to return.").optional()
|
|
6529
6585
|
}),
|
|
6530
6586
|
outputSchema: juniorToolResultSchema,
|
|
6531
6587
|
execute: async ({ limit }) => {
|
|
@@ -6550,21 +6606,21 @@ function createSlackListGetItemsTool(state) {
|
|
|
6550
6606
|
}
|
|
6551
6607
|
|
|
6552
6608
|
// src/chat/slack/tools/list/update-item.ts
|
|
6553
|
-
import { z as
|
|
6554
|
-
var booleanInput3 = (description) =>
|
|
6609
|
+
import { z as z29 } from "zod";
|
|
6610
|
+
var booleanInput3 = (description) => z29.preprocess(
|
|
6555
6611
|
(value) => value === "true" ? true : value === "false" ? false : value,
|
|
6556
|
-
|
|
6612
|
+
z29.boolean()
|
|
6557
6613
|
).describe(description);
|
|
6558
|
-
var updateListItemInputSchema =
|
|
6559
|
-
|
|
6560
|
-
item_id:
|
|
6614
|
+
var updateListItemInputSchema = z29.union([
|
|
6615
|
+
z29.object({
|
|
6616
|
+
item_id: z29.string().min(1).describe("ID of the Slack list item to update."),
|
|
6561
6617
|
completed: booleanInput3("Optional completion status update."),
|
|
6562
|
-
title:
|
|
6618
|
+
title: z29.string().min(1).describe("Optional new item title.").optional()
|
|
6563
6619
|
}),
|
|
6564
|
-
|
|
6565
|
-
item_id:
|
|
6620
|
+
z29.object({
|
|
6621
|
+
item_id: z29.string().min(1).describe("ID of the Slack list item to update."),
|
|
6566
6622
|
completed: booleanInput3("Optional completion status update.").optional(),
|
|
6567
|
-
title:
|
|
6623
|
+
title: z29.string().min(1).describe("Optional new item title.")
|
|
6568
6624
|
})
|
|
6569
6625
|
]);
|
|
6570
6626
|
function createSlackListUpdateItemTool(state) {
|
|
@@ -6640,7 +6696,7 @@ async function checkSlackChannelReadAccess(args) {
|
|
|
6640
6696
|
}
|
|
6641
6697
|
|
|
6642
6698
|
// src/chat/slack/tools/thread-read.ts
|
|
6643
|
-
import { z as
|
|
6699
|
+
import { z as z30 } from "zod";
|
|
6644
6700
|
|
|
6645
6701
|
// src/chat/slack/tools/slack-message-url.ts
|
|
6646
6702
|
var SLACK_HOST_PATTERN = /^[a-z0-9-]+\.slack(?:-gov)?\.com$/;
|
|
@@ -6813,8 +6869,8 @@ function createSlackThreadReadTool(context, deps = {}) {
|
|
|
6813
6869
|
return zodTool({
|
|
6814
6870
|
description: "Read a Slack thread from a shared Slack message archive URL or explicit channel + timestamp. Use when the user shares a Slack message link (https://*.slack.com/archives/...) and you need the referenced message and its thread context. Only the current conversation and public channels Junior has seen in this workspace are readable.",
|
|
6815
6871
|
annotations: { readOnlyHint: true, destructiveHint: false },
|
|
6816
|
-
inputSchema:
|
|
6817
|
-
url:
|
|
6872
|
+
inputSchema: z30.object({
|
|
6873
|
+
url: z30.string().min(1).describe(
|
|
6818
6874
|
"Slack message archive URL, e.g. https://workspace.slack.com/archives/C123/p1700000000123456"
|
|
6819
6875
|
).optional(),
|
|
6820
6876
|
channel_id: slackChannelIdParam(
|
|
@@ -6823,8 +6879,8 @@ function createSlackThreadReadTool(context, deps = {}) {
|
|
|
6823
6879
|
ts: slackTimestampParam(
|
|
6824
6880
|
"Slack message timestamp (e.g. 1700000000.123456). May be the thread root or any message in the thread."
|
|
6825
6881
|
).optional(),
|
|
6826
|
-
limit:
|
|
6827
|
-
max_pages:
|
|
6882
|
+
limit: z30.coerce.number().int().min(1).max(1e3).describe("Maximum number of thread messages to fetch.").optional(),
|
|
6883
|
+
max_pages: z30.coerce.number().int().min(1).max(10).describe("Maximum number of Slack API pages to traverse.").optional()
|
|
6828
6884
|
}),
|
|
6829
6885
|
outputSchema: juniorToolResultSchema,
|
|
6830
6886
|
execute: async ({ url, channel_id, ts, limit, max_pages }) => {
|
|
@@ -7080,29 +7136,29 @@ async function searchSlackUsers(options) {
|
|
|
7080
7136
|
}
|
|
7081
7137
|
|
|
7082
7138
|
// src/chat/slack/tools/user-lookup.ts
|
|
7083
|
-
import { z as
|
|
7084
|
-
var booleanInput4 = (description) =>
|
|
7139
|
+
import { z as z31 } from "zod";
|
|
7140
|
+
var booleanInput4 = (description) => z31.preprocess(
|
|
7085
7141
|
(value) => value === "true" ? true : value === "false" ? false : value,
|
|
7086
|
-
|
|
7142
|
+
z31.boolean()
|
|
7087
7143
|
).describe(description);
|
|
7088
7144
|
function createSlackUserLookupTool() {
|
|
7089
7145
|
return zodTool({
|
|
7090
7146
|
description: "Look up Slack user profiles by user ID, email, or name search. Use when you need to identify a user, resolve cross-platform identity, or look up profile details like title or status. Returns profile fields including custom fields. For user ID lookup, pass a Slack user ID (e.g. U039RR91S). For search, pass a name query.",
|
|
7091
7147
|
annotations: { readOnlyHint: true, destructiveHint: false },
|
|
7092
|
-
inputSchema:
|
|
7148
|
+
inputSchema: z31.object({
|
|
7093
7149
|
user_id: slackUserIdParam(
|
|
7094
7150
|
"Slack user ID to look up (e.g. U039RR91S). Mutually exclusive with email and query."
|
|
7095
7151
|
).optional(),
|
|
7096
|
-
email:
|
|
7152
|
+
email: z31.string().min(3).describe(
|
|
7097
7153
|
"Email address to look up. Mutually exclusive with user_id and query."
|
|
7098
7154
|
).optional(),
|
|
7099
|
-
query:
|
|
7155
|
+
query: z31.string().min(2).describe(
|
|
7100
7156
|
"Name to search for (matches against username, display name, real name). Mutually exclusive with user_id and email."
|
|
7101
7157
|
).optional(),
|
|
7102
|
-
limit:
|
|
7158
|
+
limit: z31.coerce.number().int().min(1).max(20).describe(
|
|
7103
7159
|
"Maximum number of results to return for name search. Defaults to 10."
|
|
7104
7160
|
).optional(),
|
|
7105
|
-
max_pages:
|
|
7161
|
+
max_pages: z31.coerce.number().int().min(1).max(5).describe(
|
|
7106
7162
|
"Maximum number of Slack API pages to scan for name search. Defaults to 3."
|
|
7107
7163
|
).optional(),
|
|
7108
7164
|
include_bots: booleanInput4(
|
|
@@ -7206,12 +7262,12 @@ function createSlackUserLookupTool() {
|
|
|
7206
7262
|
}
|
|
7207
7263
|
|
|
7208
7264
|
// src/chat/tools/system-time.ts
|
|
7209
|
-
import { z as
|
|
7265
|
+
import { z as z32 } from "zod";
|
|
7210
7266
|
function createSystemTimeTool() {
|
|
7211
7267
|
return zodTool({
|
|
7212
7268
|
description: "Return current system time in UTC and local ISO formats. Use when the user asks for current time/date context. Do not use as a substitute for historical or timezone-conversion research.",
|
|
7213
7269
|
annotations: { readOnlyHint: true, destructiveHint: false },
|
|
7214
|
-
inputSchema:
|
|
7270
|
+
inputSchema: z32.object({}),
|
|
7215
7271
|
outputSchema: juniorToolResultSchema,
|
|
7216
7272
|
execute: async () => {
|
|
7217
7273
|
const now = /* @__PURE__ */ new Date();
|
|
@@ -7268,7 +7324,7 @@ function createStateAdvisorSessionStore() {
|
|
|
7268
7324
|
}
|
|
7269
7325
|
|
|
7270
7326
|
// src/chat/tools/advisor/tool.ts
|
|
7271
|
-
import { z as
|
|
7327
|
+
import { z as z33 } from "zod";
|
|
7272
7328
|
var ADVISOR_TOOL_DESCRIPTION = "Second-opinion advisor for hard technical work. Call when you reach a consequential workflow moment: after enough exploration to frame a non-obvious plan; before a non-trivial code change or broad refactor; after repeated failures or when requirements or next steps feel ambiguous or risky; and when verifying a complex change before declaring it done, opening a PR, or reporting results. Ask a focused question and pass curated context: exact evidence, constraints, relevant code snippets, command output, diffs, current plan, and alternatives considered. The advisor has its own history, does not automatically receive the parent transcript, and may use read-only tools to verify. Follow up only with new evidence or changed constraints. Do not use for greetings, simple deterministic edits, routine formatting, or when fresh output makes the next action obvious.";
|
|
7273
7329
|
var ADVISOR_SYSTEM_PROMPT = [
|
|
7274
7330
|
"You are a senior technical advisor for the executor.",
|
|
@@ -7321,9 +7377,9 @@ function createAdvisorTool(context) {
|
|
|
7321
7377
|
const spanContext = context.logContext ?? {};
|
|
7322
7378
|
return zodTool({
|
|
7323
7379
|
description: ADVISOR_TOOL_DESCRIPTION,
|
|
7324
|
-
inputSchema:
|
|
7325
|
-
question:
|
|
7326
|
-
context:
|
|
7380
|
+
inputSchema: z33.object({
|
|
7381
|
+
question: z33.string().min(1).describe("Focused advisor question or decision point."),
|
|
7382
|
+
context: z33.string().min(1).describe(
|
|
7327
7383
|
"Curated evidence packet: relevant requirements, constraints, current plan, alternatives, code snippets, diffs, command output, and open questions."
|
|
7328
7384
|
)
|
|
7329
7385
|
}),
|
|
@@ -7392,15 +7448,11 @@ function createAdvisorTool(context) {
|
|
|
7392
7448
|
].join("\n");
|
|
7393
7449
|
const advisorInputMessage = {
|
|
7394
7450
|
role: "user",
|
|
7395
|
-
content: [
|
|
7396
|
-
|
|
7397
|
-
type: "text",
|
|
7398
|
-
text: requestText
|
|
7399
|
-
}
|
|
7400
|
-
]
|
|
7451
|
+
content: [{ type: "text", text: requestText }],
|
|
7452
|
+
timestamp: Date.now()
|
|
7401
7453
|
};
|
|
7402
7454
|
const advisorInputMessagesAttribute = serializeGenAiAttribute(
|
|
7403
|
-
conversationPrivacy !== "public" ? [toGenAiMessageMetadata(advisorInputMessage)] : [advisorInputMessage]
|
|
7455
|
+
conversationPrivacy !== "public" ? [toGenAiMessageMetadata(advisorInputMessage)] : [toCanonicalInputMessage(advisorInputMessage)]
|
|
7404
7456
|
);
|
|
7405
7457
|
return await withSpan(
|
|
7406
7458
|
`invoke_agent ${context.config.modelId}`,
|
|
@@ -7451,7 +7503,7 @@ function createAdvisorTool(context) {
|
|
|
7451
7503
|
const newAdvisorMessages = advisorAgent.state.messages.slice(beforeMessageCount);
|
|
7452
7504
|
const outputMessages = newAdvisorMessages.filter(isAssistantMessage);
|
|
7453
7505
|
const outputMessagesAttribute = serializeGenAiAttribute(
|
|
7454
|
-
conversationPrivacy !== "public" ? outputMessages.map(toGenAiMessageMetadata) : outputMessages
|
|
7506
|
+
conversationPrivacy !== "public" ? outputMessages.map(toGenAiMessageMetadata) : outputMessages.map(toCanonicalOutputMessage)
|
|
7455
7507
|
);
|
|
7456
7508
|
setSpanAttributes({
|
|
7457
7509
|
...outputMessagesAttribute ? { "gen_ai.output.messages": outputMessagesAttribute } : {},
|
|
@@ -7506,7 +7558,7 @@ function createAdvisorTool(context) {
|
|
|
7506
7558
|
}
|
|
7507
7559
|
|
|
7508
7560
|
// src/chat/tools/web/fetch-tool.ts
|
|
7509
|
-
import { z as
|
|
7561
|
+
import { z as z34 } from "zod";
|
|
7510
7562
|
|
|
7511
7563
|
// src/chat/tools/web/constants.ts
|
|
7512
7564
|
var USER_AGENT = "junior-bot/0.1";
|
|
@@ -7953,9 +8005,9 @@ function createWebFetchTool(hooks, options = {}) {
|
|
|
7953
8005
|
destructiveHint: false,
|
|
7954
8006
|
openWorldHint: true
|
|
7955
8007
|
},
|
|
7956
|
-
inputSchema:
|
|
7957
|
-
url:
|
|
7958
|
-
max_chars:
|
|
8008
|
+
inputSchema: z34.object({
|
|
8009
|
+
url: z34.string().min(1).describe("HTTP(S) URL to fetch."),
|
|
8010
|
+
max_chars: z34.coerce.number().int().min(500).max(MAX_FETCH_CHARS).describe("Optional maximum number of extracted characters to return.").optional()
|
|
7959
8011
|
}),
|
|
7960
8012
|
outputSchema: juniorToolResultSchema,
|
|
7961
8013
|
execute: async ({ url, max_chars }) => {
|
|
@@ -8022,7 +8074,7 @@ function createWebFetchTool(hooks, options = {}) {
|
|
|
8022
8074
|
}
|
|
8023
8075
|
|
|
8024
8076
|
// src/chat/tools/web/search.ts
|
|
8025
|
-
import { z as
|
|
8077
|
+
import { z as z35 } from "zod";
|
|
8026
8078
|
import { generateText } from "ai";
|
|
8027
8079
|
import { createGatewayProvider } from "@ai-sdk/gateway";
|
|
8028
8080
|
import { getModel } from "@earendil-works/pi-ai";
|
|
@@ -8073,9 +8125,9 @@ function createWebSearchTool(override) {
|
|
|
8073
8125
|
destructiveHint: false,
|
|
8074
8126
|
openWorldHint: true
|
|
8075
8127
|
},
|
|
8076
|
-
inputSchema:
|
|
8077
|
-
query:
|
|
8078
|
-
max_results:
|
|
8128
|
+
inputSchema: z35.object({
|
|
8129
|
+
query: z35.string().min(1).max(500).describe("Search query."),
|
|
8130
|
+
max_results: z35.coerce.number().int().min(1).max(MAX_RESULTS2).describe("Max results to return.").optional()
|
|
8079
8131
|
}),
|
|
8080
8132
|
outputSchema: juniorToolResultSchema,
|
|
8081
8133
|
execute: async ({ query, max_results }) => {
|
|
@@ -8145,14 +8197,14 @@ function createWebSearchTool(override) {
|
|
|
8145
8197
|
}
|
|
8146
8198
|
|
|
8147
8199
|
// src/chat/tools/sandbox/write-file.ts
|
|
8148
|
-
import { z as
|
|
8200
|
+
import { z as z36 } from "zod";
|
|
8149
8201
|
function createWriteFileTool() {
|
|
8150
8202
|
return zodTool({
|
|
8151
8203
|
description: "Write UTF-8 content to a file in the sandbox workspace. Use for intentional file creation or deliberate full-file replacement after validation; use editFile instead for targeted changes to existing files. Do not use for exploratory analysis-only turns.",
|
|
8152
8204
|
executionMode: "sequential",
|
|
8153
|
-
inputSchema:
|
|
8154
|
-
path:
|
|
8155
|
-
content:
|
|
8205
|
+
inputSchema: z36.object({
|
|
8206
|
+
path: z36.string().min(1).describe("Path to write in the sandbox workspace."),
|
|
8207
|
+
content: z36.string().describe("UTF-8 file content to write.")
|
|
8156
8208
|
}),
|
|
8157
8209
|
outputSchema: juniorToolResultSchema,
|
|
8158
8210
|
execute: async () => {
|
|
@@ -8546,7 +8598,7 @@ function upstreamPermissionDeniedText(value) {
|
|
|
8546
8598
|
...sso ? [`Provider SSO: ${sso}`] : [],
|
|
8547
8599
|
...command ? [`Command: ${command}`] : [],
|
|
8548
8600
|
"",
|
|
8549
|
-
"Junior had a credential lease for this grant and forwarded the request. Do not diagnose this as a missing user token or a local Junior runtime block; diagnose provider-side permissions, installation scope, SSO, or
|
|
8601
|
+
"Junior had a credential lease for this grant and forwarded the request. Do not diagnose this as a missing user token or a local Junior runtime block; diagnose provider-side permissions, installation scope, SSO, or actor-provider account access.",
|
|
8550
8602
|
...stderr ? ["", `stderr:
|
|
8551
8603
|
${stderr}`] : [],
|
|
8552
8604
|
...stdout ? ["", `stdout:
|
|
@@ -8891,6 +8943,13 @@ import { randomBytes } from "crypto";
|
|
|
8891
8943
|
import {
|
|
8892
8944
|
sourceSchema as sourceSchema2
|
|
8893
8945
|
} from "@sentry/junior-plugin-api";
|
|
8946
|
+
|
|
8947
|
+
// src/chat/oauth-authorization-message.ts
|
|
8948
|
+
function formatOAuthAuthorizationMessage(args) {
|
|
8949
|
+
return `${formatSlackLink(args.authorizationUrl, args.label)}. ${args.completionText}`;
|
|
8950
|
+
}
|
|
8951
|
+
|
|
8952
|
+
// src/chat/oauth-flow.ts
|
|
8894
8953
|
var OAUTH_STATE_TTL_MS = 10 * 60 * 1e3;
|
|
8895
8954
|
function optionalString(value) {
|
|
8896
8955
|
return typeof value === "string" ? value : void 0;
|
|
@@ -9046,7 +9105,7 @@ async function startOAuthFlow(provider, input) {
|
|
|
9046
9105
|
await getStateAdapter().set(
|
|
9047
9106
|
`oauth-state:${state}`,
|
|
9048
9107
|
{
|
|
9049
|
-
userId: input.
|
|
9108
|
+
userId: input.actorId,
|
|
9050
9109
|
provider,
|
|
9051
9110
|
...input.channelId ? { channelId: input.channelId } : {},
|
|
9052
9111
|
...input.destination ? { destination: input.destination } : {},
|
|
@@ -9083,71 +9142,76 @@ async function startOAuthFlow(provider, input) {
|
|
|
9083
9142
|
},
|
|
9084
9143
|
"Initiated OAuth authorization code flow"
|
|
9085
9144
|
);
|
|
9145
|
+
const authorizationUrl = `${providerConfig.authorizeEndpoint}?${authorizeParams.toString()}`;
|
|
9086
9146
|
return {
|
|
9087
9147
|
ok: true,
|
|
9088
9148
|
delivery: await deliverPrivateMessage({
|
|
9089
9149
|
channelId: input.channelId,
|
|
9090
9150
|
threadTs: input.threadTs,
|
|
9091
|
-
userId: input.
|
|
9092
|
-
text:
|
|
9151
|
+
userId: input.actorId,
|
|
9152
|
+
text: formatOAuthAuthorizationMessage({
|
|
9153
|
+
authorizationUrl,
|
|
9154
|
+
label: `Click here to link your ${formatProviderLabel(provider)} account`,
|
|
9155
|
+
completionText: "Once you've authorized, you'll see a confirmation in Slack."
|
|
9156
|
+
})
|
|
9093
9157
|
})
|
|
9094
9158
|
};
|
|
9095
9159
|
}
|
|
9096
9160
|
|
|
9097
9161
|
// src/chat/sandbox/egress/schemas.ts
|
|
9098
|
-
import { z as
|
|
9162
|
+
import { z as z37 } from "zod";
|
|
9099
9163
|
import {
|
|
9100
9164
|
pluginAuthorizationSchema,
|
|
9101
9165
|
pluginCredentialHeaderTransformSchema,
|
|
9102
9166
|
pluginGrantSchema,
|
|
9103
9167
|
pluginProviderAccountSchema
|
|
9104
9168
|
} from "@sentry/junior-plugin-api";
|
|
9105
|
-
var finiteNumberSchema =
|
|
9106
|
-
var httpStatusSchema =
|
|
9107
|
-
var providerNameSchema =
|
|
9108
|
-
var credentialSignalKindSchema =
|
|
9169
|
+
var finiteNumberSchema = z37.number().refine(Number.isFinite);
|
|
9170
|
+
var httpStatusSchema = z37.number().int().min(100).max(599);
|
|
9171
|
+
var providerNameSchema = z37.string().regex(/^[a-z][a-z0-9-]*$/);
|
|
9172
|
+
var credentialSignalKindSchema = z37.enum(["auth_required", "unavailable"]);
|
|
9109
9173
|
var sandboxEgressGrantSchema = pluginGrantSchema;
|
|
9110
|
-
var sandboxEgressCredentialContextSchema =
|
|
9174
|
+
var sandboxEgressCredentialContextSchema = z37.object({
|
|
9111
9175
|
credentials: credentialContextSchema,
|
|
9112
|
-
egressId:
|
|
9176
|
+
egressId: z37.string().min(1),
|
|
9113
9177
|
expiresAtMs: finiteNumberSchema,
|
|
9114
|
-
contextId:
|
|
9178
|
+
contextId: z37.string().min(1)
|
|
9115
9179
|
}).strict();
|
|
9116
|
-
var sandboxEgressCredentialLeaseSchema =
|
|
9180
|
+
var sandboxEgressCredentialLeaseSchema = z37.object({
|
|
9117
9181
|
account: pluginProviderAccountSchema.optional(),
|
|
9118
9182
|
authorization: pluginAuthorizationSchema.optional(),
|
|
9119
9183
|
grant: sandboxEgressGrantSchema,
|
|
9120
9184
|
provider: providerNameSchema,
|
|
9121
|
-
expiresAt:
|
|
9122
|
-
headerTransforms:
|
|
9185
|
+
expiresAt: z37.string().min(1),
|
|
9186
|
+
headerTransforms: z37.array(pluginCredentialHeaderTransformSchema).min(1)
|
|
9123
9187
|
}).strict();
|
|
9124
|
-
var sandboxEgressAuthRequiredSignalSchema =
|
|
9188
|
+
var sandboxEgressAuthRequiredSignalSchema = z37.object({
|
|
9125
9189
|
authorization: pluginAuthorizationSchema.optional(),
|
|
9126
9190
|
grant: sandboxEgressGrantSchema,
|
|
9127
9191
|
kind: credentialSignalKindSchema.default("auth_required"),
|
|
9128
9192
|
provider: providerNameSchema,
|
|
9129
|
-
message:
|
|
9193
|
+
message: z37.string().optional(),
|
|
9130
9194
|
createdAtMs: finiteNumberSchema
|
|
9131
9195
|
}).strict().superRefine((signal, ctx) => {
|
|
9132
9196
|
if (signal.authorization && signal.authorization.provider !== signal.provider) {
|
|
9133
9197
|
ctx.addIssue({
|
|
9134
|
-
code:
|
|
9198
|
+
code: z37.ZodIssueCode.custom,
|
|
9135
9199
|
message: "Auth signal authorization provider must match provider",
|
|
9136
9200
|
path: ["authorization", "provider"]
|
|
9137
9201
|
});
|
|
9138
9202
|
}
|
|
9139
9203
|
});
|
|
9140
|
-
var sandboxEgressPermissionDeniedSignalSchema =
|
|
9204
|
+
var sandboxEgressPermissionDeniedSignalSchema = z37.object({
|
|
9141
9205
|
account: pluginProviderAccountSchema.optional(),
|
|
9142
|
-
acceptedPermissions:
|
|
9206
|
+
acceptedPermissions: z37.string().optional(),
|
|
9143
9207
|
grant: sandboxEgressGrantSchema,
|
|
9144
|
-
message:
|
|
9208
|
+
message: z37.string().min(1),
|
|
9145
9209
|
provider: providerNameSchema,
|
|
9146
|
-
source:
|
|
9147
|
-
sso:
|
|
9210
|
+
source: z37.literal("upstream"),
|
|
9211
|
+
sso: z37.string().optional(),
|
|
9148
9212
|
status: httpStatusSchema,
|
|
9149
|
-
upstreamHost:
|
|
9150
|
-
upstreamPath:
|
|
9213
|
+
upstreamHost: z37.string().min(1),
|
|
9214
|
+
upstreamPath: z37.string().min(1),
|
|
9151
9215
|
createdAtMs: finiteNumberSchema
|
|
9152
9216
|
}).strict();
|
|
9153
9217
|
function parseSandboxEgressAuthRequiredSignal(value) {
|
|
@@ -9199,7 +9263,7 @@ function createPluginAuthOrchestration(input) {
|
|
|
9199
9263
|
if (pendingPause) {
|
|
9200
9264
|
throw pendingPause;
|
|
9201
9265
|
}
|
|
9202
|
-
if (!input.
|
|
9266
|
+
if (!input.actorId || !pluginCatalogRuntime.getOAuthConfig(provider)) {
|
|
9203
9267
|
throw new Error(`Cannot start plugin authorization for ${provider}`);
|
|
9204
9268
|
}
|
|
9205
9269
|
if (input.authorizationFlowMode === "disabled") {
|
|
@@ -9216,13 +9280,13 @@ function createPluginAuthOrchestration(input) {
|
|
|
9216
9280
|
pendingAuth: input.pendingAuth,
|
|
9217
9281
|
kind: "plugin",
|
|
9218
9282
|
provider,
|
|
9219
|
-
|
|
9283
|
+
actorId: input.actorId,
|
|
9220
9284
|
sessionId: input.sessionId,
|
|
9221
9285
|
...options?.scope ? { scope: options.scope } : {}
|
|
9222
9286
|
}) : false;
|
|
9223
9287
|
if (!reusingPendingLink) {
|
|
9224
9288
|
const oauthResult = await startOAuthFlow(provider, {
|
|
9225
|
-
|
|
9289
|
+
actorId: input.actorId,
|
|
9226
9290
|
channelId: input.channelId,
|
|
9227
9291
|
destination: input.destination,
|
|
9228
9292
|
source: input.source,
|
|
@@ -9242,14 +9306,14 @@ function createPluginAuthOrchestration(input) {
|
|
|
9242
9306
|
);
|
|
9243
9307
|
}
|
|
9244
9308
|
}
|
|
9245
|
-
if (options?.unlinkExistingProvider && input.
|
|
9246
|
-
await unlinkProvider(input.
|
|
9309
|
+
if (options?.unlinkExistingProvider && input.actorId && input.userTokenStore) {
|
|
9310
|
+
await unlinkProvider(input.actorId, provider, input.userTokenStore);
|
|
9247
9311
|
}
|
|
9248
9312
|
if (input.sessionId && recordPendingAuth) {
|
|
9249
9313
|
await recordPendingAuth({
|
|
9250
9314
|
kind: "plugin",
|
|
9251
9315
|
provider,
|
|
9252
|
-
|
|
9316
|
+
actorId: input.actorId,
|
|
9253
9317
|
...options?.scope ? { scope: options.scope } : {},
|
|
9254
9318
|
sessionId: input.sessionId,
|
|
9255
9319
|
linkSentAtMs: reusingPendingLink ? input.pendingAuth.linkSentAtMs : Date.now()
|
|
@@ -9260,7 +9324,7 @@ function createPluginAuthOrchestration(input) {
|
|
|
9260
9324
|
conversationId: input.conversationId,
|
|
9261
9325
|
kind: "plugin",
|
|
9262
9326
|
provider,
|
|
9263
|
-
|
|
9327
|
+
actorId: input.actorId,
|
|
9264
9328
|
authorizationId: authorizationId({
|
|
9265
9329
|
kind: "plugin",
|
|
9266
9330
|
provider,
|
|
@@ -9297,7 +9361,7 @@ function createPluginAuthOrchestration(input) {
|
|
|
9297
9361
|
signal.message ?? `${formatProviderLabel(provider)} credentials are required but no OAuth flow is available for this provider.`
|
|
9298
9362
|
);
|
|
9299
9363
|
}
|
|
9300
|
-
if (!input.
|
|
9364
|
+
if (!input.actorId || !input.userTokenStore) {
|
|
9301
9365
|
if (input.authorizationFlowMode === "disabled") {
|
|
9302
9366
|
throw new AuthorizationFlowDisabledError("plugin", provider);
|
|
9303
9367
|
}
|
|
@@ -9404,15 +9468,15 @@ function handleToolExecutionError(error, toolName, toolCallId, shouldTrace, trac
|
|
|
9404
9468
|
}
|
|
9405
9469
|
|
|
9406
9470
|
// src/chat/tools/execute-tool.ts
|
|
9407
|
-
import { z as
|
|
9471
|
+
import { z as z38 } from "zod";
|
|
9408
9472
|
var EXECUTE_TOOL_NAME = "executeTool";
|
|
9409
9473
|
function createExecuteToolTool() {
|
|
9410
9474
|
return zodTool({
|
|
9411
9475
|
description: "Execute any catalog tool by exact tool_name from searchTools. Put tool-specific parameters inside arguments.",
|
|
9412
9476
|
executionMode: "sequential",
|
|
9413
|
-
inputSchema:
|
|
9414
|
-
tool_name:
|
|
9415
|
-
arguments:
|
|
9477
|
+
inputSchema: z38.object({
|
|
9478
|
+
tool_name: z38.string().min(1).describe("Exact catalog tool_name returned by searchTools."),
|
|
9479
|
+
arguments: z38.record(z38.string(), z38.unknown()).describe(
|
|
9416
9480
|
'Arguments matching the selected catalog tool schema, for example { "query": "..." }.'
|
|
9417
9481
|
).optional()
|
|
9418
9482
|
}).strict(),
|
|
@@ -9452,13 +9516,54 @@ function planToolExposure(tools) {
|
|
|
9452
9516
|
}
|
|
9453
9517
|
|
|
9454
9518
|
// src/chat/tools/search-tools.ts
|
|
9455
|
-
import { z as
|
|
9519
|
+
import { z as z39 } from "zod";
|
|
9456
9520
|
var SEARCH_TOOLS_NAME = "searchTools";
|
|
9457
9521
|
var DEFAULT_MAX_RESULTS2 = 5;
|
|
9458
9522
|
var MAX_RESULTS3 = 20;
|
|
9523
|
+
var MODEL_VISIBLE_DESCRIPTION_CAP = 180;
|
|
9524
|
+
var searchToolsSourceSchema = z39.object({
|
|
9525
|
+
id: z39.string(),
|
|
9526
|
+
description: z39.string()
|
|
9527
|
+
}).strict();
|
|
9528
|
+
var toolCallExampleSchema = z39.object({
|
|
9529
|
+
tool_name: z39.string(),
|
|
9530
|
+
arguments: z39.record(z39.string(), z39.string())
|
|
9531
|
+
}).strict();
|
|
9532
|
+
var searchToolsToolSchema = z39.object({
|
|
9533
|
+
tool_name: z39.string(),
|
|
9534
|
+
description: z39.string(),
|
|
9535
|
+
exposure: z39.enum(["direct", "deferred", "modelOnly", "hidden"]),
|
|
9536
|
+
source: z39.string().optional(),
|
|
9537
|
+
signature: z39.string(),
|
|
9538
|
+
call: toolCallExampleSchema,
|
|
9539
|
+
input_schema: z39.unknown(),
|
|
9540
|
+
input_schema_summary: z39.string(),
|
|
9541
|
+
call_notes: z39.array(z39.string()),
|
|
9542
|
+
annotations: z39.record(z39.string(), z39.unknown())
|
|
9543
|
+
}).strict();
|
|
9544
|
+
var searchToolsOutputSchema = juniorToolResultSchema.extend({
|
|
9545
|
+
query: z39.string().nullable(),
|
|
9546
|
+
source: z39.string().nullable(),
|
|
9547
|
+
sources: z39.array(searchToolsSourceSchema),
|
|
9548
|
+
total_catalog_tools: z39.number().int().nonnegative(),
|
|
9549
|
+
total_eligible_tools: z39.number().int().nonnegative(),
|
|
9550
|
+
total_matches: z39.number().int().nonnegative(),
|
|
9551
|
+
returned_tools: z39.number().int().nonnegative(),
|
|
9552
|
+
execution_tool: z39.literal("executeTool"),
|
|
9553
|
+
execution_example: toolCallExampleSchema,
|
|
9554
|
+
tools: z39.array(searchToolsToolSchema)
|
|
9555
|
+
}).strict();
|
|
9459
9556
|
function normalize2(value) {
|
|
9460
9557
|
return value.toLowerCase().replace(/[^a-z0-9_]+/g, " ").trim();
|
|
9461
9558
|
}
|
|
9559
|
+
function summarizeModelVisibleDescription(description) {
|
|
9560
|
+
const paragraph = description.split(/\n\s*\n/).map((part) => part.trim()).find(Boolean) ?? "";
|
|
9561
|
+
const normalized = paragraph.replace(/\s+/g, " ").trim();
|
|
9562
|
+
if (normalized.length <= MODEL_VISIBLE_DESCRIPTION_CAP) {
|
|
9563
|
+
return normalized;
|
|
9564
|
+
}
|
|
9565
|
+
return `${normalized.slice(0, MODEL_VISIBLE_DESCRIPTION_CAP - 3).trimEnd()}...`;
|
|
9566
|
+
}
|
|
9462
9567
|
function schemaText(schema) {
|
|
9463
9568
|
try {
|
|
9464
9569
|
return JSON.stringify(schema);
|
|
@@ -9473,6 +9578,8 @@ function searchableToolText2(name, definition) {
|
|
|
9473
9578
|
definition.identity?.id,
|
|
9474
9579
|
definition.identity?.name,
|
|
9475
9580
|
definition.identity?.plugin,
|
|
9581
|
+
definition.source?.id,
|
|
9582
|
+
definition.source?.description,
|
|
9476
9583
|
definition.description,
|
|
9477
9584
|
definition.promptSnippet,
|
|
9478
9585
|
...definition.promptGuidelines ?? [],
|
|
@@ -9481,15 +9588,16 @@ function searchableToolText2(name, definition) {
|
|
|
9481
9588
|
].filter(Boolean).join(" ")
|
|
9482
9589
|
);
|
|
9483
9590
|
}
|
|
9484
|
-
function searchCatalogTools(tools, query) {
|
|
9591
|
+
function searchCatalogTools(tools, query, source) {
|
|
9485
9592
|
const entries = Object.entries(tools).sort(
|
|
9486
9593
|
([left], [right]) => left.localeCompare(right)
|
|
9487
9594
|
);
|
|
9595
|
+
const sourceEntries = source ? entries.filter(([, definition]) => definition.source?.id === source) : entries;
|
|
9488
9596
|
if (!normalize2(query)) {
|
|
9489
|
-
return
|
|
9597
|
+
return sourceEntries.map(([name]) => name);
|
|
9490
9598
|
}
|
|
9491
9599
|
const terms = normalize2(query).split(/\s+/).filter(Boolean);
|
|
9492
|
-
return
|
|
9600
|
+
return sourceEntries.filter(([name, definition]) => {
|
|
9493
9601
|
const text = searchableToolText2(name, definition);
|
|
9494
9602
|
return terms.every((term) => text.includes(term));
|
|
9495
9603
|
}).map(([name]) => name);
|
|
@@ -9500,17 +9608,128 @@ function callNotes(definition) {
|
|
|
9500
9608
|
...definition.promptGuidelines?.map((guideline) => guideline.trim()).filter(Boolean) ?? []
|
|
9501
9609
|
];
|
|
9502
9610
|
}
|
|
9503
|
-
function
|
|
9611
|
+
function getSchemaProperties3(schema) {
|
|
9612
|
+
if (!schema || typeof schema !== "object" || !("properties" in schema)) {
|
|
9613
|
+
return {};
|
|
9614
|
+
}
|
|
9615
|
+
const properties = schema.properties;
|
|
9616
|
+
return properties && typeof properties === "object" && !Array.isArray(properties) ? properties : {};
|
|
9617
|
+
}
|
|
9618
|
+
function getRequiredFields3(schema) {
|
|
9619
|
+
if (!schema || typeof schema !== "object" || !("required" in schema)) {
|
|
9620
|
+
return /* @__PURE__ */ new Set();
|
|
9621
|
+
}
|
|
9622
|
+
const required = schema.required;
|
|
9623
|
+
return Array.isArray(required) ? new Set(
|
|
9624
|
+
required.filter((value) => typeof value === "string")
|
|
9625
|
+
) : /* @__PURE__ */ new Set();
|
|
9626
|
+
}
|
|
9627
|
+
function formatSchemaType2(schema) {
|
|
9628
|
+
if (!schema || typeof schema !== "object") {
|
|
9629
|
+
return "unknown";
|
|
9630
|
+
}
|
|
9631
|
+
const typed = schema;
|
|
9632
|
+
const type = typed.type;
|
|
9633
|
+
if (typeof type === "string") {
|
|
9634
|
+
if (type === "array") {
|
|
9635
|
+
return `${formatSchemaType2(typed.items)}[]`;
|
|
9636
|
+
}
|
|
9637
|
+
return type;
|
|
9638
|
+
}
|
|
9639
|
+
if (Array.isArray(type)) {
|
|
9640
|
+
return type.filter((value) => typeof value === "string").join(" | ");
|
|
9641
|
+
}
|
|
9642
|
+
if (Array.isArray(typed.enum) && typed.enum.length > 0) {
|
|
9643
|
+
return typed.enum.map((value) => JSON.stringify(value)).join(" | ");
|
|
9644
|
+
}
|
|
9645
|
+
return "unknown";
|
|
9646
|
+
}
|
|
9647
|
+
function formatArgumentPlaceholder2(name, schema) {
|
|
9648
|
+
const type = formatSchemaType2(schema);
|
|
9649
|
+
if (type === "string") {
|
|
9650
|
+
return `<${name}>`;
|
|
9651
|
+
}
|
|
9652
|
+
if (type === "number" || type === "integer") {
|
|
9653
|
+
return "<number>";
|
|
9654
|
+
}
|
|
9655
|
+
if (type === "boolean") {
|
|
9656
|
+
return "<boolean>";
|
|
9657
|
+
}
|
|
9658
|
+
if (type.endsWith("[]")) {
|
|
9659
|
+
return "<array>";
|
|
9660
|
+
}
|
|
9661
|
+
if (type === "object") {
|
|
9662
|
+
return "<object>";
|
|
9663
|
+
}
|
|
9664
|
+
return `<${type}>`;
|
|
9665
|
+
}
|
|
9666
|
+
function formatToolSignature(name, schema) {
|
|
9667
|
+
const properties = getSchemaProperties3(schema);
|
|
9668
|
+
const required = getRequiredFields3(schema);
|
|
9669
|
+
const fields = Object.entries(properties).map(([field, propertySchema]) => {
|
|
9670
|
+
const marker = required.has(field) ? "" : "?";
|
|
9671
|
+
return `${field}${marker}: ${formatSchemaType2(propertySchema)}`;
|
|
9672
|
+
});
|
|
9673
|
+
return fields.length > 0 ? `${name}({ ${fields.join(", ")} })` : `${name}()`;
|
|
9674
|
+
}
|
|
9675
|
+
function formatToolCallExample(name, schema) {
|
|
9504
9676
|
return {
|
|
9505
9677
|
tool_name: name,
|
|
9506
|
-
|
|
9678
|
+
arguments: Object.fromEntries(
|
|
9679
|
+
Object.entries(getSchemaProperties3(schema)).map(
|
|
9680
|
+
([field, propertySchema]) => [
|
|
9681
|
+
field,
|
|
9682
|
+
formatArgumentPlaceholder2(field, propertySchema)
|
|
9683
|
+
]
|
|
9684
|
+
)
|
|
9685
|
+
)
|
|
9686
|
+
};
|
|
9687
|
+
}
|
|
9688
|
+
function sourceSummaries(tools) {
|
|
9689
|
+
const sources = /* @__PURE__ */ new Map();
|
|
9690
|
+
for (const definition of Object.values(tools)) {
|
|
9691
|
+
if (!definition.source) {
|
|
9692
|
+
continue;
|
|
9693
|
+
}
|
|
9694
|
+
sources.set(definition.source.id, {
|
|
9695
|
+
id: definition.source.id,
|
|
9696
|
+
description: summarizeModelVisibleDescription(
|
|
9697
|
+
definition.source.description
|
|
9698
|
+
)
|
|
9699
|
+
});
|
|
9700
|
+
}
|
|
9701
|
+
return [...sources.values()].sort(
|
|
9702
|
+
(left, right) => left.id.localeCompare(right.id)
|
|
9703
|
+
);
|
|
9704
|
+
}
|
|
9705
|
+
function selectedSourceSummaries(tools, matches, requestedSource, knownSources) {
|
|
9706
|
+
if (requestedSource) {
|
|
9707
|
+
return knownSources.filter((source) => source.id === requestedSource);
|
|
9708
|
+
}
|
|
9709
|
+
const matchedSourceIds = new Set(
|
|
9710
|
+
matches.map((name) => tools[name]?.source?.id).filter((source) => Boolean(source))
|
|
9711
|
+
);
|
|
9712
|
+
return knownSources.filter((source) => matchedSourceIds.has(source.id));
|
|
9713
|
+
}
|
|
9714
|
+
function renderSearchToolsDescription(knownSources) {
|
|
9715
|
+
const intro = "Search the executable tool catalog. Deferred tools are grouped by source; use searchTools with source to inspect one source, then executeTool with the exact returned tool_name.";
|
|
9716
|
+
if (knownSources.length === 0) {
|
|
9717
|
+
return intro;
|
|
9718
|
+
}
|
|
9719
|
+
return [
|
|
9720
|
+
intro,
|
|
9721
|
+
"Available sources:",
|
|
9722
|
+
...knownSources.map((source) => `- ${source.id}: ${source.description}`)
|
|
9723
|
+
].join("\n");
|
|
9724
|
+
}
|
|
9725
|
+
function toolMetadata(name, definition, includeSource) {
|
|
9726
|
+
return {
|
|
9727
|
+
tool_name: name,
|
|
9728
|
+
description: summarizeModelVisibleDescription(definition.description),
|
|
9507
9729
|
exposure: effectiveToolExposure(definition),
|
|
9508
|
-
source: definition.
|
|
9509
|
-
|
|
9510
|
-
|
|
9511
|
-
name: definition.identity.name,
|
|
9512
|
-
plugin: definition.identity.plugin
|
|
9513
|
-
} : { type: "core" },
|
|
9730
|
+
...includeSource && definition.source ? { source: definition.source.id } : {},
|
|
9731
|
+
signature: formatToolSignature(name, definition.inputSchema),
|
|
9732
|
+
call: formatToolCallExample(name, definition.inputSchema),
|
|
9514
9733
|
input_schema: definition.inputSchema,
|
|
9515
9734
|
input_schema_summary: summarizeInputSchema(
|
|
9516
9735
|
definition.inputSchema
|
|
@@ -9520,27 +9739,55 @@ function toolMetadata(name, definition) {
|
|
|
9520
9739
|
};
|
|
9521
9740
|
}
|
|
9522
9741
|
function createSearchToolsTool(catalogTools) {
|
|
9742
|
+
const knownSources = sourceSummaries(catalogTools);
|
|
9523
9743
|
return zodTool({
|
|
9524
|
-
description:
|
|
9744
|
+
description: renderSearchToolsDescription(knownSources),
|
|
9525
9745
|
annotations: { readOnlyHint: true, destructiveHint: false },
|
|
9526
|
-
inputSchema:
|
|
9527
|
-
query:
|
|
9746
|
+
inputSchema: z39.object({
|
|
9747
|
+
query: z39.string().nullable().describe(
|
|
9528
9748
|
"Optional search terms describing the tool, owner, action, or arguments needed. Empty string lists catalog tools."
|
|
9529
9749
|
).optional(),
|
|
9530
|
-
|
|
9750
|
+
source: z39.string().nullable().describe(
|
|
9751
|
+
"Optional source id to search within, such as a plugin source returned in sources."
|
|
9752
|
+
).optional(),
|
|
9753
|
+
max_results: z39.number().int().min(1).max(MAX_RESULTS3).nullable().describe("Maximum matching catalog tool descriptors to return.").optional()
|
|
9531
9754
|
}).strict(),
|
|
9532
|
-
outputSchema:
|
|
9533
|
-
execute: async ({ query, max_results }) => {
|
|
9755
|
+
outputSchema: searchToolsOutputSchema,
|
|
9756
|
+
execute: async ({ query, source, max_results }) => {
|
|
9534
9757
|
const maxResults = max_results ?? DEFAULT_MAX_RESULTS2;
|
|
9535
|
-
const
|
|
9536
|
-
|
|
9537
|
-
|
|
9758
|
+
const requestedSource = source ?? null;
|
|
9759
|
+
const sourceExists = requestedSource === null || knownSources.some((candidate) => candidate.id === requestedSource);
|
|
9760
|
+
const allMatches = sourceExists ? searchCatalogTools(catalogTools, query ?? "", requestedSource) : [];
|
|
9761
|
+
const matches = allMatches.slice(0, maxResults);
|
|
9762
|
+
const sources = !sourceExists ? knownSources : (query ?? "").trim() ? selectedSourceSummaries(
|
|
9763
|
+
catalogTools,
|
|
9764
|
+
matches,
|
|
9765
|
+
requestedSource,
|
|
9766
|
+
knownSources
|
|
9767
|
+
) : requestedSource ? knownSources.filter(
|
|
9768
|
+
(candidate) => candidate.id === requestedSource
|
|
9769
|
+
) : knownSources;
|
|
9770
|
+
const totalEligibleTools = sourceExists ? searchCatalogTools(catalogTools, "", requestedSource).length : 0;
|
|
9771
|
+
const includePerToolSource = requestedSource === null;
|
|
9772
|
+
const renderedTools = matches.map(
|
|
9773
|
+
(name) => toolMetadata(name, catalogTools[name], includePerToolSource)
|
|
9538
9774
|
);
|
|
9539
9775
|
const data = {
|
|
9540
9776
|
query: query ?? null,
|
|
9777
|
+
source: requestedSource,
|
|
9778
|
+
sources,
|
|
9541
9779
|
total_catalog_tools: Object.keys(catalogTools).length,
|
|
9542
|
-
|
|
9543
|
-
|
|
9780
|
+
total_eligible_tools: totalEligibleTools,
|
|
9781
|
+
total_matches: allMatches.length,
|
|
9782
|
+
returned_tools: renderedTools.length,
|
|
9783
|
+
execution_tool: "executeTool",
|
|
9784
|
+
execution_example: {
|
|
9785
|
+
tool_name: "<returned tool_name>",
|
|
9786
|
+
arguments: {
|
|
9787
|
+
"<argument>": "<value from input_schema>"
|
|
9788
|
+
}
|
|
9789
|
+
},
|
|
9790
|
+
tools: renderedTools
|
|
9544
9791
|
};
|
|
9545
9792
|
return {
|
|
9546
9793
|
ok: true,
|
|
@@ -9752,7 +9999,7 @@ var SANDBOX_EGRESS_LEASE_PREFIX = "sandbox-egress-lease";
|
|
|
9752
9999
|
var DEFAULT_SESSION_TTL_MS = 30 * 60 * 1e3;
|
|
9753
10000
|
function leaseKey(provider, grantName, context) {
|
|
9754
10001
|
const actor = context.credentials.actor;
|
|
9755
|
-
const actorKey =
|
|
10002
|
+
const actorKey = "type" in actor ? `user:${actor.userId}` : `system:${actor.name}`;
|
|
9756
10003
|
return `${SANDBOX_EGRESS_LEASE_PREFIX}:${provider}:${grantName}:${actorKey}:${context.egressId}:${context.contextId}`;
|
|
9757
10004
|
}
|
|
9758
10005
|
function authSignalKey(egressId, access) {
|
|
@@ -11594,6 +11841,13 @@ function createClientMetadata(callbackUrl) {
|
|
|
11594
11841
|
token_endpoint_auth_method: "none"
|
|
11595
11842
|
};
|
|
11596
11843
|
}
|
|
11844
|
+
function clientAllowsRedirectUri(clientInformation, callbackUrl) {
|
|
11845
|
+
const redirectUris = clientInformation.redirect_uris;
|
|
11846
|
+
if (!Array.isArray(redirectUris)) {
|
|
11847
|
+
return true;
|
|
11848
|
+
}
|
|
11849
|
+
return redirectUris.includes(callbackUrl);
|
|
11850
|
+
}
|
|
11597
11851
|
var StateBackedMcpOAuthClientProvider = class {
|
|
11598
11852
|
constructor(authSessionId, callbackUrl, sessionContext) {
|
|
11599
11853
|
this.authSessionId = authSessionId;
|
|
@@ -11617,7 +11871,14 @@ var StateBackedMcpOAuthClientProvider = class {
|
|
|
11617
11871
|
session.userId,
|
|
11618
11872
|
session.provider
|
|
11619
11873
|
);
|
|
11620
|
-
|
|
11874
|
+
const clientInformation = credentials?.clientInformation;
|
|
11875
|
+
if (!clientInformation) {
|
|
11876
|
+
return void 0;
|
|
11877
|
+
}
|
|
11878
|
+
if (clientAllowsRedirectUri(clientInformation, this.callbackUrl)) {
|
|
11879
|
+
return clientInformation;
|
|
11880
|
+
}
|
|
11881
|
+
return void 0;
|
|
11621
11882
|
}
|
|
11622
11883
|
async saveClientInformation(clientInformation) {
|
|
11623
11884
|
const session = await this.getCredentialContext();
|
|
@@ -11857,7 +12118,7 @@ function createMcpAuthOrchestration(input) {
|
|
|
11857
12118
|
let pendingPause;
|
|
11858
12119
|
const authSessionIdsByProvider = /* @__PURE__ */ new Map();
|
|
11859
12120
|
const authProviderFactory = async (plugin) => {
|
|
11860
|
-
if (!input.conversationId || !input.sessionId || !input.
|
|
12121
|
+
if (!input.conversationId || !input.sessionId || !input.actorId) {
|
|
11861
12122
|
return void 0;
|
|
11862
12123
|
}
|
|
11863
12124
|
if (!input.recordPendingAuth && input.authorizationFlowMode !== "disabled") {
|
|
@@ -11871,7 +12132,7 @@ function createMcpAuthOrchestration(input) {
|
|
|
11871
12132
|
destination: input.destination,
|
|
11872
12133
|
source: input.source,
|
|
11873
12134
|
sessionId: input.sessionId,
|
|
11874
|
-
userId: input.
|
|
12135
|
+
userId: input.actorId,
|
|
11875
12136
|
userMessage: input.userMessage,
|
|
11876
12137
|
...input.channelId ? { channelId: input.channelId } : {},
|
|
11877
12138
|
...input.threadTs ? { threadTs: input.threadTs } : {},
|
|
@@ -11889,8 +12150,8 @@ function createMcpAuthOrchestration(input) {
|
|
|
11889
12150
|
const authSessionId = authSessionIdsByProvider.get(provider);
|
|
11890
12151
|
const conversationId = input.conversationId;
|
|
11891
12152
|
const sessionId = input.sessionId;
|
|
11892
|
-
const
|
|
11893
|
-
if (!authSessionId || !conversationId || !sessionId || !
|
|
12153
|
+
const actorId = input.actorId;
|
|
12154
|
+
if (!authSessionId || !conversationId || !sessionId || !actorId) {
|
|
11894
12155
|
throw new Error(
|
|
11895
12156
|
`Missing MCP auth session context for plugin "${provider}"`
|
|
11896
12157
|
);
|
|
@@ -11919,7 +12180,7 @@ function createMcpAuthOrchestration(input) {
|
|
|
11919
12180
|
pendingAuth: input.pendingAuth,
|
|
11920
12181
|
kind: "mcp",
|
|
11921
12182
|
provider,
|
|
11922
|
-
|
|
12183
|
+
actorId,
|
|
11923
12184
|
sessionId
|
|
11924
12185
|
});
|
|
11925
12186
|
const providerLabel = formatProviderLabel(provider);
|
|
@@ -11928,7 +12189,11 @@ function createMcpAuthOrchestration(input) {
|
|
|
11928
12189
|
channelId: authSession.channelId,
|
|
11929
12190
|
threadTs: authSession.threadTs,
|
|
11930
12191
|
userId: authSession.userId,
|
|
11931
|
-
text:
|
|
12192
|
+
text: formatOAuthAuthorizationMessage({
|
|
12193
|
+
authorizationUrl: authSession.authorizationUrl,
|
|
12194
|
+
label: `Click here to link your ${providerLabel} MCP access`,
|
|
12195
|
+
completionText: "Once you've authorized, this thread will continue automatically."
|
|
12196
|
+
})
|
|
11932
12197
|
});
|
|
11933
12198
|
if (!delivery) {
|
|
11934
12199
|
throw new Error(
|
|
@@ -11941,7 +12206,7 @@ function createMcpAuthOrchestration(input) {
|
|
|
11941
12206
|
await recordPendingAuth({
|
|
11942
12207
|
kind: "mcp",
|
|
11943
12208
|
provider,
|
|
11944
|
-
|
|
12209
|
+
actorId,
|
|
11945
12210
|
sessionId,
|
|
11946
12211
|
linkSentAtMs: reusingPendingLink ? input.pendingAuth.linkSentAtMs : Date.now()
|
|
11947
12212
|
});
|
|
@@ -11949,7 +12214,7 @@ function createMcpAuthOrchestration(input) {
|
|
|
11949
12214
|
conversationId,
|
|
11950
12215
|
kind: "mcp",
|
|
11951
12216
|
provider,
|
|
11952
|
-
|
|
12217
|
+
actorId,
|
|
11953
12218
|
authorizationId: authorizationId2({
|
|
11954
12219
|
kind: "mcp",
|
|
11955
12220
|
provider,
|
|
@@ -12111,7 +12376,7 @@ async function issuePluginCredential(input) {
|
|
|
12111
12376
|
if (!plugin || !hook) {
|
|
12112
12377
|
throw new Error(`Plugin "${input.provider}" has no issueCredential hook`);
|
|
12113
12378
|
}
|
|
12114
|
-
const currentUserId = input.actor
|
|
12379
|
+
const currentUserId = "type" in input.actor ? input.actor.userId : void 0;
|
|
12115
12380
|
const credentialSubjectUserId = input.credentialSubject?.userId;
|
|
12116
12381
|
const result = await hook({
|
|
12117
12382
|
...basePluginContext(plugin),
|
|
@@ -13090,10 +13355,10 @@ async function writeSandboxGeneratedArtifacts(sandbox, files) {
|
|
|
13090
13355
|
// src/chat/agent/tools.ts
|
|
13091
13356
|
async function wireAgentTools(args) {
|
|
13092
13357
|
const runSource = args.routing.source;
|
|
13093
|
-
const
|
|
13358
|
+
const authActorId = args.routing.credentialContext && "type" in args.routing.credentialContext.actor ? args.routing.credentialContext.actor.userId : void 0;
|
|
13094
13359
|
const userTokenStore = createUserTokenStore();
|
|
13095
13360
|
const pluginHooks = createPluginHookRunner({
|
|
13096
|
-
|
|
13361
|
+
actor: args.currentActor
|
|
13097
13362
|
});
|
|
13098
13363
|
const sandboxExecutor = createSandboxExecutor({
|
|
13099
13364
|
sandboxId: args.state.sandbox?.sandboxId,
|
|
@@ -13113,7 +13378,7 @@ async function wireAgentTools(args) {
|
|
|
13113
13378
|
const result = await maybeExecuteJrRpcCustomCommand(command, {
|
|
13114
13379
|
activeSkill: args.skillSandbox.getActiveSkill(),
|
|
13115
13380
|
channelConfiguration: args.policy.channelConfiguration,
|
|
13116
|
-
|
|
13381
|
+
actorId: isUserActor(args.currentActor) ? args.currentActor.userId : void 0,
|
|
13117
13382
|
onConfigurationValueChanged: (key, value) => {
|
|
13118
13383
|
if (value === void 0) {
|
|
13119
13384
|
delete args.configurationValues[key];
|
|
@@ -13137,7 +13402,7 @@ async function wireAgentTools(args) {
|
|
|
13137
13402
|
abortAgent: args.abortAgent,
|
|
13138
13403
|
conversationId: args.sessionConversationId,
|
|
13139
13404
|
sessionId: args.sessionId,
|
|
13140
|
-
|
|
13405
|
+
actorId: authActorId,
|
|
13141
13406
|
channelId: slackChannelId,
|
|
13142
13407
|
destination: args.routing.destination,
|
|
13143
13408
|
source: runSource,
|
|
@@ -13158,7 +13423,7 @@ async function wireAgentTools(args) {
|
|
|
13158
13423
|
abortAgent: args.abortAgent,
|
|
13159
13424
|
conversationId: args.sessionConversationId,
|
|
13160
13425
|
sessionId: args.sessionId,
|
|
13161
|
-
|
|
13426
|
+
actorId: authActorId,
|
|
13162
13427
|
channelId: slackChannelId,
|
|
13163
13428
|
destination: args.routing.destination,
|
|
13164
13429
|
source: runSource,
|
|
@@ -13228,7 +13493,7 @@ async function wireAgentTools(args) {
|
|
|
13228
13493
|
toolRuntimeContext = {
|
|
13229
13494
|
...commonToolRuntimeContext,
|
|
13230
13495
|
destination: toolDestination,
|
|
13231
|
-
|
|
13496
|
+
actor: args.currentActor?.platform === "slack" ? args.currentActor : void 0,
|
|
13232
13497
|
source: runSource
|
|
13233
13498
|
};
|
|
13234
13499
|
} else {
|
|
@@ -13238,7 +13503,7 @@ async function wireAgentTools(args) {
|
|
|
13238
13503
|
toolRuntimeContext = {
|
|
13239
13504
|
...commonToolRuntimeContext,
|
|
13240
13505
|
destination: toolDestination,
|
|
13241
|
-
|
|
13506
|
+
actor: args.currentActor?.platform === "local" ? args.currentActor : void 0,
|
|
13242
13507
|
source: runSource
|
|
13243
13508
|
};
|
|
13244
13509
|
}
|
|
@@ -13413,7 +13678,7 @@ function createResumeState(args) {
|
|
|
13413
13678
|
sessionId: args.sessionId,
|
|
13414
13679
|
loadedSkillNames: args.getLoadedSkillNames(),
|
|
13415
13680
|
logContext: args.logContext,
|
|
13416
|
-
|
|
13681
|
+
actor: args.actor,
|
|
13417
13682
|
...args.surface ? { surface: args.surface } : {}
|
|
13418
13683
|
});
|
|
13419
13684
|
return {
|
|
@@ -13451,7 +13716,7 @@ function createResumeState(args) {
|
|
|
13451
13716
|
await args.durability.onInputCommitted?.();
|
|
13452
13717
|
inputCommitted = true;
|
|
13453
13718
|
},
|
|
13454
|
-
async persistSafeBoundary(messages) {
|
|
13719
|
+
async persistSafeBoundary(messages, trailingMessageProvenance) {
|
|
13455
13720
|
if (!canPersistSession) {
|
|
13456
13721
|
return false;
|
|
13457
13722
|
}
|
|
@@ -13459,6 +13724,7 @@ function createResumeState(args) {
|
|
|
13459
13724
|
...sessionRecordBase(),
|
|
13460
13725
|
sliceId: currentSliceId,
|
|
13461
13726
|
messages,
|
|
13727
|
+
...trailingMessageProvenance ? { trailingMessageProvenance } : {},
|
|
13462
13728
|
...turnStartMessageIndex !== void 0 ? { turnStartMessageIndex } : {}
|
|
13463
13729
|
});
|
|
13464
13730
|
if (!persisted) {
|
|
@@ -13467,8 +13733,11 @@ function createResumeState(args) {
|
|
|
13467
13733
|
latestSafeBoundaryMessages = [...messages];
|
|
13468
13734
|
return true;
|
|
13469
13735
|
},
|
|
13470
|
-
async requireDurableInputCheckpoint(messages) {
|
|
13471
|
-
const persisted = await this.persistSafeBoundary(
|
|
13736
|
+
async requireDurableInputCheckpoint(messages, trailingMessageProvenance) {
|
|
13737
|
+
const persisted = await this.persistSafeBoundary(
|
|
13738
|
+
messages,
|
|
13739
|
+
trailingMessageProvenance
|
|
13740
|
+
);
|
|
13472
13741
|
if (!persisted && args.durability.onInputCommitted) {
|
|
13473
13742
|
throw new TurnInputCommitLostError(
|
|
13474
13743
|
`Durable turn input could not be checkpointed for conversation=${args.sessionConversationId ?? "unknown"} session=${args.sessionId ?? "unknown"}`
|
|
@@ -13627,7 +13896,7 @@ async function executeAgentRunInPrivacyContext(request, conversationPrivacy) {
|
|
|
13627
13896
|
if (!routing.destination) {
|
|
13628
13897
|
throw new TypeError("Assistant reply generation requires a destination");
|
|
13629
13898
|
}
|
|
13630
|
-
|
|
13899
|
+
assertActorDestinationMatch(routing);
|
|
13631
13900
|
assertCorrelationDestinationMatch(routing);
|
|
13632
13901
|
const replyStartedAtMs = Date.now();
|
|
13633
13902
|
const configuredTurnDeadlineAtMs = replyStartedAtMs + botConfig.turnTimeoutMs;
|
|
@@ -13642,18 +13911,18 @@ async function executeAgentRunInPrivacyContext(request, conversationPrivacy) {
|
|
|
13642
13911
|
let canRecordMcpProviders = false;
|
|
13643
13912
|
let turnUsage;
|
|
13644
13913
|
let thinkingSelection;
|
|
13645
|
-
const
|
|
13914
|
+
const actor = actorFromRouting(routing);
|
|
13646
13915
|
const surface = surfaceFromRouting(routing);
|
|
13647
13916
|
const runSource = routing.source;
|
|
13648
13917
|
const userInput = input.messageText;
|
|
13649
13918
|
const credentialActor = routing.credentialContext?.actor;
|
|
13650
13919
|
const credentialActorLogContext = credentialActor ? {
|
|
13651
|
-
actorType: credentialActor.type,
|
|
13652
|
-
actorId:
|
|
13920
|
+
actorType: "type" in credentialActor ? credentialActor.type : "system",
|
|
13921
|
+
actorId: "type" in credentialActor ? credentialActor.userId : credentialActor.name
|
|
13653
13922
|
} : {};
|
|
13654
13923
|
const sessionRecordLogContext = {
|
|
13655
13924
|
threadId: routing.correlation?.threadId,
|
|
13656
|
-
|
|
13925
|
+
actorId: routing.correlation?.actorId,
|
|
13657
13926
|
channelId: routing.correlation?.channelId,
|
|
13658
13927
|
runId: routing.correlation?.runId,
|
|
13659
13928
|
...credentialActorLogContext,
|
|
@@ -13689,7 +13958,7 @@ async function executeAgentRunInPrivacyContext(request, conversationPrivacy) {
|
|
|
13689
13958
|
const spanContext = {
|
|
13690
13959
|
conversationId: sessionConversationId,
|
|
13691
13960
|
slackThreadId: routing.correlation?.threadId,
|
|
13692
|
-
slackUserId: routing.correlation?.
|
|
13961
|
+
slackUserId: routing.correlation?.actorId,
|
|
13693
13962
|
slackChannelId: routing.correlation?.channelId,
|
|
13694
13963
|
runId: routing.correlation?.runId,
|
|
13695
13964
|
...credentialActorLogContext,
|
|
@@ -13743,7 +14012,7 @@ async function executeAgentRunInPrivacyContext(request, conversationPrivacy) {
|
|
|
13743
14012
|
getLoadedSkillNames: () => loadedSkillNamesForResume,
|
|
13744
14013
|
logContext: sessionRecordLogContext,
|
|
13745
14014
|
recordActiveMcpProviders,
|
|
13746
|
-
|
|
14015
|
+
actor,
|
|
13747
14016
|
runSource,
|
|
13748
14017
|
sessionConversationId,
|
|
13749
14018
|
sessionId,
|
|
@@ -13804,7 +14073,7 @@ async function executeAgentRunInPrivacyContext(request, conversationPrivacy) {
|
|
|
13804
14073
|
context: {
|
|
13805
14074
|
threadId: routing.correlation?.threadId,
|
|
13806
14075
|
channelId: routing.correlation?.channelId,
|
|
13807
|
-
|
|
14076
|
+
actorId: routing.correlation?.actorId,
|
|
13808
14077
|
runId: routing.correlation?.runId
|
|
13809
14078
|
},
|
|
13810
14079
|
currentTurnBlocks: routerBlocks,
|
|
@@ -13813,7 +14082,7 @@ async function executeAgentRunInPrivacyContext(request, conversationPrivacy) {
|
|
|
13813
14082
|
});
|
|
13814
14083
|
setSpanAttributes({
|
|
13815
14084
|
"gen_ai.request.model": botConfig.modelId,
|
|
13816
|
-
"
|
|
14085
|
+
"gen_ai.request.reasoning.level": thinkingSelection.thinkingLevel,
|
|
13817
14086
|
"app.ai.thinking_level_reason": thinkingSelection.reason,
|
|
13818
14087
|
...thinkingSelection.confidence !== void 0 ? {
|
|
13819
14088
|
"app.ai.thinking_level_confidence": thinkingSelection.confidence
|
|
@@ -13827,7 +14096,7 @@ async function executeAgentRunInPrivacyContext(request, conversationPrivacy) {
|
|
|
13827
14096
|
setTags({
|
|
13828
14097
|
conversationId: spanContext.conversationId,
|
|
13829
14098
|
slackThreadId: routing.correlation?.threadId,
|
|
13830
|
-
slackUserId: routing.correlation?.
|
|
14099
|
+
slackUserId: routing.correlation?.actorId,
|
|
13831
14100
|
slackChannelId: routing.correlation?.channelId,
|
|
13832
14101
|
runId: routing.correlation?.runId,
|
|
13833
14102
|
...credentialActorLogContext,
|
|
@@ -13837,7 +14106,7 @@ async function executeAgentRunInPrivacyContext(request, conversationPrivacy) {
|
|
|
13837
14106
|
const wiring = await wireAgentTools({
|
|
13838
14107
|
abortAgent: () => agent?.abort(),
|
|
13839
14108
|
activeSkills,
|
|
13840
|
-
|
|
14109
|
+
currentActor: actor,
|
|
13841
14110
|
artifactStatePatch,
|
|
13842
14111
|
availableSkills,
|
|
13843
14112
|
configurationValues,
|
|
@@ -13879,7 +14148,7 @@ async function executeAgentRunInPrivacyContext(request, conversationPrivacy) {
|
|
|
13879
14148
|
shouldPromptAgent
|
|
13880
14149
|
} = await assemblePrompt({
|
|
13881
14150
|
activeMcpCatalogs: wiring.activeMcpCatalogs,
|
|
13882
|
-
|
|
14151
|
+
currentActor: actor,
|
|
13883
14152
|
artifactState: state.artifactState,
|
|
13884
14153
|
availableSkills,
|
|
13885
14154
|
configurationValues,
|
|
@@ -13908,10 +14177,10 @@ async function executeAgentRunInPrivacyContext(request, conversationPrivacy) {
|
|
|
13908
14177
|
if (piMessages.length === 0) {
|
|
13909
14178
|
return;
|
|
13910
14179
|
}
|
|
13911
|
-
await runResume.requireDurableInputCheckpoint(
|
|
13912
|
-
...agent.state.messages,
|
|
13913
|
-
|
|
13914
|
-
|
|
14180
|
+
await runResume.requireDurableInputCheckpoint(
|
|
14181
|
+
[...agent.state.messages, ...piMessages],
|
|
14182
|
+
messages.map((message) => message.provenance)
|
|
14183
|
+
);
|
|
13915
14184
|
for (const message of piMessages) {
|
|
13916
14185
|
agent.steer(message);
|
|
13917
14186
|
}
|
|
@@ -14066,7 +14335,7 @@ async function executeAgentRunInPrivacyContext(request, conversationPrivacy) {
|
|
|
14066
14335
|
"gen_ai.operation.name": "invoke_agent",
|
|
14067
14336
|
"gen_ai.request.model": botConfig.modelId,
|
|
14068
14337
|
...thinkingSelection ? {
|
|
14069
|
-
"
|
|
14338
|
+
"gen_ai.request.reasoning.level": thinkingSelection.thinkingLevel
|
|
14070
14339
|
} : {},
|
|
14071
14340
|
"app.ai.turn_timeout_ms": turnTimeoutBudgetMs,
|
|
14072
14341
|
"app.ai.turn_deadline_remaining_ms": Math.max(
|
|
@@ -14119,7 +14388,7 @@ async function executeAgentRunInPrivacyContext(request, conversationPrivacy) {
|
|
|
14119
14388
|
);
|
|
14120
14389
|
const outputMessages = newMessages.filter(isAssistantMessage);
|
|
14121
14390
|
const outputMessagesAttribute = serializeGenAiAttribute(
|
|
14122
|
-
conversationPrivacy !== "public" ? outputMessages.map(toGenAiMessageMetadata) : outputMessages
|
|
14391
|
+
conversationPrivacy !== "public" ? outputMessages.map(toGenAiMessageMetadata) : outputMessages.map(toCanonicalOutputMessage)
|
|
14123
14392
|
);
|
|
14124
14393
|
const usageSummary = extractGenAiUsageSummary(
|
|
14125
14394
|
promptResult,
|
|
@@ -14175,7 +14444,7 @@ async function executeAgentRunInPrivacyContext(request, conversationPrivacy) {
|
|
|
14175
14444
|
...sessionConversationId ? { "app.ai.session.conversation_id": sessionConversationId } : {},
|
|
14176
14445
|
...sessionId ? { "app.ai.turn.session_id": sessionId } : {},
|
|
14177
14446
|
...currentSliceId ? { "app.ai.turn.slice_id": currentSliceId } : {},
|
|
14178
|
-
"
|
|
14447
|
+
"gen_ai.request.reasoning.level": thinkingSelection.thinkingLevel,
|
|
14179
14448
|
...toGenAiMessagesTraceAttributes("app.ai.input", inputMessages),
|
|
14180
14449
|
...inputMessagesAttribute ? { "gen_ai.input.messages": inputMessagesAttribute } : {}
|
|
14181
14450
|
}
|
|
@@ -14233,7 +14502,7 @@ async function executeAgentRunInPrivacyContext(request, conversationPrivacy) {
|
|
|
14233
14502
|
"assistant_reply_generation_failed",
|
|
14234
14503
|
{
|
|
14235
14504
|
slackThreadId: routing.correlation?.threadId,
|
|
14236
|
-
slackUserId: routing.correlation?.
|
|
14505
|
+
slackUserId: routing.correlation?.actorId,
|
|
14237
14506
|
slackChannelId: routing.correlation?.channelId,
|
|
14238
14507
|
runId: routing.correlation?.runId,
|
|
14239
14508
|
...credentialActorLogContext,
|