@sentry/junior 0.94.0 → 0.96.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 (127) hide show
  1. package/dist/{agent-hooks-ZG7IDOIN.js → agent-hooks-5URSMY3O.js} +10 -11
  2. package/dist/api/people/list.js +8 -8
  3. package/dist/api/people/profile.js +8 -8
  4. package/dist/api/people/shared.d.ts +2 -2
  5. package/dist/api-reference.d.ts +2 -2
  6. package/dist/app.js +434 -199
  7. package/dist/{catalog-runtime-NZHMSMYC.js → catalog-runtime-MSMAYYIK.js} +4 -4
  8. package/dist/chat/advisor-request.d.ts +4 -0
  9. package/dist/chat/agent/request.d.ts +2 -0
  10. package/dist/chat/agent/resume.d.ts +2 -0
  11. package/dist/chat/conversations/history.d.ts +128 -0
  12. package/dist/chat/conversations/legacy-import.d.ts +38 -0
  13. package/dist/chat/conversations/messages.d.ts +39 -0
  14. package/dist/chat/conversations/projection.d.ts +94 -0
  15. package/dist/chat/conversations/retention.d.ts +36 -0
  16. package/dist/chat/conversations/sql/conversation-row.d.ts +14 -0
  17. package/dist/chat/conversations/sql/history.d.ts +4 -0
  18. package/dist/chat/conversations/sql/legacy-history-import.d.ts +55 -0
  19. package/dist/chat/conversations/sql/messages.d.ts +4 -0
  20. package/dist/chat/conversations/sql/migrations.d.ts +14 -3
  21. package/dist/chat/conversations/sql/purge.d.ts +53 -0
  22. package/dist/chat/conversations/sql/store.d.ts +7 -2
  23. package/dist/chat/conversations/store.d.ts +19 -0
  24. package/dist/chat/conversations/visible-compactions.d.ts +11 -0
  25. package/dist/chat/conversations/visible-messages.d.ts +47 -0
  26. package/dist/chat/db.d.ts +12 -1
  27. package/dist/chat/identities/sql.d.ts +1 -1
  28. package/dist/chat/logging.d.ts +4 -3
  29. package/dist/chat/plugins/auth/oauth-request.d.ts +2 -0
  30. package/dist/chat/resource-events/notification.d.ts +2 -0
  31. package/dist/chat/resource-events/store.d.ts +2 -1
  32. package/dist/chat/runtime/agent-run-outcome.d.ts +3 -0
  33. package/dist/chat/runtime/reply-executor.d.ts +8 -0
  34. package/dist/chat/runtime/thread-state.d.ts +2 -0
  35. package/dist/chat/sandbox/resources.d.ts +4 -0
  36. package/dist/chat/sentry.d.ts +1 -1
  37. package/dist/chat/services/mcp-auth-orchestration.d.ts +8 -0
  38. package/dist/chat/services/plugin-auth-orchestration.d.ts +12 -0
  39. package/dist/chat/services/turn-session-record.d.ts +14 -2
  40. package/dist/chat/sleep.d.ts +2 -0
  41. package/dist/chat/state/conversation.d.ts +7 -4
  42. package/dist/chat/state/session-log.d.ts +23 -1
  43. package/dist/chat/state/turn-session.d.ts +9 -1
  44. package/dist/chat/tool-support/private-trace-result.d.ts +4 -0
  45. package/dist/chat/tool-support/zod-tool.d.ts +1 -0
  46. package/dist/chat/tools/advisor/tool.d.ts +9 -4
  47. package/dist/chat/tools/definition.d.ts +2 -0
  48. package/dist/chat/tools/execution/tool-error-handler.d.ts +2 -2
  49. package/dist/chat/tools/system-time.d.ts +8 -0
  50. package/dist/chat/usage.d.ts +27 -13
  51. package/dist/chat/xml.d.ts +2 -0
  52. package/dist/{chunk-TNUUATT7.js → chunk-2NAZZPPS.js} +2 -2
  53. package/dist/{chunk-NYWPISSO.js → chunk-2XXEKR44.js} +1 -1
  54. package/dist/chunk-5C6XTTFI.js +1037 -0
  55. package/dist/{chunk-3DA7X2U3.js → chunk-6GWA276C.js} +15 -0
  56. package/dist/{chunk-LFLTJQVR.js → chunk-7FBGKXPE.js} +4 -0
  57. package/dist/{chunk-LNCREA5Z.js → chunk-AAZXTVJT.js} +4 -128
  58. package/dist/{chunk-GHGPTPBL.js → chunk-B7PUBQQM.js} +1 -1
  59. package/dist/{chunk-6H4PP63X.js → chunk-BYZWPRJA.js} +24 -14
  60. package/dist/chunk-CM5EZD5F.js +17 -0
  61. package/dist/{chunk-G3E7SCME.js → chunk-CZEX6KIQ.js} +23 -0
  62. package/dist/{chunk-YJ4OPVNA.js → chunk-DZENG5ML.js} +1 -1
  63. package/dist/{chunk-QGEWC27H.js → chunk-GQ3GK22G.js} +5 -7
  64. package/dist/{chunk-YYBX2BD5.js → chunk-GY34VGP5.js} +1 -1
  65. package/dist/{chunk-S6QKIGRM.js → chunk-I35CTGPO.js} +71 -29
  66. package/dist/{chunk-KRMANDHI.js → chunk-IYM2SIVG.js} +1489 -355
  67. package/dist/{chunk-BTH37NCU.js → chunk-L7CDEIVJ.js} +12 -4
  68. package/dist/chunk-MNTINMWR.js +865 -0
  69. package/dist/{chunk-MAVOJ54A.js → chunk-P3YFQLEN.js} +25 -388
  70. package/dist/{chunk-YTNPU7I2.js → chunk-PMNN6ST4.js} +2 -2
  71. package/dist/{chunk-PFXC67GJ.js → chunk-RAIB6WSG.js} +6 -80
  72. package/dist/{chunk-NFXSLTYG.js → chunk-RITD7E5L.js} +864 -62
  73. package/dist/{chunk-UUB3D2XI.js → chunk-S5KZ5LPG.js} +8 -10
  74. package/dist/{chunk-HDNWZMUN.js → chunk-UKHVMPX5.js} +112 -103
  75. package/dist/chunk-WM6KHPBQ.js +48 -0
  76. package/dist/{chunk-MC4ZZE4Q.js → chunk-YDT7SNCN.js} +1 -1
  77. package/dist/{chunk-NAPITCZ6.js → chunk-YDVEH3SB.js} +251 -6
  78. package/dist/cli/chat.js +25 -24
  79. package/dist/cli/check.js +5 -5
  80. package/dist/cli/main.js +1 -1
  81. package/dist/cli/plugins.js +12 -13
  82. package/dist/cli/snapshot-warmup.js +8 -9
  83. package/dist/cli/upgrade.js +79 -18
  84. package/dist/db/schema/agent-steps.d.ts +134 -0
  85. package/dist/db/schema/conversation-messages.d.ts +153 -0
  86. package/dist/{chat/conversations/sql → db}/schema/conversations.d.ts +34 -0
  87. package/dist/{chat/conversations/sql → db}/schema.d.ts +319 -8
  88. package/dist/db-2D6RMG67.js +24 -0
  89. package/dist/deployment.d.ts +2 -0
  90. package/dist/handlers/retention.d.ts +6 -0
  91. package/dist/instrumentation.js +17 -4
  92. package/dist/legacy-import-VZ2MEGP7.js +17 -0
  93. package/dist/nitro.js +14 -4
  94. package/dist/reporting/conversations/activity.d.ts +40 -0
  95. package/dist/reporting/conversations/context.d.ts +8 -0
  96. package/dist/reporting/conversations/details.d.ts +6 -0
  97. package/dist/reporting/conversations/index.d.ts +4 -0
  98. package/dist/reporting/conversations/shared.d.ts +9 -0
  99. package/dist/reporting/conversations/statistics.d.ts +4 -0
  100. package/dist/reporting/conversations/summaries.d.ts +20 -0
  101. package/dist/reporting/conversations/transcript.d.ts +28 -0
  102. package/dist/reporting/conversations/types.d.ts +191 -0
  103. package/dist/reporting/conversations.d.ts +1 -178
  104. package/dist/reporting.d.ts +5 -4
  105. package/dist/reporting.js +703 -837
  106. package/dist/{runner-XAZPJNAQ.js → runner-JZBRQP4F.js} +36 -42
  107. package/dist/{sentry-EGFOV3DH.js → sentry-JMWTS32N.js} +11 -1
  108. package/dist/{validation-KYAWETI4.js → validation-6XOOQGME.js} +5 -5
  109. package/migrations/README.md +32 -0
  110. package/migrations/meta/0000_snapshot.json +978 -0
  111. package/migrations/meta/_journal.json +13 -0
  112. package/package.json +10 -7
  113. package/dist/chat/sql/schema.d.ts +0 -1049
  114. package/dist/chat/state/conversation-details.d.ts +0 -47
  115. package/dist/chunk-7STN2ZSK.js +0 -250
  116. package/dist/chunk-LE5ANBUZ.js +0 -1040
  117. package/dist/chunk-QL66APYJ.js +0 -1377
  118. package/dist/db-YDN6AFJH.js +0 -18
  119. /package/dist/{chat/sql → db}/db.d.ts +0 -0
  120. /package/dist/{chat/sql → db}/executor.d.ts +0 -0
  121. /package/dist/{chat/sql → db}/neon.d.ts +0 -0
  122. /package/dist/{chat/sql → db}/postgres.d.ts +0 -0
  123. /package/dist/{chat/conversations/sql → db}/schema/destinations.d.ts +0 -0
  124. /package/dist/{chat/conversations/sql → db}/schema/identities.d.ts +0 -0
  125. /package/dist/{chat/conversations/sql → db}/schema/migrations.d.ts +0 -0
  126. /package/dist/{chat/conversations/sql → db}/schema/timestamps.d.ts +0 -0
  127. /package/dist/{chat/conversations/sql → db}/schema/users.d.ts +0 -0
