@sentry/junior 0.96.0 → 0.97.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 (135) hide show
  1. package/dist/{agent-hooks-5URSMY3O.js → agent-hooks-XSUIVRQS.js} +8 -6
  2. package/dist/{reporting → api}/conversations/activity.d.ts +1 -1
  3. package/dist/api/conversations/detail-projection.d.ts +10 -0
  4. package/dist/api/conversations/detail.d.ts +3 -0
  5. package/dist/api/conversations/detail.query.d.ts +3 -0
  6. package/dist/api/conversations/list.d.ts +3 -0
  7. package/dist/api/conversations/list.query.d.ts +94 -0
  8. package/dist/api/conversations/projection.d.ts +14 -0
  9. package/dist/api/conversations/schema.d.ts +683 -0
  10. package/dist/{reporting → api}/conversations/shared.d.ts +1 -5
  11. package/dist/api/conversations/stats.d.ts +3 -0
  12. package/dist/api/conversations/stats.query.d.ts +3 -0
  13. package/dist/api/conversations/subagent.d.ts +3 -0
  14. package/dist/{reporting → api}/conversations/transcript.d.ts +4 -4
  15. package/dist/api/people/list.d.ts +1 -2
  16. package/dist/api/people/list.query.d.ts +3 -4
  17. package/dist/api/people/profile.d.ts +1 -2
  18. package/dist/api/people/profile.query.d.ts +3 -4
  19. package/dist/api/people/schema.d.ts +193 -0
  20. package/dist/api/people/shared.d.ts +31 -9
  21. package/dist/api/schema.d.ts +20 -0
  22. package/dist/api/schema.js +50 -0
  23. package/dist/api-reference.d.ts +4 -3
  24. package/dist/api.d.ts +3 -0
  25. package/dist/api.js +156 -0
  26. package/dist/app.d.ts +1 -4
  27. package/dist/app.js +100 -366
  28. package/dist/build/virtual-config.d.ts +2 -2
  29. package/dist/{catalog-runtime-MSMAYYIK.js → catalog-runtime-PFHVMHDR.js} +3 -2
  30. package/dist/chat/agent/resume.d.ts +3 -1
  31. package/dist/chat/agent/tools.d.ts +2 -1
  32. package/dist/chat/config.d.ts +1 -8
  33. package/dist/chat/conversations/history.d.ts +241 -27
  34. package/dist/chat/conversations/legacy-advisor-session.d.ts +7 -0
  35. package/dist/chat/conversations/legacy-import.d.ts +2 -2
  36. package/dist/chat/conversations/projection.d.ts +19 -3
  37. package/dist/chat/conversations/sql/legacy-history-import.d.ts +1 -1
  38. package/dist/chat/conversations/sql/store.d.ts +15 -9
  39. package/dist/chat/conversations/store.d.ts +9 -4
  40. package/dist/chat/model-profile.d.ts +14 -0
  41. package/dist/chat/pi/transcript.d.ts +5 -3
  42. package/dist/chat/resource-events/store.d.ts +2 -2
  43. package/dist/chat/services/context-compaction.d.ts +15 -0
  44. package/dist/chat/services/turn-result.d.ts +1 -0
  45. package/dist/chat/services/turn-session-record.d.ts +6 -6
  46. package/dist/chat/state/turn-session.d.ts +16 -5
  47. package/dist/chat/task-execution/store.d.ts +2 -2
  48. package/dist/chat/tools/handoff/tool.d.ts +45 -0
  49. package/dist/chat/tools/types.d.ts +7 -2
  50. package/dist/chat/usage.d.ts +25 -25
  51. package/dist/{chunk-RITD7E5L.js → chunk-35BNLDOJ.js} +338 -577
  52. package/dist/{chunk-PMNN6ST4.js → chunk-3ECW2K2O.js} +7 -2
  53. package/dist/{chunk-5C6XTTFI.js → chunk-3F4OPKGF.js} +89 -55
  54. package/dist/chunk-3V7OFJZC.js +264 -0
  55. package/dist/chunk-4ZNGQH7C.js +25 -0
  56. package/dist/{chunk-S5KZ5LPG.js → chunk-5HLDPVYS.js} +14 -447
  57. package/dist/{chunk-DZENG5ML.js → chunk-6U26PYI5.js} +24 -14
  58. package/dist/chunk-AUUCAFDE.js +546 -0
  59. package/dist/{chunk-6APU57E6.js → chunk-B3IT5END.js} +41 -260
  60. package/dist/chunk-CEA3A3UA.js +86 -0
  61. package/dist/{chunk-YDT7SNCN.js → chunk-D5KZYS4T.js} +1 -1
  62. package/dist/{chunk-YDVEH3SB.js → chunk-EEZCY5WX.js} +78 -28
  63. package/dist/{chunk-2NAZZPPS.js → chunk-EOWXRY5E.js} +1 -1
  64. package/dist/{chunk-GQ3GK22G.js → chunk-FBHZJFHI.js} +2 -2
  65. package/dist/{chunk-CZEX6KIQ.js → chunk-G3E7SCME.js} +0 -23
  66. package/dist/chunk-GUAP3H7O.js +319 -0
  67. package/dist/{chunk-BYZWPRJA.js → chunk-H66UCBPW.js} +6 -4
  68. package/dist/{chunk-L7CDEIVJ.js → chunk-LMJPRYHP.js} +4 -2
  69. package/dist/chunk-LUAE4MGW.js +199 -0
  70. package/dist/{chunk-GY34VGP5.js → chunk-LVA4I4H7.js} +3 -1
  71. package/dist/chunk-LVUKF5CE.js +63 -0
  72. package/dist/{chunk-AAZXTVJT.js → chunk-NG2AV7IB.js} +2 -72
  73. package/dist/chunk-ON6YKIQ7.js +260 -0
  74. package/dist/chunk-PDO5BLNM.js +22 -0
  75. package/dist/chunk-QNVHH5PU.js +20 -0
  76. package/dist/{chunk-P3YFQLEN.js → chunk-T533JLM3.js} +8 -10
  77. package/dist/chunk-UAMKJPDF.js +11 -0
  78. package/dist/chunk-VFH4ZKZT.js +66 -0
  79. package/dist/{chunk-UKHVMPX5.js → chunk-WGXMTFNU.js} +15 -17
  80. package/dist/{chunk-MNTINMWR.js → chunk-WJOSZOON.js} +184 -300
  81. package/dist/chunk-WTYEKPXU.js +451 -0
  82. package/dist/{chunk-IYM2SIVG.js → chunk-XIRPQQVE.js} +605 -363
  83. package/dist/cli/chat.js +24 -21
  84. package/dist/cli/check.js +4 -3
  85. package/dist/cli/init.js +12 -0
  86. package/dist/cli/plugins.js +12 -9
  87. package/dist/cli/snapshot-warmup.js +8 -6
  88. package/dist/cli/upgrade.js +265 -137
  89. package/dist/db/db.d.ts +4 -0
  90. package/dist/db/schema/conversations.d.ts +128 -0
  91. package/dist/db/schema.d.ts +129 -60
  92. package/dist/{db-2D6RMG67.js → db-BWXYIKFQ.js} +3 -3
  93. package/dist/detail-GA6NXWQJ.js +43 -0
  94. package/dist/discovery-RMHYSRL7.js +43 -0
  95. package/dist/handlers/health.d.ts +3 -0
  96. package/dist/instrumentation.js +1 -1
  97. package/dist/{legacy-import-VZ2MEGP7.js → legacy-import-3NQJVGQL.js} +4 -4
  98. package/dist/{api/people/list.js → list-A3WFRIYX.js} +26 -16
  99. package/dist/list-UXJI5Q5X.js +27 -0
  100. package/dist/nitro.d.ts +1 -1
  101. package/dist/nitro.js +2 -1
  102. package/dist/plugin-conversations-DDNGC35A.js +36 -0
  103. package/dist/{api/people/profile.js → profile-4RYDXWTF.js} +33 -18
  104. package/dist/reporting/plugin-conversations.d.ts +3 -0
  105. package/dist/reporting-schema.d.ts +140 -0
  106. package/dist/reporting.d.ts +12 -81
  107. package/dist/{runner-JZBRQP4F.js → runner-JALSYH2P.js} +17 -12
  108. package/dist/skills-MAZXZ2KE.js +26 -0
  109. package/dist/stats-XKXH3PTY.js +217 -0
  110. package/dist/subagent-TZ55XY37.js +48 -0
  111. package/dist/usage-schema.d.ts +25 -0
  112. package/dist/{validation-6XOOQGME.js → validation-FMEAEKCY.js} +4 -3
  113. package/migrations/0000_initial.sql +115 -0
  114. package/migrations/0001_conversation_metrics.sql +4 -0
  115. package/migrations/README.md +12 -30
  116. package/migrations/meta/0000_snapshot.json +1 -33
  117. package/migrations/meta/0001_snapshot.json +972 -0
  118. package/migrations/meta/_journal.json +9 -2
  119. package/package.json +14 -18
  120. package/dist/api/people/types.d.ts +0 -85
  121. package/dist/chat/advisor-request.d.ts +0 -4
  122. package/dist/chat/conversations/sql/migrations.d.ts +0 -22
  123. package/dist/chat/tools/advisor/session-store.d.ts +0 -9
  124. package/dist/chat/tools/advisor/tool.d.ts +0 -72
  125. package/dist/chunk-RAIB6WSG.js +0 -142
  126. package/dist/chunk-WM6KHPBQ.js +0 -48
  127. package/dist/db/schema/migrations.d.ts +0 -58
  128. package/dist/reporting/conversations/context.d.ts +0 -8
  129. package/dist/reporting/conversations/details.d.ts +0 -6
  130. package/dist/reporting/conversations/index.d.ts +0 -4
  131. package/dist/reporting/conversations/statistics.d.ts +0 -4
  132. package/dist/reporting/conversations/summaries.d.ts +0 -20
  133. package/dist/reporting/conversations/types.d.ts +0 -191
  134. package/dist/reporting/conversations.d.ts +0 -1
  135. package/dist/reporting.js +0 -1155
