@sentry/junior 0.109.0 → 0.110.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 (92) hide show
  1. package/dist/{agent-hooks-FHHVLNPA.js → agent-hooks-ELT4ODFF.js} +12 -13
  2. package/dist/api/conversations/access.d.ts +9 -0
  3. package/dist/api/conversations/aggregate.d.ts +12 -1
  4. package/dist/api/conversations/archive.d.ts +3 -5
  5. package/dist/api/conversations/detail.d.ts +156 -7
  6. package/dist/api/conversations/events.d.ts +1 -1
  7. package/dist/api/conversations/list.d.ts +57 -6
  8. package/dist/api/conversations/projection.d.ts +6 -7
  9. package/dist/api/conversations/reporting.d.ts +10 -4
  10. package/dist/api/conversations/routes.d.ts +2 -1
  11. package/dist/api/conversations/shared.d.ts +1 -1
  12. package/dist/api/conversations/stats.d.ts +37 -6
  13. package/dist/api/conversations/stats.query.d.ts +1 -1
  14. package/dist/api/conversations/usage.d.ts +9 -0
  15. package/dist/api/http.d.ts +7 -0
  16. package/dist/api/locations/detail.d.ts +102 -6
  17. package/dist/api/locations/list.d.ts +43 -5
  18. package/dist/api/locations/query.d.ts +4 -2
  19. package/dist/api/locations/routes.d.ts +2 -1
  20. package/dist/api/people/list.d.ts +28 -6
  21. package/dist/api/people/list.query.d.ts +1 -1
  22. package/dist/api/people/profile.d.ts +96 -7
  23. package/dist/api/people/profile.query.d.ts +4 -2
  24. package/dist/api/people/routes.d.ts +2 -1
  25. package/dist/api/people/shared.d.ts +1219 -2
  26. package/dist/api/route.d.ts +18 -4
  27. package/dist/api/schema/common.d.ts +6 -0
  28. package/dist/api/{conversations/schema.d.ts → schema/conversation.d.ts} +31 -3
  29. package/dist/api/{locations/schema.d.ts → schema/location.d.ts} +5 -0
  30. package/dist/api/{people/schema.d.ts → schema/person.d.ts} +37 -45
  31. package/dist/api/schema.d.ts +8 -22
  32. package/dist/api/schema.js +10 -2
  33. package/dist/api.d.ts +5 -1
  34. package/dist/api.js +767 -384
  35. package/dist/app.js +87 -70
  36. package/dist/catalog-runtime-4GI22PXK.js +16 -0
  37. package/dist/chat/agent/resume.d.ts +11 -12
  38. package/dist/chat/conversations/history.d.ts +3 -0
  39. package/dist/chat/conversations/sql/privacy.d.ts +3 -15
  40. package/dist/chat/pi/messages.d.ts +2 -2
  41. package/dist/chat/pi/sql-model-usage.d.ts +4 -1
  42. package/dist/chat/services/auth-pause.d.ts +4 -0
  43. package/dist/chat/services/context-compaction.d.ts +1 -0
  44. package/dist/chat/task-execution/queue-signing.d.ts +10 -8
  45. package/dist/chat/task-execution/queue.d.ts +9 -7
  46. package/dist/chat/task-execution/slack-work.d.ts +6 -6
  47. package/dist/{chunk-QY636HZU.js → chunk-2T7TIEXI.js} +90 -7
  48. package/dist/{chunk-CEA3A3UA.js → chunk-2ZTTXTSZ.js} +24 -1
  49. package/dist/{chunk-FWJRXN4F.js → chunk-3S7YYHBI.js} +3 -139
  50. package/dist/{chunk-3SXUV423.js → chunk-3TV7OEHL.js} +1 -1
  51. package/dist/{chunk-MXW4GL53.js → chunk-3UBQI73J.js} +7 -7
  52. package/dist/{chunk-IVVGFRQQ.js → chunk-42WRQLJ6.js} +10 -38
  53. package/dist/{chunk-FENLIFJD.js → chunk-4QU44P7Q.js} +69 -10
  54. package/dist/{chunk-O3JMSZLI.js → chunk-6Y5L4BOM.js} +3 -5
  55. package/dist/{chunk-PLB7MRCQ.js → chunk-C4MZ3GP5.js} +1 -1
  56. package/dist/{chunk-72OMGPDS.js → chunk-C5XAFTHY.js} +7 -9
  57. package/dist/{chunk-HHVY4SMP.js → chunk-FPK7XY3F.js} +98 -92
  58. package/dist/{chunk-OUHNWH46.js → chunk-GK47NBDE.js} +1 -1
  59. package/dist/{chunk-ISMWX44P.js → chunk-IYKPU7H6.js} +2 -2
  60. package/dist/{chunk-TMBRFULF.js → chunk-JQFJO5WH.js} +7 -1
  61. package/dist/{chunk-RGX4V75M.js → chunk-L5XQPJ7T.js} +3 -3
  62. package/dist/{chunk-7Q6WCISF.js → chunk-MIAKQNYX.js} +43 -31
  63. package/dist/{chunk-IXKSQGIO.js → chunk-RHHRKSPI.js} +178 -142
  64. package/dist/{chunk-WHMOBKT7.js → chunk-SBOBTS27.js} +2 -2
  65. package/dist/{chunk-HO5NT6OE.js → chunk-W6RJZG7F.js} +4 -4
  66. package/dist/chunk-W75ZPAGG.js +44 -0
  67. package/dist/{chunk-JNAVF45E.js → chunk-WNOVRQ67.js} +2 -2
  68. package/dist/{chunk-TT6GMXNA.js → chunk-Y3H2DN6F.js} +2 -2
  69. package/dist/{chunk-MGUMR35T.js → chunk-Y5FK3CNG.js} +1 -1
  70. package/dist/{chunk-OCD3OZRK.js → chunk-ZKIOWEFL.js} +1 -1
  71. package/dist/cli/chat.js +23 -24
  72. package/dist/cli/check.js +8 -8
  73. package/dist/cli/plugins.js +15 -16
  74. package/dist/cli/snapshot-warmup.js +11 -11
  75. package/dist/cli/upgrade.js +9 -9
  76. package/dist/db/schema/conversations.d.ts +17 -0
  77. package/dist/db/schema.d.ts +17 -0
  78. package/dist/{db-V3NU72O2.js → db-Y6W6CWWW.js} +8 -9
  79. package/dist/instrumentation.js +4 -4
  80. package/dist/nitro.js +3 -4
  81. package/dist/reporting-schema.d.ts +46 -0
  82. package/dist/{runner-JYBCQBLK.js → runner-BBFV5GLR.js} +14 -15
  83. package/dist/{skills-U6MDAST7.js → skills-AR4AF32L.js} +8 -8
  84. package/dist/{validation-72N3JVRU.js → validation-FBIEPTC2.js} +8 -8
  85. package/dist/version.js +1 -1
  86. package/migrations/0007_thick_sugar_man.sql +23 -0
  87. package/migrations/meta/0007_snapshot.json +1013 -0
  88. package/migrations/meta/_journal.json +7 -0
  89. package/package.json +5 -5
  90. package/dist/catalog-runtime-DMGJSLV2.js +0 -16
  91. package/dist/chunk-OB42YVAE.js +0 -16
  92. package/dist/chunk-SYAQIR5Z.js +0 -53
