@sentry/junior 0.98.0 → 0.100.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 (82) hide show
  1. package/dist/{agent-hooks-OSW6C3CJ.js → agent-hooks-V6KU7PQN.js} +6 -5
  2. package/dist/api/activity.d.ts +14 -0
  3. package/dist/api/conversations/aggregate.d.ts +16 -0
  4. package/dist/api/conversations/detail-projection.d.ts +1 -0
  5. package/dist/api/conversations/list.d.ts +7 -2
  6. package/dist/api/conversations/list.query.d.ts +12 -3
  7. package/dist/api/conversations/projection.d.ts +1 -0
  8. package/dist/api/conversations/reporting.d.ts +42 -0
  9. package/dist/api/conversations/schema.d.ts +7 -7
  10. package/dist/api/conversations/stats.query.d.ts +1 -1
  11. package/dist/api/locations/detail.d.ts +81 -0
  12. package/dist/api/locations/list.d.ts +30 -0
  13. package/dist/api/locations/query.d.ts +5 -0
  14. package/dist/api/locations/schema.d.ts +175 -0
  15. package/dist/api/people/list.query.d.ts +1 -1
  16. package/dist/api/people/profile.query.d.ts +1 -1
  17. package/dist/api/people/schema.d.ts +10 -14
  18. package/dist/api/people/shared.d.ts +38 -78
  19. package/dist/api/schema.d.ts +11 -0
  20. package/dist/api/schema.js +16 -3
  21. package/dist/api-reference.d.ts +1 -1
  22. package/dist/api.js +41 -13
  23. package/dist/app.js +35 -27
  24. package/dist/chat/agent/request.d.ts +3 -0
  25. package/dist/chat/config.d.ts +2 -0
  26. package/dist/chat/reasoning-level.d.ts +4 -0
  27. package/dist/chat/services/context-compaction.d.ts +1 -0
  28. package/dist/chat/services/{turn-thinking-level.d.ts → turn-reasoning-level.d.ts} +11 -10
  29. package/dist/chat/services/turn-result.d.ts +3 -3
  30. package/dist/chat/tools/search-tools.d.ts +2 -2
  31. package/dist/{chunk-UAMKJPDF.js → chunk-2RNOB32R.js} +7 -1
  32. package/dist/{chunk-NJEDJFK4.js → chunk-2T7DCRAW.js} +1 -1
  33. package/dist/{chunk-DPHWDS6I.js → chunk-45DMFMY2.js} +81 -69
  34. package/dist/chunk-4AQUWWEM.js +75 -0
  35. package/dist/{chunk-EEZCY5WX.js → chunk-A7X2FDUO.js} +18 -2
  36. package/dist/{chunk-WTYEKPXU.js → chunk-FP5N5OWZ.js} +1 -1
  37. package/dist/chunk-FXFQNHRU.js +48 -0
  38. package/dist/chunk-GEUUJRQF.js +102 -0
  39. package/dist/{chunk-CRQVIHDI.js → chunk-IDZBM3NW.js} +2 -8
  40. package/dist/{chunk-DHHU2WSG.js → chunk-IQIBZXGB.js} +2 -2
  41. package/dist/{chunk-OL6XQ23W.js → chunk-IVXL57YF.js} +3 -3
  42. package/dist/{chunk-IO65E4ZD.js → chunk-JPQISMMJ.js} +3 -3
  43. package/dist/{chunk-KJHAW6VE.js → chunk-JSAANELJ.js} +28 -9
  44. package/dist/{chunk-EUZ44ROE.js → chunk-MM5UFDAC.js} +1 -3
  45. package/dist/{chunk-WJ7STXT6.js → chunk-NSOCZGOH.js} +3 -3
  46. package/dist/chunk-PGGEOCQY.js +77 -0
  47. package/dist/{chunk-EOWXRY5E.js → chunk-PWC24W5F.js} +1 -1
  48. package/dist/chunk-QOZOJNSE.js +96 -0
  49. package/dist/chunk-QSBQJ3PA.js +275 -0
  50. package/dist/{chunk-FTTFV6DC.js → chunk-TPTJEHUE.js} +4 -4
  51. package/dist/{chunk-OGHXZ4KQ.js → chunk-VHRM6GNH.js} +88 -122
  52. package/dist/{chunk-NG2AV7IB.js → chunk-VVIXK2BX.js} +1 -1
  53. package/dist/{chunk-6HHEZENZ.js → chunk-VY7BT4SM.js} +16 -7
  54. package/dist/{chunk-H66UCBPW.js → chunk-XJA7BPHS.js} +1 -1
  55. package/dist/{chunk-ER45IV77.js → chunk-XSBIISXS.js} +9 -9
  56. package/dist/cli/chat.js +15 -14
  57. package/dist/cli/plugins.js +6 -5
  58. package/dist/cli/snapshot-warmup.js +2 -2
  59. package/dist/cli/upgrade.js +8 -7
  60. package/dist/db/schema/conversations.d.ts +17 -0
  61. package/dist/db/schema/destinations.d.ts +12 -3
  62. package/dist/db/schema.d.ts +19 -2
  63. package/dist/{db-GFSCDAHS.js → db-RCZB7KNM.js} +3 -2
  64. package/dist/detail-5SLCGT6J.js +29 -0
  65. package/dist/{detail-W4ZSD45K.js → detail-LU6COZO6.js} +11 -10
  66. package/dist/{legacy-import-6WWXMALY.js → legacy-import-VCYLWT2V.js} +4 -3
  67. package/dist/list-2FI5SFV7.js +80 -0
  68. package/dist/list-4ALSU6ZW.js +30 -0
  69. package/dist/{list-3KZNG3SJ.js → list-KHRAWZWU.js} +11 -8
  70. package/dist/{plugin-conversations-ZYRWZYEA.js → plugin-conversations-JANXC4GA.js} +7 -6
  71. package/dist/profile-3O3OVENT.js +212 -0
  72. package/dist/{runner-267ZRLZD.js → runner-BM7D35YW.js} +12 -11
  73. package/dist/stats-J3YGCYDF.js +174 -0
  74. package/dist/{subagent-5HZPQC7V.js → subagent-P7HOSMVC.js} +10 -9
  75. package/migrations/0003_peaceful_scalphunter.sql +4 -0
  76. package/migrations/meta/0003_snapshot.json +1035 -0
  77. package/migrations/meta/_journal.json +8 -1
  78. package/package.json +5 -5
  79. package/dist/chunk-CV22LUIV.js +0 -261
  80. package/dist/list-M5BRWW3D.js +0 -92
  81. package/dist/profile-UEIRSVT3.js +0 -146
  82. package/dist/stats-L62E4O4U.js +0 -207