@@ -1,294 +1,161 @@
1
1
  import {
2
- ensureLegacyConversationImport
3
- } from "./chunk-5C6XTTFI.js";
2
+ commitMessages,
3
+ loadTurnProjection
4
+ } from "./chunk-GUAP3H7O.js";
5
+ import {
6
+ usageSchema
7
+ } from "./chunk-PDO5BLNM.js";
4
8
  import {
5
- contextProvenance,
6
- getAgentStepStore,
7
9
  getConversationStore,
8
10
  instructionActors,
9
11
  instructionProvenanceFor
10
- } from "./chunk-RITD7E5L.js";
12
+ } from "./chunk-35BNLDOJ.js";
11
13
  import {
12
14
  getStateAdapter
13
- } from "./chunk-YDVEH3SB.js";
15
+ } from "./chunk-EEZCY5WX.js";
14
16
  import {
15
17
  toStoredSlackActor
16
18
  } from "./chunk-I35CTGPO.js";
19
+ import {
20
+ isRecord,
21
+ toOptionalNumber,
22
+ toOptionalString
23
+ } from "./chunk-OB42YVAE.js";
17
24
 
18
- // src/chat/conversations/projection.ts
19
- import { isDeepStrictEqual } from "util";
20
- function authorizationObservationMessage(entry, createdAtMs) {
21
- const label = entry.kind === "mcp" ? "MCP authorization" : "Authorization";
25
+ // src/chat/state/conversation.ts
26
+ function defaultConversationState() {
27
+ const nowMs = Date.now();
22
28
  return {
23
- role: "user",
24
- content: [
25
- {
26
- type: "text",
27
- text: `${label} completed for provider "${entry.provider}". Continue the blocked request and retry the provider operation if needed.`
28
- }
29
- ],
30
- timestamp: createdAtMs
31
- };
32
- }
33
- function piEntryProvenance(entry) {
34
- return entry.provenance ?? contextProvenance;
35
- }
36
- function projectSteps(steps, opts) {
37
- const messages = [];
38
- const provenance = [];
39
- const seqs = [];
40
- for (const step of steps) {
41
- if (opts?.maxSeq !== void 0 && step.seq > opts.maxSeq) {
42
- break;
43
- }
44
- if (step.entry.type === "pi_message") {
45
- messages.push(step.entry.message);
46
- provenance.push(piEntryProvenance(step.entry));
47
- seqs.push(step.seq);
48
- continue;
49
- }
50
- if (step.entry.type === "authorization_completed") {
51
- messages.push(
52
- authorizationObservationMessage(step.entry, step.createdAtMs)
53
- );
54
- provenance.push(contextProvenance);
55
- seqs.push(step.seq);
56
- }
57
- }
58
- return { messages, provenance, seqs };
59
- }
60
- function connectedMcpProvidersFromSteps(steps) {
61
- const providers = /* @__PURE__ */ new Set();
62
- for (const step of steps) {
63
- if (step.entry.type === "mcp_provider_connected") {
64
- providers.add(step.entry.provider);
65
- }
66
- }
67
- return [...providers].sort((left, right) => left.localeCompare(right));
68
- }
69
- function isUserMessage(message) {
70
- return message.role === "user";
71
- }
72
- function countMatchingPrefix(left, right) {
73
- const limit = Math.min(left.length, right.length);
74
- for (let index = 0; index < limit; index += 1) {
75
- if (!isDeepStrictEqual(left[index], right[index])) {
76
- return index;
77
- }
78
- }
79
- return limit;
80
- }
81
- function resolveCommitProvenance(args) {
82
- if (args.explicitProvenance) {
83
- if (args.explicitProvenance.length !== args.nextMessages.length) {
84
- throw new Error("commit provenance must align one-to-one with messages");
85
- }
86
- return args.explicitProvenance;
87
- }
88
- const matchingPrefix = args.matchingPrefix;
89
- const provenance = args.nextMessages.map(
90
- (_, index) => index < matchingPrefix ? args.existing.provenance[index] ?? contextProvenance : contextProvenance
91
- );
92
- if (args.newMessageProvenance) {
93
- for (let index = args.nextMessages.length - 1; index >= matchingPrefix; index -= 1) {
94
- if (isUserMessage(args.nextMessages[index])) {
95
- provenance[index] = args.newMessageProvenance;
96
- break;
97
- }
98
- }
99
- }
100
- if (args.trailingMessageProvenance) {
101
- if (args.trailingMessageProvenance.length > provenance.length) {
102
- throw new Error(
103
- "trailing commit provenance cannot exceed committed messages"
104
- );
105
- }
106
- const newMessageCount = args.nextMessages.length - matchingPrefix;
107
- if (args.trailingMessageProvenance.length > newMessageCount) {
108
- throw new Error(
109
- "trailing commit provenance must align to newly committed messages"
110
- );
29
+ schemaVersion: 1,
30
+ messages: [],
31
+ compactions: [],
32
+ backfill: {},
33
+ processing: {},
34
+ stats: {
35
+ estimatedContextTokens: 0,
36
+ totalMessageCount: 0,
37
+ compactedMessageCount: 0,
38
+ updatedAtMs: nowMs
39
+ },
40
+ vision: {
41
+ byFileId: {}
111
42
  }
112
- const start = provenance.length - args.trailingMessageProvenance.length;
113
- args.trailingMessageProvenance.forEach((entry, offset) => {
114
- provenance[start + offset] = entry;
115
- });
116
- }
117
- return provenance;
118
- }
119
- async function importLegacyIfNeeded(args) {
120
- await ensureLegacyConversationImport({ conversationId: args.conversationId });
121
- }
122
- async function loadProjection(args) {
123
- await importLegacyIfNeeded(args);
124
- const steps = await getAgentStepStore().loadCurrentEpoch(args.conversationId);
125
- return projectSteps(steps).messages;
126
- }
127
- async function loadProjectionWithProvenance(args) {
128
- await importLegacyIfNeeded(args);
129
- const steps = await getAgentStepStore().loadCurrentEpoch(args.conversationId);
130
- const { messages, provenance } = projectSteps(steps);
131
- return { messages, provenance };
43
+ };
132
44
  }
133
- async function loadTurnProjection(args) {
134
- await importLegacyIfNeeded(args);
135
- const stepStore = getAgentStepStore();
136
- if (args.committedSeq < 0) {
137
- return projectSteps(await stepStore.loadCurrentEpoch(args.conversationId));
138
- }
139
- const history = await stepStore.loadHistory(args.conversationId);
140
- const committedStep = history.find((step) => step.seq === args.committedSeq);
141
- if (!committedStep) {
45
+ function coercePendingAuthState(value) {
46
+ if (!isRecord(value)) {
142
47
  return void 0;
143
48
  }
144
- const epochSteps = history.filter(
145
- (step) => step.contextEpoch === committedStep.contextEpoch
146
- );
147
- return args.includeTail ? projectSteps(epochSteps) : projectSteps(epochSteps, { maxSeq: args.committedSeq });
148
- }
149
- async function loadConnectedMcpProviders(args) {
150
- await importLegacyIfNeeded(args);
151
- const steps = await getAgentStepStore().loadCurrentEpoch(args.conversationId);
152
- return connectedMcpProvidersFromSteps(steps);
153
- }
154
- function messageTimestamp(message) {
155
- const timestamp = message.timestamp;
156
- return typeof timestamp === "number" ? timestamp : Date.now();
157
- }
158
- async function commitMessages(args) {
159
- const stepStore = getAgentStepStore();
160
- const existing = projectSteps(
161
- await stepStore.loadCurrentEpoch(args.conversationId)
162
- );
163
- const matchingPrefix = countMatchingPrefix(existing.messages, args.messages);
164
- const nextProvenance = resolveCommitProvenance({
165
- existing,
166
- nextMessages: args.messages,
167
- matchingPrefix,
168
- ...args.provenance ? { explicitProvenance: args.provenance } : {},
169
- ...args.trailingMessageProvenance ? { trailingMessageProvenance: args.trailingMessageProvenance } : {},
170
- ...args.newMessageProvenance ? { newMessageProvenance: args.newMessageProvenance } : {}
171
- });
172
- if (matchingPrefix === existing.messages.length) {
173
- const newMessages = args.messages.slice(matchingPrefix);
174
- await stepStore.append(
175
- args.conversationId,
176
- newMessages.map((message, index) => ({
177
- entry: {
178
- type: "pi_message",
179
- message,
180
- provenance: nextProvenance[matchingPrefix + index]
181
- },
182
- createdAtMs: messageTimestamp(message)
183
- }))
184
- );
185
- } else {
186
- await stepStore.startEpoch(args.conversationId, {
187
- reason: "rollback",
188
- messages: args.messages.map((message, index) => ({
189
- message,
190
- createdAtMs: messageTimestamp(message),
191
- provenance: nextProvenance[index]
192
- }))
193
- });
49
+ const kind = value.kind;
50
+ const provider = toOptionalString(value.provider);
51
+ const actorId = toOptionalString(value.actorId);
52
+ const scope = toOptionalString(value.scope);
53
+ const sessionId = toOptionalString(value.sessionId);
54
+ const linkSentAtMs = toOptionalNumber(value.linkSentAtMs);
55
+ if (kind !== "mcp" && kind !== "plugin" || !provider || !actorId || !sessionId || typeof linkSentAtMs !== "number") {
56
+ return void 0;
194
57
  }
195
- const committed = projectSteps(
196
- await stepStore.loadCurrentEpoch(args.conversationId)
197
- );
198
58
  return {
199
- committedSeq: committed.seqs.at(-1) ?? -1,
200
- messageSeqs: committed.seqs,
201
- provenance: nextProvenance
59
+ kind,
60
+ provider,
61
+ actorId,
62
+ ...scope ? { scope } : {},
63
+ sessionId,
64
+ linkSentAtMs
202
65
  };
203
66
  }
204
- async function recordMcpProviderConnected(args) {
205
- const stepStore = getAgentStepStore();
206
- const steps = await stepStore.loadCurrentEpoch(args.conversationId);
207
- if (connectedMcpProvidersFromSteps(steps).includes(args.provider)) {
208
- return;
67
+ function coerceThreadConversationState(value) {
68
+ if (!isRecord(value)) {
69
+ return defaultConversationState();
209
70
  }
210
- await stepStore.append(args.conversationId, [
211
- {
212
- entry: { type: "mcp_provider_connected", provider: args.provider },
213
- createdAtMs: Date.now()
214
- }
215
- ]);
216
- }
217
- async function recordAuthorizationRequested(args) {
218
- const stepStore = getAgentStepStore();
219
- const steps = await stepStore.loadCurrentEpoch(args.conversationId);
220
- if (steps.some(
221
- (step) => step.entry.type === "authorization_requested" && step.entry.authorizationId === args.authorizationId
222
- )) {
223
- return;
71
+ const root = value;
72
+ const rawConversation = isRecord(root.conversation) ? root.conversation : {};
73
+ const base = defaultConversationState();
74
+ const messages = [];
75
+ const rawCompactions = Array.isArray(rawConversation.compactions) ? rawConversation.compactions : [];
76
+ const compactions = [];
77
+ for (const item of rawCompactions) {
78
+ if (!isRecord(item)) continue;
79
+ const id = toOptionalString(item.id);
80
+ const summary = toOptionalString(item.summary);
81
+ const createdAtMs = toOptionalNumber(item.createdAtMs);
82
+ if (!id || !summary || !createdAtMs) continue;
83
+ const coveredMessageIds = Array.isArray(item.coveredMessageIds) ? item.coveredMessageIds.filter(
84
+ (entry) => typeof entry === "string" && entry.length > 0
85
+ ) : [];
86
+ compactions.push({
87
+ id,
88
+ summary,
89
+ createdAtMs,
90
+ coveredMessageIds
91
+ });
224
92
  }
225
- await stepStore.append(args.conversationId, [
226
- {
227
- entry: {
228
- type: "authorization_requested",
229
- kind: args.kind,
230
- provider: args.provider,
231
- actorId: args.actorId,
232
- authorizationId: args.authorizationId,
233
- delivery: args.delivery
234
- },
235
- createdAtMs: Date.now()
236
- }
237
- ]);
238
- }
239
- async function recordAuthorizationCompleted(args) {
240
- const stepStore = getAgentStepStore();
241
- const steps = await stepStore.loadCurrentEpoch(args.conversationId);
242
- if (steps.some(
243
- (step) => step.entry.type === "authorization_completed" && step.entry.authorizationId === args.authorizationId
244
- )) {
245
- return;
93
+ const rawBackfill = isRecord(rawConversation.backfill) ? rawConversation.backfill : {};
94
+ const backfill = {
95
+ completedAtMs: toOptionalNumber(rawBackfill.completedAtMs),
96
+ source: rawBackfill.source === "recent_messages" || rawBackfill.source === "thread_fetch" ? rawBackfill.source : void 0
97
+ };
98
+ const rawProcessing = isRecord(rawConversation.processing) ? rawConversation.processing : {};
99
+ const processing = {
100
+ activeTurnId: toOptionalString(rawProcessing.activeTurnId),
101
+ lastCompletedAtMs: toOptionalNumber(rawProcessing.lastCompletedAtMs),
102
+ pendingAuth: coercePendingAuthState(rawProcessing.pendingAuth)
103
+ };
104
+ const rawStats = isRecord(rawConversation.stats) ? rawConversation.stats : {};
105
+ const stats = {
106
+ estimatedContextTokens: toOptionalNumber(rawStats.estimatedContextTokens) ?? base.stats.estimatedContextTokens,
107
+ totalMessageCount: toOptionalNumber(rawStats.totalMessageCount) ?? messages.length,
108
+ compactedMessageCount: toOptionalNumber(rawStats.compactedMessageCount) ?? 0,
109
+ updatedAtMs: toOptionalNumber(rawStats.updatedAtMs) ?? base.stats.updatedAtMs
110
+ };
111
+ const rawVision = isRecord(rawConversation.vision) ? rawConversation.vision : {};
112
+ const rawVisionByFileId = isRecord(rawVision.byFileId) ? rawVision.byFileId : {};
113
+ const byFileId = {};
114
+ for (const [fileId, value2] of Object.entries(rawVisionByFileId)) {
115
+ if (typeof fileId !== "string" || fileId.trim().length === 0) continue;
116
+ if (!isRecord(value2)) continue;
117
+ const summary = toOptionalString(value2.summary);
118
+ const analyzedAtMs = toOptionalNumber(value2.analyzedAtMs);
119
+ if (!summary || !analyzedAtMs) continue;
120
+ byFileId[fileId] = {
121
+ summary,
122
+ analyzedAtMs
123
+ };
246
124
  }
247
- await stepStore.append(args.conversationId, [
248
- {
249
- entry: {
250
- type: "authorization_completed",
251
- kind: args.kind,
252
- provider: args.provider,
253
- actorId: args.actorId,
254
- authorizationId: args.authorizationId
255
- },
256
- createdAtMs: Date.now()
125
+ return {
126
+ schemaVersion: 1,
127
+ messages,
128
+ compactions,
129
+ backfill,
130
+ processing,
131
+ stats,
132
+ vision: {
133
+ backfillCompletedAtMs: toOptionalNumber(rawVision.backfillCompletedAtMs),
134
+ byFileId
257
135
  }
258
- ]);
136
+ };
259
137
  }
260
- async function recordToolExecutionStarted(args) {
261
- await getAgentStepStore().append(args.conversationId, [
262
- {
263
- entry: {
264
- type: "tool_execution_started",
265
- toolCallId: args.toolCallId,
266
- toolName: args.toolName,
267
- ...args.args !== void 0 ? { args: args.args } : {}
268
- },
269
- createdAtMs: args.createdAtMs ?? Date.now()
138
+ function buildConversationStatePatch(conversation) {
139
+ const {
140
+ compactions: _compactions,
141
+ messages: _messages,
142
+ ...scratch
143
+ } = conversation;
144
+ return {
145
+ conversation: {
146
+ ...scratch,
147
+ schemaVersion: 1,
148
+ stats: {
149
+ ...conversation.stats,
150
+ totalMessageCount: conversation.messages.length,
151
+ updatedAtMs: Date.now()
152
+ }
270
153
  }
271
- ]);
154
+ };
272
155
  }
273
156
 
274
157
  // src/chat/usage.ts
275
- import { z } from "zod";
276
- var agentTurnCostSchema = z.object({
277
- input: z.number().finite().nonnegative().optional(),
278
- output: z.number().finite().nonnegative().optional(),
279
- cacheRead: z.number().finite().nonnegative().optional(),
280
- cacheWrite: z.number().finite().nonnegative().optional(),
281
- total: z.number().finite().nonnegative().optional()
282
- }).strict();
283
- var agentTurnUsageSchema = z.object({
284
- inputTokens: z.number().int().nonnegative().optional(),
285
- outputTokens: z.number().int().nonnegative().optional(),
286
- cachedInputTokens: z.number().int().nonnegative().optional(),
287
- cacheCreationTokens: z.number().int().nonnegative().optional(),
288
- reasoningTokens: z.number().int().nonnegative().optional(),
289
- totalTokens: z.number().int().nonnegative().optional(),
290
- cost: agentTurnCostSchema.optional()
291
- }).strict();
158
+ var agentTurnUsageSchema = usageSchema;
292
159
  var COMPONENT_USAGE_FIELDS = [
293
160
  "inputTokens",
294
161
  "outputTokens",
@@ -384,58 +251,59 @@ import {
384
251
  destinationSchema,
385
252
  sourceSchema
386
253
  } from "@sentry/junior-plugin-api";
387
- import { z as z2 } from "zod";
254
+ import { z } from "zod";
388
255
  var AGENT_TURN_SESSION_PREFIX = "junior:agent_turn_session";
389
256
  var AGENT_TURN_SESSION_INDEX_KEY = `${AGENT_TURN_SESSION_PREFIX}:index`;
390
257
  var AGENT_TURN_SESSION_INDEX_MAX_LENGTH = 5e3;
391
258
  var AGENT_TURN_SESSION_INDEX_READ_CONCURRENCY = 25;
392
259
  var AGENT_TURN_SESSION_TTL_MS = THREAD_STATE_TTL_MS;
393
- var agentTurnSessionStatusSchema = z2.enum([
260
+ var agentTurnSessionStatusSchema = z.enum([
394
261
  "running",
395
262
  "awaiting_resume",
396
263
  "completed",
397
264
  "failed",
398
265
  "abandoned"
399
266
  ]);
400
- var agentTurnSurfaceSchema = z2.enum([
267
+ var agentTurnSurfaceSchema = z.enum([
401
268
  "slack",
402
269
  "api",
403
270
  "scheduler",
404
271
  "internal"
405
272
  ]);
406
- var agentTurnResumeReasonSchema = z2.enum([
273
+ var agentTurnResumeReasonSchema = z.enum([
407
274
  "timeout",
408
275
  "auth",
409
276
  "yield"
410
277
  ]);
411
- var nonNegativeNumberSchema = z2.number().finite().nonnegative();
412
- var seqCursorSchema = z2.number().int().min(-1);
413
- var agentTurnSessionSummarySchema = z2.object({
414
- channelName: z2.string().min(1).optional(),
415
- version: z2.number().int().nonnegative(),
416
- conversationId: z2.string().min(1),
278
+ var nonNegativeNumberSchema = z.number().finite().nonnegative();
279
+ var seqCursorSchema = z.number().int().min(-1);
280
+ var agentTurnSessionSummarySchema = z.object({
281
+ channelName: z.string().min(1).optional(),
282
+ version: z.number().int().nonnegative(),
283
+ conversationId: z.string().min(1),
417
284
  cumulativeDurationMs: nonNegativeNumberSchema,
418
285
  cumulativeUsage: agentTurnUsageSchema.optional(),
419
286
  destination: destinationSchema.optional(),
420
287
  source: sourceSchema.optional(),
421
288
  lastProgressAtMs: nonNegativeNumberSchema,
422
- loadedSkillNames: z2.array(z2.string()).optional(),
423
- modelId: z2.string().min(1).optional(),
424
- reasoningLevel: z2.string().min(1).optional(),
289
+ loadedSkillNames: z.array(z.string()).optional(),
290
+ modelId: z.string().min(1).optional(),
291
+ reasoningLevel: z.string().min(1).optional(),
425
292
  actor: actorSchema.optional(),
426
293
  resumeReason: agentTurnResumeReasonSchema.optional(),
427
- resumedFromSliceId: z2.number().int().nonnegative().optional(),
428
- sessionId: z2.string().min(1),
429
- sliceId: z2.number().int().nonnegative(),
294
+ resumedFromSliceId: z.number().int().nonnegative().optional(),
295
+ sessionId: z.string().min(1),
296
+ sliceId: z.number().int().nonnegative(),
430
297
  startedAtMs: nonNegativeNumberSchema,
431
298
  state: agentTurnSessionStatusSchema,
432
299
  surface: agentTurnSurfaceSchema.optional(),
433
- traceId: z2.string().optional(),
300
+ traceId: z.string().optional(),
434
301
  updatedAtMs: nonNegativeNumberSchema
435
302
  }).strict();
436
303
  var storedAgentTurnSessionRecordSchema = agentTurnSessionSummarySchema.extend({
304
+ actors: z.array(actorSchema).optional(),
437
305
  committedSeq: seqCursorSchema,
438
- errorMessage: z2.string().optional(),
306
+ errorMessage: z.string().optional(),
439
307
  turnStartSeq: seqCursorSchema.optional()
440
308
  }).strict();
441
309
  function agentTurnSessionKey(conversationId, sessionId) {
@@ -495,6 +363,10 @@ async function recordConversationActivityMetadata(args) {
495
363
  destination: args.summary.destination,
496
364
  execution: conversationExecutionFromSummary(args.summary),
497
365
  lastActivityAtMs: args.summary.updatedAtMs,
366
+ metrics: {
367
+ durationMs: args.summary.cumulativeDurationMs,
368
+ ...args.summary.cumulativeUsage ? { usage: args.summary.cumulativeUsage } : {}
369
+ },
498
370
  actor: sessionLogActor(args.summary.actor),
499
371
  source,
500
372
  updatedAtMs: args.nowMs,
@@ -514,7 +386,7 @@ function materializeAgentTurnSessionRecord(stored, piProjection, turnStartMessag
514
386
  updatedAtMs: stored.updatedAtMs,
515
387
  piMessages: piProjection.messages,
516
388
  piMessageProvenance: piProjection.provenance,
517
- actors: instructionActors(piProjection.provenance),
389
+ actors: stored.actors ?? instructionActors(piProjection.provenance),
518
390
  cumulativeDurationMs: stored.cumulativeDurationMs,
519
391
  ...stored.destination ? { destination: stored.destination } : {},
520
392
  ...stored.source ? { source: stored.source } : {},
@@ -583,6 +455,7 @@ function buildStoredRecord(args) {
583
455
  ...args.destination ? { destination: args.destination } : {},
584
456
  ...args.source ? { source: args.source } : {},
585
457
  ...args.actor ? { actor: args.actor } : {},
458
+ ...args.actors ? { actors: args.actors } : {},
586
459
  ...args.loadedSkillNames ? { loadedSkillNames: args.loadedSkillNames } : {},
587
460
  ...args.modelId ? { modelId: args.modelId } : {},
588
461
  ...args.reasoningLevel ? { reasoningLevel: args.reasoningLevel } : {},
@@ -608,6 +481,7 @@ async function setStoredRecord(args) {
608
481
  args.ttlMs
609
482
  );
610
483
  const {
484
+ actors: _actors,
611
485
  committedSeq: _committedSeq,
612
486
  errorMessage: _errorMessage,
613
487
  turnStartSeq: _turnStartSeq,
@@ -655,6 +529,7 @@ async function updateAgentTurnSessionState(args) {
655
529
  ...args.existing.modelId ? { modelId: args.existing.modelId } : {},
656
530
  ...args.existing.reasoningLevel ? { reasoningLevel: args.existing.reasoningLevel } : {},
657
531
  ...args.existing.actor ? { actor: args.existing.actor } : {},
532
+ actors: args.existing.actors,
658
533
  ...args.existing.resumeReason ? { resumeReason: args.existing.resumeReason } : {},
659
534
  ...args.existing.resumedFromSliceId !== void 0 ? { resumedFromSliceId: args.existing.resumedFromSliceId } : {},
660
535
  ...args.existing.surface ? { surface: args.existing.surface } : {},
@@ -672,6 +547,7 @@ async function upsertAgentTurnSessionRecord(args) {
672
547
  const instructionActor = args.actor ?? existingRecord?.actor;
673
548
  const commit = await commitMessages({
674
549
  conversationId: args.conversationId,
550
+ modelId: args.modelId,
675
551
  messages: args.piMessages,
676
552
  ...instructionActor ? { newMessageProvenance: instructionProvenanceFor(instructionActor) } : {},
677
553
  ...args.trailingMessageProvenance ? { trailingMessageProvenance: args.trailingMessageProvenance } : {}
@@ -701,11 +577,16 @@ async function upsertAgentTurnSessionRecord(args) {
701
577
  ...args.destination ?? existingRecord?.destination ? { destination: args.destination ?? existingRecord?.destination } : {},
702
578
  ...args.source ?? existingRecord?.source ? { source: args.source ?? existingRecord?.source } : {},
703
579
  ...args.loadedSkillNames ? { loadedSkillNames: args.loadedSkillNames } : {},
704
- ...existingRecord?.modelId ?? args.modelId ? { modelId: existingRecord?.modelId ?? args.modelId } : {},
580
+ modelId: args.modelId,
705
581
  ...args.reasoningLevel ?? existingRecord?.reasoningLevel ? {
706
582
  reasoningLevel: args.reasoningLevel ?? existingRecord?.reasoningLevel
707
583
  } : {},
708
584
  ...args.actor ?? existingRecord?.actor ? { actor: args.actor ?? existingRecord?.actor } : {},
585
+ actors: instructionActors([
586
+ ...(existingRecord?.actors ?? []).map(instructionProvenanceFor),
587
+ ...(args.actors ?? []).map(instructionProvenanceFor),
588
+ ...commit.provenance
589
+ ]),
709
590
  ...args.resumeReason ? { resumeReason: args.resumeReason } : {},
710
591
  ...args.errorMessage ? { errorMessage: args.errorMessage } : {},
711
592
  ...args.resumedFromSliceId !== void 0 ? { resumedFromSliceId: args.resumedFromSliceId } : {},
@@ -737,7 +618,7 @@ async function recordAgentTurnSessionSummary(args) {
737
618
  ...args.source ?? existing?.source ? { source: args.source ?? existing?.source } : {},
738
619
  ...args.actor ?? existing?.actor ? { actor: args.actor ?? existing?.actor } : {},
739
620
  ...args.loadedSkillNames ? { loadedSkillNames: args.loadedSkillNames } : existing?.loadedSkillNames ? { loadedSkillNames: existing.loadedSkillNames } : {},
740
- ...existing?.modelId ?? args.modelId ? { modelId: existing?.modelId ?? args.modelId } : {},
621
+ ...args.modelId ?? existing?.modelId ? { modelId: args.modelId ?? existing?.modelId } : {},
741
622
  ...args.reasoningLevel ?? existing?.reasoningLevel ? { reasoningLevel: args.reasoningLevel ?? existing?.reasoningLevel } : {},
742
623
  ...args.resumeReason ? { resumeReason: args.resumeReason } : {},
743
624
  ...args.surface ?? existing?.surface ? { surface: args.surface ?? existing?.surface } : {},
@@ -751,8 +632,7 @@ async function recordAgentTurnSessionSummary(args) {
751
632
  });
752
633
  await appendAgentTurnSessionSummary(summary, ttlMs);
753
634
  }
754
- async function readAgentTurnSessionSummariesFromIndex(key) {
755
- const stateAdapter = getStateAdapter();
635
+ async function readAgentTurnSessionSummariesFromIndex(key, stateAdapter) {
756
636
  await stateAdapter.connect();
757
637
  const values = await stateAdapter.getList(key);
758
638
  const summaries = /* @__PURE__ */ new Map();
@@ -768,18 +648,24 @@ async function readAgentTurnSessionSummariesFromIndex(key) {
768
648
  );
769
649
  }
770
650
  async function listAgentTurnSessionSummariesForConversation(conversationId) {
651
+ const stateAdapter = getStateAdapter();
771
652
  const summaries = await readAgentTurnSessionSummariesFromIndex(
772
- agentTurnSessionConversationIndexKey(conversationId)
653
+ agentTurnSessionConversationIndexKey(conversationId),
654
+ stateAdapter
773
655
  );
774
656
  if (summaries.length > 0) {
775
657
  return summaries;
776
658
  }
777
- return (await readAgentTurnSessionSummariesFromIndex(AGENT_TURN_SESSION_INDEX_KEY)).filter((summary) => summary.conversationId === conversationId);
659
+ return (await readAgentTurnSessionSummariesFromIndex(
660
+ AGENT_TURN_SESSION_INDEX_KEY,
661
+ stateAdapter
662
+ )).filter((summary) => summary.conversationId === conversationId);
778
663
  }
779
- async function listAgentTurnSessionSummariesForConversations(conversationIds) {
664
+ async function listAgentTurnSessionSummariesForConversations(stateAdapter, conversationIds) {
780
665
  const ids = [...new Set(conversationIds)];
781
666
  const globalSummaries = await readAgentTurnSessionSummariesFromIndex(
782
- AGENT_TURN_SESSION_INDEX_KEY
667
+ AGENT_TURN_SESSION_INDEX_KEY,
668
+ stateAdapter
783
669
  );
784
670
  const globalByConversation = /* @__PURE__ */ new Map();
785
671
  for (const summary of globalSummaries) {
@@ -796,7 +682,8 @@ async function listAgentTurnSessionSummariesForConversations(conversationIds) {
796
682
  nextIndex += 1;
797
683
  if (!conversationId) continue;
798
684
  const summaries = await readAgentTurnSessionSummariesFromIndex(
799
- agentTurnSessionConversationIndexKey(conversationId)
685
+ agentTurnSessionConversationIndexKey(conversationId),
686
+ stateAdapter
800
687
  );
801
688
  summariesByConversation.set(
802
689
  conversationId,
@@ -843,16 +730,10 @@ async function failAgentTurnSessionRecord(args) {
843
730
  });
844
731
  }
845
732
 
733
+ // src/chat/state/ttl.ts
734
+ var JUNIOR_THREAD_STATE_TTL_MS = 7 * 24 * 60 * 60 * 1e3;
735
+
846
736
  export {
847
- projectSteps,
848
- loadProjection,
849
- loadProjectionWithProvenance,
850
- loadConnectedMcpProviders,
851
- commitMessages,
852
- recordMcpProviderConnected,
853
- recordAuthorizationRequested,
854
- recordAuthorizationCompleted,
855
- recordToolExecutionStarted,
856
737
  hasAgentTurnUsage,
857
738
  addAgentTurnUsage,
858
739
  getAgentTurnSessionRecord,
@@ -861,5 +742,8 @@ export {
861
742
  listAgentTurnSessionSummariesForConversation,
862
743
  listAgentTurnSessionSummariesForConversations,
863
744
  abandonAgentTurnSessionRecord,
864
- failAgentTurnSessionRecord
745
+ failAgentTurnSessionRecord,
746
+ JUNIOR_THREAD_STATE_TTL_MS,
747
+ coerceThreadConversationState,
748
+ buildConversationStatePatch
865
749
  };