@sentry/junior 0.124.2 → 0.126.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 (87) hide show
  1. package/dist/{agent-hooks-HJQTURNC.js → agent-hooks-HDSNWDQM.js} +9 -10
  2. package/dist/api/conversations/auxiliary-costs.d.ts +6 -0
  3. package/dist/api/conversations/detail.d.ts +10 -0
  4. package/dist/api/conversations/list.d.ts +11 -0
  5. package/dist/api/conversations/projection.d.ts +2 -1
  6. package/dist/api/locations/detail.d.ts +20 -0
  7. package/dist/api/people/profile.d.ts +10 -0
  8. package/dist/api/people/shared.d.ts +36 -0
  9. package/dist/api/plugin-reports.d.ts +1 -0
  10. package/dist/api/schema/conversation.d.ts +40 -0
  11. package/dist/api/schema/location.d.ts +10 -0
  12. package/dist/api/schema/person.d.ts +10 -0
  13. package/dist/api/schema.d.ts +2 -2
  14. package/dist/api/schema.js +4 -2
  15. package/dist/api.js +339 -180
  16. package/dist/app.js +52 -41
  17. package/dist/{catalog-runtime-F356WNZS.js → catalog-runtime-BDC3UWPG.js} +5 -6
  18. package/dist/chat/agent/prompt.d.ts +1 -0
  19. package/dist/chat/agent/request.d.ts +2 -1
  20. package/dist/chat/agent/resume.d.ts +2 -0
  21. package/dist/chat/agent-dispatch/types.d.ts +2 -1
  22. package/dist/chat/conversation-privacy.d.ts +7 -12
  23. package/dist/chat/conversations/destination-visibility.d.ts +7 -0
  24. package/dist/chat/conversations/history.d.ts +4 -2
  25. package/dist/chat/conversations/sql/conversation-row.d.ts +7 -4
  26. package/dist/chat/conversations/sql/store.d.ts +2 -1
  27. package/dist/chat/conversations/store.d.ts +12 -4
  28. package/dist/chat/pi/client.d.ts +1 -0
  29. package/dist/chat/plugins/agent-hooks.d.ts +1 -0
  30. package/dist/chat/plugins/conversation-event-stats.d.ts +3 -0
  31. package/dist/chat/plugins/conversation-events.d.ts +1 -1
  32. package/dist/chat/services/turn-session-record.d.ts +4 -1
  33. package/dist/chat/slack/conversation-context.d.ts +4 -7
  34. package/dist/chat/slack/footer.d.ts +10 -1
  35. package/dist/chat/slack/reply.d.ts +9 -2
  36. package/dist/chat/slack/source-link.d.ts +5 -0
  37. package/dist/chat/source.d.ts +16 -0
  38. package/dist/chat/state/turn-session.d.ts +2 -6
  39. package/dist/{chunk-L7EZRQ2J.js → chunk-4PV73JHH.js} +11 -13
  40. package/dist/{chunk-IXTIJQ7Z.js → chunk-6KWO5DU3.js} +167 -20
  41. package/dist/{chunk-AYQZCJZJ.js → chunk-6ZBSTNYN.js} +14 -0
  42. package/dist/chunk-72SDEHFP.js +102 -0
  43. package/dist/{chunk-SMTAXLX4.js → chunk-ACJZZY5W.js} +2 -2
  44. package/dist/{chunk-KYKLQYSU.js → chunk-APYVVX2Y.js} +1 -1
  45. package/dist/{chunk-EOSC6JOC.js → chunk-EFQX6XBW.js} +1 -1
  46. package/dist/{chunk-IMLJE2NY.js → chunk-EQMSKORN.js} +2 -2
  47. package/dist/{chunk-ZO6E537B.js → chunk-GHNO2WUH.js} +1 -1
  48. package/dist/{chunk-WKBPFZ25.js → chunk-GK55KLEH.js} +1 -1
  49. package/dist/{chunk-PR3M62LK.js → chunk-HX236W2U.js} +6 -4
  50. package/dist/{chunk-7LDOW4QA.js → chunk-JFW62B3Y.js} +1 -1
  51. package/dist/{chunk-ASK74NM6.js → chunk-JP2ZOSQK.js} +15 -5
  52. package/dist/{chunk-NNKVDYXN.js → chunk-KISG7E24.js} +57 -36
  53. package/dist/{chunk-DW6SLS5F.js → chunk-KP7E267S.js} +83 -24
  54. package/dist/{chunk-VMRKIKGO.js → chunk-LCRWDMCH.js} +1 -1
  55. package/dist/{chunk-AQKVWIPR.js → chunk-LIDEU7QS.js} +4 -4
  56. package/dist/{chunk-GCGJGSQL.js → chunk-S4PUICSB.js} +2 -0
  57. package/dist/{chunk-SS7MAJF5.js → chunk-TUHUIBDX.js} +60 -40
  58. package/dist/{chunk-PE44LDDQ.js → chunk-UTL3MHPC.js} +1 -0
  59. package/dist/{chunk-S7G34U75.js → chunk-VUBUFT66.js} +5 -121
  60. package/dist/{chunk-CMYDYVOD.js → chunk-WRH7DWFO.js} +15 -12
  61. package/dist/{chunk-574YK7QW.js → chunk-XLIAQRDI.js} +25 -10
  62. package/dist/{chunk-7P7YVJKH.js → chunk-XVKJJXHF.js} +17 -15
  63. package/dist/{chunk-4JW3YNQZ.js → chunk-YMSVBWBY.js} +9 -11
  64. package/dist/cli/chat.js +25 -25
  65. package/dist/cli/check.js +6 -7
  66. package/dist/cli/plugins.js +12 -13
  67. package/dist/cli/snapshot-create.js +9 -10
  68. package/dist/cli/upgrade.js +7 -8
  69. package/dist/db/schema/conversations.d.ts +20 -0
  70. package/dist/db/schema.d.ts +19 -0
  71. package/dist/{db-4SU2HJSV.js → db-AZB6AGJL.js} +7 -8
  72. package/dist/instrumentation.js +4 -5
  73. package/dist/nitro.js +2 -2
  74. package/dist/{oauth-callback-server-MMCH5QV6.js → oauth-callback-server-XK4QJLPZ.js} +18 -19
  75. package/dist/reporting-schema.d.ts +2 -0
  76. package/dist/{runner-ZDSNVGYA.js → runner-DSGDSATN.js} +13 -15
  77. package/dist/{skills-7G7LBHLK.js → skills-CO6E3BQJ.js} +6 -7
  78. package/dist/{validation-2ETDADPB.js → validation-IHLISKM5.js} +6 -7
  79. package/dist/version.js +1 -1
  80. package/migrations/0013_conversation_session_source.sql +38 -0
  81. package/migrations/0014_source_visibility.sql +8 -0
  82. package/migrations/meta/0013_snapshot.json +1250 -0
  83. package/migrations/meta/0014_snapshot.json +1201 -0
  84. package/migrations/meta/_journal.json +14 -0
  85. package/package.json +6 -6
  86. package/dist/chunk-BA5KHLPQ.js +0 -55
  87. package/dist/chunk-OB42YVAE.js +0 -16