@@ -5,409 +5,54 @@ import {
5
5
  } from "./chunk-KNFROR7R.js";
6
6
  import {
7
7
  clearPendingAuth,
8
+ getInterruptionMarker,
8
9
  getPersistedThreadState,
9
10
  markTurnCompleted,
10
11
  mergeArtifactsState
11
- } from "./chunk-HDNWZMUN.js";
12
+ } from "./chunk-UKHVMPX5.js";
12
13
  import {
13
14
  coerceThreadConversationState
14
- } from "./chunk-PFXC67GJ.js";
15
+ } from "./chunk-RAIB6WSG.js";
15
16
  import {
16
- getAgentTurnSessionRecord,
17
- getInterruptionMarker
18
- } from "./chunk-QL66APYJ.js";
17
+ getAgentTurnSessionRecord
18
+ } from "./chunk-MNTINMWR.js";
19
+ import {
20
+ generateConversationId,
21
+ hydrateConversationMessages,
22
+ markConversationMessage,
23
+ normalizeConversationText,
24
+ updateConversationStats,
25
+ upsertConversationMessage
26
+ } from "./chunk-5C6XTTFI.js";
19
27
  import {
20
28
  createPluginEmbedder,
21
29
  createPluginModel,
22
30
  getPlugins
23
- } from "./chunk-UUB3D2XI.js";
31
+ } from "./chunk-S5KZ5LPG.js";
24
32
  import {
25
33
  createPluginLogger,
26
34
  createPluginState
27
- } from "./chunk-TNUUATT7.js";
28
- import {
29
- getStateAdapter
30
- } from "./chunk-7STN2ZSK.js";
35
+ } from "./chunk-2NAZZPPS.js";
31
36
  import {
32
37
  getDb
33
- } from "./chunk-NFXSLTYG.js";
38
+ } from "./chunk-RITD7E5L.js";
34
39
  import {
35
40
  GEN_AI_PROVIDER_NAME,
36
41
  botConfig,
37
- escapeXml,
38
42
  getPiMessageRole,
43
+ getStateAdapter,
39
44
  instructionTextForProjection,
40
45
  isToolResultError,
41
46
  isToolResultMessage,
42
47
  normalizeToolNameFromResult,
43
- resolveGatewayModel,
44
48
  stripRuntimeTurnContext
45
- } from "./chunk-NAPITCZ6.js";
49
+ } from "./chunk-YDVEH3SB.js";
46
50
  import {
47
- buildTurnFailureResponse,
48
- logWarn,
49
- setSpanAttributes
50
- } from "./chunk-S6QKIGRM.js";
51
+ buildTurnFailureResponse
52
+ } from "./chunk-I35CTGPO.js";
51
53
  import {
52
54
  parseSlackMessageTs
53
- } from "./chunk-LFLTJQVR.js";
54
-
55
- // src/chat/services/context-budget.ts
56
- var COMPACTION_TRIGGER_INPUT_RATIO = 0.75;
57
- var COMPACTION_OUTPUT_RESERVE_RATIO = 0.25;
58
- var COMPACTION_TARGET_RATIO = 0.8;
59
- var FALLBACK_CONTEXT_WINDOW_TOKENS = 4e5;
60
- var FALLBACK_MAX_OUTPUT_TOKENS = 128e3;
61
- function positiveInteger(value, fallback) {
62
- return Number.isFinite(value) && value > 0 ? Math.floor(value) : fallback;
63
- }
64
- function estimateTextTokens(text) {
65
- return Math.ceil(text.length / 4);
66
- }
67
- function calculateContextCompactionTriggerTokens(model) {
68
- const contextWindow = positiveInteger(
69
- model.contextWindow,
70
- FALLBACK_CONTEXT_WINDOW_TOKENS
71
- );
72
- const maxTokens = positiveInteger(
73
- model.maxTokens,
74
- FALLBACK_MAX_OUTPUT_TOKENS
75
- );
76
- const outputReserve = Math.min(
77
- maxTokens,
78
- Math.floor(contextWindow * COMPACTION_OUTPUT_RESERVE_RATIO)
79
- );
80
- const usableInputTokens = Math.max(1, contextWindow - outputReserve);
81
- return Math.max(
82
- 1,
83
- Math.floor(usableInputTokens * COMPACTION_TRIGGER_INPUT_RATIO)
84
- );
85
- }
86
- function calculateContextCompactionTargetTokens(triggerTokens) {
87
- return Math.max(1, Math.floor(triggerTokens * COMPACTION_TARGET_RATIO));
88
- }
89
- function getAgentContextCompactionTriggerTokens() {
90
- const model = resolveGatewayModel(botConfig.modelId);
91
- return calculateContextCompactionTriggerTokens({
92
- contextWindow: botConfig.modelContextWindowTokens ?? model.contextWindow,
93
- maxTokens: model.maxTokens
94
- });
95
- }
96
- function getConversationContextCompactionTriggerTokens() {
97
- const model = resolveGatewayModel(botConfig.fastModelId);
98
- return calculateContextCompactionTriggerTokens({
99
- contextWindow: model.contextWindow,
100
- maxTokens: model.maxTokens
101
- });
102
- }
103
-
104
- // src/chat/services/conversation-memory.ts
105
- var CONTEXT_MIN_LIVE_MESSAGES = 12;
106
- var CONTEXT_COMPACTION_BATCH_SIZE = 24;
107
- var CONTEXT_MAX_COMPACTIONS = 16;
108
- var CONTEXT_MAX_MESSAGE_CHARS = 3200;
109
- var SLACK_USER_ID_DISPLAY_PATTERN = /^[UW][A-Z0-9]{5,}$/;
110
- function generateConversationId(prefix) {
111
- return `${prefix}_${Date.now()}_${Math.random().toString(36).slice(2, 10)}`;
112
- }
113
- function normalizeConversationText(text) {
114
- return text.trim().replace(/\s+/g, " ").slice(0, CONTEXT_MAX_MESSAGE_CHARS);
115
- }
116
- function buildImageContextSuffix(message, conversation) {
117
- const byFileId = conversation?.vision.byFileId;
118
- const imageFileIds = message.meta?.imageFileIds ?? [];
119
- if (!byFileId || imageFileIds.length === 0) {
120
- return "";
121
- }
122
- const summaries = imageFileIds.map((fileId) => byFileId[fileId]?.summary?.trim()).filter((summary) => Boolean(summary));
123
- if (summaries.length === 0) {
124
- return "";
125
- }
126
- return ` [image context: ${summaries.join(" | ")}]`;
127
- }
128
- function renderConversationMessageLine(message, conversation) {
129
- const displayName = conversationAuthorDisplayName(message);
130
- const markers = [];
131
- if (message.meta?.replied === false) {
132
- markers.push(
133
- `assistant skipped: ${message.meta?.skippedReason ?? "no-reply route"}`
134
- );
135
- }
136
- if (message.meta?.explicitMention) {
137
- markers.push("explicit mention");
138
- }
139
- const markerSuffix = markers.length > 0 ? ` (${markers.join("; ")})` : "";
140
- const imageContext = buildImageContextSuffix(message, conversation);
141
- return `[${message.role}] ${displayName}: ${message.text}${imageContext}${markerSuffix}`;
142
- }
143
- function conversationAuthorDisplayName(message) {
144
- const author = message.author;
145
- const fullName = authorDisplayField(author?.fullName, author?.userId);
146
- const userName = authorDisplayField(author?.userName, author?.userId);
147
- return fullName ?? userName ?? (message.role === "assistant" ? botConfig.userName : message.role);
148
- }
149
- function authorDisplayField(value, userId) {
150
- if (!value || value === userId || SLACK_USER_ID_DISPLAY_PATTERN.test(value)) {
151
- return void 0;
152
- }
153
- return value;
154
- }
155
- function updateConversationStats(conversation) {
156
- const contextText = buildConversationContext(conversation);
157
- conversation.stats.estimatedContextTokens = estimateTextTokens(
158
- contextText ?? ""
159
- );
160
- conversation.stats.totalMessageCount = conversation.messages.length;
161
- conversation.stats.updatedAtMs = Date.now();
162
- }
163
- function upsertConversationMessage(conversation, message) {
164
- const existingIndex = conversation.messages.findIndex(
165
- (entry) => entry.id === message.id
166
- );
167
- if (existingIndex >= 0) {
168
- conversation.messages[existingIndex] = {
169
- ...conversation.messages[existingIndex],
170
- ...message,
171
- meta: {
172
- ...conversation.messages[existingIndex]?.meta,
173
- ...message.meta
174
- }
175
- };
176
- updateConversationStats(conversation);
177
- return message.id;
178
- }
179
- conversation.messages.push(message);
180
- updateConversationStats(conversation);
181
- return message.id;
182
- }
183
- function markConversationMessage(conversation, messageId, patch) {
184
- if (!messageId) return;
185
- const messageIndex = conversation.messages.findIndex(
186
- (entry) => entry.id === messageId
187
- );
188
- if (messageIndex < 0) return;
189
- const current = conversation.messages[messageIndex];
190
- conversation.messages[messageIndex] = {
191
- ...current,
192
- meta: {
193
- ...current.meta ?? {},
194
- ...patch
195
- }
196
- };
197
- updateConversationStats(conversation);
198
- }
199
- function buildConversationContext(conversation, options = {}) {
200
- const messages = conversation.messages.filter(
201
- (entry) => entry.id !== options.excludeMessageId
202
- );
203
- if (messages.length === 0 && conversation.compactions.length === 0) {
204
- return void 0;
205
- }
206
- const lines = [];
207
- if (conversation.compactions.length > 0) {
208
- lines.push("<thread-compactions>");
209
- for (const [index, compaction] of conversation.compactions.entries()) {
210
- lines.push(
211
- ` <compaction index="${index + 1}" covered_messages="${compaction.coveredMessageIds.length}" created_at="${new Date(compaction.createdAtMs).toISOString()}">`,
212
- compaction.summary,
213
- " </compaction>"
214
- );
215
- }
216
- lines.push("</thread-compactions>");
217
- }
218
- if (messages.length > 0) {
219
- if (lines.length > 0) {
220
- lines.push("");
221
- }
222
- lines.push("<thread-transcript>");
223
- for (const [index, message] of messages.entries()) {
224
- const author = escapeXml(conversationAuthorDisplayName(message));
225
- const actorIdAttr = message.author?.userId ? ` actor_id="${escapeXml(message.author.userId)}"` : "";
226
- const ts = new Date(message.createdAtMs).toISOString();
227
- const slackTsAttr = message.meta?.slackTs ? ` slack_ts="${escapeXml(message.meta.slackTs)}"` : "";
228
- lines.push(
229
- ` <message index="${index + 1}" ts="${ts}" role="${message.role}" author="${author}"${actorIdAttr}${slackTsAttr}>`,
230
- renderConversationMessageLine(message, conversation),
231
- " </message>"
232
- );
233
- }
234
- lines.push("</thread-transcript>");
235
- }
236
- return lines.join("\n");
237
- }
238
- function pruneCompactions(compactions) {
239
- if (compactions.length <= CONTEXT_MAX_COMPACTIONS) {
240
- return compactions;
241
- }
242
- const overflowCount = compactions.length - CONTEXT_MAX_COMPACTIONS + 1;
243
- const merged = compactions.slice(0, overflowCount);
244
- const mergedSummary = merged.map((entry) => entry.summary).join("\n").slice(0, 3500);
245
- const mergedIds = merged.flatMap((entry) => entry.coveredMessageIds).slice(0, 500);
246
- const compacted = {
247
- id: generateConversationId("compaction"),
248
- createdAtMs: Date.now(),
249
- summary: mergedSummary,
250
- coveredMessageIds: mergedIds
251
- };
252
- return [compacted, ...compactions.slice(overflowCount)];
253
- }
254
- async function summarizeConversationChunk(messages, conversation, context, deps) {
255
- const transcript = messages.map((message) => renderConversationMessageLine(message, conversation)).join("\n");
256
- try {
257
- const result = await deps.completeText({
258
- modelId: botConfig.fastModelId,
259
- temperature: 0,
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(
293
- "conversation_compaction_summary_failed",
294
- {
295
- slackThreadId: context.threadId,
296
- slackUserId: context.actorId,
297
- slackChannelId: context.channelId,
298
- runId: context.runId,
299
- assistantUserName: botConfig.userName,
300
- modelId: botConfig.fastModelId
301
- },
302
- {
303
- "exception.message": error instanceof Error ? error.message : String(error),
304
- "app.compaction_messages_covered": messages.length
305
- },
306
- "Compaction summarization failed; using fallback summary"
307
- );
308
- }
309
- return transcript.slice(0, 2800);
310
- }
311
- async function generateThreadTitleWithDeps(sourceText, deps) {
312
- const result = await deps.completeText({
313
- modelId: botConfig.fastModelId,
314
- temperature: 0,
315
- messages: [
316
- {
317
- role: "user",
318
- content: [
319
- "Generate a concise 5-8 word Slack conversation title from the first user message below.",
320
- "Capture the user's main request.",
321
- "Reply with ONLY the title, with no quotes or trailing punctuation.",
322
- "",
323
- `First user message: ${sourceText.slice(0, 500)}`
324
- ].join("\n"),
325
- timestamp: Date.now()
326
- }
327
- ],
328
- metadata: {
329
- modelId: botConfig.fastModelId
330
- }
331
- });
332
- return result.text.trim().slice(0, 60);
333
- }
334
- function getThreadTitleSourceMessage(conversation) {
335
- let firstMessage;
336
- for (const message of conversation.messages) {
337
- if (!isHumanConversationMessage(message)) {
338
- continue;
339
- }
340
- if (!firstMessage) {
341
- firstMessage = message;
342
- continue;
343
- }
344
- if (message.createdAtMs < firstMessage.createdAtMs) {
345
- firstMessage = message;
346
- continue;
347
- }
348
- if (message.createdAtMs === firstMessage.createdAtMs && message.id < firstMessage.id) {
349
- firstMessage = message;
350
- }
351
- }
352
- return firstMessage;
353
- }
354
- async function compactConversationIfNeededWithDeps(conversation, context, deps) {
355
- updateConversationStats(conversation);
356
- let estimatedTokens = conversation.stats.estimatedContextTokens;
357
- setSpanAttributes({
358
- "app.context_tokens_estimated": estimatedTokens
359
- });
360
- const triggerTokens = getConversationContextCompactionTriggerTokens();
361
- const targetTokens = calculateContextCompactionTargetTokens(triggerTokens);
362
- while (estimatedTokens > triggerTokens && conversation.messages.length > CONTEXT_MIN_LIVE_MESSAGES) {
363
- const compactCount = Math.min(
364
- CONTEXT_COMPACTION_BATCH_SIZE,
365
- conversation.messages.length - CONTEXT_MIN_LIVE_MESSAGES
366
- );
367
- if (compactCount <= 0) {
368
- break;
369
- }
370
- const compactedChunk = conversation.messages.slice(0, compactCount);
371
- const summary = await summarizeConversationChunk(
372
- compactedChunk,
373
- conversation,
374
- context,
375
- deps
376
- );
377
- conversation.compactions.push({
378
- id: generateConversationId("compaction"),
379
- createdAtMs: Date.now(),
380
- summary,
381
- coveredMessageIds: compactedChunk.map((entry) => entry.id)
382
- });
383
- conversation.compactions = pruneCompactions(conversation.compactions);
384
- conversation.messages = conversation.messages.slice(compactCount);
385
- conversation.stats.compactedMessageCount += compactCount;
386
- updateConversationStats(conversation);
387
- estimatedTokens = conversation.stats.estimatedContextTokens;
388
- setSpanAttributes({
389
- "app.compaction_messages_covered": compactCount,
390
- "app.compaction.trigger_tokens": triggerTokens,
391
- "app.compaction.target_tokens": targetTokens,
392
- "app.context_tokens_estimated": estimatedTokens
393
- });
394
- if (estimatedTokens <= targetTokens) {
395
- break;
396
- }
397
- }
398
- }
399
- function createConversationMemoryService(deps) {
400
- return {
401
- compactConversationIfNeeded: async (conversation, context) => await compactConversationIfNeededWithDeps(conversation, context, deps),
402
- generateThreadTitle: async (sourceText) => await generateThreadTitleWithDeps(sourceText, deps)
403
- };
404
- }
405
- function isHumanConversationMessage(message) {
406
- return message.role === "user" && message.author?.isBot !== true;
407
- }
408
- function getConversationMessageSlackTs(message) {
409
- return parseSlackMessageTs(message.meta?.slackTs);
410
- }
55
+ } from "./chunk-7FBGKXPE.js";
411
56
 
412
57
  // src/chat/services/turn-failure-response.ts
413
58
  function requireTurnFailureEventId(eventId, eventName) {
@@ -652,6 +297,10 @@ async function loadConversationContextTranscriptEntries(record) {
652
297
  }
653
298
  const state = await getPersistedThreadState(record.conversationId);
654
299
  const conversation = coerceThreadConversationState(state);
300
+ await hydrateConversationMessages({
301
+ conversation,
302
+ conversationId: record.conversationId
303
+ });
655
304
  const entries = [];
656
305
  for (const message of conversation.messages) {
657
306
  if (message.role !== "user") {
@@ -849,18 +498,6 @@ function buildDeliveredTurnStatePatch(args) {
849
498
  }
850
499
 
851
500
  export {
852
- estimateTextTokens,
853
- getAgentContextCompactionTriggerTokens,
854
- generateConversationId,
855
- normalizeConversationText,
856
- updateConversationStats,
857
- upsertConversationMessage,
858
- markConversationMessage,
859
- buildConversationContext,
860
- getThreadTitleSourceMessage,
861
- createConversationMemoryService,
862
- isHumanConversationMessage,
863
- getConversationMessageSlackTs,
864
501
  requireTurnFailureEventId,
865
502
  getAgentTurnDiagnosticsAttributes,
866
503
  finalizeFailedTurnReply,
@@ -1,9 +1,9 @@
1
1
  import {
2
2
  pluginCatalogRuntime
3
- } from "./chunk-BTH37NCU.js";
3
+ } from "./chunk-L7CDEIVJ.js";
4
4
  import {
5
5
  logWarn
6
- } from "./chunk-S6QKIGRM.js";
6
+ } from "./chunk-I35CTGPO.js";
7
7
  import {
8
8
  skillRoots
9
9
  } from "./chunk-6APU57E6.js";
@@ -5,69 +5,11 @@ import {
5
5
  } from "./chunk-OB42YVAE.js";
6
6
 
7
7
  // src/chat/state/conversation.ts
8
- function coerceRole(value) {
9
- return value === "assistant" || value === "system" || value === "user" ? value : "user";
10
- }
11
- function coerceAuthor(value) {
12
- if (!isRecord(value)) return void 0;
13
- const author = {
14
- fullName: toOptionalString(value.fullName),
15
- userId: toOptionalString(value.userId),
16
- userName: toOptionalString(value.userName)
17
- };
18
- if (typeof value.isBot === "boolean") {
19
- author.isBot = value.isBot;
20
- }
21
- if (!author.fullName && !author.userId && !author.userName && author.isBot === void 0) {
22
- return void 0;
23
- }
24
- return author;
25
- }
26
- function coerceMessageMeta(value) {
27
- if (!isRecord(value)) return void 0;
28
- const meta = {};
29
- const attachmentCount = toOptionalNumber(value.attachmentCount);
30
- if (typeof attachmentCount === "number" && attachmentCount > 0) {
31
- meta.attachmentCount = attachmentCount;
32
- }
33
- if (typeof value.explicitMention === "boolean") {
34
- meta.explicitMention = value.explicitMention;
35
- }
36
- const imageAttachmentCount = toOptionalNumber(value.imageAttachmentCount);
37
- if (typeof imageAttachmentCount === "number" && imageAttachmentCount > 0) {
38
- meta.imageAttachmentCount = imageAttachmentCount;
39
- }
40
- if (typeof value.replied === "boolean") {
41
- meta.replied = value.replied;
42
- }
43
- if (typeof value.skippedReason === "string" && value.skippedReason.trim().length > 0) {
44
- meta.skippedReason = value.skippedReason;
45
- }
46
- if (typeof value.slackTs === "string" && value.slackTs.trim().length > 0) {
47
- meta.slackTs = value.slackTs;
48
- }
49
- if (Array.isArray(value.imageFileIds)) {
50
- const imageFileIds = value.imageFileIds.filter(
51
- (entry) => typeof entry === "string" && entry.trim().length > 0
52
- );
53
- if (imageFileIds.length > 0) {
54
- meta.imageFileIds = imageFileIds;
55
- }
56
- }
57
- if (typeof value.imagesHydrated === "boolean") {
58
- meta.imagesHydrated = value.imagesHydrated;
59
- }
60
- if (meta.attachmentCount === void 0 && meta.explicitMention === void 0 && meta.imageAttachmentCount === void 0 && meta.replied === void 0 && meta.skippedReason === void 0 && meta.slackTs === void 0 && meta.imageFileIds === void 0 && meta.imagesHydrated === void 0) {
61
- return void 0;
62
- }
63
- return meta;
64
- }
65
8
  function defaultConversationState() {
66
9
  const nowMs = Date.now();
67
10
  return {
68
11
  schemaVersion: 1,
69
12
  messages: [],
70
- piMessages: [],
71
13
  compactions: [],
72
14
  backfill: {},
73
15
  processing: {},
@@ -111,23 +53,7 @@ function coerceThreadConversationState(value) {
111
53
  const root = value;
112
54
  const rawConversation = isRecord(root.conversation) ? root.conversation : {};
113
55
  const base = defaultConversationState();
114
- const rawMessages = Array.isArray(rawConversation.messages) ? rawConversation.messages : [];
115
56
  const messages = [];
116
- for (const item of rawMessages) {
117
- if (!isRecord(item)) continue;
118
- const id = toOptionalString(item.id);
119
- const text = toOptionalString(item.text);
120
- const createdAtMs = toOptionalNumber(item.createdAtMs);
121
- if (!id || !text || !createdAtMs) continue;
122
- messages.push({
123
- id,
124
- role: coerceRole(item.role),
125
- text,
126
- createdAtMs,
127
- author: coerceAuthor(item.author),
128
- meta: coerceMessageMeta(item.meta)
129
- });
130
- }
131
57
  const rawCompactions = Array.isArray(rawConversation.compactions) ? rawConversation.compactions : [];
132
58
  const compactions = [];
133
59
  for (const item of rawCompactions) {
@@ -181,7 +107,6 @@ function coerceThreadConversationState(value) {
181
107
  return {
182
108
  schemaVersion: 1,
183
109
  messages,
184
- piMessages: Array.isArray(rawConversation.piMessages) ? rawConversation.piMessages : [],
185
110
  compactions,
186
111
  backfill,
187
112
  processing,
@@ -193,9 +118,14 @@ function coerceThreadConversationState(value) {
193
118
  };
194
119
  }
195
120
  function buildConversationStatePatch(conversation) {
121
+ const {
122
+ compactions: _compactions,
123
+ messages: _messages,
124
+ ...scratch
125
+ } = conversation;
196
126
  return {
197
127
  conversation: {
198
- ...conversation,
128
+ ...scratch,
199
129
  schemaVersion: 1,
200
130
  stats: {
201
131
  ...conversation.stats,
@@ -206,11 +136,7 @@ function buildConversationStatePatch(conversation) {
206
136
  };
207
137
  }
208
138
 
209
- // src/chat/state/ttl.ts
210
- var JUNIOR_THREAD_STATE_TTL_MS = 7 * 24 * 60 * 60 * 1e3;
211
-
212
139
  export {
213
- JUNIOR_THREAD_STATE_TTL_MS,
214
140
  coerceThreadConversationState,
215
141
  buildConversationStatePatch
216
142
  };