@sentry/junior 0.147.0 → 0.149.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 (162) hide show
  1. package/dist/{agent-hooks-HS6VGUPM.js → agent-hooks-CWMCXAMT.js} +10 -10
  2. package/dist/api/conversations/access.d.ts +2 -1
  3. package/dist/api/conversations/aggregate.d.ts +2 -0
  4. package/dist/api/conversations/archive.d.ts +3 -5
  5. package/dist/api/conversations/create.d.ts +6 -0
  6. package/dist/api/conversations/detail.d.ts +2 -296
  7. package/dist/api/conversations/event-list.d.ts +2 -193
  8. package/dist/api/conversations/list.d.ts +4 -66
  9. package/dist/api/conversations/pending-messages.d.ts +15 -0
  10. package/dist/api/conversations/routes.d.ts +1 -1
  11. package/dist/api/conversations/stats.d.ts +0 -54
  12. package/dist/api/http.d.ts +2 -6
  13. package/dist/api/locations/detail.d.ts +3 -111
  14. package/dist/api/locations/list.d.ts +0 -45
  15. package/dist/api/locations/query.d.ts +2 -1
  16. package/dist/api/locations/routes.d.ts +1 -1
  17. package/dist/api/people/list.d.ts +0 -29
  18. package/dist/api/people/profile.d.ts +2 -106
  19. package/dist/api/people/profile.query.d.ts +2 -1
  20. package/dist/api/people/routes.d.ts +1 -1
  21. package/dist/api/people/shared.d.ts +3 -1
  22. package/dist/api/people/spend.d.ts +3 -4
  23. package/dist/api/personal-tokens/routes.d.ts +2 -2
  24. package/dist/api/route.d.ts +8 -14
  25. package/dist/api/schema/conversation.d.ts +130 -25
  26. package/dist/api/schema/location.d.ts +4 -0
  27. package/dist/api/schema/person.d.ts +7 -3
  28. package/dist/api/schema.d.ts +2 -2
  29. package/dist/api/schema.js +13 -1
  30. package/dist/api/stats.d.ts +0 -13
  31. package/dist/api/validation.d.ts +7 -0
  32. package/dist/api/viewer.d.ts +3 -0
  33. package/dist/api.d.ts +2 -1
  34. package/dist/api.js +772 -561
  35. package/dist/app.js +241 -204
  36. package/dist/{catalog-runtime-M6ZTPYRV.js → catalog-runtime-GAW5APVI.js} +5 -5
  37. package/dist/chat/actor.d.ts +4 -1
  38. package/dist/chat/agent/request.d.ts +2 -0
  39. package/dist/chat/agent/resume.d.ts +1 -0
  40. package/dist/chat/agent-dispatch/context.d.ts +2 -2
  41. package/dist/chat/agent-invocations/types.d.ts +52 -0
  42. package/dist/chat/api-turns/work.d.ts +108 -0
  43. package/dist/chat/app/services.d.ts +1 -1
  44. package/dist/chat/conversations/history.d.ts +60 -0
  45. package/dist/chat/conversations/provenance.d.ts +6 -0
  46. package/dist/chat/conversations/sql/actor-identity.d.ts +19 -0
  47. package/dist/chat/conversations/store.d.ts +1 -1
  48. package/dist/chat/resource-events/store.d.ts +1 -1
  49. package/dist/chat/runtime/reply-executor.d.ts +1 -3
  50. package/dist/chat/runtime/slack-runtime.d.ts +2 -1
  51. package/dist/chat/runtime/turn-preparation.d.ts +9 -0
  52. package/dist/chat/scheduled-tasks/tool-support.d.ts +5 -5
  53. package/dist/chat/scheduled-tasks/tools/create.d.ts +2 -2
  54. package/dist/chat/scheduled-tasks/tools/delete.d.ts +2 -2
  55. package/dist/chat/scheduled-tasks/tools/list.d.ts +2 -2
  56. package/dist/chat/scheduled-tasks/tools/run-now.d.ts +2 -2
  57. package/dist/chat/scheduled-tasks/tools/update.d.ts +2 -2
  58. package/dist/chat/services/conversation-memory.d.ts +2 -2
  59. package/dist/chat/services/conversation-title.d.ts +20 -0
  60. package/dist/chat/slack/assistant-thread/title.d.ts +10 -27
  61. package/dist/chat/slack/channel.d.ts +26 -0
  62. package/dist/chat/slack/dispatch-turn.d.ts +1 -0
  63. package/dist/chat/slack/timestamp-param.d.ts +0 -2
  64. package/dist/chat/slack/{tools → tool-support}/canvas/api.d.ts +1 -1
  65. package/dist/chat/slack/{tools → tool-support}/canvas/context.d.ts +3 -0
  66. package/dist/chat/slack/tool-support/channel-access.d.ts +42 -0
  67. package/dist/chat/slack/tool-support/channel-target.d.ts +27 -0
  68. package/dist/chat/slack/tool-support/list/params.d.ts +5 -0
  69. package/dist/chat/slack/tools/canvas/create.d.ts +1 -1
  70. package/dist/chat/slack/tools/channel-join.d.ts +28 -0
  71. package/dist/chat/slack/tools/channel-list-messages.d.ts +3 -2
  72. package/dist/chat/slack/tools/conversation-message-search.d.ts +2 -8
  73. package/dist/chat/slack/tools/message-add-reaction.d.ts +1 -1
  74. package/dist/chat/slack/tools/public-search.d.ts +63 -2
  75. package/dist/chat/slack/tools/send-files.d.ts +1 -1
  76. package/dist/chat/slack/tools/thread-read.d.ts +2 -5
  77. package/dist/chat/source.d.ts +2 -0
  78. package/dist/chat/state/conversation.d.ts +1 -0
  79. package/dist/chat/task-execution/checkpoint.d.ts +1 -0
  80. package/dist/chat/task-execution/state.d.ts +9 -4
  81. package/dist/chat/task-execution/store.d.ts +3 -2
  82. package/dist/chat/task-execution/turn-cursor.d.ts +2 -0
  83. package/dist/chat/task-execution/worker.d.ts +2 -0
  84. package/dist/chat/tasks/read.d.ts +1 -1
  85. package/dist/chat/tools/search-conversation-events.d.ts +1 -1
  86. package/dist/chat/tools/types.d.ts +11 -4
  87. package/dist/chat/tools/watch-resource-events.d.ts +2 -2
  88. package/dist/{chunk-ORO3PWKQ.js → chunk-25SC7D6Z.js} +1 -1
  89. package/dist/{chunk-GGB4WL5A.js → chunk-2JHKISQA.js} +1 -1
  90. package/dist/{chunk-AVZDSUFB.js → chunk-2P6BQQER.js} +4 -4
  91. package/dist/{chunk-7NVJVJID.js → chunk-32CXPIZE.js} +2 -2
  92. package/dist/{chunk-YSB2N563.js → chunk-3GYZ5YEH.js} +121 -87
  93. package/dist/{chunk-DU74WPIC.js → chunk-3I2IVWSZ.js} +1 -1
  94. package/dist/{chunk-SVHUEHUL.js → chunk-3JVUWLR7.js} +65 -4
  95. package/dist/{chunk-RXBVB2JM.js → chunk-3KGQOKIG.js} +1 -1
  96. package/dist/{chunk-YBVXBNSV.js → chunk-4JGM7FXO.js} +2 -2
  97. package/dist/{chunk-AZ7EAOBE.js → chunk-4YKPOYRV.js} +5 -5
  98. package/dist/chunk-5CWUQXXT.js +806 -0
  99. package/dist/{chunk-DLDRQHG5.js → chunk-6G5RCDKP.js} +1 -1
  100. package/dist/{chunk-AYU72WO7.js → chunk-75DSYFFB.js} +47 -70
  101. package/dist/{chunk-YHDERDRO.js → chunk-7BH46NB4.js} +91 -75
  102. package/dist/{chunk-745QJ3ZA.js → chunk-ALJG73MQ.js} +2 -2
  103. package/dist/chunk-ART7P442.js +48 -0
  104. package/dist/{chunk-7A4M7PCV.js → chunk-DK5UT6PQ.js} +1180 -556
  105. package/dist/{chunk-AIOK6LAG.js → chunk-EW2LNCRL.js} +813 -44
  106. package/dist/chunk-EXW76GW4.js +36 -0
  107. package/dist/chunk-GDFF3BQG.js +136 -0
  108. package/dist/{chunk-7UQIVT6G.js → chunk-JMH3DBM5.js} +6 -6
  109. package/dist/{chunk-CWP5RHVX.js → chunk-JMSMXXED.js} +12 -5
  110. package/dist/{chunk-CSZINQJ2.js → chunk-MEMURSBG.js} +1 -1
  111. package/dist/{chunk-YNTTROJT.js → chunk-QIW7OQEO.js} +1 -1
  112. package/dist/{chunk-Q4R73I43.js → chunk-RB26T3LU.js} +58 -28
  113. package/dist/{chunk-4LJO56OJ.js → chunk-RLVZIWNQ.js} +1 -1
  114. package/dist/{chunk-SGZO7UWH.js → chunk-SWHPVZBV.js} +2 -2
  115. package/dist/{chunk-PVNG6UMU.js → chunk-TFBNBXPU.js} +22 -10
  116. package/dist/{chunk-EFLJ2WJH.js → chunk-URDCZAL4.js} +5 -5
  117. package/dist/{chunk-6H5SZR24.js → chunk-UZGASGOD.js} +300 -383
  118. package/dist/{chunk-YEO3VX72.js → chunk-W7UONUIZ.js} +8 -6
  119. package/dist/{chunk-JUUKWRBE.js → chunk-X22XXSZA.js} +1 -1
  120. package/dist/{chunk-X5UY34KT.js → chunk-XPYWWMHR.js} +8 -8
  121. package/dist/{chunk-IIOOO4FQ.js → chunk-ZYMYLLWG.js} +2 -1
  122. package/dist/cli/chat.js +32 -35
  123. package/dist/cli/check.js +6 -6
  124. package/dist/cli/plugins.js +13 -13
  125. package/dist/cli/snapshot-create.js +9 -9
  126. package/dist/cli/upgrade.js +7 -7
  127. package/dist/db/schema/agent-invocations.d.ts +20 -0
  128. package/dist/db/schema/conversation-annotations.d.ts +2 -2
  129. package/dist/db/schema.d.ts +22 -2
  130. package/dist/{db-CSEW4RII.js → db-JBZLRIVY.js} +7 -7
  131. package/dist/instrumentation.js +4 -4
  132. package/dist/nitro.js +2 -2
  133. package/dist/{oauth-callback-server-FUEV5HNG.js → oauth-callback-server-MNTVYY2I.js} +24 -26
  134. package/dist/{runner-U3XHSKSH.js → runner-K24BWZSZ.js} +23 -25
  135. package/dist/{skills-AKE6W3WI.js → skills-AU5ST2CG.js} +6 -6
  136. package/dist/spawn-6PO7CVJ6.js +38 -0
  137. package/dist/{validation-WDTAULUF.js → validation-IXGZCFRO.js} +6 -6
  138. package/dist/version.js +1 -1
  139. package/dist/{work-C3HAO2BG.js → work-WCZIYILX.js} +18 -19
  140. package/dist/{worker-LNP4YKBM.js → worker-U2AACBEY.js} +11 -10
  141. package/package.json +6 -5
  142. package/dist/api/health.d.ts +0 -7
  143. package/dist/api/personal-tokens/create.d.ts +0 -11
  144. package/dist/api/personal-tokens/list.d.ts +0 -12
  145. package/dist/api/personal-tokens/revoke.d.ts +0 -5
  146. package/dist/api/plugin-reports.d.ts +0 -63
  147. package/dist/api/plugins.d.ts +0 -8
  148. package/dist/api/runtime.d.ts +0 -24
  149. package/dist/api/skills.d.ts +0 -6
  150. package/dist/chat/slack/tools/channel-access.d.ts +0 -30
  151. package/dist/chunk-34GS7B6L.js +0 -115
  152. package/dist/chunk-AVOCH2Z5.js +0 -285
  153. package/dist/chunk-HLXXQI5Q.js +0 -238
  154. package/dist/chunk-K4SZAP3K.js +0 -67
  155. package/dist/chunk-R776HKPK.js +0 -81
  156. package/dist/chunk-Z4YU7Z4L.js +0 -76
  157. package/dist/spawn-B6GDTWJ4.js +0 -39
  158. /package/dist/chat/slack/{tools → tool-support}/canvas/markdown.d.ts +0 -0
  159. /package/dist/chat/slack/{tools → tool-support}/channel-capabilities.d.ts +0 -0
  160. /package/dist/chat/slack/{tools → tool-support}/context.d.ts +0 -0
  161. /package/dist/chat/slack/{tools → tool-support}/list/api.d.ts +0 -0
  162. /package/dist/chat/slack/{tools → tool-support}/slack-message-url.d.ts +0 -0