@@ -0,0 +1,16 @@
1
+ import { type Source } from "@sentry/junior-plugin-api";
2
+ /** Source coordinates reduced to the stable locator for one conversation. */
3
+ export type SessionSource = Extract<Source, {
4
+ platform: "local";
5
+ }> | (Omit<Extract<Source, {
6
+ platform: "slack";
7
+ }>, "messageTs" | "threadTs"> & {
8
+ threadTs: string;
9
+ });
10
+ /**
11
+ * Normalize a turn Source into the session-stable locator persisted on a
12
+ * conversation. Drops per-message timestamps; requires a Slack thread anchor.
13
+ */
14
+ export declare function normalizeSessionSource(value: Source | undefined): SessionSource | undefined;
15
+ /** Parse a serialized Source into the stable locator stored on a conversation. */
16
+ export declare function parseSessionSource(value: unknown): SessionSource | undefined;
@@ -75,7 +75,7 @@ export declare function upsertAgentTurnSessionRecord(args: {
75
75
  dispatchId?: string;
76
76
  dispatchOutcome?: AgentDispatchOutcome;
77
77
  resultMessageId?: string;
78
- /** Source-confirmed destination visibility from the current event's signal. */
78
+ /** Confirmed destination visibility; omit when unavailable. */
79
79
  destinationVisibility?: ConversationPrivacy;
80
80
  source?: Source;
81
81
  lastProgressAtMs?: number;
@@ -110,11 +110,7 @@ export declare function recordAgentTurnSessionSummary(args: {
110
110
  dispatchId?: string;
111
111
  dispatchOutcome?: AgentDispatchOutcome;
112
112
  resultMessageId?: string;
113
- /**
114
- * Source-confirmed destination visibility from the current event's signal
115
- * (Slack `channel_type`). Leave unset when no live signal exists so an
116
- * existing destination visibility is not overwritten.
117
- */
113
+ /** Confirmed destination visibility; omit when unavailable. */
118
114
  destinationVisibility?: ConversationPrivacy;
119
115
  source?: Source;
120
116
  lastProgressAtMs?: number;
@@ -6,36 +6,34 @@ import {
6
6
  isDmChannel,
7
7
  normalizeSlackConversationId,
8
8
  withSlackRetries
9
- } from "./chunk-IXTIJQ7Z.js";
9
+ } from "./chunk-6KWO5DU3.js";
10
10
  import {
11
11
  getDb,
12
12
  parseDestination
13
- } from "./chunk-DW6SLS5F.js";
13
+ } from "./chunk-KP7E267S.js";
14
14
  import {
15
15
  acquireActiveLock,
16
16
  getStateAdapter,
17
17
  sleep
18
- } from "./chunk-KYKLQYSU.js";
18
+ } from "./chunk-APYVVX2Y.js";
19
19
  import {
20
20
  normalizeSlackEmojiName
21
- } from "./chunk-574YK7QW.js";
21
+ } from "./chunk-XLIAQRDI.js";
22
22
  import {
23
23
  pluginCatalogRuntime
24
- } from "./chunk-ZO6E537B.js";
24
+ } from "./chunk-GHNO2WUH.js";
25
25
  import {
26
26
  fetchWithBoundedOAuthErrorBodies
27
- } from "./chunk-EOSC6JOC.js";
28
- import {
29
- logInfo,
30
- logWarn
31
- } from "./chunk-ASK74NM6.js";
32
- import {
33
- isRecord
34
- } from "./chunk-OB42YVAE.js";
27
+ } from "./chunk-EFQX6XBW.js";
35
28
  import {
36
29
  parseSlackMessageTs,
37
30
  parseSlackUserId
38
31
  } from "./chunk-F3B2YJ76.js";
