@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.
- 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.d.ts +7 -2
- package/dist/api/conversations/list.query.d.ts +12 -3
- 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 +7 -7
- 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 +11 -0
- package/dist/api/schema.js +16 -3
- package/dist/api-reference.d.ts +1 -1
- package/dist/api.js +41 -13
- package/dist/app.js +35 -27
- package/dist/chat/agent/request.d.ts +3 -0
- package/dist/chat/config.d.ts +2 -0
- package/dist/chat/reasoning-level.d.ts +4 -0
- package/dist/chat/services/context-compaction.d.ts +1 -0
- 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/tools/search-tools.d.ts +2 -2
- package/dist/{chunk-UAMKJPDF.js → chunk-2RNOB32R.js} +7 -1
- package/dist/{chunk-NJEDJFK4.js → chunk-2T7DCRAW.js} +1 -1
- package/dist/{chunk-DPHWDS6I.js → chunk-45DMFMY2.js} +81 -69
- package/dist/chunk-4AQUWWEM.js +75 -0
- package/dist/{chunk-EEZCY5WX.js → chunk-A7X2FDUO.js} +18 -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-CRQVIHDI.js → chunk-IDZBM3NW.js} +2 -8
- 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-KJHAW6VE.js → chunk-JSAANELJ.js} +28 -9
- package/dist/{chunk-EUZ44ROE.js → chunk-MM5UFDAC.js} +1 -3
- package/dist/{chunk-WJ7STXT6.js → chunk-NSOCZGOH.js} +3 -3
- 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-QSBQJ3PA.js +275 -0
- package/dist/{chunk-FTTFV6DC.js → chunk-TPTJEHUE.js} +4 -4
- package/dist/{chunk-OGHXZ4KQ.js → chunk-VHRM6GNH.js} +88 -122
- package/dist/{chunk-NG2AV7IB.js → chunk-VVIXK2BX.js} +1 -1
- package/dist/{chunk-6HHEZENZ.js → chunk-VY7BT4SM.js} +16 -7
- package/dist/{chunk-H66UCBPW.js → chunk-XJA7BPHS.js} +1 -1
- package/dist/{chunk-ER45IV77.js → chunk-XSBIISXS.js} +9 -9
- package/dist/cli/chat.js +15 -14
- package/dist/cli/plugins.js +6 -5
- package/dist/cli/snapshot-warmup.js +2 -2
- package/dist/cli/upgrade.js +8 -7
- 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-5SLCGT6J.js +29 -0
- package/dist/{detail-W4ZSD45K.js → detail-LU6COZO6.js} +11 -10
- package/dist/{legacy-import-6WWXMALY.js → legacy-import-VCYLWT2V.js} +4 -3
- package/dist/list-2FI5SFV7.js +80 -0
- package/dist/list-4ALSU6ZW.js +30 -0
- package/dist/{list-3KZNG3SJ.js → list-KHRAWZWU.js} +11 -8
- package/dist/{plugin-conversations-ZYRWZYEA.js → plugin-conversations-JANXC4GA.js} +7 -6
- package/dist/profile-3O3OVENT.js +212 -0
- package/dist/{runner-267ZRLZD.js → runner-BM7D35YW.js} +12 -11
- package/dist/stats-J3YGCYDF.js +174 -0
- package/dist/{subagent-5HZPQC7V.js → subagent-P7HOSMVC.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 +5 -5
- 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,102 @@
|
|
|
1
|
+
import {
|
|
2
|
+
getDb,
|
|
3
|
+
juniorConversations,
|
|
4
|
+
juniorIdentities,
|
|
5
|
+
juniorUsers
|
|
6
|
+
} from "./chunk-VHRM6GNH.js";
|
|
7
|
+
import {
|
|
8
|
+
juniorDestinations
|
|
9
|
+
} from "./chunk-FXFQNHRU.js";
|
|
10
|
+
|
|
11
|
+
// src/api/people/shared.ts
|
|
12
|
+
import { and, asc, desc, eq, sql } from "drizzle-orm";
|
|
13
|
+
var RECENT_LIMIT = 25;
|
|
14
|
+
var ACTIVITY_DAYS = 366;
|
|
15
|
+
function normalizeEmail(email) {
|
|
16
|
+
const normalized = email?.trim().toLowerCase();
|
|
17
|
+
return normalized || void 0;
|
|
18
|
+
}
|
|
19
|
+
function emptyTotals() {
|
|
20
|
+
return {
|
|
21
|
+
active: 0,
|
|
22
|
+
activeDays: 0,
|
|
23
|
+
conversations: 0,
|
|
24
|
+
durationMs: 0,
|
|
25
|
+
failed: 0
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
function emptyActivityDay(date) {
|
|
29
|
+
return {
|
|
30
|
+
active: 0,
|
|
31
|
+
conversations: 0,
|
|
32
|
+
date,
|
|
33
|
+
durationMs: 0,
|
|
34
|
+
failed: 0
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
function activityDays(days, nowMs) {
|
|
38
|
+
const items = [];
|
|
39
|
+
const end = new Date(nowMs);
|
|
40
|
+
end.setUTCHours(0, 0, 0, 0);
|
|
41
|
+
const start = new Date(end);
|
|
42
|
+
start.setUTCDate(start.getUTCDate() - (ACTIVITY_DAYS - 1));
|
|
43
|
+
for (const cursor = new Date(start); cursor.getTime() <= end.getTime(); cursor.setUTCDate(cursor.getUTCDate() + 1)) {
|
|
44
|
+
const date = cursor.toISOString().slice(0, 10);
|
|
45
|
+
items.push(days.get(date) ?? emptyActivityDay(date));
|
|
46
|
+
}
|
|
47
|
+
return items;
|
|
48
|
+
}
|
|
49
|
+
function statsItems(map) {
|
|
50
|
+
return [...map.values()].sort(
|
|
51
|
+
(left, right) => right.conversations - left.conversations || right.durationMs - left.durationMs || left.label.localeCompare(right.label)
|
|
52
|
+
);
|
|
53
|
+
}
|
|
54
|
+
function verifiedActorWhere(email) {
|
|
55
|
+
const normalizedEmail = normalizeEmail(email);
|
|
56
|
+
return and(
|
|
57
|
+
eq(juniorIdentities.provider, "slack"),
|
|
58
|
+
eq(juniorIdentities.emailVerified, true),
|
|
59
|
+
sql`${juniorUsers.primaryEmailNormalized} IS NOT NULL`,
|
|
60
|
+
normalizedEmail ? eq(juniorUsers.primaryEmailNormalized, normalizedEmail) : void 0
|
|
61
|
+
);
|
|
62
|
+
}
|
|
63
|
+
async function recentActorRows(email) {
|
|
64
|
+
return getDb().select({
|
|
65
|
+
channelName: juniorConversations.channelName,
|
|
66
|
+
conversationId: juniorConversations.conversationId,
|
|
67
|
+
createdAt: juniorConversations.createdAt,
|
|
68
|
+
destinationId: juniorDestinations.id,
|
|
69
|
+
destinationVisibility: juniorDestinations.visibility,
|
|
70
|
+
durationMs: juniorConversations.durationMs,
|
|
71
|
+
email: juniorUsers.primaryEmailNormalized,
|
|
72
|
+
executionStatus: juniorConversations.executionStatus,
|
|
73
|
+
executionUpdatedAt: juniorConversations.executionUpdatedAt,
|
|
74
|
+
fullName: juniorUsers.displayName,
|
|
75
|
+
handle: juniorIdentities.handle,
|
|
76
|
+
lastActivityAt: juniorConversations.lastActivityAt,
|
|
77
|
+
providerSubjectId: juniorIdentities.providerSubjectId,
|
|
78
|
+
source: juniorConversations.source,
|
|
79
|
+
title: juniorConversations.title,
|
|
80
|
+
updatedAt: juniorConversations.updatedAt,
|
|
81
|
+
usage: juniorConversations.usage
|
|
82
|
+
}).from(juniorConversations).innerJoin(
|
|
83
|
+
juniorIdentities,
|
|
84
|
+
eq(juniorIdentities.id, juniorConversations.actorIdentityId)
|
|
85
|
+
).innerJoin(juniorUsers, eq(juniorUsers.id, juniorIdentities.userId)).leftJoin(
|
|
86
|
+
juniorDestinations,
|
|
87
|
+
eq(juniorDestinations.id, juniorConversations.destinationId)
|
|
88
|
+
).where(verifiedActorWhere(email)).orderBy(
|
|
89
|
+
desc(juniorConversations.lastActivityAt),
|
|
90
|
+
asc(juniorConversations.conversationId)
|
|
91
|
+
).limit(RECENT_LIMIT);
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
export {
|
|
95
|
+
ACTIVITY_DAYS,
|
|
96
|
+
normalizeEmail,
|
|
97
|
+
emptyTotals,
|
|
98
|
+
activityDays,
|
|
99
|
+
statsItems,
|
|
100
|
+
verifiedActorWhere,
|
|
101
|
+
recentActorRows
|
|
102
|
+
};
|
|
@@ -2,7 +2,7 @@ import {
|
|
|
2
2
|
actorIdentitySchema,
|
|
3
3
|
conversationStatsItemSchema,
|
|
4
4
|
conversationSummaryReportSchema
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-MM5UFDAC.js";
|
|
6
6
|
|
|
7
7
|
// src/api/people/schema.ts
|
|
8
8
|
import { z } from "zod";
|
|
@@ -37,10 +37,7 @@ var actorSummaryReportSchema = actorTotalsReportSchema.extend({
|
|
|
37
37
|
var actorDirectoryReportSchema = z.object({
|
|
38
38
|
generatedAt: z.string(),
|
|
39
39
|
people: z.array(actorSummaryReportSchema),
|
|
40
|
-
|
|
41
|
-
sampleSize: z.number(),
|
|
42
|
-
source: z.literal("conversation_index"),
|
|
43
|
-
truncated: z.boolean()
|
|
40
|
+
source: z.literal("conversation_index")
|
|
44
41
|
}).strict();
|
|
45
42
|
var actorProfileReportSchema = z.object({
|
|
46
43
|
activityDays: z.array(actorActivityDayReportSchema),
|
|
@@ -48,12 +45,9 @@ var actorProfileReportSchema = z.object({
|
|
|
48
45
|
locations: z.array(peopleConversationStatsItemSchema),
|
|
49
46
|
recentConversations: z.array(peopleConversationSummaryReportSchema),
|
|
50
47
|
actor: identifiedActorSchema,
|
|
51
|
-
sampleLimit: z.number(),
|
|
52
|
-
sampleSize: z.number(),
|
|
53
48
|
source: z.literal("conversation_index"),
|
|
54
49
|
surfaces: z.array(peopleConversationStatsItemSchema),
|
|
55
50
|
totals: actorTotalsReportSchema,
|
|
56
|
-
truncated: z.boolean(),
|
|
57
51
|
windowEnd: z.string(),
|
|
58
52
|
windowStart: z.string()
|
|
59
53
|
}).strict();
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import {
|
|
2
2
|
ensureLegacyConversationImport
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-JPQISMMJ.js";
|
|
4
4
|
import {
|
|
5
5
|
contextProvenance,
|
|
6
6
|
getAgentStepStore
|
|
7
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-VHRM6GNH.js";
|
|
8
8
|
|
|
9
9
|
// src/chat/conversations/projection.ts
|
|
10
10
|
import { isDeepStrictEqual } from "util";
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import {
|
|
2
2
|
commitMessages,
|
|
3
3
|
loadTurnProjection
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-IQIBZXGB.js";
|
|
5
5
|
import {
|
|
6
6
|
usageSchema
|
|
7
7
|
} from "./chunk-PDO5BLNM.js";
|
|
@@ -9,10 +9,10 @@ import {
|
|
|
9
9
|
getConversationStore,
|
|
10
10
|
instructionActors,
|
|
11
11
|
instructionProvenanceFor
|
|
12
|
-
} from "./chunk-
|
|
12
|
+
} from "./chunk-VHRM6GNH.js";
|
|
13
13
|
import {
|
|
14
14
|
getStateAdapter
|
|
15
|
-
} from "./chunk-
|
|
15
|
+
} from "./chunk-A7X2FDUO.js";
|
|
16
16
|
import {
|
|
17
17
|
toStoredSlackActor
|
|
18
18
|
} from "./chunk-I35CTGPO.js";
|
|
@@ -11,14 +11,14 @@ import {
|
|
|
11
11
|
legacyActorProvenance,
|
|
12
12
|
piMessageSchema,
|
|
13
13
|
readSessionLogEntries
|
|
14
|
-
} from "./chunk-
|
|
14
|
+
} from "./chunk-VHRM6GNH.js";
|
|
15
15
|
import {
|
|
16
16
|
botConfig,
|
|
17
17
|
escapeXml,
|
|
18
18
|
getStateAdapter,
|
|
19
19
|
resolveGatewayModel,
|
|
20
20
|
unescapeXml
|
|
21
|
-
} from "./chunk-
|
|
21
|
+
} from "./chunk-A7X2FDUO.js";
|
|
22
22
|
import {
|
|
23
23
|
logWarn,
|
|
24
24
|
setSpanAttributes
|
|
@@ -464,7 +464,7 @@ async function hydrateConversationMessages(args) {
|
|
|
464
464
|
args.conversation.messages = [];
|
|
465
465
|
return;
|
|
466
466
|
}
|
|
467
|
-
const { ensureLegacyConversationImport: ensureLegacyConversationImport2 } = await import("./legacy-import-
|
|
467
|
+
const { ensureLegacyConversationImport: ensureLegacyConversationImport2 } = await import("./legacy-import-VCYLWT2V.js");
|
|
468
468
|
await ensureLegacyConversationImport2({ conversationId: args.conversationId });
|
|
469
469
|
await hydrateConversationCompactions({
|
|
470
470
|
conversation: args.conversation,
|
|
@@ -1,20 +1,22 @@
|
|
|
1
1
|
import {
|
|
2
2
|
formatSlackConversationRedactedLabel,
|
|
3
3
|
resolveSlackConversationContextFromThreadId
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-VVIXK2BX.js";
|
|
5
5
|
import {
|
|
6
6
|
getDb,
|
|
7
7
|
juniorConversations,
|
|
8
|
-
juniorDestinations,
|
|
9
8
|
juniorIdentities
|
|
10
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-VHRM6GNH.js";
|
|
10
|
+
import {
|
|
11
|
+
juniorDestinations
|
|
12
|
+
} from "./chunk-FXFQNHRU.js";
|
|
11
13
|
import {
|
|
12
14
|
parseSlackThreadId,
|
|
13
15
|
resolveConversationPrivacy
|
|
14
16
|
} from "./chunk-LVA4I4H7.js";
|
|
15
17
|
|
|
16
18
|
// src/api/conversations/list.query.ts
|
|
17
|
-
import { asc, desc, eq, isNull } from "drizzle-orm";
|
|
19
|
+
import { and, asc, desc, eq, isNull } from "drizzle-orm";
|
|
18
20
|
|
|
19
21
|
// src/api/conversations/shared.ts
|
|
20
22
|
function slackStatsLocationLabel(input) {
|
|
@@ -148,15 +150,17 @@ function conversationSummaryFromStoredConversation(args) {
|
|
|
148
150
|
...actorIdentity ? { actorIdentity } : {},
|
|
149
151
|
...slackThread ? { channel: slackThread.channelId } : {},
|
|
150
152
|
...channelName ? { channelName } : {},
|
|
151
|
-
...channelNameRedacted ? { channelNameRedacted: true } : {}
|
|
153
|
+
...channelNameRedacted ? { channelNameRedacted: true } : {},
|
|
154
|
+
...args.locationId && !channelNameRedacted ? { locationId: args.locationId } : {}
|
|
152
155
|
};
|
|
153
156
|
}
|
|
154
157
|
|
|
155
158
|
// src/api/conversations/list.query.ts
|
|
156
159
|
var CONVERSATION_FEED_LIMIT = 50;
|
|
157
|
-
async function conversationRows(db, limit) {
|
|
160
|
+
async function conversationRows(db, limit, actorEmail) {
|
|
158
161
|
return db.select({
|
|
159
162
|
conversation: juniorConversations,
|
|
163
|
+
destinationId: juniorDestinations.id,
|
|
160
164
|
destinationVisibility: juniorDestinations.visibility,
|
|
161
165
|
identityDisplayName: juniorIdentities.displayName,
|
|
162
166
|
identityEmail: juniorIdentities.email,
|
|
@@ -170,7 +174,15 @@ async function conversationRows(db, limit) {
|
|
|
170
174
|
).leftJoin(
|
|
171
175
|
juniorIdentities,
|
|
172
176
|
eq(juniorIdentities.id, juniorConversations.actorIdentityId)
|
|
173
|
-
).where(
|
|
177
|
+
).where(
|
|
178
|
+
and(
|
|
179
|
+
isNull(juniorConversations.parentConversationId),
|
|
180
|
+
actorEmail ? and(
|
|
181
|
+
eq(juniorIdentities.emailNormalized, actorEmail),
|
|
182
|
+
eq(juniorIdentities.emailVerified, true)
|
|
183
|
+
) : void 0
|
|
184
|
+
)
|
|
185
|
+
).orderBy(
|
|
174
186
|
desc(juniorConversations.lastActivityAt),
|
|
175
187
|
asc(juniorConversations.conversationId)
|
|
176
188
|
).limit(limit);
|
|
@@ -210,6 +222,7 @@ async function readConversationRecordFromSql(conversationId) {
|
|
|
210
222
|
const db = getDb();
|
|
211
223
|
const rows = await db.select({
|
|
212
224
|
conversation: juniorConversations,
|
|
225
|
+
destinationId: juniorDestinations.id,
|
|
213
226
|
destinationVisibility: juniorDestinations.visibility,
|
|
214
227
|
identityDisplayName: juniorIdentities.displayName,
|
|
215
228
|
identityEmail: juniorIdentities.email,
|
|
@@ -228,17 +241,23 @@ async function readConversationRecordFromSql(conversationId) {
|
|
|
228
241
|
return row ? {
|
|
229
242
|
conversation: conversationFromRow(row),
|
|
230
243
|
durationMs: row.conversation.durationMs,
|
|
244
|
+
...row.destinationVisibility === "public" && row.destinationId ? { locationId: row.destinationId } : {},
|
|
231
245
|
usage: row.conversation.usage
|
|
232
246
|
} : void 0;
|
|
233
247
|
}
|
|
234
|
-
async function readConversationFeedFromSql(
|
|
248
|
+
async function readConversationFeedFromSql(options = {}) {
|
|
235
249
|
const nowMs = Date.now();
|
|
236
|
-
const rows = await conversationRows(
|
|
250
|
+
const rows = await conversationRows(
|
|
251
|
+
getDb(),
|
|
252
|
+
options.limit ?? CONVERSATION_FEED_LIMIT,
|
|
253
|
+
options.actorEmail
|
|
254
|
+
);
|
|
237
255
|
return {
|
|
238
256
|
conversations: rows.map(
|
|
239
257
|
(row) => conversationSummaryFromStoredConversation({
|
|
240
258
|
conversation: conversationFromRow(row),
|
|
241
259
|
durationMs: row.conversation.durationMs,
|
|
260
|
+
...row.destinationVisibility === "public" && row.destinationId ? { locationId: row.destinationId } : {},
|
|
242
261
|
usage: row.conversation.usage ?? void 0
|
|
243
262
|
})
|
|
244
263
|
),
|
|
@@ -36,6 +36,7 @@ var conversationSummaryReportSchema = z.object({
|
|
|
36
36
|
channel: z.string().optional(),
|
|
37
37
|
channelName: z.string().optional(),
|
|
38
38
|
channelNameRedacted: z.boolean().optional(),
|
|
39
|
+
locationId: z.string().optional(),
|
|
39
40
|
sentryTraceUrl: z.string().optional(),
|
|
40
41
|
traceId: z.string().optional()
|
|
41
42
|
}).strict();
|
|
@@ -195,12 +196,9 @@ var conversationStatsReportSchema = z.object({
|
|
|
195
196
|
generatedAt: z.string(),
|
|
196
197
|
locations: z.array(conversationStatsItemSchema),
|
|
197
198
|
actors: z.array(conversationStatsItemSchema),
|
|
198
|
-
sampleLimit: z.number(),
|
|
199
|
-
sampleSize: z.number(),
|
|
200
199
|
source: z.literal("conversation_index"),
|
|
201
200
|
costUsd: z.number().optional(),
|
|
202
201
|
tokens: z.number().optional(),
|
|
203
|
-
truncated: z.boolean(),
|
|
204
202
|
windowEnd: z.string(),
|
|
205
203
|
windowStart: z.string()
|
|
206
204
|
}).strict();
|
|
@@ -7,10 +7,10 @@ import {
|
|
|
7
7
|
addAgentTurnUsage,
|
|
8
8
|
getAgentTurnSessionRecord,
|
|
9
9
|
upsertAgentTurnSessionRecord
|
|
10
|
-
} from "./chunk-
|
|
10
|
+
} from "./chunk-IVXL57YF.js";
|
|
11
11
|
import {
|
|
12
12
|
persistConversationMessages
|
|
13
|
-
} from "./chunk-
|
|
13
|
+
} from "./chunk-JPQISMMJ.js";
|
|
14
14
|
import {
|
|
15
15
|
sleep
|
|
16
16
|
} from "./chunk-4ZNGQH7C.js";
|
|
@@ -18,7 +18,7 @@ import {
|
|
|
18
18
|
getPiMessageRole,
|
|
19
19
|
getStateAdapter,
|
|
20
20
|
trimTrailingAssistantMessages
|
|
21
|
-
} from "./chunk-
|
|
21
|
+
} from "./chunk-A7X2FDUO.js";
|
|
22
22
|
import {
|
|
23
23
|
getActiveTraceId,
|
|
24
24
|
logException
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import {
|
|
2
|
+
juniorConversations
|
|
3
|
+
} from "./chunk-VHRM6GNH.js";
|
|
4
|
+
|
|
5
|
+
// src/api/conversations/aggregate.ts
|
|
6
|
+
import { sql } from "drizzle-orm";
|
|
7
|
+
function tokenValue() {
|
|
8
|
+
return sql`
|
|
9
|
+
CASE
|
|
10
|
+
WHEN ${juniorConversations.usage}->>'totalTokens' IS NOT NULL
|
|
11
|
+
THEN (${juniorConversations.usage}->>'totalTokens')::double precision
|
|
12
|
+
WHEN COALESCE(
|
|
13
|
+
${juniorConversations.usage}->>'inputTokens',
|
|
14
|
+
${juniorConversations.usage}->>'outputTokens',
|
|
15
|
+
${juniorConversations.usage}->>'cachedInputTokens',
|
|
16
|
+
${juniorConversations.usage}->>'cacheCreationTokens'
|
|
17
|
+
) IS NOT NULL
|
|
18
|
+
THEN COALESCE((${juniorConversations.usage}->>'inputTokens')::double precision, 0)
|
|
19
|
+
+ COALESCE((${juniorConversations.usage}->>'outputTokens')::double precision, 0)
|
|
20
|
+
+ COALESCE((${juniorConversations.usage}->>'cachedInputTokens')::double precision, 0)
|
|
21
|
+
+ COALESCE((${juniorConversations.usage}->>'cacheCreationTokens')::double precision, 0)
|
|
22
|
+
ELSE NULL
|
|
23
|
+
END
|
|
24
|
+
`;
|
|
25
|
+
}
|
|
26
|
+
function costValue() {
|
|
27
|
+
return sql`
|
|
28
|
+
CASE
|
|
29
|
+
WHEN ${juniorConversations.usage}->'cost'->>'total' IS NOT NULL
|
|
30
|
+
THEN (${juniorConversations.usage}->'cost'->>'total')::double precision
|
|
31
|
+
WHEN COALESCE(
|
|
32
|
+
${juniorConversations.usage}->'cost'->>'input',
|
|
33
|
+
${juniorConversations.usage}->'cost'->>'output',
|
|
34
|
+
${juniorConversations.usage}->'cost'->>'cacheRead',
|
|
35
|
+
${juniorConversations.usage}->'cost'->>'cacheWrite'
|
|
36
|
+
) IS NOT NULL
|
|
37
|
+
THEN COALESCE((${juniorConversations.usage}->'cost'->>'input')::double precision, 0)
|
|
38
|
+
+ COALESCE((${juniorConversations.usage}->'cost'->>'output')::double precision, 0)
|
|
39
|
+
+ COALESCE((${juniorConversations.usage}->'cost'->>'cacheRead')::double precision, 0)
|
|
40
|
+
+ COALESCE((${juniorConversations.usage}->'cost'->>'cacheWrite')::double precision, 0)
|
|
41
|
+
ELSE NULL
|
|
42
|
+
END
|
|
43
|
+
`;
|
|
44
|
+
}
|
|
45
|
+
function conversationAggregateColumns() {
|
|
46
|
+
return {
|
|
47
|
+
active: sql`COUNT(*) FILTER (
|
|
48
|
+
WHERE ${juniorConversations.executionStatus} NOT IN ('idle', 'failed')
|
|
49
|
+
)::integer`,
|
|
50
|
+
conversations: sql`COUNT(*)::integer`,
|
|
51
|
+
costUsd: sql`SUM(${costValue()})::double precision`,
|
|
52
|
+
durationMs: sql`COALESCE(SUM(${juniorConversations.durationMs}), 0)::double precision`,
|
|
53
|
+
failed: sql`COUNT(*) FILTER (
|
|
54
|
+
WHERE ${juniorConversations.executionStatus} = 'failed'
|
|
55
|
+
)::integer`,
|
|
56
|
+
tokens: sql`SUM(${tokenValue()})::double precision`
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
function conversationRangeColumns() {
|
|
60
|
+
return {
|
|
61
|
+
firstSeenAt: sql`MIN(${juniorConversations.createdAt})`.mapWith(
|
|
62
|
+
juniorConversations.createdAt
|
|
63
|
+
),
|
|
64
|
+
lastSeenAt: sql`MAX(${juniorConversations.lastActivityAt})`.mapWith(
|
|
65
|
+
juniorConversations.lastActivityAt
|
|
66
|
+
)
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
function conversationActiveDaysColumn() {
|
|
70
|
+
return sql`COUNT(DISTINCT (${juniorConversations.lastActivityAt} AT TIME ZONE 'UTC')::date)::integer`;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
export {
|
|
74
|
+
conversationAggregateColumns,
|
|
75
|
+
conversationRangeColumns,
|
|
76
|
+
conversationActiveDaysColumn
|
|
77
|
+
};
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
// src/api/conversations/reporting.ts
|
|
2
|
+
var PRIVATE_CONVERSATION_LABEL = "Private Conversation";
|
|
3
|
+
function channelFromConversationId(conversationId) {
|
|
4
|
+
const [provider, channel] = conversationId.split(":");
|
|
5
|
+
return provider === "slack" && channel ? channel : void 0;
|
|
6
|
+
}
|
|
7
|
+
function surfaceFromRow(row) {
|
|
8
|
+
if (row.source === "api" || row.source === "scheduler" || row.source === "slack") {
|
|
9
|
+
return row.source;
|
|
10
|
+
}
|
|
11
|
+
if (row.conversationId.startsWith("slack:")) return "slack";
|
|
12
|
+
if (row.conversationId.startsWith("scheduler:")) return "scheduler";
|
|
13
|
+
if (row.conversationId.startsWith("api:")) return "api";
|
|
14
|
+
return "internal";
|
|
15
|
+
}
|
|
16
|
+
function statusFromRow(row) {
|
|
17
|
+
if (row.executionStatus === "failed") return "failed";
|
|
18
|
+
if (row.executionStatus === "idle") return "completed";
|
|
19
|
+
return "active";
|
|
20
|
+
}
|
|
21
|
+
function surfaceLabel(surface) {
|
|
22
|
+
if (surface === "scheduler") return "Scheduler";
|
|
23
|
+
if (surface === "api") return "API";
|
|
24
|
+
if (surface === "internal") return "Internal";
|
|
25
|
+
return "Conversation";
|
|
26
|
+
}
|
|
27
|
+
function slackLocationLabel(args) {
|
|
28
|
+
const channelId = args.channel;
|
|
29
|
+
if (!channelId) return void 0;
|
|
30
|
+
if (args.channelNameRedacted && args.channelName) return args.channelName;
|
|
31
|
+
const name = args.channelName?.replace(/^#/, "");
|
|
32
|
+
if (channelId.startsWith("D")) return "Direct Message";
|
|
33
|
+
if (channelId.startsWith("C")) {
|
|
34
|
+
return name ? `#${name}` : "Public Channel";
|
|
35
|
+
}
|
|
36
|
+
if (channelId.startsWith("G")) {
|
|
37
|
+
if (name?.startsWith("mpdm-")) return "Group DM";
|
|
38
|
+
return "Private Channel";
|
|
39
|
+
}
|
|
40
|
+
return name || channelId;
|
|
41
|
+
}
|
|
42
|
+
function channelNameFromRow(row) {
|
|
43
|
+
if (row.destinationVisibility !== "public") {
|
|
44
|
+
return PRIVATE_CONVERSATION_LABEL;
|
|
45
|
+
}
|
|
46
|
+
return row.channelName ?? void 0;
|
|
47
|
+
}
|
|
48
|
+
function titleFromRow(row, surface) {
|
|
49
|
+
if (row.destinationVisibility !== "public") {
|
|
50
|
+
return PRIVATE_CONVERSATION_LABEL;
|
|
51
|
+
}
|
|
52
|
+
const channel = channelFromConversationId(row.conversationId);
|
|
53
|
+
return row.title ?? slackLocationLabel({
|
|
54
|
+
channel,
|
|
55
|
+
channelName: row.channelName ?? void 0
|
|
56
|
+
}) ?? surfaceLabel(surface);
|
|
57
|
+
}
|
|
58
|
+
function actorFromRow(row) {
|
|
59
|
+
const actor = {
|
|
60
|
+
...row.email ? { email: row.email } : {},
|
|
61
|
+
...row.fullName ? { fullName: row.fullName } : {},
|
|
62
|
+
...row.providerSubjectId ? { slackUserId: row.providerSubjectId } : {},
|
|
63
|
+
...row.handle ? { slackUserName: row.handle } : {}
|
|
64
|
+
};
|
|
65
|
+
return Object.keys(actor).length ? actor : void 0;
|
|
66
|
+
}
|
|
67
|
+
function summaryFromRow(row) {
|
|
68
|
+
const surface = surfaceFromRow(row);
|
|
69
|
+
const channel = channelFromConversationId(row.conversationId);
|
|
70
|
+
const channelName = channelNameFromRow(row);
|
|
71
|
+
const channelNameRedacted = row.destinationVisibility !== "public";
|
|
72
|
+
const actorIdentity = actorFromRow(row);
|
|
73
|
+
return {
|
|
74
|
+
conversationId: row.conversationId,
|
|
75
|
+
cumulativeDurationMs: row.durationMs,
|
|
76
|
+
displayTitle: titleFromRow(row, surface),
|
|
77
|
+
lastProgressAt: new Date(
|
|
78
|
+
row.executionUpdatedAt ?? row.updatedAt
|
|
79
|
+
).toISOString(),
|
|
80
|
+
lastSeenAt: row.lastActivityAt.toISOString(),
|
|
81
|
+
startedAt: row.createdAt.toISOString(),
|
|
82
|
+
status: statusFromRow(row),
|
|
83
|
+
surface,
|
|
84
|
+
...actorIdentity ? { actorIdentity } : {},
|
|
85
|
+
...channel ? { channel } : {},
|
|
86
|
+
...channelName ? { channelName } : {},
|
|
87
|
+
...channelNameRedacted ? { channelNameRedacted: true } : {},
|
|
88
|
+
...row.destinationVisibility === "public" && row.destinationId ? { locationId: row.destinationId } : {}
|
|
89
|
+
};
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
export {
|
|
93
|
+
surfaceLabel,
|
|
94
|
+
slackLocationLabel,
|
|
95
|
+
summaryFromRow
|
|
96
|
+
};
|