@@ -1,21 +1,12 @@
1
1
  import {
2
2
  coerceThreadConversationState,
3
- getPersistedThreadState,
4
- persistThreadStateById
5
- } from "./chunk-AZ7EAOBE.js";
6
- import {
7
- recordTaskExecution
8
- } from "./chunk-AVOCH2Z5.js";
3
+ getPersistedThreadState
4
+ } from "./chunk-4YKPOYRV.js";
9
5
  import {
10
6
  pluginTaskId,
11
7
  pluginTaskParamsSchema,
12
8
  sendVercelPluginTask
13
9
  } from "./chunk-5I6ORJUY.js";
14
- import {
15
- calculateContextCompactionTargetTokens,
16
- estimateTextTokens,
17
- getConversationContextCompactionTriggerTokens
18
- } from "./chunk-K4SZAP3K.js";
19
10
  import {
20
11
  buildDeterministicTurnId,
21
12
  clearPendingAuth,
@@ -25,18 +16,14 @@ import {
25
16
  instructionTextForProjection,
26
17
  isToolResultError,
27
18
  isToolResultMessage,
28
- markTurnClosed,
19
+ markConversationMessage,
29
20
  markTurnCompleted,
30
21
  normalizeToolNameFromResult,
31
22
  stripRuntimeTurnContext
32
- } from "./chunk-AIOK6LAG.js";
23
+ } from "./chunk-EW2LNCRL.js";
33
24
  import {
34
25
  JUNIOR_THREAD_STATE_TTL_MS
35
26
  } from "./chunk-3Y47VMHV.js";