32
+ import {
33
+ isRecord,
34
+ logInfo,
35
+ logWarn
36
+ } from "./chunk-JP2ZOSQK.js";
39
37
 
40
38
  // src/chat/capabilities/router.ts
41
39
  var ProviderCredentialRouter = class {
@@ -1,27 +1,34 @@
1
1
  import {
2
+ getConversationEventStore,
2
3
  getDb
3
- } from "./chunk-DW6SLS5F.js";
4
+ } from "./chunk-KP7E267S.js";
4
5
  import {
5
6
  juniorConversationAnnotations,
7
+ juniorConversationEvents,
6
8
  juniorIdentities,
7
9
  juniorUsers
8
- } from "./chunk-GCGJGSQL.js";
10
+ } from "./chunk-S4PUICSB.js";
9
11
  import {
10
12
  SANDBOX_WORKSPACE_ROOT,
11
13
  getStateAdapter,
12
14
  sleep
13
- } from "./chunk-KYKLQYSU.js";
15
+ } from "./chunk-APYVVX2Y.js";
14
16
  import {
15
17
  botConfig,
16
18
  completeObject,
17
19
  embedTexts,
18
20
  getSlackBotToken,
19
21
  standardModelId
20
- } from "./chunk-574YK7QW.js";
22
+ } from "./chunk-XLIAQRDI.js";
21
23
  import {
22
24
  isActorUserId,
23
25
  parseActorUserId
24
26
  } from "./chunk-HZF5P5UN.js";
27
+ import {
28
+ parseSlackChannelReferenceId,
29
+ parseSlackMessageTs,
30
+ parseSlackTeamId
31
+ } from "./chunk-F3B2YJ76.js";
25
32
  import {
26
33
  logException,
27
34
  logInfo,
@@ -30,12 +37,7 @@ import {
30
37
  setSpanAttributes,
31
38
  setSpanStatus,
32
39
  withSpan
33
- } from "./chunk-ASK74NM6.js";
34
- import {
35
- parseSlackChannelReferenceId,
36
- parseSlackMessageTs,
37
- parseSlackTeamId
38
- } from "./chunk-F3B2YJ76.js";
40
+ } from "./chunk-JP2ZOSQK.js";
39
41
 
40
42
  // src/chat/plugins/agent-hooks.ts
41
43
  import {
@@ -106,6 +108,133 @@ async function listConversationAnnotations(db, conversationId) {
106
108
  });
107
109
  }
108
110
 
