@sentry/junior 0.124.2 → 0.125.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/dist/{agent-hooks-HJQTURNC.js → agent-hooks-MF5UZRCO.js} +8 -8
- package/dist/api/conversations/auxiliary-costs.d.ts +6 -0
- package/dist/api/conversations/detail.d.ts +10 -0
- package/dist/api/conversations/list.d.ts +11 -0
- package/dist/api/conversations/projection.d.ts +2 -1
- package/dist/api/locations/detail.d.ts +20 -0
- package/dist/api/people/profile.d.ts +10 -0
- package/dist/api/people/shared.d.ts +36 -0
- package/dist/api/plugin-reports.d.ts +1 -0
- package/dist/api/schema/conversation.d.ts +40 -0
- package/dist/api/schema/location.d.ts +10 -0
- package/dist/api/schema/person.d.ts +10 -0
- package/dist/api/schema.d.ts +2 -2
- package/dist/api/schema.js +4 -2
- package/dist/api.js +322 -169
- package/dist/app.js +22 -23
- package/dist/{catalog-runtime-F356WNZS.js → catalog-runtime-V6SJTUV7.js} +5 -5
- package/dist/chat/agent/prompt.d.ts +1 -0
- package/dist/chat/conversations/history.d.ts +4 -2
- package/dist/chat/conversations/sql/conversation-row.d.ts +7 -4
- package/dist/chat/conversations/sql/store.d.ts +2 -1
- package/dist/chat/conversations/store.d.ts +9 -1
- package/dist/chat/pi/client.d.ts +1 -0
- package/dist/chat/plugins/agent-hooks.d.ts +1 -0
- package/dist/chat/plugins/conversation-event-stats.d.ts +3 -0
- package/dist/chat/plugins/conversation-events.d.ts +1 -1
- package/dist/chat/slack/source-link.d.ts +5 -0
- package/dist/chat/source.d.ts +16 -0
- package/dist/{chunk-VMRKIKGO.js → chunk-2R5MASH3.js} +1 -1
- package/dist/{chunk-EOSC6JOC.js → chunk-2U5CLBYF.js} +1 -1
- package/dist/{chunk-AYQZCJZJ.js → chunk-6ZBSTNYN.js} +14 -0
- package/dist/{chunk-CMYDYVOD.js → chunk-7K57FJXR.js} +6 -5
- package/dist/{chunk-SMTAXLX4.js → chunk-CAPBVX4L.js} +2 -2
- package/dist/{chunk-7P7YVJKH.js → chunk-EXD2Z3YR.js} +2 -2
- package/dist/{chunk-SS7MAJF5.js → chunk-HT7DSLKL.js} +16 -14
- package/dist/{chunk-PR3M62LK.js → chunk-HX236W2U.js} +6 -4
- package/dist/{chunk-WKBPFZ25.js → chunk-IHNBJHEP.js} +1 -1
- package/dist/{chunk-DW6SLS5F.js → chunk-IS4DGI5J.js} +73 -17
- package/dist/{chunk-4JW3YNQZ.js → chunk-JT3YMQR3.js} +7 -9
- package/dist/{chunk-L7EZRQ2J.js → chunk-K6MQWEEJ.js} +7 -7
- package/dist/{chunk-574YK7QW.js → chunk-KN7QI56S.js} +23 -3
- package/dist/{chunk-NNKVDYXN.js → chunk-LG5TXWXI.js} +11 -11
- package/dist/{chunk-ASK74NM6.js → chunk-MVYNJECP.js} +1 -1
- package/dist/{chunk-AQKVWIPR.js → chunk-MYKSUTUV.js} +4 -4
- package/dist/{chunk-ZO6E537B.js → chunk-NM3PMQS6.js} +1 -1
- package/dist/{chunk-IXTIJQ7Z.js → chunk-ODB55JM7.js} +162 -15
- package/dist/{chunk-IMLJE2NY.js → chunk-Q3UF3K77.js} +2 -2
- package/dist/{chunk-GCGJGSQL.js → chunk-S4PUICSB.js} +2 -0
- package/dist/{chunk-PE44LDDQ.js → chunk-UTL3MHPC.js} +1 -0
- package/dist/{chunk-KYKLQYSU.js → chunk-XJYGLTYI.js} +1 -1
- package/dist/{chunk-7LDOW4QA.js → chunk-ZXGBLAYQ.js} +1 -1
- package/dist/cli/chat.js +23 -23
- package/dist/cli/check.js +6 -6
- package/dist/cli/plugins.js +11 -11
- package/dist/cli/snapshot-create.js +8 -8
- package/dist/cli/upgrade.js +6 -6
- package/dist/db/schema/conversations.d.ts +20 -0
- package/dist/db/schema.d.ts +19 -0
- package/dist/{db-4SU2HJSV.js → db-JSDSWK7T.js} +6 -6
- package/dist/instrumentation.js +2 -2
- package/dist/nitro.js +2 -2
- package/dist/{oauth-callback-server-MMCH5QV6.js → oauth-callback-server-UMS2T3HN.js} +16 -17
- package/dist/reporting-schema.d.ts +2 -0
- package/dist/{runner-ZDSNVGYA.js → runner-RGOANIRV.js} +11 -12
- package/dist/{skills-7G7LBHLK.js → skills-GBLPOQOD.js} +6 -6
- package/dist/{validation-2ETDADPB.js → validation-BMQY6CD4.js} +6 -6
- package/dist/version.js +1 -1
- package/migrations/0013_conversation_session_source.sql +38 -0
- package/migrations/meta/0013_snapshot.json +1250 -0
- package/migrations/meta/_journal.json +8 -1
- package/package.json +6 -6
- package/dist/chunk-BA5KHLPQ.js +0 -55
package/dist/api.js
CHANGED
|
@@ -24,54 +24,53 @@ import {
|
|
|
24
24
|
personalTokenParamsSchema,
|
|
25
25
|
revokePersonalTokenResponseSchema,
|
|
26
26
|
statsReportSchema
|
|
27
|
-
} from "./chunk-
|
|
27
|
+
} from "./chunk-6ZBSTNYN.js";
|
|
28
28
|
import {
|
|
29
29
|
formatSlackConversationRedactedLabel,
|
|
30
30
|
readHealthReport,
|
|
31
31
|
resolveSlackConversationContextFromThreadId
|
|
32
|
-
} from "./chunk-
|
|
32
|
+
} from "./chunk-EXD2Z3YR.js";
|
|
33
33
|
import {
|
|
34
34
|
buildSentryConversationUrl
|
|
35
35
|
} from "./chunk-4CODA7P5.js";
|
|
36
|
-
import {
|
|
37
|
-
renderPluginConversationEvent
|
|
38
|
-
} from "./chunk-BA5KHLPQ.js";
|
|
39
36
|
import {
|
|
40
37
|
healthReportSchema,
|
|
41
38
|
pluginOperationalReportFeedSchema,
|
|
42
39
|
pluginsSchema,
|
|
43
40
|
runtimeInfoReportSchema,
|
|
44
41
|
skillReportsSchema
|
|
45
|
-
} from "./chunk-
|
|
42
|
+
} from "./chunk-UTL3MHPC.js";
|
|
46
43
|
import {
|
|
47
44
|
readStats
|
|
48
|
-
} from "./chunk-
|
|
45
|
+
} from "./chunk-Q3UF3K77.js";
|
|
49
46
|
import {
|
|
50
47
|
agentTurnUsageSchema,
|
|
51
48
|
hasAgentTurnUsage,
|
|
52
49
|
renderJuniorNativeConversationEvent
|
|
53
|
-
} from "./chunk-
|
|
50
|
+
} from "./chunk-HX236W2U.js";
|
|
54
51
|
import "./chunk-PDO5BLNM.js";
|
|
55
52
|
import {
|
|
56
53
|
createPluginLogger,
|
|
57
54
|
getPlugins,
|
|
58
55
|
listConversationAnnotations,
|
|
59
|
-
readViewerActors
|
|
60
|
-
|
|
56
|
+
readViewerActors,
|
|
57
|
+
renderPluginConversationEvent
|
|
58
|
+
} from "./chunk-ODB55JM7.js";
|
|
61
59
|
import {
|
|
62
60
|
decodeStoredConversationEvent,
|
|
63
61
|
getDb,
|
|
64
|
-
getSqlExecutor
|
|
65
|
-
|
|
62
|
+
getSqlExecutor,
|
|
63
|
+
parseSessionSource
|
|
64
|
+
} from "./chunk-IS4DGI5J.js";
|
|
66
65
|
import {
|
|
67
66
|
juniorApiTokens,
|
|
68
67
|
juniorConversationEvents,
|
|
69
68
|
juniorConversations,
|
|
70
69
|
juniorIdentities,
|
|
71
70
|
juniorUsers
|
|
72
|
-
} from "./chunk-
|
|
73
|
-
import "./chunk-
|
|
74
|
-
import "./chunk-
|
|
71
|
+
} from "./chunk-S4PUICSB.js";
|
|
72
|
+
import "./chunk-XJYGLTYI.js";
|
|
73
|
+
import "./chunk-KN7QI56S.js";
|
|
75
74
|
import {
|
|
76
75
|
juniorDestinations
|
|
77
76
|
} from "./chunk-VFUK3X5B.js";
|
|
@@ -80,12 +79,15 @@ import {
|
|
|
80
79
|
parseSlackThreadId
|
|
81
80
|
} from "./chunk-S7G34U75.js";
|
|
82
81
|
import "./chunk-HZF5P5UN.js";
|
|
83
|
-
import "./chunk-
|
|
82
|
+
import "./chunk-MVYNJECP.js";
|
|
84
83
|
import "./chunk-OB42YVAE.js";
|
|
85
|
-
import
|
|
84
|
+
import {
|
|
85
|
+
parseSlackChannelId,
|
|
86
|
+
parseSlackTeamId
|
|
87
|
+
} from "./chunk-F3B2YJ76.js";
|
|
86
88
|
import "./chunk-6GWA276C.js";
|
|
87
|
-
import "./chunk-
|
|
88
|
-
import "./chunk-
|
|
89
|
+
import "./chunk-2R5MASH3.js";
|
|
90
|
+
import "./chunk-ZXGBLAYQ.js";
|
|
89
91
|
import "./chunk-MLKGABMK.js";
|
|
90
92
|
|
|
91
93
|
// src/api.ts
|
|
@@ -853,7 +855,18 @@ async function readConversationEventPage(executor, args) {
|
|
|
853
855
|
}
|
|
854
856
|
|
|
855
857
|
// src/api/conversations/list.ts
|
|
856
|
-
import { and as
|
|
858
|
+
import { and as and6, asc as asc2, desc as desc2, eq as eq7, isNull as isNull3 } from "drizzle-orm";
|
|
859
|
+
|
|
860
|
+
// src/chat/slack/source-link.ts
|
|
861
|
+
function buildSlackSourceUrl(args) {
|
|
862
|
+
const channelId = parseSlackChannelId(args.channelId);
|
|
863
|
+
const teamId = parseSlackTeamId(args.teamId);
|
|
864
|
+
if (!channelId || !teamId) return void 0;
|
|
865
|
+
const url = new URL("https://slack.com/app_redirect");
|
|
866
|
+
url.searchParams.set("channel", channelId);
|
|
867
|
+
url.searchParams.set("team", teamId);
|
|
868
|
+
return url.toString();
|
|
869
|
+
}
|
|
857
870
|
|
|
858
871
|
// src/api/conversations/shared.ts
|
|
859
872
|
function slackStatsLocationLabel(input) {
|
|
@@ -898,6 +911,12 @@ function surfaceFromSource(source, conversationId) {
|
|
|
898
911
|
}
|
|
899
912
|
return surfaceFromConversationId(conversationId);
|
|
900
913
|
}
|
|
914
|
+
function sourceUrlFromConversation(conversation, canViewPrivateContent) {
|
|
915
|
+
if (!canViewPrivateContent || conversation.sessionSource?.platform !== "slack") {
|
|
916
|
+
return void 0;
|
|
917
|
+
}
|
|
918
|
+
return buildSlackSourceUrl(conversation.sessionSource);
|
|
919
|
+
}
|
|
901
920
|
function actorIdentityReport(actor) {
|
|
902
921
|
if (!actor) return void 0;
|
|
903
922
|
const identity = {
|
|
@@ -970,6 +989,10 @@ function conversationSummaryFromStoredConversation(args) {
|
|
|
970
989
|
conversation.conversationId
|
|
971
990
|
);
|
|
972
991
|
const actorIdentity = actorIdentityReport(conversation.actor);
|
|
992
|
+
const sourceUrl = sourceUrlFromConversation(
|
|
993
|
+
conversation,
|
|
994
|
+
canViewPrivateContent
|
|
995
|
+
);
|
|
973
996
|
const slackThread = parseSlackThreadId(conversation.conversationId);
|
|
974
997
|
const channelName = channelNameFromConversation(
|
|
975
998
|
conversation,
|
|
@@ -995,8 +1018,10 @@ function conversationSummaryFromStoredConversation(args) {
|
|
|
995
1018
|
startedAt: new Date(conversation.createdAtMs).toISOString(),
|
|
996
1019
|
status: statusFromConversation(conversation),
|
|
997
1020
|
surface,
|
|
1021
|
+
...args.auxiliaryCosts ? { auxiliaryCosts: args.auxiliaryCosts } : {},
|
|
998
1022
|
...usage3 ? { cumulativeUsage: usage3 } : {},
|
|
999
1023
|
...actorIdentity ? { actorIdentity } : {},
|
|
1024
|
+
...sourceUrl ? { sourceUrl } : {},
|
|
1000
1025
|
...conversation.archivedAtMs ? { archivedAt: new Date(conversation.archivedAtMs).toISOString() } : {},
|
|
1001
1026
|
...slackThread ? { channel: slackThread.channelId } : {},
|
|
1002
1027
|
...channelName ? { channelName } : {},
|
|
@@ -1162,6 +1187,112 @@ async function readRootConversationMetricsFromSql(db, rootConversationIds) {
|
|
|
1162
1187
|
);
|
|
1163
1188
|
}
|
|
1164
1189
|
|
|
1190
|
+
// src/api/conversations/auxiliary-costs.ts
|
|
1191
|
+
import {
|
|
1192
|
+
and as and5,
|
|
1193
|
+
eq as eq6,
|
|
1194
|
+
inArray as inArray4,
|
|
1195
|
+
isNotNull as isNotNull2,
|
|
1196
|
+
isNull as isNull2,
|
|
1197
|
+
or,
|
|
1198
|
+
sql as sql4
|
|
1199
|
+
} from "drizzle-orm";
|
|
1200
|
+
import { alias as alias3 } from "drizzle-orm/pg-core";
|
|
1201
|
+
var auxiliaryRootConversation = alias3(
|
|
1202
|
+
juniorConversations,
|
|
1203
|
+
"auxiliary_root_conversation"
|
|
1204
|
+
);
|
|
1205
|
+
function eventCost() {
|
|
1206
|
+
return sql4`CASE
|
|
1207
|
+
WHEN ${juniorConversationEvents.type} = 'structured_event'
|
|
1208
|
+
AND jsonb_typeof(${juniorConversationEvents.payload}->'content'->'costUsd') = 'number'
|
|
1209
|
+
THEN (${juniorConversationEvents.payload}->'content'->>'costUsd')::numeric
|
|
1210
|
+
WHEN ${juniorConversationEvents.type} = 'guardian_action_reviewed'
|
|
1211
|
+
AND jsonb_typeof(${juniorConversationEvents.payload}->'costUsd') = 'number'
|
|
1212
|
+
THEN (${juniorConversationEvents.payload}->>'costUsd')::numeric
|
|
1213
|
+
ELSE NULL
|
|
1214
|
+
END`;
|
|
1215
|
+
}
|
|
1216
|
+
async function readConversationAuxiliaryCostsFromSql(db, conversationIds, options) {
|
|
1217
|
+
if (conversationIds.length === 0) return /* @__PURE__ */ new Map();
|
|
1218
|
+
const selectedIds = [...conversationIds];
|
|
1219
|
+
const conversationId = options.includeDescendants ? sql4`coalesce(
|
|
1220
|
+
${auxiliaryRootConversation.conversationId},
|
|
1221
|
+
${juniorConversations.conversationId}
|
|
1222
|
+
)` : sql4`${juniorConversations.conversationId}`;
|
|
1223
|
+
const namespace = sql4`CASE
|
|
1224
|
+
WHEN ${juniorConversationEvents.type} = 'structured_event'
|
|
1225
|
+
THEN ${juniorConversationEvents.payload}->>'namespace'
|
|
1226
|
+
ELSE 'junior'
|
|
1227
|
+
END`;
|
|
1228
|
+
const name = sql4`CASE
|
|
1229
|
+
WHEN ${juniorConversationEvents.type} = 'structured_event'
|
|
1230
|
+
THEN ${juniorConversationEvents.payload}->>'name'
|
|
1231
|
+
ELSE ${juniorConversationEvents.type}
|
|
1232
|
+
END`;
|
|
1233
|
+
const cost2 = eventCost();
|
|
1234
|
+
const selectedConversation = options.includeDescendants ? or(
|
|
1235
|
+
and5(
|
|
1236
|
+
inArray4(juniorConversations.rootConversationId, selectedIds),
|
|
1237
|
+
isNotNull2(auxiliaryRootConversation.conversationId)
|
|
1238
|
+
),
|
|
1239
|
+
inArray4(juniorConversations.conversationId, selectedIds)
|
|
1240
|
+
) : inArray4(juniorConversations.conversationId, selectedIds);
|
|
1241
|
+
const rows = await db.select({
|
|
1242
|
+
conversationId,
|
|
1243
|
+
costUsd: sql4`round(sum(${cost2}), 12)::double precision`.mapWith(
|
|
1244
|
+
Number
|
|
1245
|
+
),
|
|
1246
|
+
events: sql4`count(*)::integer`.mapWith(Number),
|
|
1247
|
+
name,
|
|
1248
|
+
namespace
|
|
1249
|
+
}).from(juniorConversationEvents).innerJoin(
|
|
1250
|
+
juniorConversations,
|
|
1251
|
+
eq6(
|
|
1252
|
+
juniorConversations.conversationId,
|
|
1253
|
+
juniorConversationEvents.conversationId
|
|
1254
|
+
)
|
|
1255
|
+
).leftJoin(
|
|
1256
|
+
auxiliaryRootConversation,
|
|
1257
|
+
and5(
|
|
1258
|
+
eq6(
|
|
1259
|
+
auxiliaryRootConversation.conversationId,
|
|
1260
|
+
juniorConversations.rootConversationId
|
|
1261
|
+
),
|
|
1262
|
+
isNull2(auxiliaryRootConversation.parentConversationId),
|
|
1263
|
+
eq6(
|
|
1264
|
+
auxiliaryRootConversation.rootConversationId,
|
|
1265
|
+
auxiliaryRootConversation.conversationId
|
|
1266
|
+
)
|
|
1267
|
+
)
|
|
1268
|
+
).where(
|
|
1269
|
+
and5(
|
|
1270
|
+
selectedConversation,
|
|
1271
|
+
or(
|
|
1272
|
+
eq6(juniorConversationEvents.type, "structured_event"),
|
|
1273
|
+
eq6(juniorConversationEvents.type, "guardian_action_reviewed")
|
|
1274
|
+
),
|
|
1275
|
+
sql4`${cost2} >= 0`
|
|
1276
|
+
)
|
|
1277
|
+
).groupBy(conversationId, namespace, name).orderBy(conversationId, namespace, name);
|
|
1278
|
+
const result = /* @__PURE__ */ new Map();
|
|
1279
|
+
for (const row of rows) {
|
|
1280
|
+
const current = result.get(row.conversationId) ?? {
|
|
1281
|
+
costUsd: 0,
|
|
1282
|
+
operations: []
|
|
1283
|
+
};
|
|
1284
|
+
current.costUsd = Math.round((current.costUsd + row.costUsd) * 1e12) / 1e12;
|
|
1285
|
+
current.operations.push({
|
|
1286
|
+
costUsd: row.costUsd,
|
|
1287
|
+
events: row.events,
|
|
1288
|
+
name: row.name,
|
|
1289
|
+
namespace: row.namespace
|
|
1290
|
+
});
|
|
1291
|
+
result.set(row.conversationId, current);
|
|
1292
|
+
}
|
|
1293
|
+
return result;
|
|
1294
|
+
}
|
|
1295
|
+
|
|
1165
1296
|
// src/api/conversations/list.ts
|
|
1166
1297
|
var CONVERSATION_FEED_LIMIT = 50;
|
|
1167
1298
|
async function conversationRows(db, limit, actorEmail) {
|
|
@@ -1178,17 +1309,17 @@ async function conversationRows(db, limit, actorEmail) {
|
|
|
1178
1309
|
userDisplayName: juniorUsers.displayName
|
|
1179
1310
|
}).from(juniorConversations).leftJoin(
|
|
1180
1311
|
juniorDestinations,
|
|
1181
|
-
|
|
1312
|
+
eq7(juniorDestinations.id, juniorConversations.destinationId)
|
|
1182
1313
|
).leftJoin(
|
|
1183
1314
|
juniorIdentities,
|
|
1184
|
-
|
|
1185
|
-
).leftJoin(juniorUsers,
|
|
1186
|
-
|
|
1187
|
-
|
|
1188
|
-
|
|
1189
|
-
actorEmail ?
|
|
1190
|
-
|
|
1191
|
-
|
|
1315
|
+
eq7(juniorIdentities.id, juniorConversations.actorIdentityId)
|
|
1316
|
+
).leftJoin(juniorUsers, eq7(juniorUsers.id, juniorIdentities.userId)).where(
|
|
1317
|
+
and6(
|
|
1318
|
+
isNull3(juniorConversations.parentConversationId),
|
|
1319
|
+
isNull3(juniorConversations.archivedAt),
|
|
1320
|
+
actorEmail ? and6(
|
|
1321
|
+
eq7(juniorIdentities.emailNormalized, actorEmail),
|
|
1322
|
+
eq7(juniorIdentities.emailVerified, true)
|
|
1192
1323
|
) : void 0
|
|
1193
1324
|
)
|
|
1194
1325
|
).orderBy(
|
|
@@ -1198,6 +1329,10 @@ async function conversationRows(db, limit, actorEmail) {
|
|
|
1198
1329
|
}
|
|
1199
1330
|
function conversationFromRow(row) {
|
|
1200
1331
|
const value = row.conversation;
|
|
1332
|
+
const sessionSource = value.sessionSource === null ? void 0 : parseSessionSource(value.sessionSource);
|
|
1333
|
+
if (value.sessionSource !== null && !sessionSource) {
|
|
1334
|
+
throw new Error("Conversation record session source is invalid");
|
|
1335
|
+
}
|
|
1201
1336
|
const actorFullName = row.userDisplayName?.trim() ? row.userDisplayName : row.identityDisplayName;
|
|
1202
1337
|
const actor = row.identityProvider === "slack" ? {
|
|
1203
1338
|
platform: "slack",
|
|
@@ -1222,6 +1357,7 @@ function conversationFromRow(row) {
|
|
|
1222
1357
|
...value.archivedAt ? { archivedAtMs: value.archivedAt.getTime() } : {},
|
|
1223
1358
|
...value.channelName ? { channelName: value.channelName } : {},
|
|
1224
1359
|
...value.source ? { source: value.source } : {},
|
|
1360
|
+
...sessionSource ? { sessionSource } : {},
|
|
1225
1361
|
...value.title ? { title: value.title } : {},
|
|
1226
1362
|
...value.transcriptPurgedAt ? { transcriptPurgedAtMs: value.transcriptPurgedAt.getTime() } : {}
|
|
1227
1363
|
};
|
|
@@ -1241,11 +1377,11 @@ async function readConversationRecordFromSql(conversationId) {
|
|
|
1241
1377
|
userDisplayName: juniorUsers.displayName
|
|
1242
1378
|
}).from(juniorConversations).leftJoin(
|
|
1243
1379
|
juniorDestinations,
|
|
1244
|
-
|
|
1380
|
+
eq7(juniorDestinations.id, juniorConversations.destinationId)
|
|
1245
1381
|
).leftJoin(
|
|
1246
1382
|
juniorIdentities,
|
|
1247
|
-
|
|
1248
|
-
).leftJoin(juniorUsers,
|
|
1383
|
+
eq7(juniorIdentities.id, juniorConversations.actorIdentityId)
|
|
1384
|
+
).leftJoin(juniorUsers, eq7(juniorUsers.id, juniorIdentities.userId)).where(eq7(juniorConversations.conversationId, conversationId)).limit(1);
|
|
1249
1385
|
const row = rows[0];
|
|
1250
1386
|
return row ? {
|
|
1251
1387
|
conversation: conversationFromRow(row),
|
|
@@ -1264,12 +1400,15 @@ async function readConversationFeedFromSql(options = {}) {
|
|
|
1264
1400
|
options.actorEmail
|
|
1265
1401
|
);
|
|
1266
1402
|
const conversationIds = rows.map((row) => row.conversation.conversationId);
|
|
1267
|
-
const [accessByConversation, metricsByRoot] = await Promise.all([
|
|
1403
|
+
const [accessByConversation, auxiliaryCostsByRoot, metricsByRoot] = await Promise.all([
|
|
1268
1404
|
readConversationAccessFromSql(
|
|
1269
1405
|
db,
|
|
1270
1406
|
conversationIds,
|
|
1271
1407
|
options.verifiedViewerEmail
|
|
1272
1408
|
),
|
|
1409
|
+
readConversationAuxiliaryCostsFromSql(db, conversationIds, {
|
|
1410
|
+
includeDescendants: true
|
|
1411
|
+
}),
|
|
1273
1412
|
readRootConversationMetricsFromSql(db, conversationIds)
|
|
1274
1413
|
]);
|
|
1275
1414
|
return {
|
|
@@ -1278,6 +1417,9 @@ async function readConversationFeedFromSql(options = {}) {
|
|
|
1278
1417
|
return conversationSummaryFromStoredConversation({
|
|
1279
1418
|
conversation: conversationFromRow(row),
|
|
1280
1419
|
access: accessByConversation.get(row.conversation.conversationId),
|
|
1420
|
+
auxiliaryCosts: auxiliaryCostsByRoot.get(
|
|
1421
|
+
row.conversation.conversationId
|
|
1422
|
+
),
|
|
1281
1423
|
durationMs: metrics?.durationMs ?? row.conversation.durationMs,
|
|
1282
1424
|
...row.destinationVisibility === "public" && row.destinationId ? { locationId: row.destinationId } : {},
|
|
1283
1425
|
usage: metrics?.usage ?? row.conversation.usage ?? void 0
|
|
@@ -1320,6 +1462,7 @@ function projectConversationDetail(args) {
|
|
|
1320
1462
|
return {
|
|
1321
1463
|
...conversationSummaryFromStoredConversation({
|
|
1322
1464
|
access: args.access,
|
|
1465
|
+
auxiliaryCosts: args.auxiliaryCosts,
|
|
1323
1466
|
conversation,
|
|
1324
1467
|
durationMs: args.durationMs,
|
|
1325
1468
|
...args.locationId ? { locationId: args.locationId } : {},
|
|
@@ -1347,13 +1490,22 @@ async function readConversationDetailFromSql(conversationId, options) {
|
|
|
1347
1490
|
if (!record) return void 0;
|
|
1348
1491
|
const executor = getSqlExecutor();
|
|
1349
1492
|
const includeDescendantMetrics = record.rootConversationId === conversationId;
|
|
1350
|
-
const [
|
|
1493
|
+
const [
|
|
1494
|
+
accessByConversation,
|
|
1495
|
+
annotations,
|
|
1496
|
+
auxiliaryCostsByConversation,
|
|
1497
|
+
modelUsage,
|
|
1498
|
+
metricsByRoot
|
|
1499
|
+
] = await Promise.all([
|
|
1351
1500
|
readConversationAccessFromSql(
|
|
1352
1501
|
getDb(),
|
|
1353
1502
|
[conversationId],
|
|
1354
1503
|
options.verifiedViewerEmail
|
|
1355
1504
|
),
|
|
1356
1505
|
listConversationAnnotations(getDb(), conversationId),
|
|
1506
|
+
readConversationAuxiliaryCostsFromSql(getDb(), [conversationId], {
|
|
1507
|
+
includeDescendants: includeDescendantMetrics
|
|
1508
|
+
}),
|
|
1357
1509
|
record.conversation.transcriptPurgedAtMs === void 0 ? readConversationModelUsageFromSql(executor, {
|
|
1358
1510
|
conversationId,
|
|
1359
1511
|
includeDescendants: includeDescendantMetrics
|
|
@@ -1374,6 +1526,7 @@ async function readConversationDetailFromSql(conversationId, options) {
|
|
|
1374
1526
|
...record,
|
|
1375
1527
|
access,
|
|
1376
1528
|
annotations,
|
|
1529
|
+
auxiliaryCosts: auxiliaryCostsByConversation.get(conversationId),
|
|
1377
1530
|
durationMs: metrics?.durationMs ?? record.durationMs,
|
|
1378
1531
|
events: page.events,
|
|
1379
1532
|
modelUsage,
|
|
@@ -1470,13 +1623,13 @@ var event_list_default = defineApiRoute({
|
|
|
1470
1623
|
});
|
|
1471
1624
|
|
|
1472
1625
|
// src/api/conversations/stats.query.ts
|
|
1473
|
-
import { and as
|
|
1474
|
-
import { alias as
|
|
1626
|
+
import { and as and7, eq as eq8, gte, isNull as isNull4, lte, sql as sql6 } from "drizzle-orm";
|
|
1627
|
+
import { alias as alias4 } from "drizzle-orm/pg-core";
|
|
1475
1628
|
|
|
1476
1629
|
// src/api/conversations/aggregate.ts
|
|
1477
|
-
import { sql as
|
|
1630
|
+
import { sql as sql5 } from "drizzle-orm";
|
|
1478
1631
|
function tokenValue(source) {
|
|
1479
|
-
return
|
|
1632
|
+
return sql5`
|
|
1480
1633
|
CASE
|
|
1481
1634
|
WHEN COALESCE(
|
|
1482
1635
|
${source.usage}->>'inputTokens',
|
|
@@ -1495,7 +1648,7 @@ function tokenValue(source) {
|
|
|
1495
1648
|
`;
|
|
1496
1649
|
}
|
|
1497
1650
|
function costValue(source) {
|
|
1498
|
-
return
|
|
1651
|
+
return sql5`
|
|
1499
1652
|
CASE
|
|
1500
1653
|
WHEN ${source.usage}->'cost'->>'total' IS NOT NULL
|
|
1501
1654
|
THEN (${source.usage}->'cost'->>'total')::double precision
|
|
@@ -1516,37 +1669,37 @@ function costValue(source) {
|
|
|
1516
1669
|
function conversationAggregateColumns(sources) {
|
|
1517
1670
|
const metrics = sources?.metrics ?? juniorConversations;
|
|
1518
1671
|
const roots = sources?.roots ?? juniorConversations;
|
|
1519
|
-
const conversationCount = sources ?
|
|
1672
|
+
const conversationCount = sources ? sql5`COUNT(DISTINCT ${roots.conversationId})` : sql5`COUNT(*)`;
|
|
1520
1673
|
return {
|
|
1521
|
-
active:
|
|
1674
|
+
active: sql5`${conversationCount} FILTER (
|
|
1522
1675
|
WHERE ${roots.executionStatus} NOT IN ('idle', 'failed')
|
|
1523
1676
|
)::integer`,
|
|
1524
|
-
conversations:
|
|
1525
|
-
costUsd:
|
|
1526
|
-
durationMs:
|
|
1527
|
-
failed:
|
|
1677
|
+
conversations: sql5`${conversationCount}::integer`,
|
|
1678
|
+
costUsd: sql5`SUM(${costValue(metrics)})::double precision`,
|
|
1679
|
+
durationMs: sql5`COALESCE(SUM(${metrics.durationMs}), 0)::double precision`,
|
|
1680
|
+
failed: sql5`${conversationCount} FILTER (
|
|
1528
1681
|
WHERE ${roots.executionStatus} = 'failed'
|
|
1529
1682
|
)::integer`,
|
|
1530
|
-
tokens:
|
|
1683
|
+
tokens: sql5`SUM(${tokenValue(metrics)})::double precision`
|
|
1531
1684
|
};
|
|
1532
1685
|
}
|
|
1533
1686
|
function conversationRangeColumns() {
|
|
1534
1687
|
return {
|
|
1535
|
-
firstSeenAt:
|
|
1688
|
+
firstSeenAt: sql5`MIN(${juniorConversations.createdAt})`.mapWith(
|
|
1536
1689
|
juniorConversations.createdAt
|
|
1537
1690
|
),
|
|
1538
|
-
lastSeenAt:
|
|
1691
|
+
lastSeenAt: sql5`MAX(${juniorConversations.lastActivityAt})`.mapWith(
|
|
1539
1692
|
juniorConversations.lastActivityAt
|
|
1540
1693
|
)
|
|
1541
1694
|
};
|
|
1542
1695
|
}
|
|
1543
1696
|
function conversationActiveDaysColumn() {
|
|
1544
|
-
return
|
|
1697
|
+
return sql5`COUNT(DISTINCT (${juniorConversations.lastActivityAt} AT TIME ZONE 'UTC')::date)::integer`;
|
|
1545
1698
|
}
|
|
1546
1699
|
|
|
1547
1700
|
// src/api/conversations/stats.query.ts
|
|
1548
1701
|
var WINDOW_DAYS = 90;
|
|
1549
|
-
var treeConversation =
|
|
1702
|
+
var treeConversation = alias4(juniorConversations, "stats_tree_conversation");
|
|
1550
1703
|
var treeAggregateColumns = conversationAggregateColumns({
|
|
1551
1704
|
metrics: treeConversation,
|
|
1552
1705
|
roots: juniorConversations
|
|
@@ -1605,8 +1758,8 @@ function statsItems(map) {
|
|
|
1605
1758
|
);
|
|
1606
1759
|
}
|
|
1607
1760
|
function statsWhere(start, end) {
|
|
1608
|
-
return
|
|
1609
|
-
|
|
1761
|
+
return and7(
|
|
1762
|
+
isNull4(juniorConversations.parentConversationId),
|
|
1610
1763
|
gte(juniorConversations.lastActivityAt, start),
|
|
1611
1764
|
lte(juniorConversations.lastActivityAt, end)
|
|
1612
1765
|
);
|
|
@@ -1679,14 +1832,14 @@ function guardianStats(rows, endMs) {
|
|
|
1679
1832
|
}
|
|
1680
1833
|
async function aggregateStats(db, start, end) {
|
|
1681
1834
|
const where = statsWhere(start, end);
|
|
1682
|
-
const activityDate =
|
|
1835
|
+
const activityDate = sql6`TO_CHAR(
|
|
1683
1836
|
${juniorConversations.lastActivityAt} AT TIME ZONE 'UTC',
|
|
1684
1837
|
'YYYY-MM-DD'
|
|
1685
1838
|
)`;
|
|
1686
1839
|
const [totalsRows, actorRows, locationRows, metricRows] = await Promise.all([
|
|
1687
1840
|
db.select(treeAggregateColumns).from(juniorConversations).innerJoin(
|
|
1688
1841
|
treeConversation,
|
|
1689
|
-
|
|
1842
|
+
eq8(
|
|
1690
1843
|
treeConversation.rootConversationId,
|
|
1691
1844
|
juniorConversations.conversationId
|
|
1692
1845
|
)
|
|
@@ -1701,14 +1854,14 @@ async function aggregateStats(db, start, end) {
|
|
|
1701
1854
|
...treeAggregateColumns
|
|
1702
1855
|
}).from(juniorConversations).innerJoin(
|
|
1703
1856
|
treeConversation,
|
|
1704
|
-
|
|
1857
|
+
eq8(
|
|
1705
1858
|
treeConversation.rootConversationId,
|
|
1706
1859
|
juniorConversations.conversationId
|
|
1707
1860
|
)
|
|
1708
1861
|
).leftJoin(
|
|
1709
1862
|
juniorIdentities,
|
|
1710
|
-
|
|
1711
|
-
).leftJoin(juniorUsers,
|
|
1863
|
+
eq8(juniorIdentities.id, juniorConversations.actorIdentityId)
|
|
1864
|
+
).leftJoin(juniorUsers, eq8(juniorUsers.id, juniorIdentities.userId)).where(where).groupBy(
|
|
1712
1865
|
juniorIdentities.displayName,
|
|
1713
1866
|
juniorIdentities.emailNormalized,
|
|
1714
1867
|
juniorIdentities.handle,
|
|
@@ -1726,13 +1879,13 @@ async function aggregateStats(db, start, end) {
|
|
|
1726
1879
|
...treeAggregateColumns
|
|
1727
1880
|
}).from(juniorConversations).innerJoin(
|
|
1728
1881
|
treeConversation,
|
|
1729
|
-
|
|
1882
|
+
eq8(
|
|
1730
1883
|
treeConversation.rootConversationId,
|
|
1731
1884
|
juniorConversations.conversationId
|
|
1732
1885
|
)
|
|
1733
1886
|
).leftJoin(
|
|
1734
1887
|
juniorDestinations,
|
|
1735
|
-
|
|
1888
|
+
eq8(juniorDestinations.id, juniorConversations.destinationId)
|
|
1736
1889
|
).where(where).groupBy(
|
|
1737
1890
|
juniorConversations.channelName,
|
|
1738
1891
|
juniorConversations.source,
|
|
@@ -1748,7 +1901,7 @@ async function aggregateStats(db, start, end) {
|
|
|
1748
1901
|
tokens: treeAggregateColumns.tokens
|
|
1749
1902
|
}).from(juniorConversations).innerJoin(
|
|
1750
1903
|
treeConversation,
|
|
1751
|
-
|
|
1904
|
+
eq8(
|
|
1752
1905
|
treeConversation.rootConversationId,
|
|
1753
1906
|
juniorConversations.conversationId
|
|
1754
1907
|
)
|
|
@@ -1757,26 +1910,26 @@ async function aggregateStats(db, start, end) {
|
|
|
1757
1910
|
return { actorRows, locationRows, metricRows, totals: totalsRows[0] };
|
|
1758
1911
|
}
|
|
1759
1912
|
async function aggregateGuardianStats(db, start, end) {
|
|
1760
|
-
const date =
|
|
1913
|
+
const date = sql6`TO_CHAR(
|
|
1761
1914
|
${juniorConversationEvents.createdAt} AT TIME ZONE 'UTC',
|
|
1762
1915
|
'YYYY-MM-DD'
|
|
1763
1916
|
)`;
|
|
1764
|
-
const decision =
|
|
1765
|
-
const cost2 =
|
|
1917
|
+
const decision = sql6`${juniorConversationEvents.payload}->>'decision'`;
|
|
1918
|
+
const cost2 = sql6`CASE
|
|
1766
1919
|
WHEN jsonb_typeof(${juniorConversationEvents.payload}->'costUsd') = 'number'
|
|
1767
1920
|
THEN (${juniorConversationEvents.payload}->>'costUsd')::double precision
|
|
1768
1921
|
ELSE NULL
|
|
1769
1922
|
END`;
|
|
1770
1923
|
return await db.select({
|
|
1771
|
-
allow:
|
|
1772
|
-
ask:
|
|
1773
|
-
costUsd:
|
|
1924
|
+
allow: sql6`COUNT(*) FILTER (WHERE ${decision} = 'allow')::integer`,
|
|
1925
|
+
ask: sql6`COUNT(*) FILTER (WHERE ${decision} = 'ask')::integer`,
|
|
1926
|
+
costUsd: sql6`SUM(${cost2})::double precision`,
|
|
1774
1927
|
date,
|
|
1775
|
-
deny:
|
|
1776
|
-
requests:
|
|
1928
|
+
deny: sql6`COUNT(*) FILTER (WHERE ${decision} = 'deny')::integer`,
|
|
1929
|
+
requests: sql6`COUNT(*)::integer`
|
|
1777
1930
|
}).from(juniorConversationEvents).where(
|
|
1778
|
-
|
|
1779
|
-
|
|
1931
|
+
and7(
|
|
1932
|
+
eq8(juniorConversationEvents.type, "guardian_action_reviewed"),
|
|
1780
1933
|
gte(juniorConversationEvents.createdAt, start),
|
|
1781
1934
|
lte(juniorConversationEvents.createdAt, end)
|
|
1782
1935
|
)
|
|
@@ -1855,7 +2008,7 @@ function readDescriptionText(home) {
|
|
|
1855
2008
|
}
|
|
1856
2009
|
}
|
|
1857
2010
|
async function readSkillReports() {
|
|
1858
|
-
const { discoverSkills } = await import("./skills-
|
|
2011
|
+
const { discoverSkills } = await import("./skills-GBLPOQOD.js");
|
|
1859
2012
|
const skills = await discoverSkills();
|
|
1860
2013
|
return skillReportsSchema.parse(
|
|
1861
2014
|
skills.map((skill) => ({
|
|
@@ -1865,7 +2018,7 @@ async function readSkillReports() {
|
|
|
1865
2018
|
);
|
|
1866
2019
|
}
|
|
1867
2020
|
async function readPlugins() {
|
|
1868
|
-
const { pluginCatalogRuntime } = await import("./catalog-runtime-
|
|
2021
|
+
const { pluginCatalogRuntime } = await import("./catalog-runtime-V6SJTUV7.js");
|
|
1869
2022
|
return pluginsSchema.parse(
|
|
1870
2023
|
pluginCatalogRuntime.getProviders().map((plugin) => ({
|
|
1871
2024
|
configKeys: plugin.manifest.configKeys ?? [],
|
|
@@ -1878,7 +2031,7 @@ async function readPlugins() {
|
|
|
1878
2031
|
async function readRuntimeInfoReport() {
|
|
1879
2032
|
const [{ homeDir }, { pluginCatalogRuntime }, plugins, skills] = await Promise.all([
|
|
1880
2033
|
import("./discovery-GUFTFBTL.js"),
|
|
1881
|
-
import("./catalog-runtime-
|
|
2034
|
+
import("./catalog-runtime-V6SJTUV7.js"),
|
|
1882
2035
|
readPlugins(),
|
|
1883
2036
|
readSkillReports()
|
|
1884
2037
|
]);
|
|
@@ -1894,7 +2047,7 @@ async function readRuntimeInfoReport() {
|
|
|
1894
2047
|
}
|
|
1895
2048
|
async function readPluginOperationalReportFeed() {
|
|
1896
2049
|
const nowMs = Date.now();
|
|
1897
|
-
const { getPluginOperationalReports } = await import("./agent-hooks-
|
|
2050
|
+
const { getPluginOperationalReports } = await import("./agent-hooks-MF5UZRCO.js");
|
|
1898
2051
|
return pluginOperationalReportFeedSchema.parse({
|
|
1899
2052
|
source: "plugins",
|
|
1900
2053
|
generatedAt: new Date(nowMs).toISOString(),
|
|
@@ -1914,8 +2067,8 @@ var health_default = defineApiRoute({
|
|
|
1914
2067
|
import { Hono as Hono2 } from "hono";
|
|
1915
2068
|
|
|
1916
2069
|
// src/api/locations/query.ts
|
|
1917
|
-
import { and as
|
|
1918
|
-
import { alias as
|
|
2070
|
+
import { and as and8, asc as asc3, desc as desc3, eq as eq9, gte as gte2, isNull as isNull5, sql as sql7 } from "drizzle-orm";
|
|
2071
|
+
import { alias as alias5 } from "drizzle-orm/pg-core";
|
|
1919
2072
|
|
|
1920
2073
|
// src/api/conversations/reporting.ts
|
|
1921
2074
|
function surfaceLabel2(surface) {
|
|
@@ -1976,7 +2129,7 @@ function summaryFromRow(row, options = {}) {
|
|
|
1976
2129
|
// src/api/locations/query.ts
|
|
1977
2130
|
var RECENT_LIMIT = 25;
|
|
1978
2131
|
var ACTIVITY_DAYS = 90;
|
|
1979
|
-
var treeConversation2 =
|
|
2132
|
+
var treeConversation2 = alias5(
|
|
1980
2133
|
juniorConversations,
|
|
1981
2134
|
"location_tree_conversation"
|
|
1982
2135
|
);
|
|
@@ -2019,13 +2172,13 @@ function emptyActor(actor) {
|
|
|
2019
2172
|
};
|
|
2020
2173
|
}
|
|
2021
2174
|
function topLevelWhere() {
|
|
2022
|
-
return
|
|
2175
|
+
return isNull5(juniorConversations.parentConversationId);
|
|
2023
2176
|
}
|
|
2024
2177
|
function publicLocationWhere(destinationId) {
|
|
2025
|
-
return
|
|
2178
|
+
return and8(
|
|
2026
2179
|
topLevelWhere(),
|
|
2027
|
-
|
|
2028
|
-
|
|
2180
|
+
eq9(juniorDestinations.id, destinationId),
|
|
2181
|
+
eq9(juniorDestinations.visibility, "public")
|
|
2029
2182
|
);
|
|
2030
2183
|
}
|
|
2031
2184
|
function locationColumns() {
|
|
@@ -2076,28 +2229,28 @@ async function directoryRows(db) {
|
|
|
2076
2229
|
...conversationRangeColumns()
|
|
2077
2230
|
}).from(juniorConversations).innerJoin(
|
|
2078
2231
|
treeConversation2,
|
|
2079
|
-
|
|
2232
|
+
eq9(
|
|
2080
2233
|
treeConversation2.rootConversationId,
|
|
2081
2234
|
juniorConversations.conversationId
|
|
2082
2235
|
)
|
|
2083
2236
|
).leftJoin(
|
|
2084
2237
|
juniorDestinations,
|
|
2085
|
-
|
|
2238
|
+
eq9(juniorDestinations.id, juniorConversations.destinationId)
|
|
2086
2239
|
).where(topLevelWhere()).groupBy(...locationGroupBy());
|
|
2087
2240
|
}
|
|
2088
2241
|
async function directoryActivityRows(db, start) {
|
|
2089
|
-
const date =
|
|
2242
|
+
const date = sql7`TO_CHAR(
|
|
2090
2243
|
${juniorConversations.lastActivityAt} AT TIME ZONE 'UTC',
|
|
2091
2244
|
'YYYY-MM-DD'
|
|
2092
2245
|
)`;
|
|
2093
2246
|
return db.select({
|
|
2094
|
-
conversations:
|
|
2247
|
+
conversations: sql7`COUNT(*)::integer`,
|
|
2095
2248
|
date,
|
|
2096
2249
|
visibility: juniorDestinations.visibility
|
|
2097
2250
|
}).from(juniorConversations).leftJoin(
|
|
2098
2251
|
juniorDestinations,
|
|
2099
|
-
|
|
2100
|
-
).where(
|
|
2252
|
+
eq9(juniorDestinations.id, juniorConversations.destinationId)
|
|
2253
|
+
).where(and8(topLevelWhere(), gte2(juniorConversations.lastActivityAt, start))).groupBy(date, juniorDestinations.visibility);
|
|
2101
2254
|
}
|
|
2102
2255
|
function directoryActivityDays(rows, nowMs) {
|
|
2103
2256
|
const days = /* @__PURE__ */ new Map();
|
|
@@ -2170,7 +2323,7 @@ async function recentLocationRows(db, locationId) {
|
|
|
2170
2323
|
createdAt: juniorConversations.createdAt,
|
|
2171
2324
|
destinationId: juniorDestinations.id,
|
|
2172
2325
|
durationMs: juniorConversations.durationMs,
|
|
2173
|
-
email:
|
|
2326
|
+
email: sql7`COALESCE(
|
|
2174
2327
|
${juniorUsers.primaryEmailNormalized},
|
|
2175
2328
|
${juniorIdentities.email}
|
|
2176
2329
|
)`,
|
|
@@ -2179,7 +2332,7 @@ async function recentLocationRows(db, locationId) {
|
|
|
2179
2332
|
fullName: juniorUsers.displayName,
|
|
2180
2333
|
handle: juniorIdentities.handle,
|
|
2181
2334
|
lastActivityAt: juniorConversations.lastActivityAt,
|
|
2182
|
-
providerSubjectId:
|
|
2335
|
+
providerSubjectId: sql7`CASE
|
|
2183
2336
|
WHEN ${juniorIdentities.provider} = 'slack'
|
|
2184
2337
|
THEN ${juniorIdentities.providerSubjectId}
|
|
2185
2338
|
ELSE NULL
|
|
@@ -2190,14 +2343,14 @@ async function recentLocationRows(db, locationId) {
|
|
|
2190
2343
|
usage: juniorConversations.usage
|
|
2191
2344
|
}).from(juniorConversations).innerJoin(
|
|
2192
2345
|
juniorDestinations,
|
|
2193
|
-
|
|
2346
|
+
eq9(juniorDestinations.id, juniorConversations.destinationId)
|
|
2194
2347
|
).leftJoin(
|
|
2195
2348
|
juniorIdentities,
|
|
2196
|
-
|
|
2197
|
-
).leftJoin(juniorUsers,
|
|
2198
|
-
|
|
2349
|
+
eq9(juniorIdentities.id, juniorConversations.actorIdentityId)
|
|
2350
|
+
).leftJoin(juniorUsers, eq9(juniorUsers.id, juniorIdentities.userId)).where(
|
|
2351
|
+
and8(
|
|
2199
2352
|
publicLocationWhere(locationId),
|
|
2200
|
-
|
|
2353
|
+
isNull5(juniorConversations.archivedAt)
|
|
2201
2354
|
)
|
|
2202
2355
|
).orderBy(
|
|
2203
2356
|
desc3(juniorConversations.lastActivityAt),
|
|
@@ -2211,7 +2364,7 @@ async function readLocationDetailFromSql(locationId, options = {}) {
|
|
|
2211
2364
|
const start = new Date(end);
|
|
2212
2365
|
start.setUTCDate(start.getUTCDate() - (ACTIVITY_DAYS - 1));
|
|
2213
2366
|
const where = publicLocationWhere(locationId);
|
|
2214
|
-
const activityDate =
|
|
2367
|
+
const activityDate = sql7`TO_CHAR(
|
|
2215
2368
|
${juniorConversations.lastActivityAt} AT TIME ZONE 'UTC',
|
|
2216
2369
|
'YYYY-MM-DD'
|
|
2217
2370
|
)`;
|
|
@@ -2222,27 +2375,27 @@ async function readLocationDetailFromSql(locationId, options = {}) {
|
|
|
2222
2375
|
...conversationRangeColumns()
|
|
2223
2376
|
}).from(juniorConversations).innerJoin(
|
|
2224
2377
|
treeConversation2,
|
|
2225
|
-
|
|
2378
|
+
eq9(
|
|
2226
2379
|
treeConversation2.rootConversationId,
|
|
2227
2380
|
juniorConversations.conversationId
|
|
2228
2381
|
)
|
|
2229
2382
|
).innerJoin(
|
|
2230
2383
|
juniorDestinations,
|
|
2231
|
-
|
|
2384
|
+
eq9(juniorDestinations.id, juniorConversations.destinationId)
|
|
2232
2385
|
).where(where).groupBy(...locationGroupBy()),
|
|
2233
2386
|
getDb().select({
|
|
2234
2387
|
date: activityDate,
|
|
2235
2388
|
...treeAggregateColumns2
|
|
2236
2389
|
}).from(juniorConversations).innerJoin(
|
|
2237
2390
|
treeConversation2,
|
|
2238
|
-
|
|
2391
|
+
eq9(
|
|
2239
2392
|
treeConversation2.rootConversationId,
|
|
2240
2393
|
juniorConversations.conversationId
|
|
2241
2394
|
)
|
|
2242
2395
|
).innerJoin(
|
|
2243
2396
|
juniorDestinations,
|
|
2244
|
-
|
|
2245
|
-
).where(
|
|
2397
|
+
eq9(juniorDestinations.id, juniorConversations.destinationId)
|
|
2398
|
+
).where(and8(where, gte2(juniorConversations.lastActivityAt, start))).groupBy(activityDate),
|
|
2246
2399
|
getDb().select({
|
|
2247
2400
|
actorIdentityId: juniorConversations.actorIdentityId,
|
|
2248
2401
|
email: juniorUsers.primaryEmailNormalized,
|
|
@@ -2254,17 +2407,17 @@ async function readLocationDetailFromSql(locationId, options = {}) {
|
|
|
2254
2407
|
...treeAggregateColumns2
|
|
2255
2408
|
}).from(juniorConversations).innerJoin(
|
|
2256
2409
|
treeConversation2,
|
|
2257
|
-
|
|
2410
|
+
eq9(
|
|
2258
2411
|
treeConversation2.rootConversationId,
|
|
2259
2412
|
juniorConversations.conversationId
|
|
2260
2413
|
)
|
|
2261
2414
|
).innerJoin(
|
|
2262
2415
|
juniorDestinations,
|
|
2263
|
-
|
|
2416
|
+
eq9(juniorDestinations.id, juniorConversations.destinationId)
|
|
2264
2417
|
).leftJoin(
|
|
2265
2418
|
juniorIdentities,
|
|
2266
|
-
|
|
2267
|
-
).leftJoin(juniorUsers,
|
|
2419
|
+
eq9(juniorIdentities.id, juniorConversations.actorIdentityId)
|
|
2420
|
+
).leftJoin(juniorUsers, eq9(juniorUsers.id, juniorIdentities.userId)).where(where).groupBy(
|
|
2268
2421
|
juniorConversations.actorIdentityId,
|
|
2269
2422
|
juniorUsers.primaryEmailNormalized,
|
|
2270
2423
|
juniorUsers.displayName,
|
|
@@ -2378,22 +2531,22 @@ function createLocationRoutes() {
|
|
|
2378
2531
|
import { Hono as Hono3 } from "hono";
|
|
2379
2532
|
|
|
2380
2533
|
// src/api/people/list.query.ts
|
|
2381
|
-
import { and as
|
|
2534
|
+
import { and as and10, eq as eq11, gte as gte3, sql as sql9 } from "drizzle-orm";
|
|
2382
2535
|
|
|
2383
2536
|
// src/api/people/shared.ts
|
|
2384
|
-
import { and as
|
|
2385
|
-
import { alias as
|
|
2537
|
+
import { and as and9, asc as asc4, desc as desc4, eq as eq10, isNull as isNull6, notExists, or as or2, sql as sql8 } from "drizzle-orm";
|
|
2538
|
+
import { alias as alias6 } from "drizzle-orm/pg-core";
|
|
2386
2539
|
var RECENT_LIMIT2 = 25;
|
|
2387
2540
|
var ACTIVITY_DAYS2 = 365;
|
|
2388
|
-
var peopleTreeConversation =
|
|
2541
|
+
var peopleTreeConversation = alias6(
|
|
2389
2542
|
juniorConversations,
|
|
2390
2543
|
"people_tree_conversation"
|
|
2391
2544
|
);
|
|
2392
|
-
var peopleRootConversation =
|
|
2545
|
+
var peopleRootConversation = alias6(
|
|
2393
2546
|
juniorConversations,
|
|
2394
2547
|
"people_root_conversation"
|
|
2395
2548
|
);
|
|
2396
|
-
var peopleRootIdentity =
|
|
2549
|
+
var peopleRootIdentity = alias6(juniorIdentities, "people_root_identity");
|
|
2397
2550
|
var peopleTreeAggregateColumns = conversationAggregateColumns({
|
|
2398
2551
|
metrics: peopleTreeConversation,
|
|
2399
2552
|
roots: juniorConversations
|
|
@@ -2401,37 +2554,37 @@ var peopleTreeAggregateColumns = conversationAggregateColumns({
|
|
|
2401
2554
|
function peopleTreeMetricsJoin() {
|
|
2402
2555
|
const rootOwnedByActor = getDb().select({ conversationId: peopleRootConversation.conversationId }).from(peopleRootConversation).innerJoin(
|
|
2403
2556
|
peopleRootIdentity,
|
|
2404
|
-
|
|
2557
|
+
eq10(peopleRootIdentity.id, peopleRootConversation.actorIdentityId)
|
|
2405
2558
|
).where(
|
|
2406
|
-
|
|
2407
|
-
|
|
2559
|
+
and9(
|
|
2560
|
+
eq10(
|
|
2408
2561
|
peopleRootConversation.conversationId,
|
|
2409
2562
|
juniorConversations.rootConversationId
|
|
2410
2563
|
),
|
|
2411
|
-
|
|
2412
|
-
|
|
2564
|
+
isNull6(peopleRootConversation.parentConversationId),
|
|
2565
|
+
eq10(
|
|
2413
2566
|
peopleRootConversation.rootConversationId,
|
|
2414
2567
|
peopleRootConversation.conversationId
|
|
2415
2568
|
),
|
|
2416
|
-
|
|
2569
|
+
eq10(
|
|
2417
2570
|
peopleRootIdentity.emailNormalized,
|
|
2418
2571
|
juniorUsers.primaryEmailNormalized
|
|
2419
2572
|
),
|
|
2420
|
-
|
|
2573
|
+
eq10(peopleRootIdentity.emailVerified, true)
|
|
2421
2574
|
)
|
|
2422
2575
|
);
|
|
2423
|
-
return
|
|
2424
|
-
|
|
2576
|
+
return and9(
|
|
2577
|
+
eq10(
|
|
2425
2578
|
peopleTreeConversation.rootConversationId,
|
|
2426
2579
|
juniorConversations.rootConversationId
|
|
2427
2580
|
),
|
|
2428
|
-
|
|
2429
|
-
|
|
2581
|
+
or2(
|
|
2582
|
+
eq10(
|
|
2430
2583
|
juniorConversations.rootConversationId,
|
|
2431
2584
|
juniorConversations.conversationId
|
|
2432
2585
|
),
|
|
2433
|
-
|
|
2434
|
-
|
|
2586
|
+
and9(
|
|
2587
|
+
eq10(
|
|
2435
2588
|
peopleTreeConversation.conversationId,
|
|
2436
2589
|
juniorConversations.conversationId
|
|
2437
2590
|
),
|
|
@@ -2481,11 +2634,11 @@ function statsItems2(map) {
|
|
|
2481
2634
|
}
|
|
2482
2635
|
function verifiedActorWhere(email) {
|
|
2483
2636
|
const normalizedEmail = normalizeEmail(email);
|
|
2484
|
-
return
|
|
2485
|
-
|
|
2486
|
-
|
|
2487
|
-
|
|
2488
|
-
normalizedEmail ?
|
|
2637
|
+
return and9(
|
|
2638
|
+
eq10(juniorIdentities.provider, "slack"),
|
|
2639
|
+
eq10(juniorIdentities.emailVerified, true),
|
|
2640
|
+
sql8`${juniorUsers.primaryEmailNormalized} IS NOT NULL`,
|
|
2641
|
+
normalizedEmail ? eq10(juniorUsers.primaryEmailNormalized, normalizedEmail) : void 0
|
|
2489
2642
|
);
|
|
2490
2643
|
}
|
|
2491
2644
|
async function recentActorRows(email) {
|
|
@@ -2508,12 +2661,12 @@ async function recentActorRows(email) {
|
|
|
2508
2661
|
usage: juniorConversations.usage
|
|
2509
2662
|
}).from(juniorConversations).innerJoin(
|
|
2510
2663
|
juniorIdentities,
|
|
2511
|
-
|
|
2512
|
-
).innerJoin(juniorUsers,
|
|
2664
|
+
eq10(juniorIdentities.id, juniorConversations.actorIdentityId)
|
|
2665
|
+
).innerJoin(juniorUsers, eq10(juniorUsers.id, juniorIdentities.userId)).leftJoin(
|
|
2513
2666
|
juniorDestinations,
|
|
2514
|
-
|
|
2667
|
+
eq10(juniorDestinations.id, juniorConversations.destinationId)
|
|
2515
2668
|
).where(
|
|
2516
|
-
|
|
2669
|
+
and9(verifiedActorWhere(email), isNull6(juniorConversations.archivedAt))
|
|
2517
2670
|
).orderBy(
|
|
2518
2671
|
desc4(juniorConversations.lastActivityAt),
|
|
2519
2672
|
asc4(juniorConversations.conversationId)
|
|
@@ -2542,7 +2695,7 @@ function directoryActivityDays2(rows, nowMs) {
|
|
|
2542
2695
|
async function readPeopleListFromSql() {
|
|
2543
2696
|
const nowMs = Date.now();
|
|
2544
2697
|
const { end, start } = activityWindow(nowMs);
|
|
2545
|
-
const activityDate =
|
|
2698
|
+
const activityDate = sql9`TO_CHAR(
|
|
2546
2699
|
${juniorConversations.lastActivityAt} AT TIME ZONE 'UTC',
|
|
2547
2700
|
'YYYY-MM-DD'
|
|
2548
2701
|
)`;
|
|
@@ -2550,24 +2703,24 @@ async function readPeopleListFromSql() {
|
|
|
2550
2703
|
getDb().select({
|
|
2551
2704
|
email: juniorUsers.primaryEmailNormalized,
|
|
2552
2705
|
fullName: juniorUsers.displayName,
|
|
2553
|
-
slackUserId:
|
|
2554
|
-
slackUserName:
|
|
2706
|
+
slackUserId: sql9`MAX(${juniorIdentities.providerSubjectId})`,
|
|
2707
|
+
slackUserName: sql9`MAX(${juniorIdentities.handle})`,
|
|
2555
2708
|
activeDays: conversationActiveDaysColumn(),
|
|
2556
2709
|
...peopleTreeAggregateColumns,
|
|
2557
2710
|
...conversationRangeColumns()
|
|
2558
2711
|
}).from(juniorConversations).innerJoin(
|
|
2559
2712
|
juniorIdentities,
|
|
2560
|
-
|
|
2561
|
-
).innerJoin(juniorUsers,
|
|
2713
|
+
eq11(juniorIdentities.id, juniorConversations.actorIdentityId)
|
|
2714
|
+
).innerJoin(juniorUsers, eq11(juniorUsers.id, juniorIdentities.userId)).leftJoin(peopleTreeConversation, peopleTreeMetricsJoin()).where(verifiedActorWhere()).groupBy(juniorUsers.primaryEmailNormalized, juniorUsers.displayName),
|
|
2562
2715
|
getDb().select({
|
|
2563
|
-
activePeople:
|
|
2564
|
-
conversations:
|
|
2716
|
+
activePeople: sql9`COUNT(DISTINCT ${juniorUsers.id})::int`,
|
|
2717
|
+
conversations: sql9`COUNT(*)::int`,
|
|
2565
2718
|
date: activityDate
|
|
2566
2719
|
}).from(juniorConversations).innerJoin(
|
|
2567
2720
|
juniorIdentities,
|
|
2568
|
-
|
|
2569
|
-
).innerJoin(juniorUsers,
|
|
2570
|
-
|
|
2721
|
+
eq11(juniorIdentities.id, juniorConversations.actorIdentityId)
|
|
2722
|
+
).innerJoin(juniorUsers, eq11(juniorUsers.id, juniorIdentities.userId)).where(
|
|
2723
|
+
and10(
|
|
2571
2724
|
verifiedActorWhere(),
|
|
2572
2725
|
gte3(juniorConversations.lastActivityAt, start)
|
|
2573
2726
|
)
|
|
@@ -2616,7 +2769,7 @@ var list_default3 = defineApiRoute({
|
|
|
2616
2769
|
});
|
|
2617
2770
|
|
|
2618
2771
|
// src/api/people/profile.query.ts
|
|
2619
|
-
import { and as
|
|
2772
|
+
import { and as and11, eq as eq12, gte as gte4, sql as sql10 } from "drizzle-orm";
|
|
2620
2773
|
function emptyProfile(email, nowMs) {
|
|
2621
2774
|
const end = new Date(nowMs);
|
|
2622
2775
|
end.setUTCHours(0, 0, 0, 0);
|
|
@@ -2651,7 +2804,7 @@ function addAggregate2(map, label, row) {
|
|
|
2651
2804
|
map.set(label, item);
|
|
2652
2805
|
}
|
|
2653
2806
|
function surfaceExpression() {
|
|
2654
|
-
return
|
|
2807
|
+
return sql10`CASE
|
|
2655
2808
|
WHEN ${juniorConversations.source} IN ('api', 'scheduler', 'slack')
|
|
2656
2809
|
THEN ${juniorConversations.source}
|
|
2657
2810
|
WHEN ${juniorConversations.conversationId} LIKE 'slack:%' THEN 'slack'
|
|
@@ -2680,30 +2833,30 @@ async function readPeopleProfileFromSql(email, options = {}) {
|
|
|
2680
2833
|
const where = verifiedActorWhere(normalizedEmail);
|
|
2681
2834
|
const metricsJoin = peopleTreeMetricsJoin();
|
|
2682
2835
|
const surface = surfaceExpression();
|
|
2683
|
-
const activityDate =
|
|
2836
|
+
const activityDate = sql10`TO_CHAR(
|
|
2684
2837
|
${juniorConversations.lastActivityAt} AT TIME ZONE 'UTC',
|
|
2685
2838
|
'YYYY-MM-DD'
|
|
2686
2839
|
)`;
|
|
2687
|
-
const channel =
|
|
2840
|
+
const channel = sql10`SPLIT_PART(${juniorConversations.conversationId}, ':', 2)`;
|
|
2688
2841
|
const [totalsRows, dayRows, locationRows, surfaceRows, recentRows] = await Promise.all([
|
|
2689
2842
|
getDb().select({
|
|
2690
2843
|
email: juniorUsers.primaryEmailNormalized,
|
|
2691
2844
|
fullName: juniorUsers.displayName,
|
|
2692
|
-
slackUserId:
|
|
2693
|
-
slackUserName:
|
|
2845
|
+
slackUserId: sql10`MAX(${juniorIdentities.providerSubjectId})`,
|
|
2846
|
+
slackUserName: sql10`MAX(${juniorIdentities.handle})`,
|
|
2694
2847
|
activeDays: conversationActiveDaysColumn(),
|
|
2695
2848
|
...peopleTreeAggregateColumns
|
|
2696
2849
|
}).from(juniorConversations).innerJoin(
|
|
2697
2850
|
juniorIdentities,
|
|
2698
|
-
|
|
2699
|
-
).innerJoin(juniorUsers,
|
|
2851
|
+
eq12(juniorIdentities.id, juniorConversations.actorIdentityId)
|
|
2852
|
+
).innerJoin(juniorUsers, eq12(juniorUsers.id, juniorIdentities.userId)).leftJoin(peopleTreeConversation, metricsJoin).where(where).groupBy(juniorUsers.primaryEmailNormalized, juniorUsers.displayName),
|
|
2700
2853
|
getDb().select({
|
|
2701
2854
|
date: activityDate,
|
|
2702
2855
|
...peopleTreeAggregateColumns
|
|
2703
2856
|
}).from(juniorConversations).innerJoin(
|
|
2704
2857
|
juniorIdentities,
|
|
2705
|
-
|
|
2706
|
-
).innerJoin(juniorUsers,
|
|
2858
|
+
eq12(juniorIdentities.id, juniorConversations.actorIdentityId)
|
|
2859
|
+
).innerJoin(juniorUsers, eq12(juniorUsers.id, juniorIdentities.userId)).leftJoin(peopleTreeConversation, metricsJoin).where(and11(where, gte4(juniorConversations.lastActivityAt, start))).groupBy(activityDate),
|
|
2707
2860
|
getDb().select({
|
|
2708
2861
|
channel,
|
|
2709
2862
|
channelName: juniorConversations.channelName,
|
|
@@ -2712,10 +2865,10 @@ async function readPeopleProfileFromSql(email, options = {}) {
|
|
|
2712
2865
|
...peopleTreeAggregateColumns
|
|
2713
2866
|
}).from(juniorConversations).innerJoin(
|
|
2714
2867
|
juniorIdentities,
|
|
2715
|
-
|
|
2716
|
-
).innerJoin(juniorUsers,
|
|
2868
|
+
eq12(juniorIdentities.id, juniorConversations.actorIdentityId)
|
|
2869
|
+
).innerJoin(juniorUsers, eq12(juniorUsers.id, juniorIdentities.userId)).leftJoin(peopleTreeConversation, metricsJoin).leftJoin(
|
|
2717
2870
|
juniorDestinations,
|
|
2718
|
-
|
|
2871
|
+
eq12(juniorDestinations.id, juniorConversations.destinationId)
|
|
2719
2872
|
).where(where).groupBy(
|
|
2720
2873
|
channel,
|
|
2721
2874
|
juniorConversations.channelName,
|
|
@@ -2724,8 +2877,8 @@ async function readPeopleProfileFromSql(email, options = {}) {
|
|
|
2724
2877
|
),
|
|
2725
2878
|
getDb().select({ surface, ...peopleTreeAggregateColumns }).from(juniorConversations).innerJoin(
|
|
2726
2879
|
juniorIdentities,
|
|
2727
|
-
|
|
2728
|
-
).innerJoin(juniorUsers,
|
|
2880
|
+
eq12(juniorIdentities.id, juniorConversations.actorIdentityId)
|
|
2881
|
+
).innerJoin(juniorUsers, eq12(juniorUsers.id, juniorIdentities.userId)).leftJoin(peopleTreeConversation, metricsJoin).where(where).groupBy(surface),
|
|
2729
2882
|
recentActorRows(normalizedEmail)
|
|
2730
2883
|
]);
|
|
2731
2884
|
const totalsRow = totalsRows[0];
|
|
@@ -2836,7 +2989,7 @@ import { Hono as Hono4 } from "hono";
|
|
|
2836
2989
|
|
|
2837
2990
|
// src/personal-tokens/store.ts
|
|
2838
2991
|
import { createHash, randomBytes, randomUUID } from "crypto";
|
|
2839
|
-
import { and as
|
|
2992
|
+
import { and as and12, desc as desc5, eq as eq13, gt, isNull as isNull7 } from "drizzle-orm";
|
|
2840
2993
|
var TOKEN_PREFIX = "jr_pat_";
|
|
2841
2994
|
var TOKEN_SUFFIX_LENGTH = 8;
|
|
2842
2995
|
var DEFAULT_TOKEN_LIFETIME_MS = 90 * 24 * 60 * 60 * 1e3;
|
|
@@ -2873,9 +3026,9 @@ async function createPersonalToken(args) {
|
|
|
2873
3026
|
}
|
|
2874
3027
|
async function listPersonalTokens(email, now = /* @__PURE__ */ new Date()) {
|
|
2875
3028
|
const rows = await getDb().select().from(juniorApiTokens).where(
|
|
2876
|
-
|
|
2877
|
-
|
|
2878
|
-
|
|
3029
|
+
and12(
|
|
3030
|
+
eq13(juniorApiTokens.ownerEmailNormalized, normalizeEmail2(email)),
|
|
3031
|
+
isNull7(juniorApiTokens.revokedAt),
|
|
2879
3032
|
gt(juniorApiTokens.expiresAt, now)
|
|
2880
3033
|
)
|
|
2881
3034
|
).orderBy(desc5(juniorApiTokens.createdAt));
|
|
@@ -2883,10 +3036,10 @@ async function listPersonalTokens(email, now = /* @__PURE__ */ new Date()) {
|
|
|
2883
3036
|
}
|
|
2884
3037
|
async function revokePersonalToken(args) {
|
|
2885
3038
|
const rows = await getDb().update(juniorApiTokens).set({ revokedAt: args.now ?? /* @__PURE__ */ new Date() }).where(
|
|
2886
|
-
|
|
2887
|
-
|
|
2888
|
-
|
|
2889
|
-
|
|
3039
|
+
and12(
|
|
3040
|
+
eq13(juniorApiTokens.id, args.id),
|
|
3041
|
+
eq13(juniorApiTokens.ownerEmailNormalized, normalizeEmail2(args.email)),
|
|
3042
|
+
isNull7(juniorApiTokens.revokedAt)
|
|
2890
3043
|
)
|
|
2891
3044
|
).returning({ id: juniorApiTokens.id });
|
|
2892
3045
|
return rows.length > 0;
|
|
@@ -2897,15 +3050,15 @@ async function authenticatePersonalToken(token2, now = /* @__PURE__ */ new Date(
|
|
|
2897
3050
|
id: juniorApiTokens.id,
|
|
2898
3051
|
ownerEmailNormalized: juniorApiTokens.ownerEmailNormalized
|
|
2899
3052
|
}).from(juniorApiTokens).where(
|
|
2900
|
-
|
|
2901
|
-
|
|
2902
|
-
|
|
3053
|
+
and12(
|
|
3054
|
+
eq13(juniorApiTokens.tokenHash, hashToken(token2)),
|
|
3055
|
+
isNull7(juniorApiTokens.revokedAt),
|
|
2903
3056
|
gt(juniorApiTokens.expiresAt, now)
|
|
2904
3057
|
)
|
|
2905
3058
|
).limit(1);
|
|
2906
3059
|
const match = rows[0];
|
|
2907
3060
|
if (!match) return void 0;
|
|
2908
|
-
await getDb().update(juniorApiTokens).set({ lastUsedAt: now }).where(
|
|
3061
|
+
await getDb().update(juniorApiTokens).set({ lastUsedAt: now }).where(eq13(juniorApiTokens.id, match.id));
|
|
2909
3062
|
return match.ownerEmailNormalized;
|
|
2910
3063
|
}
|
|
2911
3064
|
|