36
- import {
37
- fallbackShortTitle,
38
- generateShortTitle
39
- } from "./chunk-Z4YU7Z4L.js";
40
27
  import {
41
28
  createPluginConversationEvents,
42
29
  createPluginEmbedder,
@@ -44,23 +31,25 @@ import {
44
31
  createPluginModel,
45
32
  createPluginState,
46
33
  getPlugins
47
- } from "./chunk-YHDERDRO.js";
34
+ } from "./chunk-7BH46NB4.js";
48
35
  import {
49
36
  getConversationStore,
50
37
  getDb,
51
38
  sameActorIdentity
52
- } from "./chunk-YSB2N563.js";
39
+ } from "./chunk-3GYZ5YEH.js";
40
+ import {
41
+ juniorConversations,
42
+ juniorTaskExecutions
43
+ } from "./chunk-3I2IVWSZ.js";
53
44
  import {
54
45
  getStateAdapter
55
- } from "./chunk-ORO3PWKQ.js";
46
+ } from "./chunk-25SC7D6Z.js";
56
47
  import {
57
48
  ProviderError,
58
- botConfig,
59
- escapeXml,
60
49
  findProviderError,
61
50
  getProviderErrorAttributes,
62
51
  getProviderErrorUserMessage
63
- } from "./chunk-7NVJVJID.js";
52
+ } from "./chunk-32CXPIZE.js";
64
53
  import {
65
54
  credentialSubjectSchema
66
55
  } from "./chunk-RUIXF3YQ.js";
@@ -69,315 +58,8 @@ import {
69
58
  } from "./chunk-F3B2YJ76.js";
