@sentry/junior 0.99.0 → 0.101.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.
- package/README.md +0 -1
- package/dist/{agent-hooks-OSW6C3CJ.js → agent-hooks-V6KU7PQN.js} +6 -5
- package/dist/api/activity.d.ts +14 -0
- package/dist/api/conversations/aggregate.d.ts +16 -0
- package/dist/api/conversations/detail-projection.d.ts +1 -0
- package/dist/api/conversations/list.query.d.ts +3 -0
- package/dist/api/conversations/projection.d.ts +1 -0
- package/dist/api/conversations/reporting.d.ts +42 -0
- package/dist/api/conversations/schema.d.ts +9 -9
- package/dist/api/conversations/stats.query.d.ts +1 -1
- package/dist/api/locations/detail.d.ts +81 -0
- package/dist/api/locations/list.d.ts +30 -0
- package/dist/api/locations/query.d.ts +5 -0
- package/dist/api/locations/schema.d.ts +175 -0
- package/dist/api/people/list.query.d.ts +1 -1
- package/dist/api/people/profile.query.d.ts +1 -1
- package/dist/api/people/schema.d.ts +10 -14
- package/dist/api/people/shared.d.ts +38 -78
- package/dist/api/schema.d.ts +8 -0
- package/dist/api/schema.js +14 -3
- package/dist/api.js +24 -11
- package/dist/app.js +126 -70
- package/dist/chat/agent/request.d.ts +4 -1
- package/dist/chat/config.d.ts +2 -0
- package/dist/chat/conversations/store.d.ts +1 -1
- package/dist/chat/mcp/auth-store.d.ts +1 -0
- package/dist/chat/mcp/client.d.ts +2 -0
- package/dist/chat/mcp/oauth-provider.d.ts +4 -1
- package/dist/chat/mcp/oauth.d.ts +3 -1
- package/dist/chat/mcp/tool-manager.d.ts +2 -0
- package/dist/chat/reasoning-level.d.ts +4 -0
- package/dist/chat/services/mcp-auth-orchestration.d.ts +1 -1
- package/dist/chat/services/pending-auth.d.ts +17 -9
- package/dist/chat/services/{turn-thinking-level.d.ts → turn-reasoning-level.d.ts} +11 -10
- package/dist/chat/services/turn-result.d.ts +3 -3
- package/dist/chat/state/conversation.d.ts +7 -3
- package/dist/chat/tools/search-tools.d.ts +2 -2
- package/dist/{chunk-T55RBE4Z.js → chunk-2RNOB32R.js} +3 -1
- package/dist/{chunk-ZZUBLPXD.js → chunk-5VGJJSSV.js} +9 -7
- package/dist/{chunk-EEZCY5WX.js → chunk-A7X2FDUO.js} +18 -2
- package/dist/{chunk-CRQVIHDI.js → chunk-DBPLXSBK.js} +2 -8
- package/dist/{chunk-NJEDJFK4.js → chunk-EBFJOOUE.js} +2 -2
- package/dist/{chunk-WTYEKPXU.js → chunk-FP5N5OWZ.js} +1 -1
- package/dist/chunk-FXFQNHRU.js +48 -0
- package/dist/chunk-GEUUJRQF.js +102 -0
- package/dist/chunk-HNIT4HXU.js +75 -0
- package/dist/{chunk-EUZ44ROE.js → chunk-HYDQULR2.js} +2 -4
- package/dist/{chunk-DHHU2WSG.js → chunk-IQIBZXGB.js} +2 -2
- package/dist/{chunk-OL6XQ23W.js → chunk-IVXL57YF.js} +3 -3
- package/dist/{chunk-IO65E4ZD.js → chunk-JPQISMMJ.js} +3 -3
- package/dist/{chunk-KFUSLFLL.js → chunk-JSAANELJ.js} +11 -4
- package/dist/{chunk-ER45IV77.js → chunk-L2JIOAA2.js} +10 -10
- package/dist/chunk-PGGEOCQY.js +77 -0
- package/dist/{chunk-EOWXRY5E.js → chunk-PWC24W5F.js} +1 -1
- package/dist/chunk-QOZOJNSE.js +96 -0
- package/dist/{chunk-FTTFV6DC.js → chunk-TPTJEHUE.js} +4 -4
- package/dist/{chunk-PYK7R5A7.js → chunk-UWGTSF5O.js} +285 -174
- package/dist/chunk-VFBFK6EY.js +275 -0
- package/dist/{chunk-OGHXZ4KQ.js → chunk-VHRM6GNH.js} +88 -122
- package/dist/{chunk-NG2AV7IB.js → chunk-VVIXK2BX.js} +1 -1
- package/dist/{chunk-6DTVCPLO.js → chunk-XIMUQ4IU.js} +4 -3
- package/dist/{chunk-H66UCBPW.js → chunk-XJA7BPHS.js} +1 -1
- package/dist/{chunk-WJ7STXT6.js → chunk-XVR4O24H.js} +8 -10
- package/dist/cli/chat.js +16 -15
- package/dist/cli/plugins.js +6 -5
- package/dist/cli/snapshot-warmup.js +2 -2
- package/dist/cli/upgrade.js +126 -8
- package/dist/db/schema/conversations.d.ts +17 -0
- package/dist/db/schema/destinations.d.ts +12 -3
- package/dist/db/schema.d.ts +19 -2
- package/dist/{db-GFSCDAHS.js → db-RCZB7KNM.js} +3 -2
- package/dist/{detail-Q4IVDNGS.js → detail-4EPUMSDU.js} +11 -10
- package/dist/detail-CD4SPJ4K.js +29 -0
- package/dist/{legacy-import-6WWXMALY.js → legacy-import-VCYLWT2V.js} +4 -3
- package/dist/list-7L5LY2WU.js +30 -0
- package/dist/list-DA2ATOM4.js +80 -0
- package/dist/{list-A3F5JDYV.js → list-J6ROVH56.js} +7 -6
- package/dist/{plugin-conversations-PDCQWU3O.js → plugin-conversations-JANXC4GA.js} +6 -5
- package/dist/profile-6NRWEKMZ.js +212 -0
- package/dist/{runner-267ZRLZD.js → runner-CZIKSWGC.js} +13 -12
- package/dist/stats-Q5FRUXLY.js +174 -0
- package/dist/{subagent-UN3MP6LV.js → subagent-YIINCFAS.js} +10 -9
- package/migrations/0003_peaceful_scalphunter.sql +4 -0
- package/migrations/meta/0003_snapshot.json +1035 -0
- package/migrations/meta/_journal.json +8 -1
- package/package.json +6 -6
- package/dist/api-reference.d.ts +0 -14
- package/dist/chunk-CV22LUIV.js +0 -261
- package/dist/list-M5BRWW3D.js +0 -92
- package/dist/profile-UEIRSVT3.js +0 -146
- 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-HNIT4HXU.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,7 +3,11 @@ import {
|
|
|
3
3
|
getConnectedStateContext,
|
|
4
4
|
getStateAdapter,
|
|
5
5
|
modelProfileSchema
|
|
6
|
-
} from "./chunk-
|
|
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
|
|
30
|
+
index as index3,
|
|
27
31
|
integer as integer2,
|
|
28
|
-
jsonb as
|
|
29
|
-
pgTable as
|
|
32
|
+
jsonb as jsonb3,
|
|
33
|
+
pgTable as pgTable4,
|
|
30
34
|
primaryKey,
|
|
31
|
-
text as
|
|
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
|
|
41
|
+
index as index2,
|
|
38
42
|
integer,
|
|
39
|
-
jsonb as
|
|
40
|
-
pgTable as
|
|
41
|
-
text as
|
|
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
|
|
85
|
-
jsonb
|
|
86
|
-
pgTable as
|
|
87
|
-
text as
|
|
88
|
-
uniqueIndex as
|
|
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
|
|
93
|
-
var juniorUsers =
|
|
60
|
+
import { text, pgTable, uniqueIndex } from "drizzle-orm/pg-core";
|
|
61
|
+
var juniorUsers = pgTable(
|
|
94
62
|
"junior_users",
|
|
95
63
|
{
|
|
96
|
-
id:
|
|
97
|
-
primaryEmail:
|
|
98
|
-
primaryEmailNormalized:
|
|
99
|
-
displayName:
|
|
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
|
-
|
|
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 =
|
|
79
|
+
var juniorIdentities = pgTable2(
|
|
112
80
|
"junior_identities",
|
|
113
81
|
{
|
|
114
|
-
id:
|
|
115
|
-
kind:
|
|
116
|
-
provider:
|
|
117
|
-
providerTenantId:
|
|
118
|
-
providerSubjectId:
|
|
119
|
-
displayName:
|
|
120
|
-
handle:
|
|
121
|
-
email:
|
|
122
|
-
avatarUrl:
|
|
123
|
-
metadata:
|
|
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:
|
|
127
|
-
emailNormalized:
|
|
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
|
-
|
|
99
|
+
uniqueIndex2("junior_identities_provider_subject_uidx").on(
|
|
132
100
|
table.provider,
|
|
133
101
|
table.providerTenantId,
|
|
134
102
|
table.providerSubjectId
|
|
135
103
|
),
|
|
136
|
-
|
|
137
|
-
|
|
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
|
-
|
|
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 =
|
|
113
|
+
var juniorConversations = pgTable3(
|
|
146
114
|
"junior_conversations",
|
|
147
115
|
{
|
|
148
|
-
conversationId:
|
|
116
|
+
conversationId: text3("conversation_id").primaryKey(),
|
|
149
117
|
schemaVersion: integer("schema_version").notNull().default(1),
|
|
150
|
-
source:
|
|
151
|
-
originType:
|
|
152
|
-
originId:
|
|
153
|
-
originRunId:
|
|
154
|
-
destinationId:
|
|
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:
|
|
158
|
-
actorIdentityId:
|
|
125
|
+
destination: jsonb2("destination_json").$type(),
|
|
126
|
+
actorIdentityId: text3("actor_identity_id").references(
|
|
159
127
|
() => juniorIdentities.id
|
|
160
128
|
),
|
|
161
|
-
creatorIdentityId:
|
|
129
|
+
creatorIdentityId: text3("creator_identity_id").references(
|
|
162
130
|
() => juniorIdentities.id
|
|
163
131
|
),
|
|
164
|
-
credentialSubjectIdentityId:
|
|
132
|
+
credentialSubjectIdentityId: text3(
|
|
165
133
|
"credential_subject_identity_id"
|
|
166
134
|
).references(() => juniorIdentities.id),
|
|
167
|
-
actor:
|
|
168
|
-
channelName:
|
|
169
|
-
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:
|
|
175
|
-
runId:
|
|
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:
|
|
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:
|
|
153
|
+
usage: jsonb2("usage_json").$type(),
|
|
186
154
|
executionDurationMs: integer("execution_duration_ms").notNull().default(0),
|
|
187
|
-
executionUsage:
|
|
155
|
+
executionUsage: jsonb2("execution_usage_json").$type(),
|
|
156
|
+
metricRunId: text3("metric_run_id")
|
|
188
157
|
},
|
|
189
158
|
(table) => [
|
|
190
|
-
|
|
159
|
+
index2("junior_conversations_last_activity_idx").on(
|
|
191
160
|
table.lastActivityAt.desc(),
|
|
192
161
|
table.conversationId
|
|
193
162
|
),
|
|
194
|
-
|
|
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
|
-
|
|
168
|
+
index2("junior_conversations_destination_activity_idx").on(
|
|
200
169
|
table.destinationId,
|
|
201
170
|
table.lastActivityAt.desc()
|
|
202
171
|
),
|
|
203
|
-
|
|
172
|
+
index2("junior_conversations_actor_activity_idx").on(
|
|
204
173
|
table.actorIdentityId,
|
|
205
174
|
table.lastActivityAt.desc()
|
|
206
175
|
),
|
|
207
|
-
|
|
176
|
+
index2("junior_conversations_origin_idx").on(
|
|
208
177
|
table.originType,
|
|
209
178
|
table.originId,
|
|
210
179
|
table.lastActivityAt.desc()
|
|
211
180
|
),
|
|
212
|
-
|
|
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 =
|
|
186
|
+
var juniorAgentSteps = pgTable4(
|
|
218
187
|
"junior_agent_steps",
|
|
219
188
|
{
|
|
220
|
-
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:
|
|
224
|
-
role:
|
|
225
|
-
payload:
|
|
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
|
-
|
|
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
|
|
241
|
-
var juniorConversationMessages =
|
|
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:
|
|
245
|
-
messageId:
|
|
246
|
-
role:
|
|
247
|
-
authorIdentityId:
|
|
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:
|
|
251
|
-
meta:
|
|
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
|
-
|
|
226
|
+
index4("junior_conversation_messages_activity_idx").on(
|
|
258
227
|
table.conversationId,
|
|
259
228
|
table.createdAt
|
|
260
229
|
),
|
|
261
|
-
|
|
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
|
|
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,
|
|
@@ -31,20 +31,21 @@ function coercePendingAuthState(value) {
|
|
|
31
31
|
const kind = value.kind;
|
|
32
32
|
const provider = toOptionalString(value.provider);
|
|
33
33
|
const actorId = toOptionalString(value.actorId);
|
|
34
|
+
const authSessionId = toOptionalString(value.authSessionId);
|
|
34
35
|
const scope = toOptionalString(value.scope);
|
|
35
36
|
const sessionId = toOptionalString(value.sessionId);
|
|
36
37
|
const linkSentAtMs = toOptionalNumber(value.linkSentAtMs);
|
|
37
|
-
if (kind !== "mcp" && kind !== "plugin" || !provider || !actorId || !sessionId || typeof linkSentAtMs !== "number") {
|
|
38
|
+
if (kind !== "mcp" && kind !== "plugin" || !provider || !actorId || kind === "mcp" && !authSessionId || !sessionId || typeof linkSentAtMs !== "number") {
|
|
38
39
|
return void 0;
|
|
39
40
|
}
|
|
40
|
-
|
|
41
|
-
kind,
|
|
41
|
+
const base = {
|
|
42
42
|
provider,
|
|
43
43
|
actorId,
|
|
44
44
|
...scope ? { scope } : {},
|
|
45
45
|
sessionId,
|
|
46
46
|
linkSentAtMs
|
|
47
47
|
};
|
|
48
|
+
return kind === "mcp" ? { ...base, authSessionId, kind } : { ...base, kind };
|
|
48
49
|
}
|
|
49
50
|
function coerceThreadConversationState(value) {
|
|
50
51
|
if (!isRecord(value)) {
|