@sentry/junior 0.91.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.
Files changed (128) hide show
  1. package/dist/{agent-hooks-MXAF7RQL.js → agent-hooks-BYSSWCNW.js} +7 -7
  2. package/dist/api/people/list.d.ts +3 -3
  3. package/dist/api/people/list.js +15 -15
  4. package/dist/api/people/list.query.d.ts +2 -2
  5. package/dist/api/people/profile.d.ts +3 -3
  6. package/dist/api/people/profile.js +12 -12
  7. package/dist/api/people/profile.query.d.ts +2 -2
  8. package/dist/api/people/shared.d.ts +13 -13
  9. package/dist/api/people/types.d.ts +12 -12
  10. package/dist/api-reference.d.ts +1 -1
  11. package/dist/app.js +334 -263
  12. package/dist/{catalog-runtime-DXE6NXHT.js → catalog-runtime-NZHMSMYC.js} +2 -2
  13. package/dist/chat/actor.d.ts +75 -0
  14. package/dist/chat/agent/prompt.d.ts +2 -2
  15. package/dist/chat/agent/request.d.ts +13 -13
  16. package/dist/chat/agent/resume.d.ts +5 -4
  17. package/dist/chat/agent/tools.d.ts +2 -2
  18. package/dist/chat/capabilities/jr-rpc-command.d.ts +1 -1
  19. package/dist/chat/conversation-privacy.d.ts +11 -0
  20. package/dist/chat/conversations/sql/migrations.d.ts +1 -1
  21. package/dist/chat/conversations/sql/schema/conversations.d.ts +2 -19
  22. package/dist/chat/conversations/sql/schema.d.ts +2 -19
  23. package/dist/chat/conversations/sql/store.d.ts +3 -3
  24. package/dist/chat/conversations/store.d.ts +4 -4
  25. package/dist/chat/credentials/context.d.ts +4 -4
  26. package/dist/chat/logging.d.ts +2 -2
  27. package/dist/chat/no-reply.d.ts +1 -1
  28. package/dist/chat/oauth-flow.d.ts +1 -1
  29. package/dist/chat/pi/messages.d.ts +2 -2
  30. package/dist/chat/pi/transcript.d.ts +15 -0
  31. package/dist/chat/plugins/agent-hooks.d.ts +3 -3
  32. package/dist/chat/plugins/credential-hooks.d.ts +2 -8
  33. package/dist/chat/prompt.d.ts +3 -6
  34. package/dist/chat/runtime/reply-executor.d.ts +1 -1
  35. package/dist/chat/runtime/turn-input.d.ts +1 -1
  36. package/dist/chat/sandbox/egress/schemas.d.ts +2 -2
  37. package/dist/chat/sandbox/egress/session.d.ts +1 -1
  38. package/dist/chat/services/context-compaction.d.ts +1 -1
  39. package/dist/chat/services/conversation-memory.d.ts +1 -1
  40. package/dist/chat/services/mcp-auth-orchestration.d.ts +1 -1
  41. package/dist/chat/services/message-actor-identity.d.ts +4 -4
  42. package/dist/chat/services/pending-auth.d.ts +2 -2
  43. package/dist/chat/services/plugin-auth-orchestration.d.ts +1 -1
  44. package/dist/chat/services/provider-default-config.d.ts +1 -1
  45. package/dist/chat/services/subscribed-decision.d.ts +1 -1
  46. package/dist/chat/services/turn-result.d.ts +1 -1
  47. package/dist/chat/services/turn-session-record.d.ts +11 -8
  48. package/dist/chat/services/turn-thinking-level.d.ts +1 -1
  49. package/dist/chat/slack/assistant-thread/title.d.ts +1 -1
  50. package/dist/chat/slack/tools/canvas/create.d.ts +41 -1
  51. package/dist/chat/slack/tools/canvas/edit.d.ts +60 -1
  52. package/dist/chat/slack/tools/canvas/read.d.ts +60 -1
  53. package/dist/chat/slack/tools/canvas/write.d.ts +41 -1
  54. package/dist/chat/slack/tools/channel-list-messages.d.ts +45 -1
  55. package/dist/chat/slack/tools/context.d.ts +3 -3
  56. package/dist/chat/slack/tools/list/add-items.d.ts +42 -1
  57. package/dist/chat/slack/tools/list/create.d.ts +40 -1
  58. package/dist/chat/slack/tools/list/get-items.d.ts +40 -1
  59. package/dist/chat/slack/tools/list/update-item.d.ts +46 -1
  60. package/dist/chat/slack/tools/message-add-reaction.d.ts +40 -1
  61. package/dist/chat/slack/tools/send-message.d.ts +45 -1
  62. package/dist/chat/slack/tools/thread-read.d.ts +44 -1
  63. package/dist/chat/slack/tools/user-lookup.d.ts +45 -1
  64. package/dist/chat/slack/user.d.ts +3 -3
  65. package/dist/chat/slack/vision-context.d.ts +2 -2
  66. package/dist/chat/sql/schema.d.ts +2 -19
  67. package/dist/chat/state/conversation-details.d.ts +4 -4
  68. package/dist/chat/state/conversation.d.ts +1 -1
  69. package/dist/chat/state/session-log.d.ts +140 -26
  70. package/dist/chat/state/turn-session.d.ts +18 -5
  71. package/dist/chat/task-execution/slack-work.d.ts +2 -2
  72. package/dist/chat/task-execution/state.d.ts +4 -4
  73. package/dist/chat/tool-support/zod-tool.d.ts +16 -4
  74. package/dist/chat/tools/advisor/tool.d.ts +41 -1
  75. package/dist/chat/tools/definition.d.ts +10 -0
  76. package/dist/chat/tools/execute-tool.d.ts +41 -1
  77. package/dist/chat/tools/resource-events.d.ts +124 -3
  78. package/dist/chat/tools/runtime/report-progress.d.ts +40 -1
  79. package/dist/chat/tools/sandbox/bash.d.ts +41 -1
  80. package/dist/chat/tools/sandbox/edit-file.d.ts +44 -1
  81. package/dist/chat/tools/sandbox/find-files.d.ts +42 -1
  82. package/dist/chat/tools/sandbox/grep.d.ts +46 -1
  83. package/dist/chat/tools/sandbox/list-dir.d.ts +41 -1
  84. package/dist/chat/tools/sandbox/read-file.d.ts +42 -1
  85. package/dist/chat/tools/sandbox/write-file.d.ts +41 -1
  86. package/dist/chat/tools/search-tools.d.ts +102 -1
  87. package/dist/chat/tools/skill/call-mcp-tool.d.ts +10 -1
  88. package/dist/chat/tools/skill/load-skill.d.ts +40 -1
  89. package/dist/chat/tools/skill/search-mcp-tools.d.ts +100 -1
  90. package/dist/chat/tools/system-time.d.ts +38 -1
  91. package/dist/chat/tools/types.d.ts +4 -4
  92. package/dist/chat/tools/web/fetch-tool.d.ts +41 -1
  93. package/dist/chat/tools/web/image-generate.d.ts +62 -1
  94. package/dist/chat/tools/web/search.d.ts +41 -1
  95. package/dist/{chunk-HXL2ZV74.js → chunk-3F54A3YM.js} +82 -11
  96. package/dist/{chunk-ZGDTBSQ7.js → chunk-7DVIELX3.js} +405 -136
  97. package/dist/{chunk-GCWD2VHP.js → chunk-7FS3K243.js} +284 -124
  98. package/dist/{chunk-AOISHLSF.js → chunk-ACJENBVF.js} +143 -20
  99. package/dist/{chunk-IRRMABQD.js → chunk-APIVR44P.js} +10 -10
  100. package/dist/{chunk-PIB4EOW6.js → chunk-BMQ5DXHV.js} +19 -72
  101. package/dist/{chunk-XP7F4LYB.js → chunk-BTH37NCU.js} +4 -4
  102. package/dist/{chunk-5GBUZI6M.js → chunk-H7KUZAMZ.js} +4 -4
  103. package/dist/{chunk-TYUXD3FN.js → chunk-MC4ZZE4Q.js} +1 -1
  104. package/dist/{chunk-QCKGI74V.js → chunk-N25HRI6B.js} +10 -10
  105. package/dist/{chunk-2S7M37HY.js → chunk-NIFONS4W.js} +86 -47
  106. package/dist/{chunk-ONFOWI2D.js → chunk-OJP53WIU.js} +16 -15
  107. package/dist/{chunk-NW7AXDA5.js → chunk-OZJXGX4U.js} +2 -2
  108. package/dist/{chunk-KC42JAAQ.js → chunk-PFXC67GJ.js} +3 -3
  109. package/dist/{chunk-ZUK7BL63.js → chunk-S6QKIGRM.js} +66 -54
  110. package/dist/{chunk-IX76WFJV.js → chunk-TF5VLGA7.js} +10 -10
  111. package/dist/{chunk-DACFZ5CI.js → chunk-VY7TVOIK.js} +16 -12
  112. package/dist/{chunk-AN2437E3.js → chunk-YTNPU7I2.js} +2 -2
  113. package/dist/{chunk-3MPOMK3K.js → chunk-YYBX2BD5.js} +61 -3
  114. package/dist/{chunk-RS6ANWVT.js → chunk-ZATRYQLR.js} +1 -1
  115. package/dist/cli/chat.js +20 -20
  116. package/dist/cli/check.js +3 -3
  117. package/dist/cli/plugins.js +9 -9
  118. package/dist/cli/snapshot-warmup.js +6 -6
  119. package/dist/cli/upgrade.js +9 -9
  120. package/dist/{db-CXI7PR5U.js → db-GCK43OO3.js} +4 -4
  121. package/dist/instrumentation.js +1 -1
  122. package/dist/reporting/conversations.d.ts +3 -3
  123. package/dist/reporting.d.ts +1 -1
  124. package/dist/reporting.js +48 -50
  125. package/dist/{runner-FKL3RAHA.js → runner-XWTFA26U.js} +20 -18
  126. package/dist/{validation-I7GD2YWS.js → validation-KYAWETI4.js} +3 -3
  127. package/package.json +6 -6
  128. 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-ONFOWI2D.js";