70
59
  import {
71
60
  buildTurnFailureResponse,
72
- logWarn,
73
- setSpanAttributes
74
- } from "./chunk-4LJO56OJ.js";
75
-
76
- // src/chat/services/conversation-memory.ts
77
- var CONTEXT_MIN_LIVE_MESSAGES = 12;
78
- var CONTEXT_COMPACTION_BATCH_SIZE = 24;
79
- var CONTEXT_MAX_COMPACTIONS = 16;
80
- var CONTEXT_MAX_MESSAGE_CHARS = 3200;
81
- var SLACK_USER_ID_DISPLAY_PATTERN = /^[UW][A-Z0-9]{5,}$/;
82
- function generateConversationId(prefix) {
83
- return `${prefix}_${Date.now()}_${Math.random().toString(36).slice(2, 10)}`;
84
- }
85
- function normalizeConversationText(text) {
86
- return text.replace(/\r\n?/g, "\n").trim();
87
- }
88
- function buildImageContextSuffix(message, conversation) {
89
- const byFileId = conversation?.vision.byFileId;
90
- const imageFileIds = message.meta?.imageFileIds ?? [];
91
- if (!byFileId || imageFileIds.length === 0) {
92
- return "";
93
- }
94
- const summaries = imageFileIds.map((fileId) => byFileId[fileId]?.summary?.trim()).filter((summary) => Boolean(summary));
95
- if (summaries.length === 0) {
96
- return "";
97
- }
98
- return ` [image context: ${summaries.join(" | ")}]`;
99
- }
100
- function renderConversationMessageLine(message, conversation) {
101
- const displayName = conversationAuthorDisplayName(message);
102
- const text = message.text.replace(/\s+/g, " ").slice(0, CONTEXT_MAX_MESSAGE_CHARS);
103
- const markers = [];
104
- if (message.meta?.replied === false) {
105
- markers.push(
106
- `assistant skipped: ${message.meta?.skippedReason ?? "no-reply route"}`
107
- );
108
- }
109
- if (message.meta?.explicitMention) {
110
- markers.push("explicit mention");
111
- }
112
- const markerSuffix = markers.length > 0 ? ` (${markers.join("; ")})` : "";
113
- const imageContext = buildImageContextSuffix(message, conversation);
114
- return `[${message.role}] ${displayName}: ${text}${imageContext}${markerSuffix}`;
115
- }
116
- function conversationAuthorDisplayName(message) {
117
- const author = message.author;
118
- const fullName = authorDisplayField(author?.fullName, author?.userId);
119
- const userName = authorDisplayField(author?.userName, author?.userId);
120
- return fullName ?? userName ?? (message.role === "assistant" ? botConfig.userName : message.role);
121
- }
122
- function authorDisplayField(value, userId) {
123
- if (!value || value === userId || SLACK_USER_ID_DISPLAY_PATTERN.test(value)) {
124
- return void 0;
125
- }
126
- return value;
127
- }
128
- function estimateConversationContextTokens(conversation) {
129
- return estimateTextTokens(buildConversationContext(conversation) ?? "");
130
- }
131
- function upsertConversationMessage(conversation, message) {
132
- const existingIndex = conversation.messages.findIndex(
133
- (entry) => entry.id === message.id
134
- );
135
- if (existingIndex >= 0) {
136
- conversation.messages[existingIndex] = {
137
- ...conversation.messages[existingIndex],
138
- ...message,
139
- meta: {
140
- ...conversation.messages[existingIndex]?.meta,
141
- ...message.meta
142
- }
143
- };
144
- return message.id;
145
- }
146
- conversation.messages.push(message);
147
- return message.id;
148
- }
149
- function recordDeliveredAssistantMessage(args) {
150
- const prefix = `${args.sessionId}:assistant:`;
151
- const ordinal = args.conversation.messages.filter(
152
- (message) => message.id.startsWith(prefix)
153
- ).length + 1;
154
- const messageId = `${prefix}${ordinal}`;
155
- markConversationMessage(args.conversation, args.userMessageId, {
156
- replied: true,
157
- skippedReason: void 0
158
- });
159
- upsertConversationMessage(args.conversation, {
160
- id: messageId,
161
- role: "assistant",
162
- text: normalizeConversationText(args.text),
163
- createdAtMs: Date.now(),
164
- author: {
165
- userName: botConfig.userName,
166
- isBot: true
167
- },
168
- meta: {
169
- replied: true
170
- }
171
- });
172
- return messageId;
173
- }
174
- function turnHasReply(conversation, turnId) {
175
- const assistantPrefix = `${turnId}:assistant:`;
176
- return conversation.messages.some(
177
- (message) => message.role === "assistant" && message.id.startsWith(assistantPrefix)
178
- );
179
- }
180
- function markConversationMessage(conversation, messageId, patch) {
181
- if (!messageId) return;
182
- const messageIndex = conversation.messages.findIndex(
183
- (entry) => entry.id === messageId
184
- );
185
- if (messageIndex < 0) return;
186
- const current = conversation.messages[messageIndex];
187
- conversation.messages[messageIndex] = {
188
- ...current,
189
- meta: {
190
- ...current.meta ?? {},
191
- ...patch
192
- }
193
- };
194
- }
195
- function buildConversationContext(conversation, options = {}) {
196
- const messages = conversation.messages.filter(
197
- (entry) => entry.id !== options.excludeMessageId
198
- );
199
- if (messages.length === 0 && conversation.compactions.length === 0) {
200
- return void 0;
201
- }
202
- const lines = [];
203
- if (conversation.compactions.length > 0) {
204
- lines.push("<thread-compactions>");
205
- for (const [index, compaction] of conversation.compactions.entries()) {
206
- lines.push(
207
- ` <compaction index="${index + 1}" covered_messages="${compaction.coveredMessageCount}" created_at="${new Date(compaction.createdAtMs).toISOString()}">`,
208
- compaction.summary,
209
- " </compaction>"
210
- );
211
- }
212
- lines.push("</thread-compactions>");
213
- }
214
- if (messages.length > 0) {
215
- if (lines.length > 0) {
216
- lines.push("");
217
- }
218
- lines.push("<thread-transcript>");
219
- for (const [index, message] of messages.entries()) {
220
- const author = escapeXml(conversationAuthorDisplayName(message));
221
- const actorIdAttr = message.author?.userId ? ` actor_id="${escapeXml(message.author.userId)}"` : "";
222
- const ts = new Date(message.createdAtMs).toISOString();
223
- const slackTsAttr = message.meta?.slackTs ? ` slack_ts="${escapeXml(message.meta.slackTs)}"` : "";
224
- lines.push(
225
- ` <message index="${index + 1}" ts="${ts}" role="${message.role}" author="${author}"${actorIdAttr}${slackTsAttr}>`,
226
- renderConversationMessageLine(message, conversation),
227
- " </message>"
228
- );
229
- }
230
- lines.push("</thread-transcript>");
231
- }
232
- return lines.join("\n");
233
- }
234
- function pruneCompactions(compactions) {
235
- if (compactions.length <= CONTEXT_MAX_COMPACTIONS) {
236
- return compactions;
237
- }
238
- const overflowCount = compactions.length - CONTEXT_MAX_COMPACTIONS + 1;
239
- const merged = compactions.slice(0, overflowCount);
240
- const mergedSummary = merged.map((entry) => entry.summary).join("\n").slice(0, 3500);
241
- const coveredMessageCount = merged.reduce(
242
- (count, entry) => count + entry.coveredMessageCount,
243
- 0
244
- );
245
- const compacted = {
246
- id: generateConversationId("compaction"),
247
- createdAtMs: Date.now(),
248
- summary: mergedSummary,
249
- coveredMessageCount
250
- };
251
- return [compacted, ...compactions.slice(overflowCount)];
252
- }
253
- async function summarizeConversationChunk(messages, conversation, context, deps) {
254
- const transcript = messages.map((message) => renderConversationMessageLine(message, conversation)).join("\n");
255
- try {
256
- const result = await deps.completeText({
257
- modelId: botConfig.fastModelId,
258
- temperature: 0,
259
- promptName: "junior.thread_compaction",
260
- messages: [
261
- {
262
- role: "user",
263
- content: [
264
- "Summarize the following older Slack thread transcript segment for future assistant turns.",
265
- "Keep the summary factual and concise. Do not invent details.",
266
- "",
267
- "Output exactly three XML sections in this order:",
268
- "<active-asks> one bullet per outstanding user ask that has not been narrowed, answered, or replaced by a later turn. Omit the section body if none. </active-asks>",
269
- "<resolved-or-replaced-asks> one bullet per ask that has been replaced, narrowed, answered, or already acted on in this segment. Include the replacement/outcome inline. Omit the section body if none. </resolved-or-replaced-asks>",
270
- "<facts> one bullet per durable fact useful regardless of scope: names, ids, URLs, decisions, locations, preferences, constraints that remain true. Omit the section body if none. </facts>",
271
- "",
272
- "Do not output any text outside the three sections.",
273
- "",
274
- transcript
275
- ].join("\n"),
276
- timestamp: Date.now()
277
- }
278
- ],
279
- metadata: {
280
- modelId: botConfig.fastModelId,
281
- threadId: context.threadId ?? "",
282
- channelId: context.channelId ?? "",
283
- actorId: context.actorId ?? "",
284
- runId: context.runId ?? ""
285
- }
286
- });
287
- const summary = result.text.trim();
288
- if (summary.length > 0) {
289
- return summary.slice(0, 3500);
290
- }
291
- } catch (error) {
292
- logWarn("conversation.compaction.summary.failed", {
293
- "exception.message": error instanceof Error ? error.message : String(error),
294
- "app.compaction_messages_covered": messages.length
295
- });
296
- }
297
- return transcript.slice(0, 2800);
298
- }
299
- async function generateThreadTitleWithDeps(sourceText, deps) {
300
- const title = await generateShortTitle({
301
- completeText: deps.completeText,
302
- kind: "conversation",
303
- sourceText
304
- });
305
- return title ?? fallbackShortTitle(sourceText, "Conversation");
306
- }
307
- function getThreadTitleSourceMessage(conversation) {
308
- let firstMessage;
309
- for (const message of conversation.messages) {
310
- if (!isHumanConversationMessage(message)) {
311
- continue;
312
- }
313
- if (!firstMessage) {
314
- firstMessage = message;
315
- continue;
316
- }
317
- if (message.createdAtMs < firstMessage.createdAtMs) {
318
- firstMessage = message;
319
- continue;
320
- }
321
- if (message.createdAtMs === firstMessage.createdAtMs && message.id < firstMessage.id) {
322
- firstMessage = message;
323
- }
324
- }
325
- return firstMessage;
326
- }
327
- async function compactConversationIfNeededWithDeps(conversation, context, deps) {
328
- let estimatedTokens = estimateConversationContextTokens(conversation);
329
- setSpanAttributes({
330
- "app.context_tokens_estimated": estimatedTokens
331
- });
332
- const triggerTokens = getConversationContextCompactionTriggerTokens();
333
- const targetTokens = calculateContextCompactionTargetTokens(triggerTokens);
334
- while (estimatedTokens > triggerTokens && conversation.messages.length > CONTEXT_MIN_LIVE_MESSAGES) {
335
- const compactCount = Math.min(
336
- CONTEXT_COMPACTION_BATCH_SIZE,
337
- conversation.messages.length - CONTEXT_MIN_LIVE_MESSAGES
338
- );
339
- if (compactCount <= 0) {
340
- break;
341
- }
342
- const compactedChunk = conversation.messages.slice(0, compactCount);
343
- const summary = await summarizeConversationChunk(
344
- compactedChunk,
345
- conversation,
346
- context,
347
- deps
348
- );
349
- conversation.compactions.push({
350
- id: generateConversationId("compaction"),
351
- createdAtMs: Date.now(),
352
- summary,
353
- coveredMessageCount: compactedChunk.length
354
- });
355
- conversation.compactions = pruneCompactions(conversation.compactions);
356
- conversation.messages = conversation.messages.slice(compactCount);
357
- estimatedTokens = estimateConversationContextTokens(conversation);
358
- setSpanAttributes({
359
- "app.compaction_messages_covered": compactCount,
360
- "app.compaction.trigger_tokens": triggerTokens,
361
- "app.compaction.target_tokens": targetTokens,
362
- "app.context_tokens_estimated": estimatedTokens
363
- });
364
- if (estimatedTokens <= targetTokens) {
365
- break;
366
- }
367
- }
368
- }
369
- function createConversationMemoryService(deps) {
370
- return {
371
- compactConversationIfNeeded: async (conversation, context) => await compactConversationIfNeededWithDeps(conversation, context, deps),
372
- generateThreadTitle: async (sourceText) => await generateThreadTitleWithDeps(sourceText, deps)
373
- };
374
- }
375
- function isHumanConversationMessage(message) {
376
- return message.role === "user" && message.author?.isBot !== true;
377
- }
378
- function getConversationMessageSlackTs(message) {
379
- return parseSlackMessageTs(message.meta?.slackTs);
380
- }
61
+ logWarn
62
+ } from "./chunk-RLVZIWNQ.js";
381
63
 