@@ -1,36 +1,36 @@
1
1
  import {
2
2
  SANDBOX_WORKSPACE_ROOT,
3
3
  getStateAdapter
4
- } from "./chunk-OUHNWH46.js";
4
+ } from "./chunk-GK47NBDE.js";
5
5
  import {
6
6
  isConversationChannel,
7
7
  isConversationScopedChannel,
8
8
  isDmChannel,
9
9
  normalizeSlackConversationId
10
- } from "./chunk-RGX4V75M.js";
10
+ } from "./chunk-L5XQPJ7T.js";
11
11
  import {
12
12
  getDb
13
- } from "./chunk-FENLIFJD.js";
13
+ } from "./chunk-4QU44P7Q.js";
14
14
  import {
15
15
  botConfig,
16
16
  completeObject,
17
17
  embedTexts,
18
18
  standardModelId
19
- } from "./chunk-JNAVF45E.js";
19
+ } from "./chunk-WNOVRQ67.js";
20
20
  import {
21
21
  isActorUserId,
22
22
  parseActorUserId
23
- } from "./chunk-PLB7MRCQ.js";
23
+ } from "./chunk-C4MZ3GP5.js";
24
24
  import {
25
25
  logException,
26
26
  logInfo,
27
27
  logWarn
28
- } from "./chunk-ISMWX44P.js";
28
+ } from "./chunk-IYKPU7H6.js";
29
29
  import {
30
30
  parseSlackChannelReferenceId,
31
31
  parseSlackMessageTs,
32
32
  parseSlackTeamId
33
- } from "./chunk-IVVGFRQQ.js";
33
+ } from "./chunk-42WRQLJ6.js";
34
34
 
35
35
  // src/chat/plugins/agent-hooks.ts