@@ -0,0 +1,275 @@
1
+ import {
2
+ summaryFromRow
3
+ } from "./chunk-QOZOJNSE.js";
4
+ import {
5
+ conversationAggregateColumns,
6
+ conversationRangeColumns
7
+ } from "./chunk-PGGEOCQY.js";
8
+ import {
9
+ activityDays
10
+ } from "./chunk-4AQUWWEM.js";
11
+ import {
12
+ getDb,
13
+ juniorConversations,
14
+ juniorIdentities,
15
+ juniorUsers
16
+ } from "./chunk-VHRM6GNH.js";
17
+ import {
18
+ juniorDestinations
19
+ } from "./chunk-FXFQNHRU.js";
20
+
21
+ // src/api/locations/query.ts
22
+ import { and, asc, desc, eq, gte, isNull, sql } from "drizzle-orm";
23
+ var RECENT_LIMIT = 25;
24
+ var ACTIVITY_DAYS = 30;
25
+ function emptyMetrics() {
26
+ return {
27
+ active: 0,
28
+ conversations: 0,
29
+ durationMs: 0,
30
+ failed: 0
31
+ };
32
+ }
33
+ function addMetrics(target, row) {
34
+ target.active += row.active;
35
+ target.conversations += row.conversations;
36
+ target.durationMs += row.durationMs;
37
+ target.failed += row.failed;
38
+ if (row.tokens !== null) {
39
+ target.tokens = (target.tokens ?? 0) + row.tokens;
40
+ }
41
+ if (row.costUsd !== null) {
42
+ target.costUsd = Math.round(((target.costUsd ?? 0) + row.costUsd) * 1e12) / 1e12;
43
+ }
44
+ }
45
+ function publicLabel(input) {
46
+ const name = input.displayName?.trim().replace(/^#/, "");
47
+ return name ? `#${name}` : `Public channel ${input.providerDestinationId}`;
48
+ }
49
+ function actorLabel(actor) {
50
+ return actor.email?.trim() || actor.fullName?.trim() || actor.slackUserName?.trim() || actor.slackUserId?.trim() || "Unknown";
51
+ }
52
+ function emptyActor(actor) {
53
+ return {
54
+ ...emptyMetrics(),
55
+ actor,
56
+ label: actorLabel(actor)
57
+ };
58
+ }
59
+ function topLevelWhere() {
60
+ return isNull(juniorConversations.parentConversationId);
61
+ }
62
+ function publicLocationWhere(destinationId) {
63
+ return and(
64
+ topLevelWhere(),
65
+ eq(juniorDestinations.id, destinationId),
66
+ eq(juniorDestinations.visibility, "public")
67
+ );
68
+ }
69
+ function locationColumns() {
70
+ return {
71
+ destinationDisplayName: juniorDestinations.displayName,
72
+ destinationId: juniorDestinations.id,
73
+ destinationKind: juniorDestinations.kind,
74
+ destinationProvider: juniorDestinations.provider,
75
+ destinationProviderId: juniorDestinations.providerDestinationId,
76
+ destinationVisibility: juniorDestinations.visibility
77
+ };
78
+ }
79
+ function locationGroupBy() {
80
+ return [
81
+ juniorDestinations.displayName,
82
+ juniorDestinations.id,
83
+ juniorDestinations.kind,
84
+ juniorDestinations.provider,
85
+ juniorDestinations.providerDestinationId,
86
+ juniorDestinations.visibility
87
+ ];
88
+ }
89
+ function locationFromAggregate(row) {
90
+ if (row.destinationVisibility !== "public" || !row.destinationId || !row.destinationProvider || !row.destinationProviderId || !row.destinationKind) {
91
+ return void 0;
92
+ }
93
+ const location = {
94
+ ...emptyMetrics(),
95
+ firstSeenAt: row.firstSeenAt.toISOString(),
96
+ id: row.destinationId,
97
+ kind: row.destinationKind,
98
+ label: publicLabel({
99
+ displayName: row.destinationDisplayName,
100
+ providerDestinationId: row.destinationProviderId
101
+ }),
102
+ lastSeenAt: row.lastSeenAt.toISOString(),
103
+ provider: row.destinationProvider,
104
+ providerDestinationId: row.destinationProviderId,
105
+ visibility: "public"
106
+ };
107
+ addMetrics(location, row);
108
+ return location;
109
+ }
110
+ async function directoryRows(db) {
111
+ return db.select({
112
+ ...locationColumns(),
113
+ ...conversationAggregateColumns(),
114
+ ...conversationRangeColumns()
115
+ }).from(juniorConversations).leftJoin(
116
+ juniorDestinations,
117
+ eq(juniorDestinations.id, juniorConversations.destinationId)
118
+ ).where(topLevelWhere()).groupBy(...locationGroupBy());
119
+ }
120
+ async function readLocationDirectoryFromSql() {
121
+ const nowMs = Date.now();
122
+ const rows = await directoryRows(getDb());
123
+ const locations = [];
124
+ const privateActivity = {
125
+ ...emptyMetrics(),
126
+ label: "Private activity"
127
+ };
128
+ for (const row of rows) {
129
+ const location = locationFromAggregate(row);
130
+ if (location) locations.push(location);
131
+ else addMetrics(privateActivity, row);
132
+ }
133
+ return {
134
+ generatedAt: new Date(nowMs).toISOString(),
135
+ locations: locations.sort(
136
+ (left, right) => Date.parse(right.lastSeenAt) - Date.parse(left.lastSeenAt) || right.conversations - left.conversations || left.label.localeCompare(right.label)
137
+ ),
138
+ privateActivity,
139
+ source: "conversation_index"
140
+ };
141
+ }
142
+ async function recentLocationRows(db, locationId) {
143
+ return db.select({
144
+ channelName: juniorConversations.channelName,
145
+ conversationId: juniorConversations.conversationId,
146
+ createdAt: juniorConversations.createdAt,
147
+ destinationId: juniorDestinations.id,
148
+ destinationVisibility: juniorDestinations.visibility,
149
+ durationMs: juniorConversations.durationMs,
150
+ email: sql`COALESCE(
151
+ ${juniorUsers.primaryEmailNormalized},
152
+ ${juniorIdentities.email}
153
+ )`,
154
+ executionStatus: juniorConversations.executionStatus,
155
+ executionUpdatedAt: juniorConversations.executionUpdatedAt,
156
+ fullName: juniorUsers.displayName,
157
+ handle: juniorIdentities.handle,
158
+ lastActivityAt: juniorConversations.lastActivityAt,
159
+ providerSubjectId: sql`CASE
160
+ WHEN ${juniorIdentities.provider} = 'slack'
161
+ THEN ${juniorIdentities.providerSubjectId}
162
+ ELSE NULL
163
+ END`,
164
+ source: juniorConversations.source,
165
+ title: juniorConversations.title,
166
+ updatedAt: juniorConversations.updatedAt,
167
+ usage: juniorConversations.usage
168
+ }).from(juniorConversations).innerJoin(
169
+ juniorDestinations,
170
+ eq(juniorDestinations.id, juniorConversations.destinationId)
171
+ ).leftJoin(
172
+ juniorIdentities,
173
+ eq(juniorIdentities.id, juniorConversations.actorIdentityId)
174
+ ).leftJoin(juniorUsers, eq(juniorUsers.id, juniorIdentities.userId)).where(publicLocationWhere(locationId)).orderBy(
175
+ desc(juniorConversations.lastActivityAt),
176
+ asc(juniorConversations.conversationId)
177
+ ).limit(RECENT_LIMIT);
178
+ }
179
+ async function readLocationDetailFromSql(locationId) {
180
+ const nowMs = Date.now();
181
+ const end = new Date(nowMs);
182
+ end.setUTCHours(0, 0, 0, 0);
183
+ const start = new Date(end);
184
+ start.setUTCDate(start.getUTCDate() - (ACTIVITY_DAYS - 1));
185
+ const where = publicLocationWhere(locationId);
186
+ const activityDate = sql`TO_CHAR(
187
+ ${juniorConversations.lastActivityAt} AT TIME ZONE 'UTC',
188
+ 'YYYY-MM-DD'
189
+ )`;
190
+ const [locationRows, dayRows, actorRows, recentRows] = await Promise.all([
191
+ getDb().select({
192
+ ...locationColumns(),
193
+ ...conversationAggregateColumns(),
194
+ ...conversationRangeColumns()
195
+ }).from(juniorConversations).innerJoin(
196
+ juniorDestinations,
197
+ eq(juniorDestinations.id, juniorConversations.destinationId)
198
+ ).where(where).groupBy(...locationGroupBy()),
199
+ getDb().select({ date: activityDate, ...conversationAggregateColumns() }).from(juniorConversations).innerJoin(
200
+ juniorDestinations,
201
+ eq(juniorDestinations.id, juniorConversations.destinationId)
202
+ ).where(and(where, gte(juniorConversations.lastActivityAt, start))).groupBy(activityDate),
203
+ getDb().select({
204
+ actorIdentityId: juniorConversations.actorIdentityId,
205
+ email: juniorUsers.primaryEmailNormalized,
206
+ fullName: juniorUsers.displayName,
207
+ handle: juniorIdentities.handle,
208
+ identityEmail: juniorIdentities.email,
209
+ identityProvider: juniorIdentities.provider,
210
+ providerSubjectId: juniorIdentities.providerSubjectId,
211
+ ...conversationAggregateColumns()
212
+ }).from(juniorConversations).innerJoin(
213
+ juniorDestinations,
214
+ eq(juniorDestinations.id, juniorConversations.destinationId)
215
+ ).leftJoin(
216
+ juniorIdentities,
217
+ eq(juniorIdentities.id, juniorConversations.actorIdentityId)
218
+ ).leftJoin(juniorUsers, eq(juniorUsers.id, juniorIdentities.userId)).where(where).groupBy(
219
+ juniorConversations.actorIdentityId,
220
+ juniorUsers.primaryEmailNormalized,
221
+ juniorUsers.displayName,
222
+ juniorIdentities.handle,
223
+ juniorIdentities.email,
224
+ juniorIdentities.provider,
225
+ juniorIdentities.providerSubjectId
226
+ ),
227
+ recentLocationRows(getDb(), locationId)
228
+ ]);
229
+ const locationRow = locationRows[0];
230
+ const location = locationRow ? locationFromAggregate(locationRow) : void 0;
231
+ if (!location) return void 0;
232
+ const days = /* @__PURE__ */ new Map();
233
+ for (const row of dayRows) {
234
+ days.set(row.date, {
235
+ active: row.active,
236
+ conversations: row.conversations,
237
+ date: row.date,
238
+ durationMs: row.durationMs,
239
+ failed: row.failed,
240
+ ...row.tokens !== null ? { tokens: row.tokens } : {}
241
+ });
242
+ }
243
+ const actors = [];
244
+ for (const row of actorRows) {
245
+ if (!row.actorIdentityId) continue;
246
+ const actor = {
247
+ ...row.email ?? row.identityEmail ? { email: row.email ?? row.identityEmail ?? void 0 } : {},
248
+ ...row.fullName ? { fullName: row.fullName } : {},
249
+ ...row.identityProvider === "slack" && row.providerSubjectId ? { slackUserId: row.providerSubjectId } : {},
250
+ ...row.handle ? { slackUserName: row.handle } : {}
251
+ };
252
+ if (!actor.email && !actor.slackUserId) continue;
253
+ const item = emptyActor(actor);
254
+ addMetrics(item, row);
255
+ actors.push(item);
256
+ }
257
+ const activity = activityDays(days, nowMs, ACTIVITY_DAYS);
258
+ return {
259
+ ...location,
260
+ activityDays: activity,
261
+ actors: actors.sort(
262
+ (left, right) => right.conversations - left.conversations || left.label.localeCompare(right.label)
263
+ ),
264
+ generatedAt: new Date(nowMs).toISOString(),
265
+ recentConversations: recentRows.map(summaryFromRow),
266
+ source: "conversation_index",
267
+ windowEnd: end.toISOString(),
268
+ windowStart: activity[0] ? `${activity[0].date}T00:00:00.000Z` : end.toISOString()
269
+ };
270
+ }
271
+
272
+ export {
273
+ readLocationDirectoryFromSql,
274
+ readLocationDetailFromSql
275
+ };
@@ -3,14 +3,14 @@ import {
3
3
  isConversationScopedChannel,
4
4
  isDmChannel,
5
5
  normalizeSlackConversationId
6
- } from "./chunk-WTYEKPXU.js";
6
+ } from "./chunk-FP5N5OWZ.js";
7
7
  import {
8
8
  createPluginLogger,
9
9
  createPluginState
10
- } from "./chunk-EOWXRY5E.js";
10
+ } from "./chunk-PWC24W5F.js";
11
11
  import {
12
12
  getDb
13
- } from "./chunk-OGHXZ4KQ.js";
13
+ } from "./chunk-VHRM6GNH.js";
14
14
  import {
15
15
  SANDBOX_WORKSPACE_ROOT
16
16
  } from "./chunk-G3E7SCME.js";