111
+ // src/chat/plugins/conversation-events.ts
112
+ function registeredDefinition(plugin, value) {
113
+ return plugin.conversationEvents?.find(
114
+ (definition) => definition === value.definition
115
+ );
116
+ }
117
+ function eventIdentityVersion(plugin, definition) {
118
+ let version = definition.version;
119
+ for (const candidate of plugin.conversationEvents ?? []) {
120
+ if (candidate.eventName === definition.eventName) {
121
+ version = Math.min(version, candidate.version);
122
+ }
123
+ }
124
+ return version;
125
+ }
126
+ function createPluginConversationEvents(args) {
127
+ return {
128
+ async emit(value) {
129
+ const definition = registeredDefinition(args.plugin, value);
130
+ if (!definition) {
131
+ throw new Error(
132
+ `Plugin "${args.plugin.manifest.name}" cannot emit an unregistered conversation event.`
133
+ );
134
+ }
135
+ const content = definition.parse(value.data);
136
+ const identityVersion = eventIdentityVersion(args.plugin, definition);
137
+ await getConversationEventStore().append(
138
+ args.conversationId,
139
+ [
140
+ {
141
+ createdAtMs: Date.now(),
142
+ idempotencyKey: `plugin:${args.plugin.manifest.name}:operation:${args.operationId}:event:${definition.eventName}@${identityVersion}`,
143
+ data: {
144
+ type: "structured_event",
145
+ namespace: args.plugin.manifest.name,
146
+ name: definition.eventName,
147
+ version: definition.version,
148
+ turnId: args.turnId,
149
+ content
150
+ }
151
+ }
152
+ ],
153
+ { activity: "preserve" }
154
+ );
155
+ }
156
+ };
157
+ }
158
+ function renderPluginConversationEvent(args) {
159
+ const plugin = getPlugins().find(
160
+ (candidate) => candidate.manifest.name === args.namespace
161
+ );
162
+ const definition = plugin?.conversationEvents?.find(
163
+ (candidate) => candidate.eventName === args.name && candidate.version === args.version
164
+ );
165
+ if (!definition) return void 0;
166
+ return definition.renderEvent(definition.parse(args.content));
167
+ }
168
+
169
+ // src/chat/plugins/conversation-event-stats.ts
170
+ import { and as and2, eq as eq2, gte, lt, sql } from "drizzle-orm";
171
+ import { z } from "zod";
172
+ var DAY_MS = 24 * 60 * 60 * 1e3;
173
+ var costRowSchema = z.object({
174
+ costUsd: z.number().finite().nonnegative(),
175
+ date: z.string().date(),
176
+ events: z.number().int().nonnegative()
177
+ }).strict();
178
+ function startOfUtcDay(value) {
179
+ const date = new Date(value);
180
+ date.setUTCHours(0, 0, 0, 0);
181
+ return date;
182
+ }
183
+ function registeredEventName(plugin, eventName) {
184
+ if (!plugin.conversationEvents?.some(
185
+ (definition) => definition.eventName === eventName
186
+ )) {
187
+ throw new TypeError(
188
+ `Plugin "${plugin.manifest.name}" did not register event "${eventName}"`
189
+ );
190
+ }
191
+ return eventName;
192
+ }
193
+ function createPluginConversationEventStats(plugin, now = Date.now) {
194
+ return {
195
+ async costsByDay(input) {
196
+ const eventName = registeredEventName(plugin, input.eventName);
197
+ const end = startOfUtcDay(now());
198
+ const start = new Date(end.getTime() - (input.days - 1) * DAY_MS);
199
+ const endExclusive = new Date(end.getTime() + DAY_MS);
200
+ const date = sql`TO_CHAR(
201
+ ${juniorConversationEvents.createdAt} AT TIME ZONE 'UTC',
202
+ 'YYYY-MM-DD'
203
+ )`;
204
+ const cost = sql`CASE
205
+ WHEN jsonb_typeof(${juniorConversationEvents.payload}->'content'->'costUsd') = 'number'
206
+ THEN (${juniorConversationEvents.payload}->'content'->>'costUsd')::double precision
207
+ ELSE 0
208
+ END`;
209
+ const rows = await getDb().select({
210
+ costUsd: sql`SUM(${cost})::double precision`.mapWith(Number),
211
+ date,
212
+ events: sql`COUNT(*)::integer`.mapWith(Number)
213
+ }).from(juniorConversationEvents).where(
214
+ and2(
215
+ eq2(juniorConversationEvents.type, "structured_event"),
216
+ sql`${juniorConversationEvents.payload}->>'namespace' = ${plugin.manifest.name}`,
217
+ sql`${juniorConversationEvents.payload}->>'name' = ${eventName}`,
218
+ gte(juniorConversationEvents.createdAt, start),
219
+ lt(juniorConversationEvents.createdAt, endExclusive)
220
+ )
221
+ ).groupBy(date);
222
+ const byDate = new Map(
223
+ z.array(costRowSchema).parse(rows).map((row) => [row.date, row])
224
+ );
225
+ return Array.from({ length: input.days }, (_, index) => {
226
+ const day = new Date(start.getTime() + index * DAY_MS);
227
+ const date2 = day.toISOString().slice(0, 10);
228
+ return byDate.get(date2) ?? {
229
+ costUsd: 0,
230
+ date: date2,
231
+ events: 0
232
+ };
233
+ });
234
+ }
235
+ };
236
+ }
237
+
109
238
  // src/chat/plugins/logging.ts