36
36
  import {
@@ -406,6 +406,9 @@ var registeredPlugins = [];
406
406
  var PLUGIN_NAME_RE = /^[a-z][a-z0-9-]*$/;
407
407
  var PLUGIN_TOOL_NAME_RE = /^[a-z][A-Za-z0-9]*$/;
408
408
  var OPERATIONAL_REPORT_MAX_METRICS = 8;
409
+ var OPERATIONAL_REPORT_MAX_WIDGETS = 12;
410
+ var OPERATIONAL_REPORT_MAX_CHART_SERIES = 8;
411
+ var OPERATIONAL_REPORT_MAX_CHART_CATEGORIES = 100;
409
412
  var OPERATIONAL_REPORT_MAX_RECORD_SETS = 8;
410
413
  var OPERATIONAL_REPORT_MAX_FIELDS = 8;
411
414
  var OPERATIONAL_REPORT_MAX_RECORDS = 25;
@@ -1004,6 +1007,83 @@ function sanitizeOperationalReport(args) {
1004
1007
  }).filter(
1005
1008
  (recordSet) => Boolean(recordSet)
1006
1009
  );
1010
+ const widgets = args.report.widgets?.slice(0, OPERATIONAL_REPORT_MAX_WIDGETS).map((widget, widgetIndex) => {
1011
+ const id = operationalReportText(widget.id, OPERATIONAL_REPORT_MAX_LABEL_LENGTH) ?? String(widgetIndex);
1012
+ const title2 = operationalReportText(
1013
+ widget.title,
1014
+ OPERATIONAL_REPORT_MAX_LABEL_LENGTH
1015
+ );
1016
+ if (!title2) {
1017
+ return void 0;
1018
+ }
1019
+ const seriesEntries = widget.series.slice(0, OPERATIONAL_REPORT_MAX_CHART_SERIES).map((item) => {
1020
+ const key = operationalReportText(
1021
+ item.key,
1022
+ OPERATIONAL_REPORT_MAX_LABEL_LENGTH
1023
+ );
1024
+ const label = operationalReportText(
1025
+ item.label,
1026
+ OPERATIONAL_REPORT_MAX_LABEL_LENGTH
1027
+ );
1028
+ if (!key || !label) {
1029
+ return void 0;
1030
+ }
1031
+ const sanitizedSeries = { key, label };
1032
+ const tone = operationalReportTone(item.tone);
1033
+ if (tone) {
1034
+ sanitizedSeries.tone = tone;
1035
+ }
1036
+ return { sanitizedSeries, sourceKey: item.key };
1037
+ }).filter((item) => Boolean(item));
1038
+ if (!seriesEntries.length) {
1039
+ return void 0;
1040
+ }
1041
+ const series = seriesEntries.map((item) => item.sanitizedSeries);
1042
+ const categories = widget.categories.slice(-OPERATIONAL_REPORT_MAX_CHART_CATEGORIES).map((category, categoryIndex) => ({
1043
+ id: operationalReportText(
1044
+ category.id,
1045
+ OPERATIONAL_REPORT_MAX_LABEL_LENGTH
1046
+ ) ?? `${widgetIndex}:${categoryIndex}`,
1047
+ label: operationalReportText(
1048
+ category.label,
1049
+ OPERATIONAL_REPORT_MAX_LABEL_LENGTH
1050
+ ) ?? String(categoryIndex + 1),
1051
+ values: Object.fromEntries(
1052
+ seriesEntries.map(({ sanitizedSeries, sourceKey }) => [
1053
+ sanitizedSeries.key,
1054
+ Number.isFinite(category.values[sourceKey]) ? category.values[sourceKey] : 0
1055
+ ])
1056
+ )
1057
+ }));
1058
+ const sanitizedWidget = {
1059
+ categories,
1060
+ id,
1061
+ series,
1062
+ title: title2,
1063
+ type: "bar_chart"
1064
+ };
1065
+ const description = operationalReportText(
1066
+ widget.description,
1067
+ OPERATIONAL_REPORT_MAX_VALUE_LENGTH
1068
+ );
1069
+ if (description) {
1070
+ sanitizedWidget.description = description;
1071
+ }
1072
+ const emptyText = operationalReportText(
1073
+ widget.emptyText,
1074
+ OPERATIONAL_REPORT_MAX_VALUE_LENGTH
1075
+ );
1076
+ if (emptyText) {
1077
+ sanitizedWidget.emptyText = emptyText;
1078
+ }
1079
+ const timeRangeDays = widget.timeRangeDays?.filter(
1080
+ (days) => days === 7 || days === 30 || days === 90
1081
+ );
1082
+ if (timeRangeDays?.length) {
1083
+ sanitizedWidget.timeRangeDays = [...new Set(timeRangeDays)];
1084
+ }
1085
+ return sanitizedWidget;
1086
+ }).filter((widget) => Boolean(widget));
1007
1087
  const sanitized = {
1008
1088
  pluginName: args.pluginName
1009
1089
  };
