@sentry/junior 0.99.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.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 +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 +8 -0
- package/dist/api/schema.js +14 -3
- package/dist/api.js +24 -11
- package/dist/app.js +25 -19
- 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/{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-T55RBE4Z.js → chunk-2RNOB32R.js} +3 -1
- package/dist/{chunk-NJEDJFK4.js → chunk-2T7DCRAW.js} +1 -1
- package/dist/{chunk-PYK7R5A7.js → chunk-45DMFMY2.js} +66 -65
- 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-KFUSLFLL.js → chunk-JSAANELJ.js} +11 -4
- 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-ZZUBLPXD.js → chunk-VY7BT4SM.js} +5 -4
- 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-Q4IVDNGS.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-A3F5JDYV.js → list-KHRAWZWU.js} +7 -6
- package/dist/{plugin-conversations-PDCQWU3O.js → plugin-conversations-JANXC4GA.js} +6 -5
- 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-UN3MP6LV.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,212 @@
|
|
|
1
|
+
import {
|
|
2
|
+
slackLocationLabel,
|
|
3
|
+
summaryFromRow,
|
|
4
|
+
surfaceLabel
|
|
5
|
+
} from "./chunk-QOZOJNSE.js";
|
|
6
|
+
import {
|
|
7
|
+
ACTIVITY_DAYS,
|
|
8
|
+
activityDays,
|
|
9
|
+
emptyTotals,
|
|
10
|
+
normalizeEmail,
|
|
11
|
+
recentActorRows,
|
|
12
|
+
statsItems,
|
|
13
|
+
verifiedActorWhere
|
|
14
|
+
} from "./chunk-GEUUJRQF.js";
|
|
15
|
+
import {
|
|
16
|
+
conversationActiveDaysColumn,
|
|
17
|
+
conversationAggregateColumns
|
|
18
|
+
} from "./chunk-PGGEOCQY.js";
|
|
19
|
+
import {
|
|
20
|
+
actorProfileReportSchema
|
|
21
|
+
} from "./chunk-IDZBM3NW.js";
|
|
22
|
+
import "./chunk-MM5UFDAC.js";
|
|
23
|
+
import "./chunk-PDO5BLNM.js";
|
|
24
|
+
import {
|
|
25
|
+
getDb,
|
|
26
|
+
juniorConversations,
|
|
27
|
+
juniorIdentities,
|
|
28
|
+
juniorUsers
|
|
29
|
+
} from "./chunk-VHRM6GNH.js";
|
|
30
|
+
import "./chunk-A7X2FDUO.js";
|
|
31
|
+
import {
|
|
32
|
+
juniorDestinations
|
|
33
|
+
} from "./chunk-FXFQNHRU.js";
|
|
34
|
+
import "./chunk-LVA4I4H7.js";
|
|
35
|
+
import "./chunk-B7PUBQQM.js";
|
|
36
|
+
import "./chunk-I35CTGPO.js";
|
|
37
|
+
import "./chunk-OB42YVAE.js";
|
|
38
|
+
import "./chunk-6GWA276C.js";
|
|
39
|
+
import "./chunk-7FBGKXPE.js";
|
|
40
|
+
import "./chunk-MLKGABMK.js";
|
|
41
|
+
|
|
42
|
+
// src/api/people/profile.query.ts
|
|
43
|
+
import { and, eq, gte, sql } from "drizzle-orm";
|
|
44
|
+
function emptyProfile(email, nowMs) {
|
|
45
|
+
const end = new Date(nowMs);
|
|
46
|
+
end.setUTCHours(0, 0, 0, 0);
|
|
47
|
+
const start = new Date(end);
|
|
48
|
+
start.setUTCDate(start.getUTCDate() - (ACTIVITY_DAYS - 1));
|
|
49
|
+
return {
|
|
50
|
+
activityDays: activityDays(/* @__PURE__ */ new Map(), nowMs),
|
|
51
|
+
generatedAt: new Date(nowMs).toISOString(),
|
|
52
|
+
locations: [],
|
|
53
|
+
recentConversations: [],
|
|
54
|
+
actor: { email },
|
|
55
|
+
source: "conversation_index",
|
|
56
|
+
surfaces: [],
|
|
57
|
+
totals: emptyTotals(),
|
|
58
|
+
windowEnd: end.toISOString(),
|
|
59
|
+
windowStart: start.toISOString()
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
function addAggregate(map, label, row) {
|
|
63
|
+
const item = map.get(label) ?? {
|
|
64
|
+
active: 0,
|
|
65
|
+
conversations: 0,
|
|
66
|
+
durationMs: 0,
|
|
67
|
+
failed: 0,
|
|
68
|
+
label
|
|
69
|
+
};
|
|
70
|
+
item.active += row.active;
|
|
71
|
+
item.conversations += row.conversations;
|
|
72
|
+
item.durationMs += row.durationMs;
|
|
73
|
+
item.failed += row.failed;
|
|
74
|
+
if (row.tokens !== null) item.tokens = (item.tokens ?? 0) + row.tokens;
|
|
75
|
+
map.set(label, item);
|
|
76
|
+
}
|
|
77
|
+
function surfaceExpression() {
|
|
78
|
+
return sql`CASE
|
|
79
|
+
WHEN ${juniorConversations.source} IN ('api', 'scheduler', 'slack')
|
|
80
|
+
THEN ${juniorConversations.source}
|
|
81
|
+
WHEN ${juniorConversations.conversationId} LIKE 'slack:%' THEN 'slack'
|
|
82
|
+
WHEN ${juniorConversations.conversationId} LIKE 'scheduler:%' THEN 'scheduler'
|
|
83
|
+
WHEN ${juniorConversations.conversationId} LIKE 'api:%' THEN 'api'
|
|
84
|
+
ELSE 'internal'
|
|
85
|
+
END`;
|
|
86
|
+
}
|
|
87
|
+
function locationLabel(row) {
|
|
88
|
+
if (row.surface !== "slack")
|
|
89
|
+
return surfaceLabel(row.surface);
|
|
90
|
+
if (row.destinationVisibility !== "public") return "Private Conversation";
|
|
91
|
+
return slackLocationLabel({
|
|
92
|
+
channel: row.channel || void 0,
|
|
93
|
+
channelName: row.channelName ?? void 0
|
|
94
|
+
}) ?? "Conversation";
|
|
95
|
+
}
|
|
96
|
+
async function readPeopleProfileFromSql(email) {
|
|
97
|
+
const nowMs = Date.now();
|
|
98
|
+
const normalizedEmail = normalizeEmail(email);
|
|
99
|
+
if (!normalizedEmail) return emptyProfile("", nowMs);
|
|
100
|
+
const end = new Date(nowMs);
|
|
101
|
+
end.setUTCHours(0, 0, 0, 0);
|
|
102
|
+
const start = new Date(end);
|
|
103
|
+
start.setUTCDate(start.getUTCDate() - (ACTIVITY_DAYS - 1));
|
|
104
|
+
const where = verifiedActorWhere(normalizedEmail);
|
|
105
|
+
const surface = surfaceExpression();
|
|
106
|
+
const activityDate = sql`TO_CHAR(
|
|
107
|
+
${juniorConversations.lastActivityAt} AT TIME ZONE 'UTC',
|
|
108
|
+
'YYYY-MM-DD'
|
|
109
|
+
)`;
|
|
110
|
+
const channel = sql`SPLIT_PART(${juniorConversations.conversationId}, ':', 2)`;
|
|
111
|
+
const [totalsRows, dayRows, locationRows, surfaceRows, recentRows] = await Promise.all([
|
|
112
|
+
getDb().select({
|
|
113
|
+
email: juniorUsers.primaryEmailNormalized,
|
|
114
|
+
fullName: juniorUsers.displayName,
|
|
115
|
+
slackUserId: sql`MAX(${juniorIdentities.providerSubjectId})`,
|
|
116
|
+
slackUserName: sql`MAX(${juniorIdentities.handle})`,
|
|
117
|
+
activeDays: conversationActiveDaysColumn(),
|
|
118
|
+
...conversationAggregateColumns()
|
|
119
|
+
}).from(juniorConversations).innerJoin(
|
|
120
|
+
juniorIdentities,
|
|
121
|
+
eq(juniorIdentities.id, juniorConversations.actorIdentityId)
|
|
122
|
+
).innerJoin(juniorUsers, eq(juniorUsers.id, juniorIdentities.userId)).where(where).groupBy(juniorUsers.primaryEmailNormalized, juniorUsers.displayName),
|
|
123
|
+
getDb().select({
|
|
124
|
+
date: activityDate,
|
|
125
|
+
...conversationAggregateColumns()
|
|
126
|
+
}).from(juniorConversations).innerJoin(
|
|
127
|
+
juniorIdentities,
|
|
128
|
+
eq(juniorIdentities.id, juniorConversations.actorIdentityId)
|
|
129
|
+
).innerJoin(juniorUsers, eq(juniorUsers.id, juniorIdentities.userId)).where(and(where, gte(juniorConversations.lastActivityAt, start))).groupBy(activityDate),
|
|
130
|
+
getDb().select({
|
|
131
|
+
channel,
|
|
132
|
+
channelName: juniorConversations.channelName,
|
|
133
|
+
destinationVisibility: juniorDestinations.visibility,
|
|
134
|
+
surface,
|
|
135
|
+
...conversationAggregateColumns()
|
|
136
|
+
}).from(juniorConversations).innerJoin(
|
|
137
|
+
juniorIdentities,
|
|
138
|
+
eq(juniorIdentities.id, juniorConversations.actorIdentityId)
|
|
139
|
+
).innerJoin(juniorUsers, eq(juniorUsers.id, juniorIdentities.userId)).leftJoin(
|
|
140
|
+
juniorDestinations,
|
|
141
|
+
eq(juniorDestinations.id, juniorConversations.destinationId)
|
|
142
|
+
).where(where).groupBy(
|
|
143
|
+
channel,
|
|
144
|
+
juniorConversations.channelName,
|
|
145
|
+
juniorDestinations.visibility,
|
|
146
|
+
surface
|
|
147
|
+
),
|
|
148
|
+
getDb().select({ surface, ...conversationAggregateColumns() }).from(juniorConversations).innerJoin(
|
|
149
|
+
juniorIdentities,
|
|
150
|
+
eq(juniorIdentities.id, juniorConversations.actorIdentityId)
|
|
151
|
+
).innerJoin(juniorUsers, eq(juniorUsers.id, juniorIdentities.userId)).where(where).groupBy(surface),
|
|
152
|
+
recentActorRows(normalizedEmail)
|
|
153
|
+
]);
|
|
154
|
+
const totalsRow = totalsRows[0];
|
|
155
|
+
if (!totalsRow) return emptyProfile(normalizedEmail, nowMs);
|
|
156
|
+
const actor = {
|
|
157
|
+
email: totalsRow.email,
|
|
158
|
+
...totalsRow.fullName ? { fullName: totalsRow.fullName } : {},
|
|
159
|
+
...totalsRow.slackUserId ? { slackUserId: totalsRow.slackUserId } : {},
|
|
160
|
+
...totalsRow.slackUserName ? { slackUserName: totalsRow.slackUserName } : {}
|
|
161
|
+
};
|
|
162
|
+
const days = /* @__PURE__ */ new Map();
|
|
163
|
+
for (const row of dayRows) {
|
|
164
|
+
days.set(row.date, {
|
|
165
|
+
active: row.active,
|
|
166
|
+
conversations: row.conversations,
|
|
167
|
+
date: row.date,
|
|
168
|
+
durationMs: row.durationMs,
|
|
169
|
+
failed: row.failed,
|
|
170
|
+
...row.tokens !== null ? { tokens: row.tokens } : {}
|
|
171
|
+
});
|
|
172
|
+
}
|
|
173
|
+
const locations = /* @__PURE__ */ new Map();
|
|
174
|
+
for (const row of locationRows) {
|
|
175
|
+
addAggregate(locations, locationLabel(row), row);
|
|
176
|
+
}
|
|
177
|
+
const surfaces = /* @__PURE__ */ new Map();
|
|
178
|
+
for (const row of surfaceRows) {
|
|
179
|
+
addAggregate(
|
|
180
|
+
surfaces,
|
|
181
|
+
surfaceLabel(row.surface),
|
|
182
|
+
row
|
|
183
|
+
);
|
|
184
|
+
}
|
|
185
|
+
return {
|
|
186
|
+
activityDays: activityDays(days, nowMs),
|
|
187
|
+
generatedAt: new Date(nowMs).toISOString(),
|
|
188
|
+
locations: statsItems(locations),
|
|
189
|
+
recentConversations: recentRows.map(summaryFromRow),
|
|
190
|
+
actor,
|
|
191
|
+
source: "conversation_index",
|
|
192
|
+
surfaces: statsItems(surfaces),
|
|
193
|
+
totals: {
|
|
194
|
+
active: totalsRow.active,
|
|
195
|
+
activeDays: totalsRow.activeDays,
|
|
196
|
+
conversations: totalsRow.conversations,
|
|
197
|
+
durationMs: totalsRow.durationMs,
|
|
198
|
+
failed: totalsRow.failed,
|
|
199
|
+
...totalsRow.tokens !== null ? { tokens: totalsRow.tokens } : {}
|
|
200
|
+
},
|
|
201
|
+
windowEnd: end.toISOString(),
|
|
202
|
+
windowStart: start.toISOString()
|
|
203
|
+
};
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
// src/api/people/profile.ts
|
|
207
|
+
async function readPeopleProfile(email) {
|
|
208
|
+
return actorProfileReportSchema.parse(await readPeopleProfileFromSql(email));
|
|
209
|
+
}
|
|
210
|
+
export {
|
|
211
|
+
readPeopleProfile
|
|
212
|
+
};
|
|
@@ -3,7 +3,7 @@ import {
|
|
|
3
3
|
finalizeFailedTurnReply,
|
|
4
4
|
processPluginTask,
|
|
5
5
|
scheduleSessionCompletedPluginTasks
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-XSBIISXS.js";
|
|
7
7
|
import "./chunk-KNFROR7R.js";
|
|
8
8
|
import {
|
|
9
9
|
coerceThreadArtifactsState,
|
|
@@ -13,15 +13,15 @@ import {
|
|
|
13
13
|
markTurnFailed,
|
|
14
14
|
persistThreadStateById,
|
|
15
15
|
startActiveTurn
|
|
16
|
-
} from "./chunk-
|
|
16
|
+
} from "./chunk-NSOCZGOH.js";
|
|
17
17
|
import {
|
|
18
18
|
coerceThreadConversationState
|
|
19
19
|
} from "./chunk-6DTVCPLO.js";
|
|
20
|
-
import "./chunk-
|
|
20
|
+
import "./chunk-IVXL57YF.js";
|
|
21
21
|
import {
|
|
22
22
|
commitMessages,
|
|
23
23
|
loadProjection
|
|
24
|
-
} from "./chunk-
|
|
24
|
+
} from "./chunk-IQIBZXGB.js";
|
|
25
25
|
import {
|
|
26
26
|
buildConversationContext,
|
|
27
27
|
hydrateConversationMessages,
|
|
@@ -29,12 +29,12 @@ import {
|
|
|
29
29
|
normalizeConversationText,
|
|
30
30
|
updateConversationStats,
|
|
31
31
|
upsertConversationMessage
|
|
32
|
-
} from "./chunk-
|
|
32
|
+
} from "./chunk-JPQISMMJ.js";
|
|
33
33
|
import "./chunk-PDO5BLNM.js";
|
|
34
|
-
import "./chunk-
|
|
35
|
-
import "./chunk-
|
|
36
|
-
import "./chunk-
|
|
37
|
-
import "./chunk-
|
|
34
|
+
import "./chunk-TPTJEHUE.js";
|
|
35
|
+
import "./chunk-FP5N5OWZ.js";
|
|
36
|
+
import "./chunk-PWC24W5F.js";
|
|
37
|
+
import "./chunk-VHRM6GNH.js";
|
|
38
38
|
import "./chunk-G3E7SCME.js";
|
|
39
39
|
import {
|
|
40
40
|
sleep
|
|
@@ -42,7 +42,8 @@ import {
|
|
|
42
42
|
import {
|
|
43
43
|
stripRuntimeTurnContext,
|
|
44
44
|
trimTrailingAssistantMessages
|
|
45
|
-
} from "./chunk-
|
|
45
|
+
} from "./chunk-A7X2FDUO.js";
|
|
46
|
+
import "./chunk-FXFQNHRU.js";
|
|
46
47
|
import "./chunk-LVA4I4H7.js";
|
|
47
48
|
import "./chunk-B7PUBQQM.js";
|
|
48
49
|
import {
|
|
@@ -287,7 +288,7 @@ async function runLocalAgentTurn(input, deps) {
|
|
|
287
288
|
modelId: reply.diagnostics.modelId,
|
|
288
289
|
durationMs: reply.diagnostics.durationMs,
|
|
289
290
|
usage: reply.diagnostics.usage,
|
|
290
|
-
reasoningLevel: reply.diagnostics.
|
|
291
|
+
reasoningLevel: reply.diagnostics.reasoningLevel,
|
|
291
292
|
destination,
|
|
292
293
|
source,
|
|
293
294
|
actor: localActor,
|
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
import {
|
|
2
|
+
conversationAggregateColumns
|
|
3
|
+
} from "./chunk-PGGEOCQY.js";
|
|
4
|
+
import {
|
|
5
|
+
conversationStatsReportSchema
|
|
6
|
+
} from "./chunk-MM5UFDAC.js";
|
|
7
|
+
import "./chunk-PDO5BLNM.js";
|
|
8
|
+
import {
|
|
9
|
+
getDb,
|
|
10
|
+
juniorConversations,
|
|
11
|
+
juniorIdentities,
|
|
12
|
+
juniorUsers
|
|
13
|
+
} from "./chunk-VHRM6GNH.js";
|
|
14
|
+
import "./chunk-A7X2FDUO.js";
|
|
15
|
+
import {
|
|
16
|
+
juniorDestinations
|
|
17
|
+
} from "./chunk-FXFQNHRU.js";
|
|
18
|
+
import "./chunk-LVA4I4H7.js";
|
|
19
|
+
import "./chunk-B7PUBQQM.js";
|
|
20
|
+
import "./chunk-I35CTGPO.js";
|
|
21
|
+
import "./chunk-OB42YVAE.js";
|
|
22
|
+
import "./chunk-6GWA276C.js";
|
|
23
|
+
import "./chunk-7FBGKXPE.js";
|
|
24
|
+
import "./chunk-MLKGABMK.js";
|
|
25
|
+
|
|
26
|
+
// src/api/conversations/stats.query.ts
|
|
27
|
+
import { and, eq, gte, isNull, lte } from "drizzle-orm";
|
|
28
|
+
var WINDOW_MS = 7 * 24 * 60 * 60 * 1e3;
|
|
29
|
+
function emptyStatsItem(label) {
|
|
30
|
+
return {
|
|
31
|
+
active: 0,
|
|
32
|
+
conversations: 0,
|
|
33
|
+
durationMs: 0,
|
|
34
|
+
failed: 0,
|
|
35
|
+
label
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
function addUsd(current, next) {
|
|
39
|
+
return Math.round(((current ?? 0) + next) * 1e12) / 1e12;
|
|
40
|
+
}
|
|
41
|
+
function actorLabel(row) {
|
|
42
|
+
return row.userEmail?.trim() || row.identityEmail?.trim() || row.userDisplayName?.trim() || row.identityDisplayName?.trim() || row.identityHandle?.trim() || row.identitySubjectId?.trim() || "Unknown";
|
|
43
|
+
}
|
|
44
|
+
function surfaceLabel(source) {
|
|
45
|
+
if (source === "scheduler") return "Scheduler";
|
|
46
|
+
if (source === "api") return "API";
|
|
47
|
+
if (source === "internal" || source === "local") return "Internal";
|
|
48
|
+
return "Conversation";
|
|
49
|
+
}
|
|
50
|
+
function locationLabel(row) {
|
|
51
|
+
if (row.destinationProvider !== "slack") {
|
|
52
|
+
return surfaceLabel(row.source);
|
|
53
|
+
}
|
|
54
|
+
if (row.destinationKind === "dm") {
|
|
55
|
+
return "Direct Message";
|
|
56
|
+
}
|
|
57
|
+
if (row.destinationVisibility !== "public") {
|
|
58
|
+
return "Private Conversation";
|
|
59
|
+
}
|
|
60
|
+
const name = (row.channelName ?? row.destinationDisplayName)?.trim().replace(/^#/, "");
|
|
61
|
+
return name ? `#${name}` : "Public Channel";
|
|
62
|
+
}
|
|
63
|
+
function addAggregate(map, label, row) {
|
|
64
|
+
const item = map.get(label) ?? emptyStatsItem(label);
|
|
65
|
+
item.active += row.active;
|
|
66
|
+
item.conversations += row.conversations;
|
|
67
|
+
item.durationMs += row.durationMs;
|
|
68
|
+
item.failed += row.failed;
|
|
69
|
+
if (row.tokens !== null) {
|
|
70
|
+
item.tokens = (item.tokens ?? 0) + row.tokens;
|
|
71
|
+
}
|
|
72
|
+
if (row.costUsd !== null) {
|
|
73
|
+
item.costUsd = addUsd(item.costUsd, row.costUsd);
|
|
74
|
+
}
|
|
75
|
+
map.set(label, item);
|
|
76
|
+
}
|
|
77
|
+
function statsItems(map) {
|
|
78
|
+
return [...map.values()].sort(
|
|
79
|
+
(left, right) => right.conversations - left.conversations || left.label.localeCompare(right.label)
|
|
80
|
+
);
|
|
81
|
+
}
|
|
82
|
+
function statsWhere(start, end) {
|
|
83
|
+
return and(
|
|
84
|
+
isNull(juniorConversations.parentConversationId),
|
|
85
|
+
gte(juniorConversations.lastActivityAt, start),
|
|
86
|
+
lte(juniorConversations.lastActivityAt, end)
|
|
87
|
+
);
|
|
88
|
+
}
|
|
89
|
+
async function aggregateStats(db, start, end) {
|
|
90
|
+
const where = statsWhere(start, end);
|
|
91
|
+
const [totalsRows, actorRows, locationRows] = await Promise.all([
|
|
92
|
+
db.select(conversationAggregateColumns()).from(juniorConversations).where(where),
|
|
93
|
+
db.select({
|
|
94
|
+
identityDisplayName: juniorIdentities.displayName,
|
|
95
|
+
identityEmail: juniorIdentities.emailNormalized,
|
|
96
|
+
identityHandle: juniorIdentities.handle,
|
|
97
|
+
identitySubjectId: juniorIdentities.providerSubjectId,
|
|
98
|
+
userDisplayName: juniorUsers.displayName,
|
|
99
|
+
userEmail: juniorUsers.primaryEmailNormalized,
|
|
100
|
+
...conversationAggregateColumns()
|
|
101
|
+
}).from(juniorConversations).leftJoin(
|
|
102
|
+
juniorIdentities,
|
|
103
|
+
eq(juniorIdentities.id, juniorConversations.actorIdentityId)
|
|
104
|
+
).leftJoin(juniorUsers, eq(juniorUsers.id, juniorIdentities.userId)).where(where).groupBy(
|
|
105
|
+
juniorIdentities.displayName,
|
|
106
|
+
juniorIdentities.emailNormalized,
|
|
107
|
+
juniorIdentities.handle,
|
|
108
|
+
juniorIdentities.providerSubjectId,
|
|
109
|
+
juniorUsers.displayName,
|
|
110
|
+
juniorUsers.primaryEmailNormalized
|
|
111
|
+
),
|
|
112
|
+
db.select({
|
|
113
|
+
channelName: juniorConversations.channelName,
|
|
114
|
+
destinationDisplayName: juniorDestinations.displayName,
|
|
115
|
+
destinationKind: juniorDestinations.kind,
|
|
116
|
+
destinationProvider: juniorDestinations.provider,
|
|
117
|
+
destinationVisibility: juniorDestinations.visibility,
|
|
118
|
+
source: juniorConversations.source,
|
|
119
|
+
...conversationAggregateColumns()
|
|
120
|
+
}).from(juniorConversations).leftJoin(
|
|
121
|
+
juniorDestinations,
|
|
122
|
+
eq(juniorDestinations.id, juniorConversations.destinationId)
|
|
123
|
+
).where(where).groupBy(
|
|
124
|
+
juniorConversations.channelName,
|
|
125
|
+
juniorConversations.source,
|
|
126
|
+
juniorDestinations.displayName,
|
|
127
|
+
juniorDestinations.kind,
|
|
128
|
+
juniorDestinations.provider,
|
|
129
|
+
juniorDestinations.visibility
|
|
130
|
+
)
|
|
131
|
+
]);
|
|
132
|
+
return { actorRows, locationRows, totals: totalsRows[0] };
|
|
133
|
+
}
|
|
134
|
+
async function readConversationStatsFromSql() {
|
|
135
|
+
const nowMs = Date.now();
|
|
136
|
+
const windowStartMs = nowMs - WINDOW_MS;
|
|
137
|
+
const { actorRows, locationRows, totals } = await aggregateStats(
|
|
138
|
+
getDb(),
|
|
139
|
+
new Date(windowStartMs),
|
|
140
|
+
new Date(nowMs)
|
|
141
|
+
);
|
|
142
|
+
const actors = /* @__PURE__ */ new Map();
|
|
143
|
+
const locations = /* @__PURE__ */ new Map();
|
|
144
|
+
for (const row of actorRows) {
|
|
145
|
+
addAggregate(actors, actorLabel(row), row);
|
|
146
|
+
}
|
|
147
|
+
for (const row of locationRows) {
|
|
148
|
+
addAggregate(locations, locationLabel(row), row);
|
|
149
|
+
}
|
|
150
|
+
return {
|
|
151
|
+
active: totals?.active ?? 0,
|
|
152
|
+
conversations: totals?.conversations ?? 0,
|
|
153
|
+
durationMs: totals?.durationMs ?? 0,
|
|
154
|
+
failed: totals?.failed ?? 0,
|
|
155
|
+
generatedAt: new Date(nowMs).toISOString(),
|
|
156
|
+
locations: statsItems(locations),
|
|
157
|
+
actors: statsItems(actors),
|
|
158
|
+
source: "conversation_index",
|
|
159
|
+
...totals?.costUsd !== null && totals?.costUsd !== void 0 ? { costUsd: addUsd(void 0, totals.costUsd) } : {},
|
|
160
|
+
...totals?.tokens !== null && totals?.tokens !== void 0 ? { tokens: totals.tokens } : {},
|
|
161
|
+
windowEnd: new Date(nowMs).toISOString(),
|
|
162
|
+
windowStart: new Date(windowStartMs).toISOString()
|
|
163
|
+
};
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
// src/api/conversations/stats.ts
|
|
167
|
+
async function readConversationStats() {
|
|
168
|
+
return conversationStatsReportSchema.parse(
|
|
169
|
+
await readConversationStatsFromSql()
|
|
170
|
+
);
|
|
171
|
+
}
|
|
172
|
+
export {
|
|
173
|
+
readConversationStats
|
|
174
|
+
};
|
|
@@ -1,21 +1,22 @@
|
|
|
1
1
|
import {
|
|
2
2
|
buildConversationSubagent
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-VY7BT4SM.js";
|
|
4
4
|
import {
|
|
5
5
|
readConversationRecordFromSql
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-JSAANELJ.js";
|
|
7
7
|
import {
|
|
8
8
|
conversationSubagentTranscriptReportSchema
|
|
9
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-MM5UFDAC.js";
|
|
10
10
|
import "./chunk-LVUKF5CE.js";
|
|
11
|
-
import "./chunk-
|
|
12
|
-
import "./chunk-
|
|
13
|
-
import "./chunk-
|
|
11
|
+
import "./chunk-VVIXK2BX.js";
|
|
12
|
+
import "./chunk-IQIBZXGB.js";
|
|
13
|
+
import "./chunk-JPQISMMJ.js";
|
|
14
14
|
import "./chunk-PDO5BLNM.js";
|
|
15
|
-
import "./chunk-
|
|
16
|
-
import "./chunk-
|
|
15
|
+
import "./chunk-FP5N5OWZ.js";
|
|
16
|
+
import "./chunk-VHRM6GNH.js";
|
|
17
17
|
import "./chunk-4ZNGQH7C.js";
|
|
18
|
-
import "./chunk-
|
|
18
|
+
import "./chunk-A7X2FDUO.js";
|
|
19
|
+
import "./chunk-FXFQNHRU.js";
|
|
19
20
|
import "./chunk-LVA4I4H7.js";
|
|
20
21
|
import "./chunk-B7PUBQQM.js";
|
|
21
22
|
import "./chunk-I35CTGPO.js";
|