110
239
  function createPluginLogger(plugin) {
111
240
  return {
@@ -149,7 +278,10 @@ function createPluginModel(pluginName, options = {}, runtime = {}) {
149
278
  pluginModelRole: "structured"
150
279
  }
151
280
  });
152
- return { object: result.object };
281
+ return {
282
+ object: result.object,
283
+ ...result.costUsd !== void 0 ? { costUsd: result.costUsd } : {}
284
+ };
153
285
  }
154
286
  };
155
287
  }
@@ -321,7 +453,7 @@ function getSlackToolContext(context) {
321
453
  }
322
454
 
323
455
  // src/chat/plugins/viewer-actors.ts
324
- import { and as and2, eq as eq2 } from "drizzle-orm";
456
+ import { and as and3, eq as eq3 } from "drizzle-orm";
325
457
  import {
326
458
  actorSchema
327
459
  } from "@sentry/junior-plugin-api";
@@ -335,10 +467,10 @@ async function readViewerActorsFromSql(db, email) {
335
467
  provider: juniorIdentities.provider,
336
468
  providerSubjectId: juniorIdentities.providerSubjectId,
337
469
  providerTenantId: juniorIdentities.providerTenantId
338
- }).from(juniorIdentities).innerJoin(juniorUsers, eq2(juniorUsers.id, juniorIdentities.userId)).where(
339
- and2(
340
- eq2(juniorUsers.primaryEmailNormalized, normalizedEmail),
341
- eq2(juniorIdentities.kind, "user")
470
+ }).from(juniorIdentities).innerJoin(juniorUsers, eq3(juniorUsers.id, juniorIdentities.userId)).where(
471
+ and3(
472
+ eq3(juniorUsers.primaryEmailNormalized, normalizedEmail),
473
+ eq3(juniorIdentities.kind, "user")
342
474
  )
343
475
  );
344
476
  const actors = [];
@@ -919,7 +1051,7 @@ function resolveChannelCapabilities(channelId) {
919
1051
  }
920
1052
 
921
1053
  // src/chat/plugins/agent-hooks.ts