@@ -1020,6 +1100,9 @@ function sanitizeOperationalReport(args) {
1020
1100
  if (metrics?.length) {
1021
1101
  sanitized.metrics = metrics;
1022
1102
  }
1103
+ if (widgets?.length) {
1104
+ sanitized.widgets = widgets;
1105
+ }
1023
1106
  const title = operationalReportText(
1024
1107
  args.report.title,
1025
1108
  OPERATIONAL_REPORT_MAX_LABEL_LENGTH
@@ -59,12 +59,35 @@ var pluginOperationalRecordSetSchema = z.object({
59
59
  records: z.array(pluginOperationalRecordSchema).optional(),
60
60
  title: z.string()
61
61
  }).strict();
62
+ var pluginOperationalBarChartWidgetSchema = z.object({
63
+ categories: z.array(
64
+ z.object({
65
+ id: z.string().min(1),
66
+ label: z.string().min(1),
67
+ values: z.record(z.string(), z.number().finite())
68
+ }).strict()
69
+ ).max(100),
70
+ description: z.string().optional(),
71
+ emptyText: z.string().optional(),
72
+ id: z.string().min(1),
73
+ series: z.array(
74
+ z.object({
75
+ key: z.string().min(1),
76
+ label: z.string().min(1),
77
+ tone: pluginOperationalToneSchema.optional()
78
+ }).strict()
79
+ ).min(1).max(8),
80
+ timeRangeDays: z.array(z.union([z.literal(7), z.literal(30), z.literal(90)])).min(1).max(3).optional(),
81
+ title: z.string().min(1),
82
+ type: z.literal("bar_chart")
83
+ }).strict();
62
84
  var pluginOperationalReportSchema = z.object({
63
85
  generatedAt: z.string().optional(),
64
86
  metrics: z.array(pluginOperationalMetricSchema).optional(),
65
87
  recordSets: z.array(pluginOperationalRecordSetSchema).optional(),
66
88
  title: z.string().optional(),
67
- pluginName: z.string()
89
+ pluginName: z.string(),
90
+ widgets: z.array(pluginOperationalBarChartWidgetSchema).max(12).optional()
68
91
  }).strict();
69
92
  var pluginOperationalReportFeedSchema = z.object({
70
93
  generatedAt: z.string(),
@@ -1,19 +1,12 @@
1
1
  import {
2
2
  healthReportSchema
3
- } from "./chunk-CEA3A3UA.js";
3
+ } from "./chunk-2ZTTXTSZ.js";
4
4
  import {
5
5
  normalizeSlackConversationId
6
- } from "./chunk-RGX4V75M.js";
7
- import {
8
- juniorConversationEvents,
9
- juniorConversations
10
- } from "./chunk-TMBRFULF.js";
11
- import {
12
- juniorDestinations
13
- } from "./chunk-VFUK3X5B.js";
6
+ } from "./chunk-L5XQPJ7T.js";
14
7
  import {
15
8
  parseSlackThreadId
16
- } from "./chunk-O3JMSZLI.js";
9
+ } from "./chunk-6Y5L4BOM.js";
17
10
  import {
18
11
  getClient
19
12
  } from "./chunk-6GWA276C.js";
@@ -66,133 +59,6 @@ function buildSentryConversationUrl(conversationId) {
66
59
  return `${buildSentryWebBaseUrl(dsn)}/organizations/${orgSlug}/${path}`;
67
60
  }
68
61
 
69
- // src/chat/conversations/sql/privacy.ts
70
- import { and, asc, eq, getTableColumns, inArray, sql } from "drizzle-orm";
71
- var MAX_LINEAGE_DEPTH = 32;
72
- var conversationEventColumns = getTableColumns(juniorConversationEvents);
73
- function rootVisibilitySnapshotSql(conversationId) {
74
- return sql`(
75
- with recursive lineage(
76
- conversation_id,
77
- parent_conversation_id,
78
- destination_id,
79
- path,
80
- depth
81
- ) as (
82
- select
83
- requested.conversation_id,
84
- requested.parent_conversation_id,
85
- requested.destination_id,
86
- array[requested.conversation_id]::text[],
87
- 1
88
- from junior_conversations requested
89
- where requested.conversation_id = ${conversationId}
90
-
91
- union all
92
-
93
- select
94
- parent.conversation_id,
95
- parent.parent_conversation_id,
96
- parent.destination_id,
97
- lineage.path || parent.conversation_id,
98
- lineage.depth + 1
99
- from lineage
100
- join junior_conversations parent
101
- on parent.conversation_id = lineage.parent_conversation_id
102
- where lineage.depth < ${MAX_LINEAGE_DEPTH}
103
- and not (parent.conversation_id = any(lineage.path))
104
- ),
105
- root_candidate as (
106
- select lineage.conversation_id, lineage.destination_id
107
- from lineage
108
- where lineage.parent_conversation_id is null
109
- and lineage.destination_id is not null
110
- limit 1
111
- )
112
- select jsonb_build_object(
113
- 'rootConversationId', coalesce(root.conversation_id, ${conversationId}),
114
- 'visibility', destination.visibility
115
- )
116
- from (select 1) seed
117
- left join root_candidate root on true
118
- left join junior_destinations destination
119
- on destination.id = root.destination_id
120
- )`;
121
- }
122
- async function readConversationEventPrivacySnapshot(executor, args) {
123
- const rows = await executor.db().select({
124
- privacy: rootVisibilitySnapshotSql(args.conversationId),
125
- event: {
126
- ...conversationEventColumns,
127
- // Replacement history is model context, never dashboard report data.
128
- // Keep the required replacement field while redacting its contents.
129
- payload: sql`case
130
- when ${juniorConversationEvents.type} in ('compaction', 'handoff')
131
- then jsonb_set(
132
- ${juniorConversationEvents.payload},
133
- '{replacementHistory}',
134
- '[]'::jsonb
135
- )
136
- else ${juniorConversationEvents.payload}
137
- end`
138
- }
139
- }).from(juniorConversations).leftJoin(
140
- juniorConversationEvents,
141
- and(
142
- eq(juniorConversationEvents.conversationId, args.conversationId),
143
- inArray(juniorConversationEvents.type, [...args.eventTypes])
144
- )
145
- ).where(eq(juniorConversations.conversationId, args.conversationId)).orderBy(asc(juniorConversationEvents.seq));
146
- const first = rows[0];
147
- if (!first) return void 0;
148
- return {
149
- ...first.privacy,
150
- events: rows.flatMap(({ event }) => event ? [event] : [])
151
- };
152
- }
153
- async function readLineageRow(executor, conversationId) {
154
- const rows = await executor.db().select({
155
- parentId: juniorConversations.parentConversationId,
156
- destinationId: juniorConversations.destinationId
157
- }).from(juniorConversations).where(eq(juniorConversations.conversationId, conversationId));
158
- return rows[0];
159
- }
160
- async function traceLineage(executor, conversationId) {
161
- let currentId = conversationId;
162
- const seen = /* @__PURE__ */ new Set();
163
- while (!seen.has(currentId) && seen.size < MAX_LINEAGE_DEPTH) {
164
- seen.add(currentId);
165
- const row = await readLineageRow(executor, currentId);
166
- if (!row) return void 0;
167
- if (row.parentId) {
168
- currentId = row.parentId;
169
- continue;
170
- }
171
- if (!row.destinationId) {
172
- return void 0;
173
- }
174
- return {
175
- destinationId: row.destinationId,
176
- rootConversationId: currentId
177
- };
178
- }
179
- return void 0;
180
- }
181
- async function readCandidateVisibility(executor, candidate) {
182
- const destinations = await executor.db().select({ visibility: juniorDestinations.visibility }).from(juniorDestinations).where(eq(juniorDestinations.id, candidate.destinationId)).for("share");
183
- return {
184
- rootConversationId: candidate.rootConversationId,
185
- visibility: destinations[0]?.visibility ?? null
186
- };
187
- }
188
- async function resolveRootVisibility(executor, conversationId) {
189
- const candidate = await traceLineage(executor, conversationId);
190
- if (!candidate) {
191
- return { rootConversationId: conversationId, visibility: null };
192
- }
193
- return readCandidateVisibility(executor, candidate);
194
- }
195
-
196
62
  // src/chat/slack/conversation-context.ts
197
63
  function normalizeConversationName(type, channelName) {
198
64
  const trimmed = channelName?.trim();
@@ -279,8 +145,6 @@ export {
279
145
  readHealthReport,
280
146
  GET,
281
147
  buildSentryConversationUrl,
282
- readConversationEventPrivacySnapshot,
283
- resolveRootVisibility,
284
148
  conversationVisibilityFromSlackChannelType,
285
149
  resolveSlackChannelTypeFromMessage,
286
150
  resolveSlackConversationContext,
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  createPluginCatalogRuntime
3
- } from "./chunk-TT6GMXNA.js";
3
+ } from "./chunk-Y3H2DN6F.js";
4
4
 
5
5
  // src/chat/plugins/catalog-runtime.ts
6
6
  var pluginCatalogRuntime = createPluginCatalogRuntime();
@@ -14,20 +14,20 @@ import {
14
14
  markTurnCompleted,
15
15
  mergeArtifactsState,
16
16
  updateConversationStats
17
- } from "./chunk-72OMGPDS.js";
17
+ } from "./chunk-C5XAFTHY.js";
18
18
  import {
19
19
  createPluginEmbedder,
20
20
  createPluginLogger,
21
21
  createPluginModel,
22
22
  createPluginState,
23
23
  getPlugins
24
- } from "./chunk-QY636HZU.js";
24
+ } from "./chunk-2T7TIEXI.js";
25
25
  import {
26
26
  getStateAdapter
27
- } from "./chunk-OUHNWH46.js";
27
+ } from "./chunk-GK47NBDE.js";
28
28
  import {
29
29
  getDb
30
- } from "./chunk-FENLIFJD.js";
30
+ } from "./chunk-4QU44P7Q.js";
31
31
  import {
32
32
  getPiMessageRole,
33
33
  instructionTextForProjection,
@@ -35,13 +35,13 @@ import {
35
35
  isToolResultMessage,
36
36
  normalizeToolNameFromResult,
37
37
  stripRuntimeTurnContext
38
- } from "./chunk-JNAVF45E.js";
38
+ } from "./chunk-WNOVRQ67.js";
39
39
  import {
40
40
  buildTurnFailureResponse
41
- } from "./chunk-ISMWX44P.js";
41
+ } from "./chunk-IYKPU7H6.js";
42
42
  import {
43
43
  parseSlackMessageTs
44
- } from "./chunk-IVVGFRQQ.js";
44
+ } from "./chunk-42WRQLJ6.js";
45
45
 