14
+ } from "./chunk-OJP53WIU.js";
15
15
  import {
16
16
  JUNIOR_THREAD_STATE_TTL_MS
17
- } from "./chunk-KC42JAAQ.js";
17
+ } from "./chunk-PFXC67GJ.js";
18
18
  import {
19
19
  buildNonInteractiveShellScript,
20
20
  createSandboxInstance,
@@ -23,7 +23,7 @@ import {
23
23
  isSnapshotMissingError,
24
24
  resolveRuntimeDependencySnapshot,
25
25
  runNonInteractiveCommand
26
- } from "./chunk-5GBUZI6M.js";
26
+ } from "./chunk-H7KUZAMZ.js";
27
27
  import {
28
28
  JUNIOR_PERSONALITY,
29
29
  buildPluginSystemPromptContributions,
@@ -32,18 +32,16 @@ import {
32
32
  containsNoReplyMarker,
33
33
  formatSlackLink,
34
34
  isNoReplyMarker,
35
- renderCurrentInstruction,
36
35
  stripNoReplyMarker
37
- } from "./chunk-PIB4EOW6.js";
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-GCWD2VHP.js";
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-DACFZ5CI.js";
61
+ } from "./chunk-VY7TVOIK.js";
64
62
  import {
65
63
  createPluginLogger
66
- } from "./chunk-NW7AXDA5.js";
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-RS6ANWVT.js";
75
+ } from "./chunk-ZATRYQLR.js";
78
76
  import {
79
77
  getConversationStore,
80
78
  getDb
81
- } from "./chunk-2S7M37HY.js";
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-HXL2ZV74.js";
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-3MPOMK3K.js";
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-AN2437E3.js";
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-XP7F4LYB.js";
132
+ } from "./chunk-BTH37NCU.js";
131
133
  import {
132
- createRequester,
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-ZUK7BL63.js";
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 markerSideEffectSuccess = exactNoReplyMarker && toolErrorCount === 0 && reactionPerformed;
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?.requesterId,
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": sideEffectOnlySuccess && !isProviderError
703
+ "app.ai.no_reply_marker_accepted": !isProviderError
702
704
  };