922
- import { z } from "zod";
1054
+ import { z as z2 } from "zod";
923
1055
  var PluginHookDeniedError = class extends Error {
924
1056
  constructor(message) {
925
1057
  super(message);
@@ -951,7 +1083,7 @@ var PLUGIN_ROUTE_METHODS = /* @__PURE__ */ new Set([
951
1083
  var PLUGIN_PROMPT_CONTRIBUTION_TOTAL_MAX_CHARS = 16e3;
952
1084
  var PLUGIN_PROMPT_CONTEXT_MAX_BYTES = 8e3;
953
1085
  var PLUGIN_PROMPT_CONTEXT_TOTAL_MAX_BYTES = 16e3;
954
- var systemPromptMessageArraySchema = z.array(promptMessageSchema);
1086
+ var systemPromptMessageArraySchema = z2.array(promptMessageSchema);
955
1087
  function isRecord(value) {
956
1088
  return Boolean(value && typeof value === "object" && !Array.isArray(value));
957
1089
  }
@@ -973,12 +1105,20 @@ function systemPromptPluginContext(plugin) {
973
1105
  ...basePluginContext(plugin)
974
1106
  };
975
1107
  }
976
- function invocationPluginContext(plugin, context) {
1108
+ function invocationPluginContext(plugin, context, turnId) {
977
1109
  const base = basePluginContext(plugin);
978
1110
  const common = {
979
1111
  ...base,
980
1112
  conversationId: context.conversationId,
981
1113
  embedder: createPluginEmbedder(plugin.manifest.name),
1114
+ ...context.conversationId && turnId ? {
1115
+ events: createPluginConversationEvents({
1116
+ conversationId: context.conversationId,
1117
+ operationId: `user-prompt:${turnId}`,
1118
+ plugin,
1119
+ turnId
1120
+ })
1121
+ } : {},
982
1122
  model: createPluginModel(plugin.manifest.name, plugin.model),
983
1123
  source: context.source,
984
1124
  text: context.userText ?? "",
@@ -1198,7 +1338,7 @@ async function getPluginUserPromptContributions(args) {
1198
1338
  }
1199
1339
  try {
1200
1340
  const rawResult = await hook({
1201
- ...invocationPluginContext(plugin, args.context)
1341
+ ...invocationPluginContext(plugin, args.context, args.turnId)
1202
1342
  });
1203
1343
  if (rawResult === void 0) {
1204
1344
  continue;
@@ -1471,6 +1611,7 @@ function getPluginApiRoutes() {
1471
1611
  }
1472
1612
  const app = hook({
1473
1613
  ...basePluginContext(plugin),
1614
+ eventStats: createPluginConversationEventStats(plugin),
1474
1615
  viewer: {
1475
1616
  actors: readViewerActors
1476
1617
  }
@@ -1647,6 +1788,9 @@ function sanitizeOperationalReport(args) {
1647
1788
  return void 0;
1648
1789
  }
1649
1790
  const sanitizedSeries = { key, label };
1791
+ if (item.format === "usd") {
1792
+ sanitizedSeries.format = "usd";
1793
+ }
1650
1794
  const tone = operationalReportTone(item.tone);
1651
1795
  if (tone) {
1652
1796
  sanitizedSeries.tone = tone;
@@ -1756,6 +1900,7 @@ async function getPluginOperationalReports(nowMs) {
1756
1900
  const state = createPluginState(pluginName);
1757
1901
  const report = await hook({
1758
1902
  ...basePluginContext(plugin),
1903
+ eventStats: createPluginConversationEventStats(plugin, () => nowMs),
1759
1904
  nowMs,
1760
1905
  state: pluginReadState(state)
1761
1906
  });
@@ -1930,6 +2075,8 @@ function createPluginHookRunner(input = {}) {
1930
2075
 
1931
2076
  export {
1932
2077
  listConversationAnnotations,
2078
+ createPluginConversationEvents,
2079
+ renderPluginConversationEvent,
1933
2080
  createPluginLogger,
1934
2081
  createPluginModel,
1935
2082
  createPluginEmbedder,
@@ -74,10 +74,22 @@ var actorIdentitySchema = z2.object({
74
74
  slackUserId: z2.string().optional(),
75
75
  slackUserName: z2.string().optional()
76
76
  }).strict();
77
+ var conversationAuxiliaryCostsSchema = z2.object({
78
+ costUsd: z2.number().finite().nonnegative(),
79
+ operations: z2.array(
80
+ z2.object({
81
+ costUsd: z2.number().finite().nonnegative(),
82
+ events: z2.number().int().positive(),
83
+ name: z2.string().min(1),
84
+ namespace: z2.string().min(1)
85
+ }).strict()
86
+ ).min(1)
87
+ }).strict();
77
88
  var conversationSummaryReportSchema = z2.object({
78
89
  displayTitle: z2.string(),
79
90
  cumulativeDurationMs: z2.number(),
80
91
  cumulativeUsage: conversationUsageSchema.optional(),
92
+ auxiliaryCosts: conversationAuxiliaryCostsSchema.optional(),
81
93
  conversationId: z2.string(),
82
94
  isParticipant: z2.boolean(),
83
95
  status: conversationReportStatusSchema,
@@ -92,6 +104,7 @@ var conversationSummaryReportSchema = z2.object({
92
104
  channelNameRedacted: z2.boolean().optional(),
93
105
  locationId: z2.string().optional(),
94
106
  sentryTraceUrl: z2.string().optional(),
107
+ sourceUrl: z2.string().url().optional(),
95
108
  traceId: z2.string().optional()
96
109
  }).strict();
97
110
  var conversationReportMessageEventDataSchema = z2.object({
@@ -592,6 +605,7 @@ export {
592
605
  conversationFeedQuerySchema,
593
606
  archiveConversationBodySchema,
594
607
  archiveConversationResponseSchema,
608
+ conversationAuxiliaryCostsSchema,
595
609
  conversationSummaryReportSchema,
596
610
  conversationReportEventDataSchema,
597
611
  conversationReportEventSchema,
@@ -0,0 +1,102 @@
1
+ import {
2
+ parseSlackChannelId,
3
+ parseSlackMessageTs,
4
+ parseSlackTeamId
5
+ } from "./chunk-F3B2YJ76.js";
6
+ import {
7
+ toOptionalString
8
+ } from "./chunk-JP2ZOSQK.js";
9
+
10
+ // src/chat/slack/context.ts
11
+ import { z } from "zod";
12
+ function toTrimmedSlackString(value) {
13
+ const normalized = toOptionalString(value);
14
+ return normalized?.trim() || void 0;
15
+ }
16
+ var slackMessageEnvelopeSchema = z.object({
17
+ raw: z.unknown().optional()
18
+ });
19
+ var rawSlackMessageSchema = z.object({
20
+ channel: z.unknown().optional(),
21
+ message: z.unknown().optional(),
22
+ team: z.unknown().optional(),
23
+ team_id: z.unknown().optional(),
24
+ thread_ts: z.unknown().optional(),
25
+ ts: z.unknown().optional(),
26
+ user_team: z.unknown().optional()
27
+ });
28
+ var nestedRawSlackMessageSchema = z.object({
29
+ ts: z.unknown().optional()
30
+ });
31
+ function readSlackRawMessageContext(message) {
32
+ const envelope = slackMessageEnvelopeSchema.safeParse(message);
33
+ if (!envelope.success) {
34
+ return void 0;
35
+ }
36
+ const raw = rawSlackMessageSchema.safeParse(envelope.data.raw);
37
+ if (!raw.success) {
38
+ return void 0;
39
+ }
40
+ const nestedMessage = nestedRawSlackMessageSchema.safeParse(raw.data.message);
41
+ const channelId = parseSlackChannelId(raw.data.channel);
42
+ const threadTs = parseSlackMessageTs(raw.data.thread_ts);
43
+ const messageTs = parseSlackMessageTs(raw.data.ts);
44
+ const nestedMessageTs = nestedMessage.success && parseSlackMessageTs(nestedMessage.data.ts);
45
+ const teamId = parseSlackTeamId(raw.data.team_id) ?? parseSlackTeamId(raw.data.team);
46
+ const authorTeamId = parseSlackTeamId(raw.data.user_team);
47
+ return {
48
+ ...channelId ? { channelId } : {},
49
+ ...threadTs ? { threadTs } : {},
50
+ ...messageTs ? { messageTs } : {},
51
+ ...nestedMessageTs ? { nestedMessageTs } : {},
52
+ ...teamId ? { teamId } : {},
53
+ ...authorTeamId ? { authorTeamId } : {}
54
+ };
55
+ }
56
+ function parseSlackThreadId(threadId) {
57
+ const normalizedThreadId = toTrimmedSlackString(threadId);
58
+ if (!normalizedThreadId) {
59
+ return void 0;
60
+ }
61
+ const parts = normalizedThreadId.split(":");
62
+ if (parts.length !== 3 || parts[0] !== "slack") {
63
+ return void 0;
64
+ }
65
+ const channelId = parseSlackChannelId(parts[1]);
66
+ const threadTs = parseSlackMessageTs(parts[2]);
67
+ if (!channelId || !threadTs) {
68
+ return void 0;
69
+ }
70
+ return { channelId, threadTs };
71
+ }
72
+ function resolveSlackChannelIdFromThreadId(threadId) {
73
+ return parseSlackThreadId(threadId)?.channelId;
74
+ }
75
+ function resolveSlackChannelIdFromMessage(message) {
76
+ const messageChannelId = parseSlackChannelId(
77
+ message.channelId
78
+ );
79
+ if (messageChannelId) {
80
+ return messageChannelId;
81
+ }
82
+ const raw = message.raw;
83
+ if (raw && typeof raw === "object") {
84
+ const rawChannel = parseSlackChannelId(
85
+ raw.channel
86
+ );
87
+ if (rawChannel) {
88
+ return rawChannel;
89
+ }
90
+ }
91
+ const threadId = toTrimmedSlackString(
92
+ message.threadId
93
+ );
94
+ return resolveSlackChannelIdFromThreadId(threadId);
95
+ }
96
+
97
+ export {
98
+ readSlackRawMessageContext,
99
+ parseSlackThreadId,
100
+ resolveSlackChannelIdFromThreadId,
101
+ resolveSlackChannelIdFromMessage
102
+ };
@@ -1,9 +1,9 @@
1
1
  import {
2
2
  pluginCatalogRuntime
3
- } from "./chunk-ZO6E537B.js";
3
+ } from "./chunk-GHNO2WUH.js";
4
4
  import {
5
5
  logWarn
6
- } from "./chunk-ASK74NM6.js";
6
+ } from "./chunk-JP2ZOSQK.js";
7
7
  import {
8
8
  skillRoots
9
9
  } from "./chunk-H4HBKISO.js";
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  getChatConfig
3
- } from "./chunk-574YK7QW.js";
3
+ } from "./chunk-XLIAQRDI.js";
4
4
 
5
5
  // src/chat/state/adapter.ts
6
6
  import { createMemoryState } from "@chat-adapter/state-memory";
@@ -5,7 +5,7 @@ import {
5
5
  logInfo,
6
6
  logWarn,
7
7
  setSpanAttributes
8
- } from "./chunk-ASK74NM6.js";
8
+ } from "./chunk-JP2ZOSQK.js";
9
9
  import {
10
10
  discoverInstalledPluginPackageContent,
11
11
  normalizePluginPackageNames
@@ -1,9 +1,9 @@
1
1
  import {
2
2
  getDb
3
- } from "./chunk-DW6SLS5F.js";
3
+ } from "./chunk-KP7E267S.js";
4
4
  import {
5
5
  juniorStats
6
- } from "./chunk-GCGJGSQL.js";
6
+ } from "./chunk-S4PUICSB.js";
7
7
 
8
8
  // src/stats.ts
9
9
  import { and, asc, gte, lte, sql } from "drizzle-orm";
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  createPluginCatalogRuntime
3
- } from "./chunk-EOSC6JOC.js";
3
+ } from "./chunk-EFQX6XBW.js";
4
4
 
5
5
  // src/chat/plugins/catalog-runtime.ts
6
6
  var pluginCatalogRuntime = createPluginCatalogRuntime();
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  pluginCatalogRuntime
3
- } from "./chunk-ZO6E537B.js";
3
+ } from "./chunk-GHNO2WUH.js";
4
4
 
5
5
  // src/chat/plugins/validation.ts
6
6
  import { isDeepStrictEqual } from "util";
@@ -57,7 +57,10 @@ var authenticationUnlinkedEvent = defineConversationEvent({
57
57
  };
58
58
  }
59
59
  });
60
- var NATIVE_EVENT_DEFINITIONS = [authenticationLinkedEvent, authenticationUnlinkedEvent];
60
+ var NATIVE_EVENT_DEFINITIONS = [
61
+ authenticationLinkedEvent,
62
+ authenticationUnlinkedEvent
63
+ ];
61
64
  function getJuniorNativeEventDefinition(args) {
62
65
  return NATIVE_EVENT_DEFINITIONS.find(
63
66
  (definition) => definition.eventName === args.name && definition.version === args.version
@@ -67,9 +70,8 @@ function renderJuniorNativeConversationEvent(args) {
67
70
  if (args.namespace !== JUNIOR_NATIVE_EVENT_NAMESPACE) return void 0;
68
71
  const definition = getJuniorNativeEventDefinition(args);
69
72
  if (!definition) return void 0;
70
- return conversationEventPresentationSchema.parse(
71
- definition.renderEvent(definition.parse(args.content))
72
- );
73
+ const presentation = definition.renderEvent(definition.parse(args.content));
74
+ return presentation === void 0 ? void 0 : conversationEventPresentationSchema.parse(presentation);
73
75
  }
74
76
 
75
77
  // src/chat/usage.ts
@@ -1,7 +1,7 @@
1
1
  // package.json
2
2
  var package_default = {
3
3
  name: "@sentry/junior",
4
- version: "0.124.2",
4
+ version: "0.126.0",
5
5
  private: false,
6
6
  publishConfig: {
7
7
  access: "public"
@@ -1,7 +1,3 @@
1
- import {
2
- toOptionalNumber,
3
- toOptionalString
4
- } from "./chunk-OB42YVAE.js";
5
1
  import {
6
2
  captureException,
7
3
  getActiveSpan,
@@ -13,7 +9,7 @@ import {
13
9
  } from "./chunk-6GWA276C.js";
14
10
  import {
15
11
  getDeploymentTelemetryAttributes
16
- } from "./chunk-VMRKIKGO.js";
12
+ } from "./chunk-LCRWDMCH.js";
17
13
 
18
14
  // src/chat/logging.ts
19
15
  import path from "path";
@@ -25,6 +21,17 @@ import {
25
21
  getLogger
26
22
  } from "@logtape/logtape";
27
23
 
24
+ // src/chat/coerce.ts
25
+ function toOptionalString(value) {
26
+ return typeof value === "string" && value.trim() ? value : void 0;
27
+ }
28
+ function toOptionalNumber(value) {
29
+ return typeof value === "number" && Number.isFinite(value) ? value : void 0;
30
+ }
31
+ function isRecord(value) {
32
+ return typeof value === "object" && value !== null;
33
+ }
34
+
28
35
  // src/chat/log-context.ts
29
36
  import { AsyncLocalStorage } from "async_hooks";
30
37
  var logContextStorage = new AsyncLocalStorage();
@@ -1455,6 +1462,9 @@ function extractGenAiUsageAttributes(...sources) {
1455
1462
  }
1456
1463
 
1457
1464
  export {
1465
+ toOptionalString,
1466
+ toOptionalNumber,
1467
+ isRecord,
1458
1468
  normalizeIdentityEmail,
1459
1469
  normalizeGenAiFinishReason,
1460
1470
  summarizeMessageText,