382
64
  // src/chat/runtime/delivered-turn-state.ts
383
65
  function buildDeliveredTurnStatePatch(args) {
@@ -399,14 +81,11 @@ function buildDeliveredTurnStatePatch(args) {
399
81
  }
400
82
 
401
83
  // src/chat/plugins/task-runner.ts
402
- import {
403
- isPrivateSource,
404
- pluginRunContextSchema
405
- } from "@sentry/junior-plugin-api";
84
+ import { pluginRunContextSchema } from "@sentry/junior-plugin-api";
406
85
 
407
86
  // src/chat/services/turn-session-routing.ts
408
87
  async function resolveTurnSessionRouting(args) {
409
- const conversationStore = args.conversationStore ?? (await import("./db-CSEW4RII.js")).getConversationStore();
88
+ const conversationStore = args.conversationStore ?? (await import("./db-JBZLRIVY.js")).getConversationStore();
410
89
  const conversation = await conversationStore.get({
411
90
  conversationId: args.conversationId
412
91
  });
@@ -431,6 +110,273 @@ import {
431
110
  sourceSchema
432
111
  } from "@sentry/junior-plugin-api";
433
112
  import { z } from "zod";
113
+
114
+ // src/chat/tasks/execution-stats.ts
115
+ import {
116
+ and,
117
+ asc,
118
+ count,
119
+ desc,
120
+ eq,
121
+ gte,
122
+ inArray,
123
+ lte,
124
+ max,
125
+ or,
126
+ sql
127
+ } from "drizzle-orm";
128
+ var TASK_EXECUTION_TYPES = ["scheduled", "event"];
129
+ var TASK_EXECUTION_STATUSES = [
130
+ "blocked",
131
+ "completed",
132
+ "failed"
133
+ ];
134
+ function utcDate(nowMs) {
135
+ return new Date(nowMs).toISOString().slice(0, 10);
136
+ }
137
+ function emptyDay(date) {
138
+ return { date, event: 0, scheduled: 0 };
139
+ }
140
+ function emptyStatusDay(date) {
141
+ return { blocked: 0, completed: 0, date, failed: 0 };
142
+ }
143
+ async function recordTaskExecution(type, taskId, options) {
144
+ const namespace = options.namespace ?? "junior";
145
+ const nowMs = options.nowMs ?? Date.now();
146
+ const status = options.status ?? "completed";
147
+ try {
148
+ await getDb().insert(juniorTaskExecutions).values({
149
+ ...options.conversationId ? { conversationId: options.conversationId } : {},
150
+ executedAtMs: nowMs,
151
+ executionId: options.executionId,
152
+ kind: type,
153
+ namespace,
154
+ status,
155
+ taskId
156
+ }).onConflictDoNothing({
157
+ target: [
158
+ juniorTaskExecutions.kind,
159
+ juniorTaskExecutions.namespace,
160
+ juniorTaskExecutions.executionId
161
+ ]
162
+ });
163
+ } catch (error) {
164
+ logWarn("task.execution.stat_failed", {
165
+ error,
166
+ "app.task.execution.id": options.executionId,
167
+ "app.task.execution.namespace": namespace,
168
+ "app.task.execution.status": status,
169
+ "app.task.execution.task_id": taskId,
170
+ "app.task.execution.type": type
171
+ });
172
+ }
173
+ }
174
+ async function readTaskExecutionSummaries(type, namespace, options = {}) {
175
+ const sevenDaysAgoMs = (options.nowMs ?? Date.now()) - 7 * 24 * 60 * 60 * 1e3;
176
+ const db = getDb();
177
+ const latest = db.selectDistinctOn([juniorTaskExecutions.taskId], {
178
+ conversationId: juniorTaskExecutions.conversationId,
179
+ taskId: juniorTaskExecutions.taskId
180
+ }).from(juniorTaskExecutions).where(
181
+ and(
182
+ eq(juniorTaskExecutions.kind, type),
183
+ eq(juniorTaskExecutions.namespace, namespace)
184
+ )
185
+ ).orderBy(
186
+ juniorTaskExecutions.taskId,
187
+ desc(juniorTaskExecutions.executedAtMs),
188
+ desc(juniorTaskExecutions.executionId)
189
+ ).as("latest_task_execution");
190
+ const rows = await db.select({
191
+ lastConversationId: latest.conversationId,
192
+ lastExecutedAtMs: max(juniorTaskExecutions.executedAtMs),
193
+ runsLast7Days: sql`count(*) filter (where ${juniorTaskExecutions.executedAtMs} >= ${sevenDaysAgoMs})::int`,
194
+ taskId: juniorTaskExecutions.taskId,
195
+ totalRuns: sql`count(*)::int`
196
+ }).from(juniorTaskExecutions).innerJoin(latest, eq(latest.taskId, juniorTaskExecutions.taskId)).where(
197
+ and(
198
+ eq(juniorTaskExecutions.kind, type),
199
+ eq(juniorTaskExecutions.namespace, namespace)
200
+ )
201
+ ).groupBy(juniorTaskExecutions.taskId, latest.conversationId);
202
+ return new Map(
203
+ rows.map((row) => [
204
+ row.taskId,
205
+ {
206
+ ...row.lastConversationId ? { lastConversationId: row.lastConversationId } : {},
207
+ ...row.lastExecutedAtMs !== null ? { lastExecutedAtMs: row.lastExecutedAtMs } : {},
208
+ runsLast7Days: row.runsLast7Days,
209
+ totalRuns: row.totalRuns
210
+ }
211
+ ])
212
+ );
213
+ }
214
+ async function readTaskExecutionDays(dayCount = 90, options = {}) {
215
+ const nowMs = options.nowMs ?? Date.now();
216
+ const end = utcDate(nowMs);
217
+ const endMs = Date.parse(`${end}T23:59:59.999Z`);
218
+ const startMs = Date.parse(`${end}T00:00:00.000Z`) - (dayCount - 1) * 864e5;
219
+ const executionDate = sql`to_char(to_timestamp(${juniorTaskExecutions.executedAtMs} / 1000.0) at time zone 'UTC', 'YYYY-MM-DD')`;
220
+ const rows = await getDb().select({
221
+ count: count(),
222
+ date: executionDate,
223
+ kind: juniorTaskExecutions.kind
224
+ }).from(juniorTaskExecutions).where(
225
+ and(
226
+ gte(juniorTaskExecutions.executedAtMs, startMs),
227
+ lte(juniorTaskExecutions.executedAtMs, endMs),
228
+ eq(juniorTaskExecutions.status, "completed")
229
+ )
230
+ ).groupBy(executionDate, juniorTaskExecutions.kind).orderBy(asc(executionDate), asc(juniorTaskExecutions.kind));
231
+ const byDate = /* @__PURE__ */ new Map();
232
+ for (let offset = 0; offset < dayCount; offset += 1) {
233
+ const date = utcDate(startMs + offset * 864e5);
234
+ byDate.set(date, emptyDay(date));
235
+ }
236
+ for (const row of rows) {
237
+ const day = byDate.get(row.date);
238
+ if (!day) continue;
239
+ if (row.kind === "scheduled") day.scheduled = row.count;
240
+ else if (row.kind === "event") day.event = row.count;
241
+ }
242
+ return [...byDate.values()];
243
+ }
244
+ async function readTaskExecutionByConversationId(args) {
245
+ const namespace = args.namespace ?? "junior";
246
+ const rows = await getDb().select({
247
+ kind: juniorTaskExecutions.kind,
248
+ taskId: juniorTaskExecutions.taskId
249
+ }).from(juniorTaskExecutions).where(
250
+ and(
251
+ eq(juniorTaskExecutions.conversationId, args.conversationId),
252
+ eq(juniorTaskExecutions.namespace, namespace),
253
+ inArray(juniorTaskExecutions.kind, [...TASK_EXECUTION_TYPES])
254
+ )
255
+ ).orderBy(
256
+ desc(juniorTaskExecutions.executedAtMs),
257
+ desc(juniorTaskExecutions.executionId)
258
+ ).limit(1);
259
+ const row = rows[0];
260
+ if (!row) return void 0;
261
+ if (row.kind !== "scheduled" && row.kind !== "event") return void 0;
262
+ return { kind: row.kind, taskId: row.taskId };
263
+ }
264
+ async function readTaskExecutions(args) {
265
+ const namespace = args.namespace ?? "junior";
266
+ const rows = await getDb().select({
267
+ conversationId: juniorTaskExecutions.conversationId,
268
+ executedAtMs: juniorTaskExecutions.executedAtMs,
269
+ executionId: juniorTaskExecutions.executionId,
270
+ status: juniorTaskExecutions.status,
271
+ title: juniorConversations.title
272
+ }).from(juniorTaskExecutions).leftJoin(
273
+ juniorConversations,
274
+ eq(
275
+ juniorConversations.conversationId,
276
+ juniorTaskExecutions.conversationId
277
+ )
278
+ ).where(
279
+ and(
280
+ eq(juniorTaskExecutions.kind, args.kind),
281
+ eq(juniorTaskExecutions.namespace, namespace),
282
+ eq(juniorTaskExecutions.taskId, args.taskId)
283
+ )
284
+ ).orderBy(
285
+ desc(juniorTaskExecutions.executedAtMs),
286
+ desc(juniorTaskExecutions.executionId)
287
+ ).limit(args.limit);
288
+ return rows.map((row) => {
289
+ const title = row.title?.trim();
290
+ return {
291
+ ...row.conversationId ? { conversationId: row.conversationId } : {},
292
+ executedAt: new Date(row.executedAtMs).toISOString(),
293
+ executionId: row.executionId,
294
+ status: row.status,
295
+ ...title ? { title } : {}
296
+ };
297
+ });
298
+ }
299
+ async function readTaskRuns(args) {
300
+ if (args.tasks.length === 0) return [];
301
+ const namespace = args.namespace ?? "junior";
302
+ const selectors = args.tasks.map(
303
+ (task) => and(
304
+ eq(juniorTaskExecutions.kind, task.kind),
305
+ eq(juniorTaskExecutions.taskId, task.taskId)
306
+ )
307
+ );
308
+ const rows = await getDb().select({
309
+ conversationId: juniorTaskExecutions.conversationId,
310
+ executedAtMs: juniorTaskExecutions.executedAtMs,
311
+ executionId: juniorTaskExecutions.executionId,
312
+ kind: juniorTaskExecutions.kind,
313
+ status: juniorTaskExecutions.status,
314
+ taskId: juniorTaskExecutions.taskId,
315
+ title: juniorConversations.title
316
+ }).from(juniorTaskExecutions).leftJoin(
317
+ juniorConversations,
318
+ eq(
319
+ juniorConversations.conversationId,
320
+ juniorTaskExecutions.conversationId
321
+ )
322
+ ).where(and(eq(juniorTaskExecutions.namespace, namespace), or(...selectors))).orderBy(
323
+ desc(juniorTaskExecutions.executedAtMs),
324
+ desc(juniorTaskExecutions.executionId)
325
+ ).limit(args.limit);
326
+ return rows.flatMap((row) => {
327
+ if (row.kind !== "scheduled" && row.kind !== "event") return [];
328
+ const title = row.title?.trim();
329
+ return [
330
+ {
331
+ ...row.conversationId ? { conversationId: row.conversationId } : {},
332
+ executedAt: new Date(row.executedAtMs).toISOString(),
333
+ executionId: row.executionId,
334
+ kind: row.kind,
335
+ status: row.status,
336
+ taskId: row.taskId,
337
+ ...title ? { title } : {}
338
+ }
339
+ ];
340
+ });
341
+ }
342
+ async function readTaskExecutionStatusDays(args) {
343
+ const dayCount = args.dayCount ?? 90;
344
+ const namespace = args.namespace ?? "junior";
345
+ const nowMs = args.nowMs ?? Date.now();
346
+ const end = utcDate(nowMs);
347
+ const endMs = Date.parse(`${end}T23:59:59.999Z`);
348
+ const startMs = Date.parse(`${end}T00:00:00.000Z`) - (dayCount - 1) * 864e5;
349
+ const executionDate = sql`to_char(to_timestamp(${juniorTaskExecutions.executedAtMs} / 1000.0) at time zone 'UTC', 'YYYY-MM-DD')`;
350
+ const rows = await getDb().select({
351
+ count: count(),
352
+ date: executionDate,
353
+ status: juniorTaskExecutions.status
354
+ }).from(juniorTaskExecutions).where(
355
+ and(
356
+ eq(juniorTaskExecutions.kind, args.kind),
357
+ eq(juniorTaskExecutions.namespace, namespace),
358
+ eq(juniorTaskExecutions.taskId, args.taskId),
359
+ gte(juniorTaskExecutions.executedAtMs, startMs),
360
+ lte(juniorTaskExecutions.executedAtMs, endMs),
361
+ inArray(juniorTaskExecutions.status, [...TASK_EXECUTION_STATUSES])
362
+ )
363
+ ).groupBy(executionDate, juniorTaskExecutions.status).orderBy(asc(executionDate), asc(juniorTaskExecutions.status));
364
+ const byDate = /* @__PURE__ */ new Map();
365
+ for (let offset = 0; offset < dayCount; offset += 1) {
366
+ const date = utcDate(startMs + offset * 864e5);
367
+ byDate.set(date, emptyStatusDay(date));
368
+ }
369
+ for (const row of rows) {
370
+ const day = byDate.get(row.date);
371
+ if (!day) continue;
372
+ if (row.status === "completed") day.completed = row.count;
373
+ else if (row.status === "failed") day.failed = row.count;
374
+ else if (row.status === "blocked") day.blocked = row.count;
375
+ }
376
+ return [...byDate.values()];
377
+ }
378
+
379
+ // src/chat/agent-dispatch/store.ts
434
380
  var DISPATCH_PREFIX = "junior:agent_dispatch";
435
381
  var DISPATCH_LOCK_TTL_MS = 10 * 60 * 1e3;
436
382
  var DISPATCH_MAILBOX_APPEND_INDEX_LOCK_TTL_MS = 1e4;
@@ -942,8 +888,15 @@ function messageExistedAtRunCompletion(message, completedAtMs) {
942
888
  return messageTimestampMs !== void 0 && messageTimestampMs <= completedAtMs;
943
889
  }
944
890
  async function loadConversationContextTranscriptEntries(record, source, runActor) {
945
- if (source.platform !== "slack" || isPrivateSource(source)) {
946
- return [];
891
+ switch (source.platform) {
892
+ case "slack":
893
+ if (source.visibility === "private") {
894
+ return [];
895
+ }
896
+ break;
897
+ case "web":
898
+ case "local":
899
+ return [];
947
900
  }
948
901
  const state = await getPersistedThreadState(record.conversationId);
949
902
  const conversation = coerceThreadConversationState(state);
@@ -1230,37 +1183,14 @@ function getTurnUserReplyAttachmentContext(message) {
1230
1183
  };
1231
1184
  }
1232
1185
 
1233
- // src/chat/runtime/auth-pause-state.ts
1234
- function completeAuthPauseTurn(args) {
1235
- markConversationMessage(
1236
- args.conversation,
1237
- getTurnUserMessageId(args.conversation, args.sessionId),
1238
- {
1239
- replied: true,
1240
- skippedReason: void 0
1241
- }
1242
- );
1243
- markTurnClosed({
1244
- conversation: args.conversation,
1245
- nowMs: Date.now(),
1246
- sessionId: args.sessionId
1247
- });
1248
- }
1249
- async function persistAuthPauseTurnState(args) {
1250
- const currentState = await getPersistedThreadState(args.threadStateId);
1251
- const conversation = coerceThreadConversationState(currentState);
1252
- await hydrateConversationMessages({
1253
- conversation,
1254
- conversationId: args.threadStateId
1255
- });
1256
- completeAuthPauseTurn({
1257
- conversation,
1258
- sessionId: args.sessionId
1259
- });
1260
- await persistThreadStateById(args.threadStateId, { conversation });
1261
- }
1262
-
1263
1186
  export {
1187
+ recordTaskExecution,
1188
+ readTaskExecutionSummaries,
1189
+ readTaskExecutionDays,
1190
+ readTaskExecutionByConversationId,
1191
+ readTaskExecutions,
1192
+ readTaskRuns,
1193
+ readTaskExecutionStatusDays,
1264
1194
  getDispatchConversationId,
1265
1195
  getDispatchInputMessageId,
1266
1196
  getDispatchInputMessageIds,
@@ -1277,17 +1207,6 @@ export {
1277
1207
  listPendingDispatchMailboxAppends,
1278
1208
  claimDispatchMailboxAppend,
1279
1209
  getPluginDispatchProjection,
1280
- normalizeConversationText,
1281
- estimateConversationContextTokens,
1282
- upsertConversationMessage,
1283
- recordDeliveredAssistantMessage,
1284
- turnHasReply,
1285
- markConversationMessage,
1286
- buildConversationContext,
1287
- getThreadTitleSourceMessage,
1288
- createConversationMemoryService,
1289
- isHumanConversationMessage,
1290
- getConversationMessageSlackTs,
1291
1210
  buildDeliveredTurnStatePatch,
1292
1211
  getTurnUserMessage,
1293
1212
  getTurnUserMessageId,
@@ -1299,7 +1218,5 @@ export {
1299
1218
  getInterruptionMarker,
1300
1219
  requireTurnFailureEventId,
1301
1220
  getAgentTurnDiagnosticsAttributes,
1302
- finalizeFailedTurnReplyWithEvent,
1303
- completeAuthPauseTurn,
1304
- persistAuthPauseTurnState
1221
+ finalizeFailedTurnReplyWithEvent
1305
1222
  };