@@ -18,7 +18,7 @@ import {
18
18
  botConfig,
19
19
  completeObject,
20
20
  embedTexts
21
- } from "./chunk-EEZCY5WX.js";
21
+ } from "./chunk-A7X2FDUO.js";
22
22
  import {
23
23
  isActorUserId,
24
24
  logInfo,
@@ -3,7 +3,11 @@ import {
3
3
  getConnectedStateContext,
4
4
  getStateAdapter,
5
5
  modelProfileSchema
6
- } from "./chunk-EEZCY5WX.js";
6
+ } from "./chunk-A7X2FDUO.js";
7
+ import {
8
+ juniorDestinations,
9
+ timestamptz
10
+ } from "./chunk-FXFQNHRU.js";
7
11
  import {
8
12
  parseDestination,
9
13
  sameDestination
@@ -23,211 +27,176 @@ import { and, eq, sql as sql4 } from "drizzle-orm";
23
27
 
24
28
  // src/db/schema/agent-steps.ts
25
29
  import {
26
- index as index4,
30
+ index as index3,
27
31
  integer as integer2,
28
- jsonb as jsonb4,
29
- pgTable as pgTable5,
32
+ jsonb as jsonb3,
33
+ pgTable as pgTable4,
30
34
  primaryKey,
31
- text as text5
35
+ text as text4
32
36
  } from "drizzle-orm/pg-core";
33
37
 
34
38
  // src/db/schema/conversations.ts
35
39
  import { sql as sql2 } from "drizzle-orm";
36
40
  import {
37
- index as index3,
41
+ index as index2,
38
42
  integer,
39
- jsonb as jsonb3,
40
- pgTable as pgTable4,
41
- text as text4
43
+ jsonb as jsonb2,
44
+ pgTable as pgTable3,
45
+ text as text3
42
46
  } from "drizzle-orm/pg-core";
43
47
 
44
- // src/db/schema/destinations.ts
45
- import { index, jsonb, pgTable, text, uniqueIndex } from "drizzle-orm/pg-core";
46
-
47
- // src/db/schema/timestamps.ts
48
- import { timestamp } from "drizzle-orm/pg-core";
49
- var timestamptz = (name) => timestamp(name, { withTimezone: true });
50
-
51
- // src/db/schema/destinations.ts
52
- var juniorDestinations = pgTable(
53
- "junior_destinations",
54
- {
55
- id: text("id").primaryKey(),
56
- provider: text("provider").notNull(),
57
- providerTenantId: text("provider_tenant_id").notNull().default(""),
58
- providerDestinationId: text("provider_destination_id").notNull(),
59
- kind: text("kind").$type().notNull(),
60
- parentDestinationId: text("parent_destination_id"),
61
- displayName: text("display_name"),
62
- visibility: text("visibility").$type().notNull().default("unknown"),
63
- metadata: jsonb("metadata_json"),
64
- createdAt: timestamptz("created_at").notNull(),
65
- updatedAt: timestamptz("updated_at").notNull()
66
- },
67
- (table) => [
68
- uniqueIndex("junior_destinations_provider_destination_uidx").on(
69
- table.provider,
70
- table.providerTenantId,
71
- table.providerDestinationId
72
- ),
73
- index("junior_destinations_provider_kind_idx").on(
74
- table.provider,
75
- table.kind
76
- )
77
- ]
78
- );
79
-
80
48
  // src/db/schema/identities.ts
81
49
  import { sql } from "drizzle-orm";
82
50
  import {
83
51
  boolean,
84
- index as index2,
85
- jsonb as jsonb2,
86
- pgTable as pgTable3,
87
- text as text3,
88
- uniqueIndex as uniqueIndex3
52
+ index,
53
+ jsonb,
54
+ pgTable as pgTable2,
55
+ text as text2,
56
+ uniqueIndex as uniqueIndex2
89
57
  } from "drizzle-orm/pg-core";
90
58
 
91
59
  // src/db/schema/users.ts
92
- import { text as text2, pgTable as pgTable2, uniqueIndex as uniqueIndex2 } from "drizzle-orm/pg-core";
93
- var juniorUsers = pgTable2(
60
+ import { text, pgTable, uniqueIndex } from "drizzle-orm/pg-core";
61
+ var juniorUsers = pgTable(
94
62
  "junior_users",
95
63
  {
96
- id: text2("id").primaryKey(),
97
- primaryEmail: text2("primary_email").notNull(),
98
- primaryEmailNormalized: text2("primary_email_normalized").notNull(),
99
- displayName: text2("display_name"),
64
+ id: text("id").primaryKey(),
65
+ primaryEmail: text("primary_email").notNull(),
66
+ primaryEmailNormalized: text("primary_email_normalized").notNull(),
67
+ displayName: text("display_name"),
100
68
  createdAt: timestamptz("created_at").notNull(),
101
69
  updatedAt: timestamptz("updated_at").notNull()
102
70
  },
103
71
  (table) => [
104
- uniqueIndex2("junior_users_primary_email_normalized_uidx").on(
72
+ uniqueIndex("junior_users_primary_email_normalized_uidx").on(
105
73
  table.primaryEmailNormalized
106
74
  )
107
75
  ]
108
76
  );
109
77
 
110
78
  // src/db/schema/identities.ts
111
- var juniorIdentities = pgTable3(
79
+ var juniorIdentities = pgTable2(
112
80
  "junior_identities",
113
81
  {
114
- id: text3("id").primaryKey(),
115
- kind: text3("kind").$type().notNull(),
116
- provider: text3("provider").notNull(),
117
- providerTenantId: text3("provider_tenant_id").notNull().default(""),
118
- providerSubjectId: text3("provider_subject_id").notNull(),
119
- displayName: text3("display_name"),
120
- handle: text3("handle"),
121
- email: text3("email"),
122
- avatarUrl: text3("avatar_url"),
123
- metadata: jsonb2("metadata_json"),
82
+ id: text2("id").primaryKey(),
83
+ kind: text2("kind").$type().notNull(),
84
+ provider: text2("provider").notNull(),
85
+ providerTenantId: text2("provider_tenant_id").notNull().default(""),
86
+ providerSubjectId: text2("provider_subject_id").notNull(),
87
+ displayName: text2("display_name"),
88
+ handle: text2("handle"),
89
+ email: text2("email"),
90
+ avatarUrl: text2("avatar_url"),
91
+ metadata: jsonb("metadata_json"),
124
92
  createdAt: timestamptz("created_at").notNull(),
125
93
  updatedAt: timestamptz("updated_at").notNull(),
126
- userId: text3("user_id").references(() => juniorUsers.id),
127
- emailNormalized: text3("email_normalized"),
94
+ userId: text2("user_id").references(() => juniorUsers.id),
95
+ emailNormalized: text2("email_normalized"),
128
96
  emailVerified: boolean("email_verified").notNull().default(false)
129
97
  },
130
98
  (table) => [
131
- uniqueIndex3("junior_identities_provider_subject_uidx").on(
99
+ uniqueIndex2("junior_identities_provider_subject_uidx").on(
132
100
  table.provider,
133
101
  table.providerTenantId,
134
102
  table.providerSubjectId
135
103
  ),
136
- index2("junior_identities_user_idx").on(table.userId),
137
- index2("junior_identities_verified_email_idx").on(table.emailNormalized).where(
104
+ index("junior_identities_user_idx").on(table.userId),
105
+ index("junior_identities_verified_email_idx").on(table.emailNormalized).where(
138
106
  sql`${table.emailVerified} = true AND ${table.emailNormalized} IS NOT NULL`
139
107
  ),
140
- index2("junior_identities_kind_provider_idx").on(table.kind, table.provider)
108
+ index("junior_identities_kind_provider_idx").on(table.kind, table.provider)
141
109
  ]
142
110
  );
143
111
 
144
112
  // src/db/schema/conversations.ts
145
- var juniorConversations = pgTable4(
113
+ var juniorConversations = pgTable3(
146
114
  "junior_conversations",
147
115
  {
148
- conversationId: text4("conversation_id").primaryKey(),
116
+ conversationId: text3("conversation_id").primaryKey(),
149
117
  schemaVersion: integer("schema_version").notNull().default(1),
150
- source: text4("source").$type(),
151
- originType: text4("origin_type"),
152
- originId: text4("origin_id"),
153
- originRunId: text4("origin_run_id"),
154
- destinationId: text4("destination_id").references(
118
+ source: text3("source").$type(),
119
+ originType: text3("origin_type"),
120
+ originId: text3("origin_id"),
121
+ originRunId: text3("origin_run_id"),
122
+ destinationId: text3("destination_id").references(
155
123
  () => juniorDestinations.id
156
124
  ),
157
- destination: jsonb3("destination_json").$type(),
158
- actorIdentityId: text4("actor_identity_id").references(
125
+ destination: jsonb2("destination_json").$type(),
126
+ actorIdentityId: text3("actor_identity_id").references(
159
127
  () => juniorIdentities.id
160
128
  ),
161
- creatorIdentityId: text4("creator_identity_id").references(
129
+ creatorIdentityId: text3("creator_identity_id").references(
162
130
  () => juniorIdentities.id
163
131
  ),
164
- credentialSubjectIdentityId: text4(
132
+ credentialSubjectIdentityId: text3(
165
133
  "credential_subject_identity_id"
166
134
  ).references(() => juniorIdentities.id),
167
- actor: jsonb3("actor_json").$type(),
168
- channelName: text4("channel_name"),
169
- title: text4("title"),
135
+ actor: jsonb2("actor_json").$type(),
136
+ channelName: text3("channel_name"),
137
+ title: text3("title"),
170
138
  createdAt: timestamptz("created_at").notNull(),
171
139
  lastActivityAt: timestamptz("last_activity_at").notNull(),
172
140
  updatedAt: timestamptz("updated_at").notNull(),
173
141
  executionUpdatedAt: timestamptz("execution_updated_at"),
174
- executionStatus: text4("execution_status").$type().notNull(),
175
- runId: text4("run_id"),
142
+ executionStatus: text3("execution_status").$type().notNull(),
143
+ runId: text3("run_id"),
176
144
  lastCheckpointAt: timestamptz("last_checkpoint_at"),
177
145
  lastEnqueuedAt: timestamptz("last_enqueued_at"),
178
146
  // Subagent runs are child conversations; top-level listings filter
179
147
  // parent_conversation_id IS NULL. Historical advisor children use this too.
180
- parentConversationId: text4("parent_conversation_id").references(
148
+ parentConversationId: text3("parent_conversation_id").references(
181
149
  () => juniorConversations.conversationId
182
150
  ),
183
151
  transcriptPurgedAt: timestamptz("transcript_purged_at"),
184
152
  durationMs: integer("duration_ms").notNull().default(0),
185
- usage: jsonb3("usage_json").$type(),
153
+ usage: jsonb2("usage_json").$type(),
186
154
  executionDurationMs: integer("execution_duration_ms").notNull().default(0),
187
- executionUsage: jsonb3("execution_usage_json").$type()
155
+ executionUsage: jsonb2("execution_usage_json").$type(),
156
+ metricRunId: text3("metric_run_id")
188
157
  },
189
158
  (table) => [
190
- index3("junior_conversations_last_activity_idx").on(
159
+ index2("junior_conversations_last_activity_idx").on(
191
160
  table.lastActivityAt.desc(),
192
161
  table.conversationId
193
162
  ),
194
- index3("junior_conversations_active_idx").using(
163
+ index2("junior_conversations_active_idx").using(
195
164
  "btree",
196
165
  sql2`coalesce(${table.executionUpdatedAt}, ${table.updatedAt})`,
197
166
  table.conversationId
198
167
  ).where(sql2`${table.executionStatus} <> 'idle'`),
199
- index3("junior_conversations_destination_activity_idx").on(
168
+ index2("junior_conversations_destination_activity_idx").on(
200
169
  table.destinationId,
201
170
  table.lastActivityAt.desc()
202
171
  ),
203
- index3("junior_conversations_actor_activity_idx").on(
172
+ index2("junior_conversations_actor_activity_idx").on(
204
173
  table.actorIdentityId,
205
174
  table.lastActivityAt.desc()
206
175
  ),
207
- index3("junior_conversations_origin_idx").on(
176
+ index2("junior_conversations_origin_idx").on(
208
177
  table.originType,
209
178
  table.originId,
210
179
  table.lastActivityAt.desc()
211
180
  ),
212
- index3("junior_conversations_parent_idx").on(table.parentConversationId)
181
+ index2("junior_conversations_parent_idx").on(table.parentConversationId)
213
182
  ]
214
183
  );
215
184
 
216
185
  // src/db/schema/agent-steps.ts
217
- var juniorAgentSteps = pgTable5(
186
+ var juniorAgentSteps = pgTable4(
218
187
  "junior_agent_steps",
219
188
  {
220
- conversationId: text5("conversation_id").notNull().references(() => juniorConversations.conversationId),
189
+ conversationId: text4("conversation_id").notNull().references(() => juniorConversations.conversationId),
221
190
  seq: integer2("seq").notNull(),
222
191
  contextEpoch: integer2("context_epoch").notNull(),
223
- type: text5("type").notNull(),
224
- role: text5("role"),
225
- payload: jsonb4("payload").$type().notNull(),
192
+ type: text4("type").notNull(),
193
+ role: text4("role"),
194
+ payload: jsonb3("payload").$type().notNull(),
226
195
  createdAt: timestamptz("created_at").notNull()
227
196
  },
228
197
  (table) => [
229
198
  primaryKey({ columns: [table.conversationId, table.seq] }),
230
- index4("junior_agent_steps_epoch_idx").on(
199
+ index3("junior_agent_steps_epoch_idx").on(
231
200
  table.conversationId,
232
201
  table.contextEpoch,
233
202
  table.seq
@@ -237,28 +206,28 @@ var juniorAgentSteps = pgTable5(
237
206
 
238
207
  // src/db/schema/conversation-messages.ts
239
208
  import { sql as sql3 } from "drizzle-orm";
240
- import { index as index5, jsonb as jsonb5, pgTable as pgTable6, primaryKey as primaryKey2, text as text6 } from "drizzle-orm/pg-core";
241
- var juniorConversationMessages = pgTable6(
209
+ import { index as index4, jsonb as jsonb4, pgTable as pgTable5, primaryKey as primaryKey2, text as text5 } from "drizzle-orm/pg-core";
210
+ var juniorConversationMessages = pgTable5(
242
211
  "junior_conversation_messages",
243
212
  {
244
- conversationId: text6("conversation_id").notNull().references(() => juniorConversations.conversationId),
245
- messageId: text6("message_id").notNull(),
246
- role: text6("role").$type().notNull(),
247
- authorIdentityId: text6("author_identity_id").references(
213
+ conversationId: text5("conversation_id").notNull().references(() => juniorConversations.conversationId),
214
+ messageId: text5("message_id").notNull(),
215
+ role: text5("role").$type().notNull(),
216
+ authorIdentityId: text5("author_identity_id").references(
248
217
  () => juniorIdentities.id
249
218
  ),
250
- text: text6("text").notNull(),
251
- meta: jsonb5("meta").$type(),
219
+ text: text5("text").notNull(),
220
+ meta: jsonb4("meta").$type(),
252
221
  repliedAt: timestamptz("replied_at"),
253
222
  createdAt: timestamptz("created_at").notNull()
254
223
  },
255
224
  (table) => [
256
225
  primaryKey2({ columns: [table.conversationId, table.messageId] }),
257
- index5("junior_conversation_messages_activity_idx").on(
226
+ index4("junior_conversation_messages_activity_idx").on(
258
227
  table.conversationId,
259
228
  table.createdAt
260
229
  ),
261
- index5("junior_conversation_messages_search_idx").using(
230
+ index4("junior_conversation_messages_search_idx").using(
262
231
  "gin",
263
232
  sql3`to_tsvector('english', ${table.text})`
264
233
  )
@@ -708,7 +677,8 @@ var SqlStore = class {
708
677
  const incomingExecutionAt = args.execution.updatedAtMs ?? args.updatedAtMs;
709
678
  const existingExecutionAt = existing?.execution.updatedAtMs ?? existing?.updatedAtMs ?? 0;
710
679
  const incomingIsFresh = incomingExecutionAt >= existingExecutionAt;
711
- const sameRun = Boolean(existing?.execution.runId) && existing?.execution.runId === args.execution.runId;
680
+ const metricRunId = existingRow?.conversation.metricRunId;
681
+ const sameRun = Boolean(metricRunId) && metricRunId === args.execution.runId;
712
682
  const execution = incomingIsFresh ? args.execution : existing?.execution ?? args.execution;
713
683
  await this.upsertConversation({
714
684
  conversation: {
@@ -736,14 +706,10 @@ var SqlStore = class {
736
706
  await this.executor.db().update(juniorConversations).set({
737
707
  durationMs: (row?.durationMs ?? 0) - (sameRun ? row?.executionDurationMs ?? 0 : 0) + args.metrics.durationMs,
738
708
  usage: usage ?? null,
709
+ metricRunId: args.execution.runId ?? null,
739
710
  executionDurationMs: args.metrics.durationMs,
740
711
  executionUsage: args.metrics.usage ?? (sameRun ? row?.executionUsage ?? null : null)
741
712
  }).where(eq2(juniorConversations.conversationId, args.conversationId));
742
- } else if (incomingIsFresh && !sameRun) {
743
- await this.executor.db().update(juniorConversations).set({
744
- executionDurationMs: 0,
745
- executionUsage: null
746
- }).where(eq2(juniorConversations.conversationId, args.conversationId));
747
713
  }
748
714
  });
749
715
  }
@@ -811,6 +777,7 @@ var SqlStore = class {
811
777
  durationMs: metrics.durationMs,
812
778
  usage: metrics.usage ?? null,
813
779
  ...refreshExecutionFromSource ? {
780
+ metricRunId: conversation.execution.runId ?? null,
814
781
  executionDurationMs: metrics.executionDurationMs,
815
782
  executionUsage: metrics.executionUsage ?? null
816
783
  } : {}
@@ -2053,7 +2020,6 @@ async function closeDb() {
2053
2020
  }
2054
2021
 
2055
2022
  export {
2056
- juniorDestinations,
2057
2023
  juniorUsers,
2058
2024
  juniorIdentities,
2059
2025
  juniorConversations,
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  normalizeSlackConversationId
3
- } from "./chunk-WTYEKPXU.js";
3
+ } from "./chunk-FP5N5OWZ.js";
4
4
  import {
5
5
  parseSlackThreadId
6
6
  } from "./chunk-LVA4I4H7.js";