46
46
  // src/chat/services/turn-failure-response.ts
47
47
  function requireTurnFailureEventId(eventId, eventName) {
@@ -1,34 +1,12 @@
1
- import {
2
- JUNIOR_VERSION
3
- } from "./chunk-OCD3OZRK.js";
4
-
5
- // src/deployment.ts
6
- var JUNIOR_HEARTBEAT_ROUTE = "/api/internal/heartbeat";
7
- var JUNIOR_HEARTBEAT_CRON_SCHEDULE = "* * * * *";
8
- var JUNIOR_RETENTION_ROUTE = "/api/internal/retention";
9
- var JUNIOR_RETENTION_CRON_SCHEDULE = "0 4 * * *";
10
- var JUNIOR_CONVERSATION_WORK_CALLBACK_ROUTE = "/api/internal/agent/continue";
11
- var JUNIOR_PLUGIN_TASK_CALLBACK_ROUTE = "/api/internal/plugin/tasks";
12
- var LEGACY_JUNIOR_CONVERSATION_WORK_FUNCTION = "api/internal/agent/continue.ts";
13
- function toOptionalTrimmed(value) {
14
- const trimmed = value?.trim();
15
- return trimmed ? trimmed : void 0;
1
+ // src/chat/coerce.ts
2
+ function toOptionalString(value) {
3
+ return typeof value === "string" && value.trim() ? value : void 0;
16
4
  }
17
- function getDeploymentServiceVersion() {
18
- return toOptionalTrimmed(process.env.SENTRY_RELEASE) ?? toOptionalTrimmed(process.env.VERCEL_GIT_COMMIT_SHA);
5
+ function toOptionalNumber(value) {
6
+ return typeof value === "number" && Number.isFinite(value) ? value : void 0;
19
7
  }
20
- function getDeploymentTelemetryAttributes() {
21
- const attributes = {};
22
- const serviceVersion = getDeploymentServiceVersion();
23
- const deploymentId = toOptionalTrimmed(process.env.VERCEL_DEPLOYMENT_ID);
24
- attributes["app.junior.version"] = JUNIOR_VERSION;
25
- if (serviceVersion) {
26
- attributes["service.version"] = serviceVersion;
27
- }
28
- if (deploymentId) {
29
- attributes["deployment.id"] = deploymentId;
30
- }
31
- return attributes;
8
+ function isRecord(value) {
9
+ return typeof value === "object" && value !== null;
32
10
  }
33
11
 
34
12
  // src/chat/slack/timestamp.ts
@@ -82,15 +60,9 @@ function parseSlackUserId(value) {
82
60
  }
83
61
 
84
62
  export {
85
- JUNIOR_HEARTBEAT_ROUTE,
86
- JUNIOR_HEARTBEAT_CRON_SCHEDULE,
87
- JUNIOR_RETENTION_ROUTE,
88
- JUNIOR_RETENTION_CRON_SCHEDULE,
89
- JUNIOR_CONVERSATION_WORK_CALLBACK_ROUTE,
90
- JUNIOR_PLUGIN_TASK_CALLBACK_ROUTE,
91
- LEGACY_JUNIOR_CONVERSATION_WORK_FUNCTION,
92
- getDeploymentServiceVersion,
93
- getDeploymentTelemetryAttributes,
63
+ toOptionalString,
64
+ toOptionalNumber,
65
+ isRecord,
94
66
  parseSlackMessageTs,
95
67
  parseSlackChannelId,
96
68
  parseSlackChannelReferenceId,
@@ -4,26 +4,67 @@ import {
4
4
  juniorConversations,
5
5
  juniorIdentities,
6
6
  juniorUsers
7
- } from "./chunk-TMBRFULF.js";
7
+ } from "./chunk-JQFJO5WH.js";
8
8
  import {
9
9
  getChatConfig,
10
10
  modelProfileSchema
11
- } from "./chunk-JNAVF45E.js";
11
+ } from "./chunk-WNOVRQ67.js";
12
12
  import {
13
13
  juniorDestinations
14
14
  } from "./chunk-VFUK3X5B.js";
15
- import {
16
- parseDestination,
17
- sameDestination
18
- } from "./chunk-SYAQIR5Z.js";
19
15
  import {
20
16
  normalizeIdentityEmail
21
- } from "./chunk-ISMWX44P.js";
17
+ } from "./chunk-IYKPU7H6.js";
18
+ import {
19
+ parseSlackChannelReferenceId,
20
+ parseSlackTeamId
21
+ } from "./chunk-42WRQLJ6.js";
22
22
 
23
23
  // src/chat/conversations/sql/store.ts
24
24
  import { randomUUID as randomUUID2 } from "crypto";
25
25
  import { and as and2, asc, desc, eq as eq2, isNull, sql as sql2 } from "drizzle-orm";
26
26
 
27
+ // src/chat/destination.ts
28
+ import {
29
+ destinationSchema
30
+ } from "@sentry/junior-plugin-api";
31
+ function createSlackDestination(input) {
32
+ const channelId = parseSlackChannelReferenceId(input.channelId);
33
+ const teamId = parseSlackTeamId(input.teamId);
34
+ if (!channelId || !teamId) {
35
+ return void 0;
36
+ }
37
+ return { platform: "slack", teamId, channelId };
38
+ }
39
+ function parseDestination(value) {
40
+ const parsed = destinationSchema.safeParse(value);
41
+ return parsed.success ? parsed.data : void 0;
42
+ }
43
+ function requireSlackDestination(destination, action) {
44
+ if (destination?.platform === "slack") {
45
+ return destination;
46
+ }
47
+ throw new Error(`${action} requires a Slack destination`);
48
+ }
49
+ function sameDestination(left, right) {
50
+ if (left.platform !== right.platform) {
51
+ return false;
52
+ }
53
+ if (left.platform === "local" && right.platform === "local") {
54
+ return left.conversationId === right.conversationId;
55
+ }
56
+ if (left.platform === "slack" && right.platform === "slack") {
57
+ return left.teamId === right.teamId && left.channelId === right.channelId;
58
+ }
59
+ return false;
60
+ }
61
+ function destinationKey(destination) {
62
+ if (destination.platform === "local") {
63
+ return destination.conversationId;
64
+ }
65
+ return `slack:${destination.teamId}:${destination.channelId}`;
66
+ }
67
+
27
68
  // src/chat/identities/sql.ts
28
69
  import { randomUUID } from "crypto";
29
70
  import { and, eq, sql } from "drizzle-orm";
@@ -592,7 +633,12 @@ var SqlStore = class {
592
633
  actorIdentityObservation,
593
634
  conversation.updatedAtMs
594
635
  ) : void 0;
595
- await this.executor.db().insert(juniorConversations).values({
636
+ const rootConversationId = conversation.lineage ? sql2`(
637
+ select parent.root_conversation_id
638
+ from junior_conversations parent
639
+ where parent.conversation_id = ${conversation.lineage.parentConversationId}
640
+ )` : conversation.conversationId;
641
+ const rows = await this.executor.db().insert(juniorConversations).values({
596
642
  conversationId: conversation.conversationId,
597
643
  schemaVersion: 1,
598
644
  source: conversation.source ?? null,
@@ -615,7 +661,8 @@ var SqlStore = class {
615
661
  runId: conversation.execution.runId ?? null,
616
662
  lastCheckpointAt: conversation.execution.lastCheckpointAtMs === void 0 ? null : dateFromMs2(conversation.execution.lastCheckpointAtMs),
617
663
  lastEnqueuedAt: conversation.execution.lastEnqueuedAtMs === void 0 ? null : dateFromMs2(conversation.execution.lastEnqueuedAtMs),
618
- parentConversationId: conversation.lineage?.parentConversationId ?? null
664
+ parentConversationId: conversation.lineage?.parentConversationId ?? null,
665
+ rootConversationId
619
666
  }).onConflictDoUpdate({
620
667
  target: juniorConversations.conversationId,
621
668
  set: {
@@ -636,9 +683,15 @@ var SqlStore = class {
636
683
  executionStatus: sql2`case when ${incomingExecutionIsFresh} then excluded.execution_status else ${juniorConversations.executionStatus} end`,
637
684
  runId: sql2`case when ${incomingExecutionIsFresh} then excluded.run_id else ${juniorConversations.runId} end`,
638
685
  lastCheckpointAt: sql2`case when ${incomingExecutionIsFresh} then coalesce(excluded.last_checkpoint_at, ${juniorConversations.lastCheckpointAt}) else ${juniorConversations.lastCheckpointAt} end`,
639
- lastEnqueuedAt: sql2`case when ${incomingExecutionIsFresh} then coalesce(excluded.last_enqueued_at, ${juniorConversations.lastEnqueuedAt}) else ${juniorConversations.lastEnqueuedAt} end`
686
+ lastEnqueuedAt: sql2`case when ${incomingExecutionIsFresh} then coalesce(excluded.last_enqueued_at, ${juniorConversations.lastEnqueuedAt}) else ${juniorConversations.lastEnqueuedAt} end`,
687
+ rootConversationId: sql2`coalesce(${juniorConversations.rootConversationId}, excluded.root_conversation_id)`
640
688
  }
689
+ }).returning({
690
+ rootConversationId: juniorConversations.rootConversationId
641
691
  });
692
+ if (!rows[0]?.rootConversationId) {
693
+ throw new Error("Conversation parent is missing its persisted root");
694
+ }
642
695
  }
643
696
  async upsertDestination(destination, nowMs) {
644
697
  if (!destination) {
@@ -761,6 +814,7 @@ var historyReplacementEventDataSchema = z2.discriminatedUnion("type", [
761
814
  type: z2.literal("handoff"),
762
815
  modelProfile: handoffModelProfileSchema,
763
816
  modelId: z2.string().min(1),
817
+ reasoningLevel: z2.string().min(1).optional(),
764
818
  triggeringToolCallId: z2.string().min(1).optional(),
765
819
  replacementHistory: replacementHistorySchema
766
820
  }).strict(),
@@ -1344,6 +1398,11 @@ async function closeDb() {
1344
1398
  }
1345
1399
 
1346
1400
  export {
1401
+ createSlackDestination,
1402
+ parseDestination,
1403
+ requireSlackDestination,
1404
+ sameDestination,
1405
+ destinationKey,
1347
1406
  instructionProvenanceFor,
1348
1407
  contextProvenance,
1349
1408
  instructionActors,
@@ -1,11 +1,9 @@
1
- import {
2
- toOptionalString
3
- } from "./chunk-OB42YVAE.js";
4
1
  import {
5
2
  parseSlackChannelId,
6
3
  parseSlackMessageTs,
7
- parseSlackTeamId
8
- } from "./chunk-IVVGFRQQ.js";
4
+ parseSlackTeamId,
5
+ toOptionalString
6
+ } from "./chunk-42WRQLJ6.js";
9
7
 
10
8
  // src/chat/conversation-privacy.ts
11
9
  import { AsyncLocalStorage } from "async_hooks";
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  parseSlackTeamId
3
- } from "./chunk-IVVGFRQQ.js";
3
+ } from "./chunk-42WRQLJ6.js";
4
4
 
5
5
  // src/chat/actor.ts
6
6
  import { z } from "zod";
@@ -4,7 +4,7 @@ import {
4
4
  } from "./chunk-MU6HHZEN.js";
5
5
  import {
6
6
  getStateAdapter
7
- } from "./chunk-OUHNWH46.js";
7
+ } from "./chunk-GK47NBDE.js";
8
8
  import {
9
9
  contextProvenance,
10
10
  createSqlConversationEventStore,
@@ -15,7 +15,7 @@ import {
15
15
  instructionProvenanceFor,
16
16
  sanitizePostgresJson,
17
17
  withConversationEventLock
18
- } from "./chunk-FENLIFJD.js";
18
+ } from "./chunk-4QU44P7Q.js";
19
19
  import {
20
20
  sleep
21
21
  } from "./chunk-4ZNGQH7C.js";
@@ -28,24 +28,22 @@ import {
28
28
  standardModelId,
29
29
  stripRuntimeTurnContext,
30
30
  trimTrailingAssistantMessages
31
- } from "./chunk-JNAVF45E.js";
31
+ } from "./chunk-WNOVRQ67.js";
32
32
  import {
33
33
  toStoredSlackActor
34
- } from "./chunk-PLB7MRCQ.js";
34
+ } from "./chunk-C4MZ3GP5.js";
35
35
  import {
36
36
  getActiveTraceId,
37
37
  logException,
38
38
  logWarn,
39
39
  setSpanAttributes
40
- } from "./chunk-ISMWX44P.js";
40
+ } from "./chunk-IYKPU7H6.js";
41
41
  import {
42
42
  isRecord,
43
+ parseSlackMessageTs,
43
44
  toOptionalNumber,
44
45
  toOptionalString
45
- } from "./chunk-OB42YVAE.js";
46
- import {
47
- parseSlackMessageTs
48
- } from "./chunk-IVVGFRQQ.js";
46
+ } from "./chunk-42WRQLJ6.js";
49
47
 
50
48
  // src/chat/conversations/projection.ts
51
49
  import { isDeepStrictEqual } from "util";