703
- if (sideEffectOnlySuccess && !isProviderError) {
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?.requesterId,
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 && !sideEffectOnlySuccess && !isProviderError && !exactNoReplyMarker) {
731
+ if (!primaryText && !silentCompletionSuccess && !isProviderError) {
737
732
  logWarn(
738
733
  "ai_model_response_empty",
739
734
  {
740
735
  slackThreadId: correlation?.threadId,
741
- slackUserId: correlation?.requesterId,
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 || sideEffectOnlySuccess) {
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 && reactionPerformed ? {
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?.requesterId,
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
- requesterId: args.context?.requesterId ?? "",
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 requesterFromRouting(routing) {
1081
- return createRequester(routing.requester, {
1082
- platform: routing.requester?.platform ?? (routing.destination.platform === "slack" ? "slack" : void 0),
1083
- teamId: (routing.destination.platform === "slack" ? routing.destination.teamId : void 0) ?? routing.correlation?.teamId ?? (routing.requester?.platform === "slack" ? routing.requester.teamId : void 0),
1084
- userId: routing.correlation?.requesterId
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 assertRequesterDestinationMatch(routing) {
1088
- const { destination, requester } = routing;
1089
- if (!requester) {
1095
+ function assertActorDestinationMatch(routing) {
1096
+ const { destination, actor } = routing;
1097
+ if (!actor) {
1090
1098
  return;
1091
1099
  }
1092
- if (requester.platform !== destination.platform) {
1100
+ if (actor.platform !== destination.platform) {
1093
1101
  throw new TypeError(
1094
- `Requester platform "${requester.platform}" does not match destination platform "${destination.platform}"`
1102
+ `Actor platform "${actor.platform}" does not match destination platform "${destination.platform}"`
1095
1103
  );
1096
1104
  }
1097
- if (requester.platform === "slack" && destination.platform === "slack" && requester.teamId !== destination.teamId) {
1098
- throw new TypeError("Slack requester team does not match destination team");
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) {
@@ -1571,7 +1579,7 @@ async function assemblePrompt(args) {
1571
1579
  source
1572
1580
  } : void 0,
1573
1581
  invocation: args.invocation,
1574
- requester: args.actorRequester,
1582
+ actor: isUserActor(args.currentActor) ? args.currentActor : void 0,
1575
1583
  artifactState: args.artifactState,
1576
1584
  configuration: args.configurationValues
1577
1585
  }) : null;
@@ -1739,7 +1747,7 @@ ${usage}
1739
1747
  const entry = await configuration.set({
1740
1748
  key,
1741
1749
  value,
1742
- updatedBy: deps.requesterId,
1750
+ updatedBy: deps.actorId,
1743
1751
  source: "jr-rpc"
1744
1752
  });
1745
1753
  logInfo(
@@ -3790,6 +3798,22 @@ function createListDirTool() {
3790
3798
  // src/chat/tools/web/image-generate.ts
3791
3799
  import { z as z9 } from "zod";
3792
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();
3793
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.
3794
3818
 
3795
3819
  <personality>
@@ -3852,7 +3876,7 @@ function createImageGenerateTool(hooks, options = {}, deps = {}) {
3852
3876
  inputSchema: z9.object({
3853
3877
  prompt: z9.string().min(1).max(4e3).describe("Image generation prompt.")
3854
3878
  }),
3855
- outputSchema: juniorToolResultSchema,
3879
+ outputSchema: imageGenerateOutputSchema,
3856
3880
  execute: async ({ prompt }) => {
3857
3881
  const fetchImpl = deps.fetch ?? fetch;
3858
3882
  const apiKey = getGatewayApiKey();
@@ -3980,7 +4004,7 @@ function createCallMcpToolTool(mcpToolManager) {
3980
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.",
3981
4005
  inputSchema: z10.object({
3982
4006
  tool_name: z10.string().min(1).describe("Exact MCP tool_name from searchMcpTools."),
3983
- arguments: z10.unknown().describe(
4007
+ arguments: z10.record(z10.string(), z10.unknown()).describe(
3984
4008
  'Arguments matching the disclosed MCP tool schema, for example { "query": "..." } when searchMcpTools shows query is required.'
3985
4009
  ).optional()
3986
4010
  }).passthrough(),
@@ -4219,6 +4243,38 @@ function toActiveMcpCatalogSummaries(toolDefs) {
4219
4243
  // src/chat/tools/skill/search-mcp-tools.ts
4220
4244
  var DEFAULT_MAX_RESULTS = 5;
4221
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();
4222
4278
  function normalize(value) {
4223
4279
  return value.toLowerCase().replace(/[^a-z0-9_]+/g, " ").trim();
4224
4280
  }
@@ -4346,7 +4402,7 @@ function createSearchMcpToolsTool(mcpToolManager) {
4346
4402
  ).optional(),
4347
4403
  max_results: z12.number().int().min(1).max(MAX_RESULTS).describe("Maximum matching tool descriptors to return.").optional()
4348
4404
  }).strict(),
4349
- outputSchema: juniorToolResultSchema,
4405
+ outputSchema: searchMcpToolsOutputSchema,
4350
4406
  execute: async ({ query, provider, max_results }) => {
4351
4407
  if (provider) {
4352
4408
  await mcpToolManager.activateProvider(provider);
@@ -4368,6 +4424,13 @@ function createSearchMcpToolsTool(mcpToolManager) {
4368
4424
  provider: provider ?? null,
4369
4425
  total_active_tools: catalog.length,
4370
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
+ },
4371
4434
  available_providers: providers,
4372
4435
  tools: matches.map(toExposedToolSummary)
4373
4436
  };
@@ -5965,6 +6028,17 @@ var editReplacementSchema2 = z22.object({
5965
6028
  ),
5966
6029
  newText: z22.string().describe("Replacement Canvas markdown for this edit.")
5967
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();
5968
6042
  function createSlackCanvasEditTool(state) {
5969
6043
  return zodTool({
5970
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.",
@@ -5976,7 +6050,7 @@ function createSlackCanvasEditTool(state) {
5976
6050
  "Exact replacements matched against the current Canvas body, not incrementally."
5977
6051
  )
5978
6052
  }),
5979
- outputSchema: juniorToolResultSchema,
6053
+ outputSchema: slackCanvasEditOutputSchema,
5980
6054
  execute: async ({ canvas, edits }) => {
5981
6055
  const target = resolveCanvasTarget(canvas);
5982
6056
  if (!target.ok) {
@@ -6051,6 +6125,18 @@ function createSlackCanvasEditTool(state) {
6051
6125
 
6052
6126
  // src/chat/slack/tools/canvas/read.ts
6053
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();
6054
6140
  function createSlackCanvasReadTool() {
6055
6141
  return zodTool({
6056
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.",
@@ -6062,7 +6148,7 @@ function createSlackCanvasReadTool() {
6062
6148
  offset: z23.coerce.number().int().min(1).describe("1-indexed line number to start reading from.").optional(),
6063
6149
  limit: z23.coerce.number().int().min(1).describe("Maximum number of lines to read. Defaults to 1000.").optional()
6064
6150
  }),
6065
- outputSchema: juniorToolResultSchema,
6151
+ outputSchema: slackCanvasReadOutputSchema,
6066
6152
  execute: async ({ canvas, offset, limit }) => {
6067
6153
  const target = resolveCanvasTarget(canvas);
6068
6154
  if (!target.ok) {
@@ -7362,15 +7448,11 @@ function createAdvisorTool(context) {
7362
7448
  ].join("\n");
7363
7449
  const advisorInputMessage = {
7364
7450
  role: "user",
7365
- content: [
7366
- {
7367
- type: "text",
7368
- text: requestText
7369
- }
7370
- ]
7451
+ content: [{ type: "text", text: requestText }],
7452
+ timestamp: Date.now()
7371
7453
  };
7372
7454
  const advisorInputMessagesAttribute = serializeGenAiAttribute(
7373
- conversationPrivacy !== "public" ? [toGenAiMessageMetadata(advisorInputMessage)] : [advisorInputMessage]
7455
+ conversationPrivacy !== "public" ? [toGenAiMessageMetadata(advisorInputMessage)] : [toCanonicalInputMessage(advisorInputMessage)]
7374
7456
  );
7375
7457
  return await withSpan(
7376
7458
  `invoke_agent ${context.config.modelId}`,
@@ -7421,7 +7503,7 @@ function createAdvisorTool(context) {
7421
7503
  const newAdvisorMessages = advisorAgent.state.messages.slice(beforeMessageCount);
7422
7504
  const outputMessages = newAdvisorMessages.filter(isAssistantMessage);
7423
7505
  const outputMessagesAttribute = serializeGenAiAttribute(
7424
- conversationPrivacy !== "public" ? outputMessages.map(toGenAiMessageMetadata) : outputMessages
7506
+ conversationPrivacy !== "public" ? outputMessages.map(toGenAiMessageMetadata) : outputMessages.map(toCanonicalOutputMessage)
7425
7507
  );
7426
7508
  setSpanAttributes({
7427
7509
  ...outputMessagesAttribute ? { "gen_ai.output.messages": outputMessagesAttribute } : {},
@@ -8516,7 +8598,7 @@ function upstreamPermissionDeniedText(value) {
8516
8598
  ...sso ? [`Provider SSO: ${sso}`] : [],
8517
8599
  ...command ? [`Command: ${command}`] : [],
8518
8600
  "",
8519
- "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 requester-provider account access.",
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.",
8520
8602
  ...stderr ? ["", `stderr:
8521
8603
  ${stderr}`] : [],
8522
8604
  ...stdout ? ["", `stdout:
@@ -9023,7 +9105,7 @@ async function startOAuthFlow(provider, input) {
9023
9105
  await getStateAdapter().set(
9024
9106
  `oauth-state:${state}`,
9025
9107
  {
9026
- userId: input.requesterId,
9108
+ userId: input.actorId,
9027
9109
  provider,
9028
9110
  ...input.channelId ? { channelId: input.channelId } : {},
9029
9111
  ...input.destination ? { destination: input.destination } : {},
@@ -9066,7 +9148,7 @@ async function startOAuthFlow(provider, input) {
9066
9148
  delivery: await deliverPrivateMessage({
9067
9149
  channelId: input.channelId,
9068
9150
  threadTs: input.threadTs,
9069
- userId: input.requesterId,
9151
+ userId: input.actorId,
9070
9152
  text: formatOAuthAuthorizationMessage({
9071
9153
  authorizationUrl,
9072
9154
  label: `Click here to link your ${formatProviderLabel(provider)} account`,
@@ -9181,7 +9263,7 @@ function createPluginAuthOrchestration(input) {
9181
9263
  if (pendingPause) {
9182
9264
  throw pendingPause;
9183
9265
  }
9184
- if (!input.requesterId || !pluginCatalogRuntime.getOAuthConfig(provider)) {
9266
+ if (!input.actorId || !pluginCatalogRuntime.getOAuthConfig(provider)) {
9185
9267
  throw new Error(`Cannot start plugin authorization for ${provider}`);
9186
9268
  }
9187
9269
  if (input.authorizationFlowMode === "disabled") {
@@ -9198,13 +9280,13 @@ function createPluginAuthOrchestration(input) {
9198
9280
  pendingAuth: input.pendingAuth,
9199
9281
  kind: "plugin",
9200
9282
  provider,
9201
- requesterId: input.requesterId,
9283
+ actorId: input.actorId,
9202
9284
  sessionId: input.sessionId,
9203
9285
  ...options?.scope ? { scope: options.scope } : {}
9204
9286
  }) : false;
9205
9287
  if (!reusingPendingLink) {
9206
9288
  const oauthResult = await startOAuthFlow(provider, {
9207
- requesterId: input.requesterId,
9289
+ actorId: input.actorId,
9208
9290
  channelId: input.channelId,
9209
9291
  destination: input.destination,
9210
9292
  source: input.source,
@@ -9224,14 +9306,14 @@ function createPluginAuthOrchestration(input) {
9224
9306
  );
9225
9307
  }
9226
9308
  }
9227
- if (options?.unlinkExistingProvider && input.requesterId && input.userTokenStore) {
9228
- await unlinkProvider(input.requesterId, provider, input.userTokenStore);
9309
+ if (options?.unlinkExistingProvider && input.actorId && input.userTokenStore) {
9310
+ await unlinkProvider(input.actorId, provider, input.userTokenStore);
9229
9311
  }
9230
9312
  if (input.sessionId && recordPendingAuth) {
9231
9313
  await recordPendingAuth({
9232
9314
  kind: "plugin",
9233
9315
  provider,
9234
- requesterId: input.requesterId,
9316
+ actorId: input.actorId,
9235
9317
  ...options?.scope ? { scope: options.scope } : {},
9236
9318
  sessionId: input.sessionId,
9237
9319
  linkSentAtMs: reusingPendingLink ? input.pendingAuth.linkSentAtMs : Date.now()
@@ -9242,7 +9324,7 @@ function createPluginAuthOrchestration(input) {
9242
9324
  conversationId: input.conversationId,
9243
9325
  kind: "plugin",
9244
9326
  provider,
9245
- requesterId: input.requesterId,
9327
+ actorId: input.actorId,
9246
9328
  authorizationId: authorizationId({
9247
9329
  kind: "plugin",
9248
9330
  provider,
@@ -9279,7 +9361,7 @@ function createPluginAuthOrchestration(input) {
9279
9361
  signal.message ?? `${formatProviderLabel(provider)} credentials are required but no OAuth flow is available for this provider.`
9280
9362
  );
9281
9363
  }
9282
- if (!input.requesterId || !input.userTokenStore) {
9364
+ if (!input.actorId || !input.userTokenStore) {
9283
9365
  if (input.authorizationFlowMode === "disabled") {
9284
9366
  throw new AuthorizationFlowDisabledError("plugin", provider);
9285
9367
  }
@@ -9438,9 +9520,50 @@ import { z as z39 } from "zod";
9438
9520
  var SEARCH_TOOLS_NAME = "searchTools";
9439
9521
  var DEFAULT_MAX_RESULTS2 = 5;
9440
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();
9441
9556
  function normalize2(value) {
9442
9557
  return value.toLowerCase().replace(/[^a-z0-9_]+/g, " ").trim();
9443
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
+ }
9444
9567
  function schemaText(schema) {
9445
9568
  try {
9446
9569
  return JSON.stringify(schema);
@@ -9455,6 +9578,8 @@ function searchableToolText2(name, definition) {
9455
9578
  definition.identity?.id,
9456
9579
  definition.identity?.name,
9457
9580
  definition.identity?.plugin,
9581
+ definition.source?.id,
9582
+ definition.source?.description,
9458
9583
  definition.description,
9459
9584
  definition.promptSnippet,
9460
9585
  ...definition.promptGuidelines ?? [],
@@ -9463,15 +9588,16 @@ function searchableToolText2(name, definition) {
9463
9588
  ].filter(Boolean).join(" ")
9464
9589
  );
9465
9590
  }
9466
- function searchCatalogTools(tools, query) {
9591
+ function searchCatalogTools(tools, query, source) {
9467
9592
  const entries = Object.entries(tools).sort(
9468
9593
  ([left], [right]) => left.localeCompare(right)
9469
9594
  );
9595
+ const sourceEntries = source ? entries.filter(([, definition]) => definition.source?.id === source) : entries;
9470
9596
  if (!normalize2(query)) {
9471
- return entries.map(([name]) => name);
9597
+ return sourceEntries.map(([name]) => name);
9472
9598
  }
9473
9599
  const terms = normalize2(query).split(/\s+/).filter(Boolean);
9474
- return entries.filter(([name, definition]) => {
9600
+ return sourceEntries.filter(([name, definition]) => {
9475
9601
  const text = searchableToolText2(name, definition);
9476
9602
  return terms.every((term) => text.includes(term));
9477
9603
  }).map(([name]) => name);
@@ -9482,17 +9608,128 @@ function callNotes(definition) {
9482
9608
  ...definition.promptGuidelines?.map((guideline) => guideline.trim()).filter(Boolean) ?? []
9483
9609
  ];
9484
9610
  }
9485
- function toolMetadata(name, definition) {
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) {
9676
+ return {
9677
+ tool_name: name,
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) {
9486
9726
  return {
9487
9727
  tool_name: name,
9488
- description: definition.description,
9728
+ description: summarizeModelVisibleDescription(definition.description),
9489
9729
  exposure: effectiveToolExposure(definition),
9490
- source: definition.identity ? {
9491
- type: "plugin",
9492
- id: definition.identity.id,
9493
- name: definition.identity.name,
9494
- plugin: definition.identity.plugin
9495
- } : { type: "core" },
9730
+ ...includeSource && definition.source ? { source: definition.source.id } : {},
9731
+ signature: formatToolSignature(name, definition.inputSchema),
9732
+ call: formatToolCallExample(name, definition.inputSchema),
9496
9733
  input_schema: definition.inputSchema,
9497
9734
  input_schema_summary: summarizeInputSchema(
9498
9735
  definition.inputSchema
@@ -9502,27 +9739,55 @@ function toolMetadata(name, definition) {
9502
9739
  };
9503
9740
  }
9504
9741
  function createSearchToolsTool(catalogTools) {
9742
+ const knownSources = sourceSummaries(catalogTools);
9505
9743
  return zodTool({
9506
- description: "Search the executable tool catalog. Use this to discover exact tool names, owners, schemas, and call notes before calling executeTool.",
9744
+ description: renderSearchToolsDescription(knownSources),
9507
9745
  annotations: { readOnlyHint: true, destructiveHint: false },
9508
9746
  inputSchema: z39.object({
9509
9747
  query: z39.string().nullable().describe(
9510
9748
  "Optional search terms describing the tool, owner, action, or arguments needed. Empty string lists catalog tools."
9511
9749
  ).optional(),
9750
+ source: z39.string().nullable().describe(
9751
+ "Optional source id to search within, such as a plugin source returned in sources."
9752
+ ).optional(),
9512
9753
  max_results: z39.number().int().min(1).max(MAX_RESULTS3).nullable().describe("Maximum matching catalog tool descriptors to return.").optional()
9513
9754
  }).strict(),
9514
- outputSchema: juniorToolResultSchema,
9515
- execute: async ({ query, max_results }) => {
9755
+ outputSchema: searchToolsOutputSchema,
9756
+ execute: async ({ query, source, max_results }) => {
9516
9757
  const maxResults = max_results ?? DEFAULT_MAX_RESULTS2;
9517
- const matches = searchCatalogTools(catalogTools, query ?? "").slice(
9518
- 0,
9519
- maxResults
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)
9520
9774
  );
9521
9775
  const data = {
9522
9776
  query: query ?? null,
9777
+ source: requestedSource,
9778
+ sources,
9523
9779
  total_catalog_tools: Object.keys(catalogTools).length,
9524
- returned_tools: matches.length,
9525
- tools: matches.map((name) => toolMetadata(name, catalogTools[name]))
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
9526
9791
  };
9527
9792
  return {
9528
9793
  ok: true,
@@ -9734,7 +9999,7 @@ var SANDBOX_EGRESS_LEASE_PREFIX = "sandbox-egress-lease";
9734
9999
  var DEFAULT_SESSION_TTL_MS = 30 * 60 * 1e3;
9735
10000
  function leaseKey(provider, grantName, context) {
9736
10001
  const actor = context.credentials.actor;
9737
- const actorKey = actor.type === "user" ? `user:${actor.userId}` : `system:${actor.id}`;
10002
+ const actorKey = "type" in actor ? `user:${actor.userId}` : `system:${actor.name}`;
9738
10003
  return `${SANDBOX_EGRESS_LEASE_PREFIX}:${provider}:${grantName}:${actorKey}:${context.egressId}:${context.contextId}`;
9739
10004
  }
9740
10005
  function authSignalKey(egressId, access) {
@@ -11853,7 +12118,7 @@ function createMcpAuthOrchestration(input) {
11853
12118
  let pendingPause;
11854
12119
  const authSessionIdsByProvider = /* @__PURE__ */ new Map();
11855
12120
  const authProviderFactory = async (plugin) => {
11856
- if (!input.conversationId || !input.sessionId || !input.requesterId) {
12121
+ if (!input.conversationId || !input.sessionId || !input.actorId) {
11857
12122
  return void 0;
11858
12123
  }
11859
12124
  if (!input.recordPendingAuth && input.authorizationFlowMode !== "disabled") {
@@ -11867,7 +12132,7 @@ function createMcpAuthOrchestration(input) {
11867
12132
  destination: input.destination,
11868
12133
  source: input.source,
11869
12134
  sessionId: input.sessionId,
11870
- userId: input.requesterId,
12135
+ userId: input.actorId,
11871
12136
  userMessage: input.userMessage,
11872
12137
  ...input.channelId ? { channelId: input.channelId } : {},
11873
12138
  ...input.threadTs ? { threadTs: input.threadTs } : {},
@@ -11885,8 +12150,8 @@ function createMcpAuthOrchestration(input) {
11885
12150
  const authSessionId = authSessionIdsByProvider.get(provider);
11886
12151
  const conversationId = input.conversationId;
11887
12152
  const sessionId = input.sessionId;
11888
- const requesterId = input.requesterId;
11889
- if (!authSessionId || !conversationId || !sessionId || !requesterId) {
12153
+ const actorId = input.actorId;
12154
+ if (!authSessionId || !conversationId || !sessionId || !actorId) {
11890
12155
  throw new Error(
11891
12156
  `Missing MCP auth session context for plugin "${provider}"`
11892
12157
  );
@@ -11915,7 +12180,7 @@ function createMcpAuthOrchestration(input) {
11915
12180
  pendingAuth: input.pendingAuth,
11916
12181
  kind: "mcp",
11917
12182
  provider,
11918
- requesterId,
12183
+ actorId,
11919
12184
  sessionId
11920
12185
  });
11921
12186
  const providerLabel = formatProviderLabel(provider);
@@ -11941,7 +12206,7 @@ function createMcpAuthOrchestration(input) {
11941
12206
  await recordPendingAuth({
11942
12207
  kind: "mcp",
11943
12208
  provider,
11944
- requesterId,
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
- requesterId,
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.type === "user" ? input.actor.userId : void 0;
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 authRequesterId = args.routing.credentialContext?.actor.type === "user" ? args.routing.credentialContext.actor.userId : void 0;
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
- requester: args.actorRequester
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
- requesterId: args.actorRequester?.userId,
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
- requesterId: authRequesterId,
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
- requesterId: authRequesterId,
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
- requester: args.actorRequester?.platform === "slack" ? args.actorRequester : void 0,
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
- requester: args.actorRequester?.platform === "local" ? args.actorRequester : void 0,
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
- requester: args.requester,
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(messages);
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
- assertRequesterDestinationMatch(routing);
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 requester = requesterFromRouting(routing);
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: credentialActor.type === "user" ? credentialActor.userId : credentialActor.id
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
- requesterId: routing.correlation?.requesterId,
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?.requesterId,
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
- requester,
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
- requesterId: routing.correlation?.requesterId,
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
- "app.ai.reasoning_effort": thinkingSelection.thinkingLevel,
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?.requesterId,
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
- actorRequester: requester,
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
- actorRequester: requester,
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
- ...piMessages
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
- "app.ai.reasoning_effort": thinkingSelection.thinkingLevel
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
- "app.ai.reasoning_effort": thinkingSelection.thinkingLevel,
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?.requesterId,
14505
+ slackUserId: routing.correlation?.actorId,
14237
14506
  slackChannelId: routing.correlation?.channelId,
14238
14507
  runId: routing.correlation?.runId,
14239
14508
  ...credentialActorLogContext,