@sentry/junior 0.190.0 → 0.192.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-3IG2FQW2.js → agent-hooks-3JY76L5X.js} +11 -11
- package/dist/api/activity.d.ts +3 -1
- package/dist/api/code/overview.d.ts +12 -0
- package/dist/api/locations/detail.d.ts +8 -0
- package/dist/api/locations/list.d.ts +5 -0
- package/dist/api/people/code.d.ts +6 -0
- package/dist/api/people/shared.d.ts +2 -0
- package/dist/api/reporting-window.d.ts +40 -0
- package/dist/api/schema/code.d.ts +14 -0
- package/dist/api/schema/conversation.d.ts +27 -0
- package/dist/api/schema/location.d.ts +15 -0
- package/dist/api/schema/person.d.ts +104 -0
- package/dist/api/schema/task.d.ts +15 -2
- package/dist/api/schema.d.ts +1 -1
- package/dist/api/schema.js +2 -2
- package/dist/api.js +536 -141
- package/dist/app.js +93 -130
- package/dist/{catalog-runtime-2OT7S3ZC.js → catalog-runtime-5JVLWXRY.js} +4 -4
- package/dist/chat/agent/resume.d.ts +0 -1
- package/dist/chat/agent/types.d.ts +0 -1
- package/dist/chat/agent-invocations/types.d.ts +4 -4
- package/dist/chat/providers/slack/runtime.d.ts +1 -2
- package/dist/chat/providers/slack/system-turn.d.ts +9 -4
- package/dist/chat/providers/slack/turn.d.ts +0 -1
- package/dist/chat/services/turn-router.d.ts +1 -1
- package/dist/chat/slack/dispatch-turn.d.ts +0 -1
- package/dist/chat/slack/timestamp-param.d.ts +1 -1
- package/dist/chat/task-execution/assistant-message.d.ts +7 -7
- package/dist/chat/task-execution/checkpoint.d.ts +0 -1
- package/dist/chat/task-execution/conversation-turn.d.ts +2 -2
- package/dist/chat/task-execution/state.d.ts +0 -3
- package/dist/chat/task-execution/store.d.ts +0 -1
- package/dist/chat/task-execution/turn-cursor.d.ts +0 -2
- package/dist/chat/task-execution/worker.d.ts +0 -1
- package/dist/chat/tasks/execution-stats.d.ts +12 -0
- package/dist/{chunk-Y4WL4OYD.js → chunk-3ADPXQBL.js} +1 -1
- package/dist/{chunk-F3K2267N.js → chunk-3O2NXVGB.js} +77 -35
- package/dist/{chunk-2MKHYSYL.js → chunk-3UJSII43.js} +3 -3
- package/dist/{chunk-RLYJYEIY.js → chunk-47JFLZSF.js} +5 -7
- package/dist/{chunk-T66GV7A3.js → chunk-4AFSQJD6.js} +2 -2
- package/dist/{chunk-DJZGQ7OL.js → chunk-4B4DQGOM.js} +22 -29
- package/dist/{chunk-OJFX2FP7.js → chunk-4CCQZHD3.js} +9 -11
- package/dist/{chunk-BUJU6C2J.js → chunk-4WIA45WD.js} +1 -1
- package/dist/{chunk-VWNIDTFR.js → chunk-4Z7B5WVV.js} +2 -2
- package/dist/{chunk-3J3BCB4J.js → chunk-5V4BAUCH.js} +1 -1
- package/dist/{chunk-663DQH5W.js → chunk-6FCKJDKS.js} +1 -1
- package/dist/{chunk-HI5KXE3C.js → chunk-6LX6KV5C.js} +3 -3
- package/dist/{chunk-67MMSYSE.js → chunk-7XO7PTZE.js} +1 -1
- package/dist/{chunk-OKAHLUSU.js → chunk-AKR6W7VV.js} +3 -3
- package/dist/{chunk-JV7U4665.js → chunk-ARSUYYQG.js} +1 -1
- package/dist/{chunk-IRQ3RSX3.js → chunk-BGLMT6KP.js} +3 -3
- package/dist/{chunk-2MRF22J4.js → chunk-BUTAWPUV.js} +50 -8
- package/dist/{chunk-62DRKZQU.js → chunk-EIYOABL4.js} +4 -4
- package/dist/{chunk-PFAZSRGR.js → chunk-EYIMZY5O.js} +114 -19
- package/dist/{chunk-DVX6U6GI.js → chunk-EYNUOZCN.js} +1 -1
- package/dist/{chunk-4PKEJK5B.js → chunk-FGYWKKTJ.js} +1 -1
- package/dist/{chunk-YFU4DGZY.js → chunk-G4E5WIRL.js} +30 -9
- package/dist/{chunk-OON4IQHH.js → chunk-H5Q2T5VC.js} +1 -1
- package/dist/{chunk-ZFCO2TMB.js → chunk-IBO4YFFZ.js} +1 -1
- package/dist/{chunk-ECOR3OXY.js → chunk-ITTEDZGY.js} +8 -8
- package/dist/{chunk-4BLFIYVK.js → chunk-KR5F3QSP.js} +9 -12
- package/dist/{chunk-6BXUSF7J.js → chunk-LRTEMMCZ.js} +1 -1
- package/dist/{chunk-MNHJ4WLE.js → chunk-MB2CTEPD.js} +74 -4
- package/dist/{chunk-YKIAUKYH.js → chunk-OBN7UEQJ.js} +2 -2
- package/dist/{chunk-OYCOLHCR.js → chunk-PXP2M32M.js} +5 -5
- package/dist/{chunk-6H7YU6XH.js → chunk-PXUBRZBU.js} +1 -1
- package/dist/{chunk-REVH4BZU.js → chunk-PYVGXGKC.js} +2 -2
- package/dist/{chunk-UTL3MHPC.js → chunk-RC745GGZ.js} +8 -1
- package/dist/{chunk-CZXZKTAI.js → chunk-RWBZZMW6.js} +3 -3
- package/dist/{chunk-GWCFXTB6.js → chunk-SSR6YBWW.js} +6 -6
- package/dist/{chunk-7UJ6IJCK.js → chunk-SZ2O3CGS.js} +1 -1
- package/dist/{chunk-BGOLRC36.js → chunk-VF3EDS7P.js} +13 -11
- package/dist/{chunk-FVFJ57RK.js → chunk-YE6DVM43.js} +9 -8
- package/dist/{chunk-7Y7XMI6P.js → chunk-YRWGJ5OO.js} +5 -5
- package/dist/{chunk-W2C4TPLB.js → chunk-Z4DNJI5F.js} +5 -5
- package/dist/cli/chat.js +33 -33
- package/dist/cli/check.js +5 -5
- package/dist/cli/plugins.js +12 -12
- package/dist/cli/snapshot-create.js +9 -9
- package/dist/cli/upgrade.js +6 -6
- package/dist/db/schema/stats.d.ts +5 -1
- package/dist/{db-2IFDMDDY.js → db-LRM6AP66.js} +6 -6
- package/dist/instrumentation.js +3 -3
- package/dist/nitro.js +6 -6
- package/dist/{oauth-callback-server-SZSS2KH6.js → oauth-callback-server-BKCDVYVH.js} +29 -29
- package/dist/reporting-schema.d.ts +2 -2
- package/dist/{runner-2N4QU77X.js → runner-RUXGS3E6.js} +21 -21
- package/dist/{skills-VU2LZAKX.js → skills-DXP2RCJF.js} +5 -5
- package/dist/spawn-HH7GH7XT.js +42 -0
- package/dist/task-runner-H5I7R3LJ.js +36 -0
- package/dist/{validation-IJGHK7NI.js → validation-F4KYLIF2.js} +5 -5
- package/dist/version.js +1 -1
- package/dist/{work-DI45MLRL.js → work-UUNMNSML.js} +21 -21
- package/dist/{worker-FY7KWG2M.js → worker-PMIJ5NLD.js} +10 -10
- package/package.json +6 -6
- package/dist/spawn-3K7RV4T5.js +0 -42
- package/dist/task-runner-52DYFHW3.js +0 -36
package/dist/api.js
CHANGED
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
import {
|
|
2
|
+
DAY_MS,
|
|
3
|
+
HOUR_MS,
|
|
2
4
|
acceptedConversationMessageSchema,
|
|
3
5
|
activityDays,
|
|
6
|
+
activityHours,
|
|
4
7
|
actorDirectoryReportSchema,
|
|
5
8
|
actorProfileReportSchema,
|
|
6
9
|
apiErrorSchema,
|
|
@@ -26,6 +29,8 @@ import {
|
|
|
26
29
|
createPersonalTokenBodySchema,
|
|
27
30
|
createdPersonalTokenSchema,
|
|
28
31
|
deleteWorkspaceResponseSchema,
|
|
32
|
+
fillUtcDays,
|
|
33
|
+
fillUtcHours,
|
|
29
34
|
locationDetailReportSchema,
|
|
30
35
|
locationDirectoryReportSchema,
|
|
31
36
|
locationParamsSchema,
|
|
@@ -39,11 +44,15 @@ import {
|
|
|
39
44
|
taskListSchema,
|
|
40
45
|
taskParamsSchema,
|
|
41
46
|
taskRunListSchema,
|
|
47
|
+
trailingUtcDayWindow,
|
|
48
|
+
trailingUtcHourWindow,
|
|
49
|
+
utcDayKey,
|
|
50
|
+
utcHourKey,
|
|
42
51
|
workspaceBodySchema,
|
|
43
52
|
workspaceListSchema,
|
|
44
53
|
workspaceParamsSchema,
|
|
45
54
|
workspaceSchema
|
|
46
|
-
} from "./chunk-
|
|
55
|
+
} from "./chunk-EYIMZY5O.js";
|
|
47
56
|
import {
|
|
48
57
|
appendAndEnqueueWebMessage,
|
|
49
58
|
conversationArchiveTimes,
|
|
@@ -63,27 +72,29 @@ import {
|
|
|
63
72
|
resolveSlackConversationContextFromThreadId,
|
|
64
73
|
viewerConversationMembership,
|
|
65
74
|
webActorFromEmail
|
|
66
|
-
} from "./chunk-
|
|
75
|
+
} from "./chunk-KR5F3QSP.js";
|
|
67
76
|
import {
|
|
68
77
|
buildSentryConversationUrl,
|
|
69
78
|
buildSentryEventUrl,
|
|
70
79
|
getWebAuthorization
|
|
71
|
-
} from "./chunk-
|
|
80
|
+
} from "./chunk-H5Q2T5VC.js";
|
|
72
81
|
import {
|
|
73
82
|
readTaskExecutionByConversationId,
|
|
74
83
|
readTaskExecutionDays,
|
|
84
|
+
readTaskExecutionHours,
|
|
75
85
|
readTaskExecutionStatusDays,
|
|
86
|
+
readTaskExecutionStatusHours,
|
|
76
87
|
readTaskExecutionSummaries,
|
|
77
88
|
readTaskExecutions,
|
|
78
89
|
readTaskRuns
|
|
79
|
-
} from "./chunk-
|
|
90
|
+
} from "./chunk-MB2CTEPD.js";
|
|
80
91
|
import {
|
|
81
92
|
healthReportSchema,
|
|
82
93
|
pluginOperationalReportFeedSchema,
|
|
83
94
|
pluginsSchema,
|
|
84
95
|
runtimeInfoReportSchema,
|
|
85
96
|
skillReportsSchema
|
|
86
|
-
} from "./chunk-
|
|
97
|
+
} from "./chunk-RC745GGZ.js";
|
|
87
98
|
import {
|
|
88
99
|
deleteEventTask,
|
|
89
100
|
eventTaskBelongsToUser,
|
|
@@ -99,24 +110,24 @@ import {
|
|
|
99
110
|
readScheduledTask,
|
|
100
111
|
readStats,
|
|
101
112
|
saveScheduledTask
|
|
102
|
-
} from "./chunk-
|
|
113
|
+
} from "./chunk-EIYOABL4.js";
|
|
103
114
|
import {
|
|
104
115
|
parseSlackThreadId
|
|
105
|
-
} from "./chunk-
|
|
116
|
+
} from "./chunk-4WIA45WD.js";
|
|
106
117
|
import {
|
|
107
118
|
cancelHumanFacingPendingMessages,
|
|
108
119
|
getConversation
|
|
109
|
-
} from "./chunk-
|
|
120
|
+
} from "./chunk-G4E5WIRL.js";
|
|
110
121
|
import "./chunk-DA2KGZZI.js";
|
|
111
122
|
import {
|
|
112
123
|
agentTurnUsageSchema,
|
|
113
124
|
fallbackShortTitle,
|
|
114
125
|
hasAgentTurnUsage,
|
|
115
126
|
renderJuniorNativeConversationEvent
|
|
116
|
-
} from "./chunk-
|
|
127
|
+
} from "./chunk-OBN7UEQJ.js";
|
|
117
128
|
import {
|
|
118
129
|
getCachedSnapshot
|
|
119
|
-
} from "./chunk-
|
|
130
|
+
} from "./chunk-3UJSII43.js";
|
|
120
131
|
import "./chunk-PDO5BLNM.js";
|
|
121
132
|
import {
|
|
122
133
|
getVercelConversationWorkQueue
|
|
@@ -142,7 +153,7 @@ import {
|
|
|
142
153
|
updateWorkspace,
|
|
143
154
|
withSlackRetries,
|
|
144
155
|
workspaceRepoCheckoutPath
|
|
145
|
-
} from "./chunk-
|
|
156
|
+
} from "./chunk-BUTAWPUV.js";
|
|
146
157
|
import "./chunk-3Y47VMHV.js";
|
|
147
158
|
import {
|
|
148
159
|
getConversationStore,
|
|
@@ -151,7 +162,7 @@ import {
|
|
|
151
162
|
locationFromRow,
|
|
152
163
|
parseSessionSource,
|
|
153
164
|
resolveRootConversationId
|
|
154
|
-
} from "./chunk-
|
|
165
|
+
} from "./chunk-AKR6W7VV.js";
|
|
155
166
|
import {
|
|
156
167
|
conversationReadColumns,
|
|
157
168
|
juniorApiTokens,
|
|
@@ -163,23 +174,23 @@ import {
|
|
|
163
174
|
juniorIdentities,
|
|
164
175
|
juniorSchedulerTasks,
|
|
165
176
|
juniorUsers
|
|
166
|
-
} from "./chunk-
|
|
177
|
+
} from "./chunk-IBO4YFFZ.js";
|
|
167
178
|
import {
|
|
168
179
|
create,
|
|
169
180
|
hash
|
|
170
|
-
} from "./chunk-
|
|
171
|
-
import "./chunk-
|
|
181
|
+
} from "./chunk-6LX6KV5C.js";
|
|
182
|
+
import "./chunk-LRTEMMCZ.js";
|
|
172
183
|
import {
|
|
173
184
|
decodeStoredConversationEvent
|
|
174
185
|
} from "./chunk-GFBR4S3Q.js";
|
|
175
186
|
import {
|
|
176
187
|
juniorDestinations
|
|
177
188
|
} from "./chunk-VFUK3X5B.js";
|
|
178
|
-
import "./chunk-
|
|
189
|
+
import "./chunk-4Z7B5WVV.js";
|
|
179
190
|
import "./chunk-D4YV5TDV.js";
|
|
180
|
-
import "./chunk-
|
|
181
|
-
import "./chunk-
|
|
182
|
-
import "./chunk-
|
|
191
|
+
import "./chunk-EYNUOZCN.js";
|
|
192
|
+
import "./chunk-FGYWKKTJ.js";
|
|
193
|
+
import "./chunk-6FCKJDKS.js";
|
|
183
194
|
import "./chunk-CEMMLV5L.js";
|
|
184
195
|
import {
|
|
185
196
|
parseSlackChannelId,
|
|
@@ -191,9 +202,9 @@ import "./chunk-TXKUKMVO.js";
|
|
|
191
202
|
import {
|
|
192
203
|
logException,
|
|
193
204
|
logWarn
|
|
194
|
-
} from "./chunk-
|
|
205
|
+
} from "./chunk-3ADPXQBL.js";
|
|
195
206
|
import "./chunk-PEQXYSSE.js";
|
|
196
|
-
import "./chunk-
|
|
207
|
+
import "./chunk-ARSUYYQG.js";
|
|
197
208
|
|
|
198
209
|
// src/api.ts
|
|
199
210
|
import { Hono as Hono9 } from "hono";
|
|
@@ -2448,8 +2459,9 @@ async function readViewerTasks(user) {
|
|
|
2448
2459
|
const visible = selected.filter(
|
|
2449
2460
|
(candidate) => candidate.ownedByViewer || destinations.get(destinationKey(candidate.task.destination))?.visibility === "public"
|
|
2450
2461
|
);
|
|
2451
|
-
const [executionDays, scheduledStats, eventStats] = await Promise.all([
|
|
2462
|
+
const [executionDays, executionHours, scheduledStats, eventStats] = await Promise.all([
|
|
2452
2463
|
readTaskExecutionDays(),
|
|
2464
|
+
readTaskExecutionHours(),
|
|
2453
2465
|
readTaskExecutionSummaries("scheduled", "junior"),
|
|
2454
2466
|
readTaskExecutionSummaries("event", "junior")
|
|
2455
2467
|
]);
|
|
@@ -2485,6 +2497,7 @@ async function readViewerTasks(user) {
|
|
|
2485
2497
|
});
|
|
2486
2498
|
return {
|
|
2487
2499
|
executionDays,
|
|
2500
|
+
executionHours,
|
|
2488
2501
|
tasks,
|
|
2489
2502
|
truncated: ownedCandidates.length > TASK_LIST_LIMIT || publicCandidates.length > TASK_LIST_LIMIT
|
|
2490
2503
|
};
|
|
@@ -2518,7 +2531,7 @@ var ViewerTaskNotFoundError = class extends Error {
|
|
|
2518
2531
|
async function readViewerTaskExecutions(user, kind, id) {
|
|
2519
2532
|
const candidate = await resolveViewerTaskCandidate(user, kind, id);
|
|
2520
2533
|
if (!candidate) throw new ViewerTaskNotFoundError();
|
|
2521
|
-
const [task, executions, executionDays] = await Promise.all([
|
|
2534
|
+
const [task, executions, executionDays, executionHours] = await Promise.all([
|
|
2522
2535
|
taskSummaryForCandidate(candidate),
|
|
2523
2536
|
readTaskExecutions({
|
|
2524
2537
|
kind,
|
|
@@ -2528,10 +2541,15 @@ async function readViewerTaskExecutions(user, kind, id) {
|
|
|
2528
2541
|
readTaskExecutionStatusDays({
|
|
2529
2542
|
kind,
|
|
2530
2543
|
taskId: id
|
|
2544
|
+
}),
|
|
2545
|
+
readTaskExecutionStatusHours({
|
|
2546
|
+
kind,
|
|
2547
|
+
taskId: id
|
|
2531
2548
|
})
|
|
2532
2549
|
]);
|
|
2533
2550
|
return {
|
|
2534
2551
|
executionDays,
|
|
2552
|
+
executionHours,
|
|
2535
2553
|
executions: executions.slice(0, TASK_EXECUTION_LIST_LIMIT),
|
|
2536
2554
|
task,
|
|
2537
2555
|
truncated: executions.length > TASK_EXECUTION_LIST_LIMIT
|
|
@@ -3073,6 +3091,27 @@ function statsWindow(nowMs) {
|
|
|
3073
3091
|
start.setUTCDate(start.getUTCDate() - (WINDOW_DAYS - 1));
|
|
3074
3092
|
return { end, start };
|
|
3075
3093
|
}
|
|
3094
|
+
var HOUR_MS2 = 60 * 60 * 1e3;
|
|
3095
|
+
var WINDOW_HOURS = 24;
|
|
3096
|
+
function startOfUtcHour(valueMs) {
|
|
3097
|
+
const date = new Date(valueMs);
|
|
3098
|
+
date.setUTCMinutes(0, 0, 0);
|
|
3099
|
+
return date;
|
|
3100
|
+
}
|
|
3101
|
+
function utcHourKey2(value) {
|
|
3102
|
+
return value.toISOString().slice(0, 13);
|
|
3103
|
+
}
|
|
3104
|
+
function metricPoint(date, row) {
|
|
3105
|
+
return {
|
|
3106
|
+
conversations: row?.conversations ?? 0,
|
|
3107
|
+
date,
|
|
3108
|
+
durationMs: row?.durationMs ?? 0,
|
|
3109
|
+
...row?.cachedInputTokens !== null && row?.cachedInputTokens !== void 0 ? { cachedInputTokens: row.cachedInputTokens } : void 0,
|
|
3110
|
+
...row?.costUsd !== null && row?.costUsd !== void 0 ? { costUsd: addUsd(void 0, row.costUsd) } : void 0,
|
|
3111
|
+
...row?.inputTokens !== null && row?.inputTokens !== void 0 ? { inputTokens: row.inputTokens } : void 0,
|
|
3112
|
+
...row?.tokens !== null && row?.tokens !== void 0 ? { tokens: row.tokens } : void 0
|
|
3113
|
+
};
|
|
3114
|
+
}
|
|
3076
3115
|
function metricDays(rows, endMs) {
|
|
3077
3116
|
const byDate = new Map(rows.map((row) => [row.date, row]));
|
|
3078
3117
|
const end = new Date(endMs);
|
|
@@ -3082,21 +3121,33 @@ function metricDays(rows, endMs) {
|
|
|
3082
3121
|
const days = [];
|
|
3083
3122
|
for (const cursor = new Date(start); cursor.getTime() <= end.getTime(); cursor.setUTCDate(cursor.getUTCDate() + 1)) {
|
|
3084
3123
|
const date = cursor.toISOString().slice(0, 10);
|
|
3085
|
-
|
|
3086
|
-
days.push({
|
|
3087
|
-
conversations: row?.conversations ?? 0,
|
|
3088
|
-
date,
|
|
3089
|
-
durationMs: row?.durationMs ?? 0,
|
|
3090
|
-
...row?.cachedInputTokens !== null && row?.cachedInputTokens !== void 0 ? { cachedInputTokens: row.cachedInputTokens } : void 0,
|
|
3091
|
-
...row?.costUsd !== null && row?.costUsd !== void 0 ? { costUsd: addUsd(void 0, row.costUsd) } : void 0,
|
|
3092
|
-
...row?.inputTokens !== null && row?.inputTokens !== void 0 ? { inputTokens: row.inputTokens } : void 0,
|
|
3093
|
-
...row?.tokens !== null && row?.tokens !== void 0 ? { tokens: row.tokens } : void 0
|
|
3094
|
-
});
|
|
3124
|
+
days.push(metricPoint(date, byDate.get(date)));
|
|
3095
3125
|
}
|
|
3096
3126
|
return days;
|
|
3097
3127
|
}
|
|
3098
|
-
function
|
|
3099
|
-
const
|
|
3128
|
+
function metricHours(rows, endMs) {
|
|
3129
|
+
const byHour = new Map(rows.map((row) => [row.date, row]));
|
|
3130
|
+
const end = startOfUtcHour(endMs);
|
|
3131
|
+
const start = new Date(end.getTime() - (WINDOW_HOURS - 1) * HOUR_MS2);
|
|
3132
|
+
const hours = [];
|
|
3133
|
+
for (const cursor = new Date(start); cursor.getTime() <= end.getTime(); cursor.setTime(cursor.getTime() + HOUR_MS2)) {
|
|
3134
|
+
const date = utcHourKey2(cursor);
|
|
3135
|
+
hours.push(metricPoint(date, byHour.get(date)));
|
|
3136
|
+
}
|
|
3137
|
+
return hours;
|
|
3138
|
+
}
|
|
3139
|
+
function guardianPoint(date, row) {
|
|
3140
|
+
return {
|
|
3141
|
+
allow: row?.allow ?? 0,
|
|
3142
|
+
ask: row?.ask ?? 0,
|
|
3143
|
+
date,
|
|
3144
|
+
deny: row?.deny ?? 0,
|
|
3145
|
+
requests: row?.requests ?? 0,
|
|
3146
|
+
...row?.costUsd !== null && row?.costUsd !== void 0 ? { costUsd: row.costUsd } : void 0
|
|
3147
|
+
};
|
|
3148
|
+
}
|
|
3149
|
+
function guardianStats(dayRows, hourRows, endMs) {
|
|
3150
|
+
const byDate = new Map(dayRows.map((row) => [row.date, row]));
|
|
3100
3151
|
const end = new Date(endMs);
|
|
3101
3152
|
end.setUTCHours(0, 0, 0, 0);
|
|
3102
3153
|
const start = new Date(end);
|
|
@@ -3117,20 +3168,22 @@ function guardianStats(rows, endMs) {
|
|
|
3117
3168
|
if (row?.costUsd !== null && row?.costUsd !== void 0) {
|
|
3118
3169
|
costUsd = addUsd(costUsd, row.costUsd);
|
|
3119
3170
|
}
|
|
3120
|
-
metricDays2.push(
|
|
3121
|
-
|
|
3122
|
-
|
|
3123
|
-
|
|
3124
|
-
|
|
3125
|
-
|
|
3126
|
-
|
|
3127
|
-
|
|
3171
|
+
metricDays2.push(guardianPoint(date, row));
|
|
3172
|
+
}
|
|
3173
|
+
const byHour = new Map(hourRows.map((row) => [row.date, row]));
|
|
3174
|
+
const hourEnd = startOfUtcHour(endMs);
|
|
3175
|
+
const hourStart = new Date(hourEnd.getTime() - (WINDOW_HOURS - 1) * HOUR_MS2);
|
|
3176
|
+
const metricHours2 = [];
|
|
3177
|
+
for (const cursor = new Date(hourStart); cursor.getTime() <= hourEnd.getTime(); cursor.setTime(cursor.getTime() + HOUR_MS2)) {
|
|
3178
|
+
const date = utcHourKey2(cursor);
|
|
3179
|
+
metricHours2.push(guardianPoint(date, byHour.get(date)));
|
|
3128
3180
|
}
|
|
3129
3181
|
return {
|
|
3130
3182
|
allow,
|
|
3131
3183
|
ask,
|
|
3132
3184
|
deny,
|
|
3133
3185
|
metricDays: metricDays2,
|
|
3186
|
+
metricHours: metricHours2,
|
|
3134
3187
|
requests,
|
|
3135
3188
|
...costUsd !== void 0 ? { costUsd } : void 0
|
|
3136
3189
|
};
|
|
@@ -3141,7 +3194,17 @@ async function aggregateStats(db, start, end) {
|
|
|
3141
3194
|
${juniorConversations.lastActivityAt} AT TIME ZONE 'UTC',
|
|
3142
3195
|
'YYYY-MM-DD'
|
|
3143
3196
|
)`;
|
|
3144
|
-
const
|
|
3197
|
+
const activityHour = sql10`TO_CHAR(
|
|
3198
|
+
${juniorConversations.lastActivityAt} AT TIME ZONE 'UTC',
|
|
3199
|
+
'YYYY-MM-DD"T"HH24'
|
|
3200
|
+
)`;
|
|
3201
|
+
const [
|
|
3202
|
+
totalsRows,
|
|
3203
|
+
actorRows,
|
|
3204
|
+
locationRows,
|
|
3205
|
+
metricRows,
|
|
3206
|
+
metricHourRows
|
|
3207
|
+
] = await Promise.all([
|
|
3145
3208
|
db.select(treeAggregateColumns).from(juniorConversations).innerJoin(
|
|
3146
3209
|
treeConversation,
|
|
3147
3210
|
eq10(
|
|
@@ -3213,41 +3276,72 @@ async function aggregateStats(db, start, end) {
|
|
|
3213
3276
|
treeConversation.rootConversationId,
|
|
3214
3277
|
juniorConversations.conversationId
|
|
3215
3278
|
)
|
|
3216
|
-
).where(where).groupBy(activityDate)
|
|
3279
|
+
).where(where).groupBy(activityDate),
|
|
3280
|
+
db.select({
|
|
3281
|
+
cachedInputTokens: treeAggregateColumns.cachedInputTokens,
|
|
3282
|
+
conversations: treeAggregateColumns.conversations,
|
|
3283
|
+
costUsd: treeAggregateColumns.costUsd,
|
|
3284
|
+
date: activityHour,
|
|
3285
|
+
durationMs: treeAggregateColumns.durationMs,
|
|
3286
|
+
inputTokens: treeAggregateColumns.inputTokens,
|
|
3287
|
+
tokens: treeAggregateColumns.tokens
|
|
3288
|
+
}).from(juniorConversations).innerJoin(
|
|
3289
|
+
treeConversation,
|
|
3290
|
+
eq10(
|
|
3291
|
+
treeConversation.rootConversationId,
|
|
3292
|
+
juniorConversations.conversationId
|
|
3293
|
+
)
|
|
3294
|
+
).where(where).groupBy(activityHour)
|
|
3217
3295
|
]);
|
|
3218
|
-
return {
|
|
3296
|
+
return {
|
|
3297
|
+
actorRows,
|
|
3298
|
+
locationRows,
|
|
3299
|
+
metricHourRows,
|
|
3300
|
+
metricRows,
|
|
3301
|
+
totals: totalsRows[0]
|
|
3302
|
+
};
|
|
3219
3303
|
}
|
|
3220
3304
|
async function aggregateGuardianStats(db, start, end) {
|
|
3221
|
-
const
|
|
3305
|
+
const day = sql10`TO_CHAR(
|
|
3222
3306
|
${juniorConversationEvents.createdAt} AT TIME ZONE 'UTC',
|
|
3223
3307
|
'YYYY-MM-DD'
|
|
3224
3308
|
)`;
|
|
3309
|
+
const hour = sql10`TO_CHAR(
|
|
3310
|
+
${juniorConversationEvents.createdAt} AT TIME ZONE 'UTC',
|
|
3311
|
+
'YYYY-MM-DD"T"HH24'
|
|
3312
|
+
)`;
|
|
3225
3313
|
const decision = sql10`${juniorConversationEvents.payload}->>'decision'`;
|
|
3226
3314
|
const cost2 = sql10`CASE
|
|
3227
3315
|
WHEN jsonb_typeof(${juniorConversationEvents.payload}->'costUsd') = 'number'
|
|
3228
3316
|
THEN (${juniorConversationEvents.payload}->>'costUsd')::double precision
|
|
3229
3317
|
ELSE NULL
|
|
3230
3318
|
END`;
|
|
3231
|
-
|
|
3319
|
+
const selectColumns = {
|
|
3232
3320
|
allow: sql10`COUNT(*) FILTER (WHERE ${decision} = 'allow')::integer`,
|
|
3233
3321
|
ask: sql10`COUNT(*) FILTER (WHERE ${decision} = 'ask')::integer`,
|
|
3234
3322
|
costUsd: sql10`SUM(${cost2})::double precision`,
|
|
3235
|
-
date,
|
|
3236
3323
|
deny: sql10`COUNT(*) FILTER (WHERE ${decision} = 'deny')::integer`,
|
|
3237
3324
|
requests: sql10`COUNT(*)::integer`
|
|
3238
|
-
}
|
|
3239
|
-
|
|
3240
|
-
|
|
3241
|
-
|
|
3242
|
-
|
|
3243
|
-
|
|
3244
|
-
|
|
3325
|
+
};
|
|
3326
|
+
const where = and10(
|
|
3327
|
+
eq10(juniorConversationEvents.type, "guardian_action_reviewed"),
|
|
3328
|
+
gte(juniorConversationEvents.createdAt, start),
|
|
3329
|
+
lte(juniorConversationEvents.createdAt, end)
|
|
3330
|
+
);
|
|
3331
|
+
const [dayRows, hourRows] = await Promise.all([
|
|
3332
|
+
db.select({ ...selectColumns, date: day }).from(juniorConversationEvents).where(where).groupBy(day),
|
|
3333
|
+
db.select({ ...selectColumns, date: hour }).from(juniorConversationEvents).where(where).groupBy(hour)
|
|
3334
|
+
]);
|
|
3335
|
+
return { dayRows, hourRows };
|
|
3245
3336
|
}
|
|
3246
3337
|
async function readConversationStatsFromSql() {
|
|
3247
3338
|
const nowMs = Date.now();
|
|
3248
3339
|
const { end, start } = statsWindow(nowMs);
|
|
3249
3340
|
const db = getDb();
|
|
3250
|
-
const [
|
|
3341
|
+
const [
|
|
3342
|
+
{ actorRows, locationRows, metricHourRows, metricRows, totals },
|
|
3343
|
+
guardian
|
|
3344
|
+
] = await Promise.all([
|
|
3251
3345
|
aggregateStats(db, start, end),
|
|
3252
3346
|
aggregateGuardianStats(db, start, end)
|
|
3253
3347
|
]);
|
|
@@ -3266,8 +3360,9 @@ async function readConversationStatsFromSql() {
|
|
|
3266
3360
|
durationMs: totals?.durationMs ?? 0,
|
|
3267
3361
|
failed: totals?.failed ?? 0,
|
|
3268
3362
|
generatedAt: new Date(nowMs).toISOString(),
|
|
3269
|
-
guardian: guardianStats(
|
|
3363
|
+
guardian: guardianStats(guardian.dayRows, guardian.hourRows, nowMs),
|
|
3270
3364
|
metricDays: metricDays(metricRows, nowMs),
|
|
3365
|
+
metricHours: metricHours(metricHourRows, nowMs),
|
|
3271
3366
|
locations: statsItems(locations),
|
|
3272
3367
|
actors: statsItems(actors),
|
|
3273
3368
|
source: "conversation_index",
|
|
@@ -3503,7 +3598,7 @@ import { Hono as Hono2 } from "hono";
|
|
|
3503
3598
|
// src/api/code/overview.ts
|
|
3504
3599
|
import { desc as desc4, eq as eq11, gte as gte2, or as or5, sql as sql11 } from "drizzle-orm";
|
|
3505
3600
|
import { z as z5 } from "zod";
|
|
3506
|
-
var
|
|
3601
|
+
var DAY_MS2 = 24 * 60 * 60 * 1e3;
|
|
3507
3602
|
var WINDOW_DAYS2 = 30;
|
|
3508
3603
|
var ACTIVITY_DAYS = 90;
|
|
3509
3604
|
var summaryRowSchema = z5.object({
|
|
@@ -3537,7 +3632,7 @@ var repositoryRowSchema = z5.object({
|
|
|
3537
3632
|
var activityDaySchema = z5.object({
|
|
3538
3633
|
closed: z5.number().int().nonnegative(),
|
|
3539
3634
|
created: z5.number().int().nonnegative(),
|
|
3540
|
-
date: z5.string().
|
|
3635
|
+
date: z5.string().regex(/^\d{4}-\d{2}-\d{2}(T\d{2})?$/),
|
|
3541
3636
|
merged: z5.number().int().nonnegative()
|
|
3542
3637
|
}).strict();
|
|
3543
3638
|
function queryRows(result) {
|
|
@@ -3602,12 +3697,17 @@ function ownershipFilter(userId) {
|
|
|
3602
3697
|
async function readCodeWindows(args) {
|
|
3603
3698
|
const db = getDb();
|
|
3604
3699
|
const windowEnd = new Date(args.nowMs);
|
|
3605
|
-
const windowStart = new Date(args.nowMs - WINDOW_DAYS2 *
|
|
3606
|
-
const activityStart = startOfUtcDay(args.nowMs - (ACTIVITY_DAYS - 1) *
|
|
3700
|
+
const windowStart = new Date(args.nowMs - WINDOW_DAYS2 * DAY_MS2);
|
|
3701
|
+
const activityStart = startOfUtcDay(args.nowMs - (ACTIVITY_DAYS - 1) * DAY_MS2);
|
|
3607
3702
|
const changes = juniorCodeChanges;
|
|
3608
3703
|
const ownership = ownershipFilter(args.userId);
|
|
3609
3704
|
const conversationTreeCost = conversationTreeCostExpr();
|
|
3610
|
-
const
|
|
3705
|
+
const activityHourEnd = new Date(args.nowMs);
|
|
3706
|
+
activityHourEnd.setUTCMinutes(0, 0, 0);
|
|
3707
|
+
const activityHourStart = new Date(
|
|
3708
|
+
activityHourEnd.getTime() - 23 * (DAY_MS2 / 24)
|
|
3709
|
+
);
|
|
3710
|
+
const [summaryResult, activityResult, activityHourResult] = await Promise.all([
|
|
3611
3711
|
db.execute(sql11`
|
|
3612
3712
|
WITH recent_changes AS (
|
|
3613
3713
|
SELECT
|
|
@@ -3707,6 +3807,47 @@ async function readCodeWindows(args) {
|
|
|
3707
3807
|
FROM days
|
|
3708
3808
|
LEFT JOIN daily ON daily.day = days.day
|
|
3709
3809
|
ORDER BY days.day
|
|
3810
|
+
`),
|
|
3811
|
+
db.execute(sql11`
|
|
3812
|
+
WITH hours AS (
|
|
3813
|
+
SELECT generate_series(
|
|
3814
|
+
date_trunc('hour', ${activityHourStart}::timestamptz AT TIME ZONE 'UTC'),
|
|
3815
|
+
date_trunc('hour', ${activityHourEnd}::timestamptz AT TIME ZONE 'UTC'),
|
|
3816
|
+
interval '1 hour'
|
|
3817
|
+
) AS hour
|
|
3818
|
+
), hourly AS (
|
|
3819
|
+
SELECT
|
|
3820
|
+
date_trunc('hour', event_at AT TIME ZONE 'UTC') AS hour,
|
|
3821
|
+
count(*) FILTER (WHERE kind = 'created')::integer AS created,
|
|
3822
|
+
count(*) FILTER (WHERE kind = 'merged')::integer AS merged,
|
|
3823
|
+
count(*) FILTER (WHERE kind = 'closed')::integer AS closed
|
|
3824
|
+
FROM (
|
|
3825
|
+
SELECT ${changes.openedAt} AS event_at, 'created'::text AS kind
|
|
3826
|
+
FROM ${changes}
|
|
3827
|
+
WHERE ${changes.openedAt} >= ${activityHourStart}
|
|
3828
|
+
${ownership ? sql11`AND ${ownership}` : sql11``}
|
|
3829
|
+
UNION ALL
|
|
3830
|
+
SELECT ${changes.mergedAt} AS event_at, 'merged'::text AS kind
|
|
3831
|
+
FROM ${changes}
|
|
3832
|
+
WHERE ${changes.mergedAt} >= ${activityHourStart}
|
|
3833
|
+
${ownership ? sql11`AND ${ownership}` : sql11``}
|
|
3834
|
+
UNION ALL
|
|
3835
|
+
SELECT ${changes.closedAt} AS event_at, 'closed'::text AS kind
|
|
3836
|
+
FROM ${changes}
|
|
3837
|
+
WHERE ${changes.state} = 'closed'
|
|
3838
|
+
AND ${changes.closedAt} >= ${activityHourStart}
|
|
3839
|
+
${ownership ? sql11`AND ${ownership}` : sql11``}
|
|
3840
|
+
) AS events
|
|
3841
|
+
GROUP BY date_trunc('hour', event_at AT TIME ZONE 'UTC')
|
|
3842
|
+
)
|
|
3843
|
+
SELECT
|
|
3844
|
+
to_char(hours.hour, 'YYYY-MM-DD"T"HH24') AS "date",
|
|
3845
|
+
coalesce(hourly.created, 0)::integer AS "created",
|
|
3846
|
+
coalesce(hourly.merged, 0)::integer AS "merged",
|
|
3847
|
+
coalesce(hourly.closed, 0)::integer AS "closed"
|
|
3848
|
+
FROM hours
|
|
3849
|
+
LEFT JOIN hourly ON hourly.hour = hours.hour
|
|
3850
|
+
ORDER BY hours.hour
|
|
3710
3851
|
`)
|
|
3711
3852
|
]);
|
|
3712
3853
|
const summary = summaryRowSchema.parse(
|
|
@@ -3722,6 +3863,7 @@ async function readCodeWindows(args) {
|
|
|
3722
3863
|
);
|
|
3723
3864
|
return {
|
|
3724
3865
|
activityDays: z5.array(activityDaySchema).parse(queryRows(activityResult)),
|
|
3866
|
+
activityHours: z5.array(activityDaySchema).parse(queryRows(activityHourResult)),
|
|
3725
3867
|
summary: {
|
|
3726
3868
|
...summary,
|
|
3727
3869
|
mergeRate: mergeRate(summary.merged, summary.closed)
|
|
@@ -3818,6 +3960,7 @@ async function readCodeOverview(nowMs = Date.now()) {
|
|
|
3818
3960
|
]);
|
|
3819
3961
|
return codeOverviewReportSchema.parse({
|
|
3820
3962
|
activityDays: windows.activityDays,
|
|
3963
|
+
activityHours: windows.activityHours,
|
|
3821
3964
|
changes: recentChanges.map((change) => ({
|
|
3822
3965
|
...change,
|
|
3823
3966
|
closedAt: change.closedAt?.toISOString(),
|
|
@@ -3845,6 +3988,7 @@ async function readPersonCodeOverview(args) {
|
|
|
3845
3988
|
});
|
|
3846
3989
|
return codePersonReportSchema.parse({
|
|
3847
3990
|
activityDays: windows.activityDays,
|
|
3991
|
+
activityHours: windows.activityHours,
|
|
3848
3992
|
generatedAt: windows.windowEnd.toISOString(),
|
|
3849
3993
|
summary: windows.summary,
|
|
3850
3994
|
windowEnd: windows.windowEnd.toISOString(),
|
|
@@ -4037,28 +4181,49 @@ async function directoryRows(db) {
|
|
|
4037
4181
|
eq12(juniorDestinations.id, juniorConversations.destinationId)
|
|
4038
4182
|
).where(topLevelWhere()).groupBy(...locationGroupBy());
|
|
4039
4183
|
}
|
|
4040
|
-
async function directoryActivityRows(db, start) {
|
|
4041
|
-
const
|
|
4184
|
+
async function directoryActivityRows(db, start, hourStart) {
|
|
4185
|
+
const day = sql12`TO_CHAR(
|
|
4042
4186
|
${juniorConversations.lastActivityAt} AT TIME ZONE 'UTC',
|
|
4043
4187
|
'YYYY-MM-DD'
|
|
4044
4188
|
)`;
|
|
4045
|
-
|
|
4189
|
+
const hour = sql12`TO_CHAR(
|
|
4190
|
+
${juniorConversations.lastActivityAt} AT TIME ZONE 'UTC',
|
|
4191
|
+
'YYYY-MM-DD"T"HH24'
|
|
4192
|
+
)`;
|
|
4193
|
+
const select = {
|
|
4046
4194
|
conversations: sql12`COUNT(*)::integer`,
|
|
4047
|
-
date,
|
|
4048
4195
|
visibility: juniorDestinations.visibility
|
|
4049
|
-
}
|
|
4050
|
-
|
|
4051
|
-
|
|
4052
|
-
|
|
4196
|
+
};
|
|
4197
|
+
const [dayRows, hourRows] = await Promise.all([
|
|
4198
|
+
db.select({ ...select, date: day }).from(juniorConversations).leftJoin(
|
|
4199
|
+
juniorDestinations,
|
|
4200
|
+
eq12(juniorDestinations.id, juniorConversations.destinationId)
|
|
4201
|
+
).where(
|
|
4202
|
+
and11(topLevelWhere(), gte3(juniorConversations.lastActivityAt, start))
|
|
4203
|
+
).groupBy(day, juniorDestinations.visibility),
|
|
4204
|
+
db.select({ ...select, date: hour }).from(juniorConversations).leftJoin(
|
|
4205
|
+
juniorDestinations,
|
|
4206
|
+
eq12(juniorDestinations.id, juniorConversations.destinationId)
|
|
4207
|
+
).where(
|
|
4208
|
+
and11(
|
|
4209
|
+
topLevelWhere(),
|
|
4210
|
+
gte3(juniorConversations.lastActivityAt, hourStart)
|
|
4211
|
+
)
|
|
4212
|
+
).groupBy(hour, juniorDestinations.visibility)
|
|
4213
|
+
]);
|
|
4214
|
+
return { dayRows, hourRows };
|
|
4053
4215
|
}
|
|
4054
|
-
function
|
|
4216
|
+
function emptyLocationActivityDay(date) {
|
|
4217
|
+
return {
|
|
4218
|
+
date,
|
|
4219
|
+
privateConversations: 0,
|
|
4220
|
+
publicConversations: 0
|
|
4221
|
+
};
|
|
4222
|
+
}
|
|
4223
|
+
function accumulateLocationActivity(rows) {
|
|
4055
4224
|
const days = /* @__PURE__ */ new Map();
|
|
4056
4225
|
for (const row of rows) {
|
|
4057
|
-
const day = days.get(row.date) ??
|
|
4058
|
-
date: row.date,
|
|
4059
|
-
privateConversations: 0,
|
|
4060
|
-
publicConversations: 0
|
|
4061
|
-
};
|
|
4226
|
+
const day = days.get(row.date) ?? emptyLocationActivityDay(row.date);
|
|
4062
4227
|
if (row.visibility === "public") {
|
|
4063
4228
|
day.publicConversations += row.conversations;
|
|
4064
4229
|
} else {
|
|
@@ -4066,32 +4231,30 @@ function directoryActivityDays(rows, nowMs) {
|
|
|
4066
4231
|
}
|
|
4067
4232
|
days.set(row.date, day);
|
|
4068
4233
|
}
|
|
4069
|
-
|
|
4070
|
-
|
|
4071
|
-
|
|
4072
|
-
|
|
4073
|
-
|
|
4074
|
-
|
|
4075
|
-
|
|
4076
|
-
|
|
4077
|
-
|
|
4078
|
-
|
|
4079
|
-
|
|
4080
|
-
|
|
4081
|
-
|
|
4082
|
-
|
|
4083
|
-
|
|
4084
|
-
|
|
4234
|
+
return days;
|
|
4235
|
+
}
|
|
4236
|
+
function directoryActivityDays(rows, nowMs) {
|
|
4237
|
+
return fillUtcDays({
|
|
4238
|
+
count: ACTIVITY_DAYS2,
|
|
4239
|
+
empty: emptyLocationActivityDay,
|
|
4240
|
+
nowMs,
|
|
4241
|
+
rows: accumulateLocationActivity(rows)
|
|
4242
|
+
});
|
|
4243
|
+
}
|
|
4244
|
+
function directoryActivityHours(rows, nowMs) {
|
|
4245
|
+
return fillUtcHours({
|
|
4246
|
+
empty: emptyLocationActivityDay,
|
|
4247
|
+
nowMs,
|
|
4248
|
+
rows: accumulateLocationActivity(rows)
|
|
4249
|
+
});
|
|
4085
4250
|
}
|
|
4086
4251
|
async function readLocationDirectoryFromSql() {
|
|
4087
4252
|
const nowMs = Date.now();
|
|
4088
|
-
const end =
|
|
4089
|
-
|
|
4090
|
-
const
|
|
4091
|
-
start.setUTCDate(start.getUTCDate() - (ACTIVITY_DAYS2 - 1));
|
|
4092
|
-
const [rows, activityRows] = await Promise.all([
|
|
4253
|
+
const { end, start } = trailingUtcDayWindow(nowMs, ACTIVITY_DAYS2);
|
|
4254
|
+
const hourWindow = trailingUtcHourWindow(nowMs);
|
|
4255
|
+
const [rows, activity] = await Promise.all([
|
|
4093
4256
|
directoryRows(getDb()),
|
|
4094
|
-
directoryActivityRows(getDb(), start)
|
|
4257
|
+
directoryActivityRows(getDb(), start, hourWindow.start)
|
|
4095
4258
|
]);
|
|
4096
4259
|
const locations = [];
|
|
4097
4260
|
const privateActivity = {
|
|
@@ -4104,7 +4267,8 @@ async function readLocationDirectoryFromSql() {
|
|
|
4104
4267
|
else addMetrics(privateActivity, row);
|
|
4105
4268
|
}
|
|
4106
4269
|
return {
|
|
4107
|
-
activityDays: directoryActivityDays(
|
|
4270
|
+
activityDays: directoryActivityDays(activity.dayRows, nowMs),
|
|
4271
|
+
activityHours: directoryActivityHours(activity.hourRows, nowMs),
|
|
4108
4272
|
generatedAt: new Date(nowMs).toISOString(),
|
|
4109
4273
|
locations: locations.sort(
|
|
4110
4274
|
(left, right) => Date.parse(right.lastSeenAt) - Date.parse(left.lastSeenAt) || right.conversations - left.conversations || left.label.localeCompare(right.label)
|
|
@@ -4153,16 +4317,18 @@ async function recentLocationRows(db, locationId) {
|
|
|
4153
4317
|
}
|
|
4154
4318
|
async function readLocationDetailFromSql(locationId, options = {}) {
|
|
4155
4319
|
const nowMs = Date.now();
|
|
4156
|
-
const end =
|
|
4157
|
-
|
|
4158
|
-
const start = new Date(end);
|
|
4159
|
-
start.setUTCDate(start.getUTCDate() - (ACTIVITY_DAYS2 - 1));
|
|
4320
|
+
const { end, start } = trailingUtcDayWindow(nowMs, ACTIVITY_DAYS2);
|
|
4321
|
+
const hourWindow = trailingUtcHourWindow(nowMs);
|
|
4160
4322
|
const where = publicLocationWhere(locationId);
|
|
4161
4323
|
const activityDate = sql12`TO_CHAR(
|
|
4162
4324
|
${juniorConversations.lastActivityAt} AT TIME ZONE 'UTC',
|
|
4163
4325
|
'YYYY-MM-DD'
|
|
4164
4326
|
)`;
|
|
4165
|
-
const
|
|
4327
|
+
const activityHour = sql12`TO_CHAR(
|
|
4328
|
+
${juniorConversations.lastActivityAt} AT TIME ZONE 'UTC',
|
|
4329
|
+
'YYYY-MM-DD"T"HH24'
|
|
4330
|
+
)`;
|
|
4331
|
+
const [locationRows, dayRows, hourRows, actorRows, recentRows] = await Promise.all([
|
|
4166
4332
|
getDb().select({
|
|
4167
4333
|
...locationColumns(),
|
|
4168
4334
|
...treeAggregateColumns2,
|
|
@@ -4190,6 +4356,21 @@ async function readLocationDetailFromSql(locationId, options = {}) {
|
|
|
4190
4356
|
juniorDestinations,
|
|
4191
4357
|
eq12(juniorDestinations.id, juniorConversations.destinationId)
|
|
4192
4358
|
).where(and11(where, gte3(juniorConversations.lastActivityAt, start))).groupBy(activityDate),
|
|
4359
|
+
getDb().select({
|
|
4360
|
+
date: activityHour,
|
|
4361
|
+
...treeAggregateColumns2
|
|
4362
|
+
}).from(juniorConversations).innerJoin(
|
|
4363
|
+
treeConversation2,
|
|
4364
|
+
eq12(
|
|
4365
|
+
treeConversation2.rootConversationId,
|
|
4366
|
+
juniorConversations.conversationId
|
|
4367
|
+
)
|
|
4368
|
+
).innerJoin(
|
|
4369
|
+
juniorDestinations,
|
|
4370
|
+
eq12(juniorDestinations.id, juniorConversations.destinationId)
|
|
4371
|
+
).where(
|
|
4372
|
+
and11(where, gte3(juniorConversations.lastActivityAt, hourWindow.start))
|
|
4373
|
+
).groupBy(activityHour),
|
|
4193
4374
|
getDb().select({
|
|
4194
4375
|
actorIdentityId: juniorConversations.actorIdentityId,
|
|
4195
4376
|
email: juniorUsers.primaryEmailNormalized,
|
|
@@ -4236,6 +4417,17 @@ async function readLocationDetailFromSql(locationId, options = {}) {
|
|
|
4236
4417
|
...row.tokens !== null ? { tokens: row.tokens } : void 0
|
|
4237
4418
|
});
|
|
4238
4419
|
}
|
|
4420
|
+
const hours = /* @__PURE__ */ new Map();
|
|
4421
|
+
for (const row of hourRows) {
|
|
4422
|
+
hours.set(row.date, {
|
|
4423
|
+
active: row.active,
|
|
4424
|
+
conversations: row.conversations,
|
|
4425
|
+
date: row.date,
|
|
4426
|
+
durationMs: row.durationMs,
|
|
4427
|
+
failed: row.failed,
|
|
4428
|
+
...row.tokens !== null ? { tokens: row.tokens } : void 0
|
|
4429
|
+
});
|
|
4430
|
+
}
|
|
4239
4431
|
const actors = [];
|
|
4240
4432
|
for (const row of actorRows) {
|
|
4241
4433
|
if (!row.actorIdentityId) continue;
|
|
@@ -4251,6 +4443,7 @@ async function readLocationDetailFromSql(locationId, options = {}) {
|
|
|
4251
4443
|
actors.push(item);
|
|
4252
4444
|
}
|
|
4253
4445
|
const activity = activityDays(days, nowMs, ACTIVITY_DAYS2);
|
|
4446
|
+
const hourlyActivity = activityHours(hours, nowMs);
|
|
4254
4447
|
const recentConversationIds = recentRows.map((row) => row.conversationId);
|
|
4255
4448
|
const [accessByConversation, metricsByRoot] = await Promise.all([
|
|
4256
4449
|
readConversationAccessFromSql(
|
|
@@ -4263,6 +4456,7 @@ async function readLocationDetailFromSql(locationId, options = {}) {
|
|
|
4263
4456
|
return {
|
|
4264
4457
|
...location,
|
|
4265
4458
|
activityDays: activity,
|
|
4459
|
+
activityHours: hourlyActivity,
|
|
4266
4460
|
actors: actors.sort(
|
|
4267
4461
|
(left, right) => right.conversations - left.conversations || left.label.localeCompare(right.label)
|
|
4268
4462
|
),
|
|
@@ -4430,16 +4624,19 @@ function emptyActivityDay(date) {
|
|
|
4430
4624
|
};
|
|
4431
4625
|
}
|
|
4432
4626
|
function activityDays2(days, nowMs) {
|
|
4433
|
-
|
|
4434
|
-
|
|
4435
|
-
|
|
4436
|
-
|
|
4437
|
-
|
|
4438
|
-
|
|
4439
|
-
|
|
4440
|
-
|
|
4441
|
-
|
|
4442
|
-
|
|
4627
|
+
return fillUtcDays({
|
|
4628
|
+
count: ACTIVITY_DAYS3,
|
|
4629
|
+
empty: emptyActivityDay,
|
|
4630
|
+
nowMs,
|
|
4631
|
+
rows: days
|
|
4632
|
+
});
|
|
4633
|
+
}
|
|
4634
|
+
function activityHours2(hours, nowMs) {
|
|
4635
|
+
return fillUtcHours({
|
|
4636
|
+
empty: emptyActivityDay,
|
|
4637
|
+
nowMs,
|
|
4638
|
+
rows: hours
|
|
4639
|
+
});
|
|
4443
4640
|
}
|
|
4444
4641
|
function statsItems2(map) {
|
|
4445
4642
|
return [...map.values()].sort(
|
|
@@ -4487,31 +4684,126 @@ async function recentActorRows(email) {
|
|
|
4487
4684
|
|
|
4488
4685
|
// src/api/people/list.query.ts
|
|
4489
4686
|
var DIRECTORY_ACTIVITY_DAYS = 90;
|
|
4490
|
-
|
|
4491
|
-
|
|
4492
|
-
|
|
4493
|
-
|
|
4494
|
-
|
|
4495
|
-
|
|
4687
|
+
var DAY_METRIC_LOOKBACK = 180;
|
|
4688
|
+
var HOUR_METRIC_LOOKBACK = 48;
|
|
4689
|
+
function emptyDirectoryDay(date) {
|
|
4690
|
+
return { activePeople: 0, conversations: 0, date };
|
|
4691
|
+
}
|
|
4692
|
+
function emptyBucket() {
|
|
4693
|
+
return { conversations: 0, costUsd: 0, durationMs: 0 };
|
|
4694
|
+
}
|
|
4695
|
+
function addUsd2(current, next) {
|
|
4696
|
+
return Math.round((current + next) * 1e12) / 1e12;
|
|
4496
4697
|
}
|
|
4497
4698
|
function directoryActivityDays2(rows, nowMs) {
|
|
4498
|
-
|
|
4499
|
-
|
|
4500
|
-
|
|
4501
|
-
|
|
4502
|
-
|
|
4503
|
-
|
|
4699
|
+
return fillUtcDays({
|
|
4700
|
+
count: DIRECTORY_ACTIVITY_DAYS,
|
|
4701
|
+
empty: emptyDirectoryDay,
|
|
4702
|
+
nowMs,
|
|
4703
|
+
rows: new Map(rows.map((row) => [row.date, row]))
|
|
4704
|
+
});
|
|
4705
|
+
}
|
|
4706
|
+
function directoryActivityHours2(rows, nowMs) {
|
|
4707
|
+
return fillUtcHours({
|
|
4708
|
+
empty: emptyDirectoryDay,
|
|
4709
|
+
nowMs,
|
|
4710
|
+
rows: new Map(rows.map((row) => [row.date, row]))
|
|
4711
|
+
});
|
|
4712
|
+
}
|
|
4713
|
+
function sumBuckets(buckets, startMs, endMs, keyFor, stepMs) {
|
|
4714
|
+
const total = emptyBucket();
|
|
4715
|
+
for (let cursor = startMs; cursor <= endMs; cursor += stepMs) {
|
|
4716
|
+
const bucket = buckets.get(keyFor(cursor));
|
|
4717
|
+
if (!bucket) continue;
|
|
4718
|
+
total.conversations += bucket.conversations;
|
|
4719
|
+
total.costUsd = addUsd2(total.costUsd, bucket.costUsd);
|
|
4720
|
+
total.durationMs += bucket.durationMs;
|
|
4721
|
+
}
|
|
4722
|
+
return total;
|
|
4723
|
+
}
|
|
4724
|
+
function rangeWindow(buckets, nowMs, range) {
|
|
4725
|
+
if (range === 1) {
|
|
4726
|
+
const current2 = trailingUtcHourWindow(nowMs, 24);
|
|
4727
|
+
const priorEndMs2 = current2.start.getTime() - HOUR_MS;
|
|
4728
|
+
const priorStartMs2 = priorEndMs2 - 23 * HOUR_MS;
|
|
4729
|
+
const currentTotals2 = sumBuckets(
|
|
4730
|
+
buckets,
|
|
4731
|
+
current2.start.getTime(),
|
|
4732
|
+
current2.end.getTime(),
|
|
4733
|
+
utcHourKey,
|
|
4734
|
+
HOUR_MS
|
|
4735
|
+
);
|
|
4736
|
+
const priorTotals2 = sumBuckets(
|
|
4737
|
+
buckets,
|
|
4738
|
+
priorStartMs2,
|
|
4739
|
+
priorEndMs2,
|
|
4740
|
+
utcHourKey,
|
|
4741
|
+
HOUR_MS
|
|
4742
|
+
);
|
|
4743
|
+
return {
|
|
4744
|
+
conversations: currentTotals2.conversations,
|
|
4745
|
+
costUsd: currentTotals2.costUsd,
|
|
4746
|
+
durationMs: currentTotals2.durationMs,
|
|
4747
|
+
priorCostUsd: priorTotals2.costUsd
|
|
4748
|
+
};
|
|
4504
4749
|
}
|
|
4505
|
-
|
|
4750
|
+
const current = trailingUtcDayWindow(nowMs, range);
|
|
4751
|
+
const priorEndMs = current.start.getTime() - DAY_MS;
|
|
4752
|
+
const priorStartMs = priorEndMs - (range - 1) * DAY_MS;
|
|
4753
|
+
const currentTotals = sumBuckets(
|
|
4754
|
+
buckets,
|
|
4755
|
+
current.start.getTime(),
|
|
4756
|
+
current.end.getTime(),
|
|
4757
|
+
utcDayKey,
|
|
4758
|
+
DAY_MS
|
|
4759
|
+
);
|
|
4760
|
+
const priorTotals = sumBuckets(
|
|
4761
|
+
buckets,
|
|
4762
|
+
priorStartMs,
|
|
4763
|
+
priorEndMs,
|
|
4764
|
+
utcDayKey,
|
|
4765
|
+
DAY_MS
|
|
4766
|
+
);
|
|
4767
|
+
return {
|
|
4768
|
+
conversations: currentTotals.conversations,
|
|
4769
|
+
costUsd: currentTotals.costUsd,
|
|
4770
|
+
durationMs: currentTotals.durationMs,
|
|
4771
|
+
priorCostUsd: priorTotals.costUsd
|
|
4772
|
+
};
|
|
4773
|
+
}
|
|
4774
|
+
function buildActorWindows(args) {
|
|
4775
|
+
return {
|
|
4776
|
+
1: rangeWindow(args.hourBuckets, args.nowMs, 1),
|
|
4777
|
+
7: rangeWindow(args.dayBuckets, args.nowMs, 7),
|
|
4778
|
+
30: rangeWindow(args.dayBuckets, args.nowMs, 30),
|
|
4779
|
+
90: rangeWindow(args.dayBuckets, args.nowMs, 90)
|
|
4780
|
+
};
|
|
4506
4781
|
}
|
|
4507
4782
|
async function readPeopleListFromSql() {
|
|
4508
4783
|
const nowMs = Date.now();
|
|
4509
|
-
const { end, start } =
|
|
4784
|
+
const { end, start } = trailingUtcDayWindow(nowMs, DIRECTORY_ACTIVITY_DAYS);
|
|
4510
4785
|
const activityDate = sql14`TO_CHAR(
|
|
4511
4786
|
${juniorConversations.lastActivityAt} AT TIME ZONE 'UTC',
|
|
4512
4787
|
'YYYY-MM-DD'
|
|
4513
4788
|
)`;
|
|
4514
|
-
const
|
|
4789
|
+
const activityHour = sql14`TO_CHAR(
|
|
4790
|
+
${juniorConversations.lastActivityAt} AT TIME ZONE 'UTC',
|
|
4791
|
+
'YYYY-MM-DD"T"HH24'
|
|
4792
|
+
)`;
|
|
4793
|
+
const hourWindow = trailingUtcHourWindow(nowMs);
|
|
4794
|
+
const dayMetricStart = trailingUtcDayWindow(nowMs, DAY_METRIC_LOOKBACK).start;
|
|
4795
|
+
const hourMetricStart = trailingUtcHourWindow(
|
|
4796
|
+
nowMs,
|
|
4797
|
+
HOUR_METRIC_LOOKBACK
|
|
4798
|
+
).start;
|
|
4799
|
+
const metricsJoin = peopleTreeMetricsJoin();
|
|
4800
|
+
const [
|
|
4801
|
+
rows,
|
|
4802
|
+
activityRows,
|
|
4803
|
+
activityHourRows,
|
|
4804
|
+
dayMetricRows,
|
|
4805
|
+
hourMetricRows
|
|
4806
|
+
] = await Promise.all([
|
|
4515
4807
|
getDb().select({
|
|
4516
4808
|
email: juniorUsers.primaryEmailNormalized,
|
|
4517
4809
|
fullName: juniorUsers.displayName,
|
|
@@ -4523,7 +4815,7 @@ async function readPeopleListFromSql() {
|
|
|
4523
4815
|
}).from(juniorConversations).innerJoin(
|
|
4524
4816
|
juniorIdentities,
|
|
4525
4817
|
eq14(juniorIdentities.id, juniorConversations.actorIdentityId)
|
|
4526
|
-
).innerJoin(juniorUsers, eq14(juniorUsers.id, juniorIdentities.userId)).leftJoin(peopleTreeConversation,
|
|
4818
|
+
).innerJoin(juniorUsers, eq14(juniorUsers.id, juniorIdentities.userId)).leftJoin(peopleTreeConversation, metricsJoin).where(verifiedActorWhere()).groupBy(juniorUsers.primaryEmailNormalized, juniorUsers.displayName),
|
|
4527
4819
|
getDb().select({
|
|
4528
4820
|
activePeople: sql14`COUNT(DISTINCT ${juniorUsers.id})::int`,
|
|
4529
4821
|
conversations: sql14`COUNT(*)::int`,
|
|
@@ -4536,8 +4828,77 @@ async function readPeopleListFromSql() {
|
|
|
4536
4828
|
verifiedActorWhere(),
|
|
4537
4829
|
gte4(juniorConversations.lastActivityAt, start)
|
|
4538
4830
|
)
|
|
4539
|
-
).groupBy(activityDate)
|
|
4831
|
+
).groupBy(activityDate),
|
|
4832
|
+
getDb().select({
|
|
4833
|
+
activePeople: sql14`COUNT(DISTINCT ${juniorUsers.id})::int`,
|
|
4834
|
+
conversations: sql14`COUNT(*)::int`,
|
|
4835
|
+
date: activityHour
|
|
4836
|
+
}).from(juniorConversations).innerJoin(
|
|
4837
|
+
juniorIdentities,
|
|
4838
|
+
eq14(juniorIdentities.id, juniorConversations.actorIdentityId)
|
|
4839
|
+
).innerJoin(juniorUsers, eq14(juniorUsers.id, juniorIdentities.userId)).where(
|
|
4840
|
+
and13(
|
|
4841
|
+
verifiedActorWhere(),
|
|
4842
|
+
gte4(juniorConversations.lastActivityAt, hourWindow.start)
|
|
4843
|
+
)
|
|
4844
|
+
).groupBy(activityHour),
|
|
4845
|
+
getDb().select({
|
|
4846
|
+
email: juniorUsers.primaryEmailNormalized,
|
|
4847
|
+
date: activityDate,
|
|
4848
|
+
conversations: peopleTreeAggregateColumns.conversations,
|
|
4849
|
+
costUsd: peopleTreeAggregateColumns.costUsd,
|
|
4850
|
+
durationMs: peopleTreeAggregateColumns.durationMs
|
|
4851
|
+
}).from(juniorConversations).innerJoin(
|
|
4852
|
+
juniorIdentities,
|
|
4853
|
+
eq14(juniorIdentities.id, juniorConversations.actorIdentityId)
|
|
4854
|
+
).innerJoin(juniorUsers, eq14(juniorUsers.id, juniorIdentities.userId)).leftJoin(peopleTreeConversation, metricsJoin).where(
|
|
4855
|
+
and13(
|
|
4856
|
+
verifiedActorWhere(),
|
|
4857
|
+
gte4(juniorConversations.lastActivityAt, dayMetricStart)
|
|
4858
|
+
)
|
|
4859
|
+
).groupBy(
|
|
4860
|
+
juniorUsers.primaryEmailNormalized,
|
|
4861
|
+
activityDate
|
|
4862
|
+
),
|
|
4863
|
+
getDb().select({
|
|
4864
|
+
email: juniorUsers.primaryEmailNormalized,
|
|
4865
|
+
date: activityHour,
|
|
4866
|
+
conversations: peopleTreeAggregateColumns.conversations,
|
|
4867
|
+
costUsd: peopleTreeAggregateColumns.costUsd,
|
|
4868
|
+
durationMs: peopleTreeAggregateColumns.durationMs
|
|
4869
|
+
}).from(juniorConversations).innerJoin(
|
|
4870
|
+
juniorIdentities,
|
|
4871
|
+
eq14(juniorIdentities.id, juniorConversations.actorIdentityId)
|
|
4872
|
+
).innerJoin(juniorUsers, eq14(juniorUsers.id, juniorIdentities.userId)).leftJoin(peopleTreeConversation, metricsJoin).where(
|
|
4873
|
+
and13(
|
|
4874
|
+
verifiedActorWhere(),
|
|
4875
|
+
gte4(juniorConversations.lastActivityAt, hourMetricStart)
|
|
4876
|
+
)
|
|
4877
|
+
).groupBy(
|
|
4878
|
+
juniorUsers.primaryEmailNormalized,
|
|
4879
|
+
activityHour
|
|
4880
|
+
)
|
|
4540
4881
|
]);
|
|
4882
|
+
const dayBucketsByEmail = /* @__PURE__ */ new Map();
|
|
4883
|
+
for (const row of dayMetricRows) {
|
|
4884
|
+
const buckets = dayBucketsByEmail.get(row.email) ?? /* @__PURE__ */ new Map();
|
|
4885
|
+
buckets.set(row.date, {
|
|
4886
|
+
conversations: row.conversations,
|
|
4887
|
+
costUsd: row.costUsd ?? 0,
|
|
4888
|
+
durationMs: row.durationMs
|
|
4889
|
+
});
|
|
4890
|
+
dayBucketsByEmail.set(row.email, buckets);
|
|
4891
|
+
}
|
|
4892
|
+
const hourBucketsByEmail = /* @__PURE__ */ new Map();
|
|
4893
|
+
for (const row of hourMetricRows) {
|
|
4894
|
+
const buckets = hourBucketsByEmail.get(row.email) ?? /* @__PURE__ */ new Map();
|
|
4895
|
+
buckets.set(row.date, {
|
|
4896
|
+
conversations: row.conversations,
|
|
4897
|
+
costUsd: row.costUsd ?? 0,
|
|
4898
|
+
durationMs: row.durationMs
|
|
4899
|
+
});
|
|
4900
|
+
hourBucketsByEmail.set(row.email, buckets);
|
|
4901
|
+
}
|
|
4541
4902
|
const people = rows.map((row) => {
|
|
4542
4903
|
const actor = {
|
|
4543
4904
|
email: row.email,
|
|
@@ -4554,11 +4915,17 @@ async function readPeopleListFromSql() {
|
|
|
4554
4915
|
firstSeenAt: row.firstSeenAt.toISOString(),
|
|
4555
4916
|
lastSeenAt: row.lastSeenAt.toISOString(),
|
|
4556
4917
|
actor,
|
|
4918
|
+
windows: buildActorWindows({
|
|
4919
|
+
dayBuckets: dayBucketsByEmail.get(row.email) ?? /* @__PURE__ */ new Map(),
|
|
4920
|
+
hourBuckets: hourBucketsByEmail.get(row.email) ?? /* @__PURE__ */ new Map(),
|
|
4921
|
+
nowMs
|
|
4922
|
+
}),
|
|
4557
4923
|
...row.tokens !== null ? { tokens: row.tokens } : void 0
|
|
4558
4924
|
};
|
|
4559
4925
|
});
|
|
4560
4926
|
return {
|
|
4561
4927
|
activityDays: directoryActivityDays2(activityRows, nowMs),
|
|
4928
|
+
activityHours: directoryActivityHours2(activityHourRows, nowMs),
|
|
4562
4929
|
generatedAt: new Date(nowMs).toISOString(),
|
|
4563
4930
|
people: people.sort(
|
|
4564
4931
|
(left, right) => Date.parse(right.lastSeenAt) - Date.parse(left.lastSeenAt) || right.conversations - left.conversations || left.actor.email.localeCompare(right.actor.email)
|
|
@@ -4585,7 +4952,7 @@ async function readPeoplePluginReports(args) {
|
|
|
4585
4952
|
source: "plugins"
|
|
4586
4953
|
});
|
|
4587
4954
|
}
|
|
4588
|
-
const { getPluginProfileReports } = await import("./agent-hooks-
|
|
4955
|
+
const { getPluginProfileReports } = await import("./agent-hooks-3JY76L5X.js");
|
|
4589
4956
|
return pluginOperationalReportFeedSchema.parse({
|
|
4590
4957
|
generatedAt: new Date(nowMs).toISOString(),
|
|
4591
4958
|
reports: await getPluginProfileReports({
|
|
@@ -4606,6 +4973,7 @@ function emptyProfile(email, nowMs) {
|
|
|
4606
4973
|
start.setUTCDate(start.getUTCDate() - (ACTIVITY_DAYS3 - 1));
|
|
4607
4974
|
return {
|
|
4608
4975
|
activityDays: activityDays2(/* @__PURE__ */ new Map(), nowMs),
|
|
4976
|
+
activityHours: activityHours2(/* @__PURE__ */ new Map(), nowMs),
|
|
4609
4977
|
generatedAt: new Date(nowMs).toISOString(),
|
|
4610
4978
|
locations: [],
|
|
4611
4979
|
recentConversations: [],
|
|
@@ -4666,8 +5034,13 @@ async function readPeopleProfileFromSql(email, options = {}) {
|
|
|
4666
5034
|
${juniorConversations.lastActivityAt} AT TIME ZONE 'UTC',
|
|
4667
5035
|
'YYYY-MM-DD'
|
|
4668
5036
|
)`;
|
|
5037
|
+
const activityHour = sql15`TO_CHAR(
|
|
5038
|
+
${juniorConversations.lastActivityAt} AT TIME ZONE 'UTC',
|
|
5039
|
+
'YYYY-MM-DD"T"HH24'
|
|
5040
|
+
)`;
|
|
4669
5041
|
const channel = sql15`SPLIT_PART(${juniorConversations.conversationId}, ':', 2)`;
|
|
4670
|
-
const
|
|
5042
|
+
const hourWindow = trailingUtcHourWindow(nowMs);
|
|
5043
|
+
const [totalsRows, dayRows, hourRows, locationRows, surfaceRows, recentRows] = await Promise.all([
|
|
4671
5044
|
getDb().select({
|
|
4672
5045
|
email: juniorUsers.primaryEmailNormalized,
|
|
4673
5046
|
fullName: juniorUsers.displayName,
|
|
@@ -4686,6 +5059,15 @@ async function readPeopleProfileFromSql(email, options = {}) {
|
|
|
4686
5059
|
juniorIdentities,
|
|
4687
5060
|
eq15(juniorIdentities.id, juniorConversations.actorIdentityId)
|
|
4688
5061
|
).innerJoin(juniorUsers, eq15(juniorUsers.id, juniorIdentities.userId)).leftJoin(peopleTreeConversation, metricsJoin).where(and14(where, gte5(juniorConversations.lastActivityAt, start))).groupBy(activityDate),
|
|
5062
|
+
getDb().select({
|
|
5063
|
+
date: activityHour,
|
|
5064
|
+
...peopleTreeAggregateColumns
|
|
5065
|
+
}).from(juniorConversations).innerJoin(
|
|
5066
|
+
juniorIdentities,
|
|
5067
|
+
eq15(juniorIdentities.id, juniorConversations.actorIdentityId)
|
|
5068
|
+
).innerJoin(juniorUsers, eq15(juniorUsers.id, juniorIdentities.userId)).leftJoin(peopleTreeConversation, metricsJoin).where(
|
|
5069
|
+
and14(where, gte5(juniorConversations.lastActivityAt, hourWindow.start))
|
|
5070
|
+
).groupBy(activityHour),
|
|
4689
5071
|
getDb().select({
|
|
4690
5072
|
channel,
|
|
4691
5073
|
channelName: juniorConversations.channelName,
|
|
@@ -4730,6 +5112,18 @@ async function readPeopleProfileFromSql(email, options = {}) {
|
|
|
4730
5112
|
...row.tokens !== null ? { tokens: row.tokens } : void 0
|
|
4731
5113
|
});
|
|
4732
5114
|
}
|
|
5115
|
+
const hours = /* @__PURE__ */ new Map();
|
|
5116
|
+
for (const row of hourRows) {
|
|
5117
|
+
hours.set(row.date, {
|
|
5118
|
+
active: row.active,
|
|
5119
|
+
conversations: row.conversations,
|
|
5120
|
+
...row.costUsd !== null ? { costUsd: row.costUsd } : void 0,
|
|
5121
|
+
date: row.date,
|
|
5122
|
+
durationMs: row.durationMs,
|
|
5123
|
+
failed: row.failed,
|
|
5124
|
+
...row.tokens !== null ? { tokens: row.tokens } : void 0
|
|
5125
|
+
});
|
|
5126
|
+
}
|
|
4733
5127
|
const locations = /* @__PURE__ */ new Map();
|
|
4734
5128
|
for (const row of locationRows) {
|
|
4735
5129
|
addAggregate2(locations, locationLabel2(row), row);
|
|
@@ -4753,6 +5147,7 @@ async function readPeopleProfileFromSql(email, options = {}) {
|
|
|
4753
5147
|
]);
|
|
4754
5148
|
return {
|
|
4755
5149
|
activityDays: activityDays2(days, nowMs),
|
|
5150
|
+
activityHours: activityHours2(hours, nowMs),
|
|
4756
5151
|
generatedAt: new Date(nowMs).toISOString(),
|
|
4757
5152
|
locations: statsItems2(locations),
|
|
4758
5153
|
recentConversations: recentRows.map(
|
|
@@ -4788,7 +5183,7 @@ async function readPeopleProfile(email, options = {}) {
|
|
|
4788
5183
|
import { and as and15, eq as eq16, gte as gte6, lte as lte2, sql as sql16 } from "drizzle-orm";
|
|
4789
5184
|
var SEVEN_DAY_OFFSET = 6;
|
|
4790
5185
|
var THIRTY_DAY_OFFSET = 29;
|
|
4791
|
-
function
|
|
5186
|
+
function addUsd3(current, next) {
|
|
4792
5187
|
return Math.round((current + next) * 1e12) / 1e12;
|
|
4793
5188
|
}
|
|
4794
5189
|
function spendWindow(nowMs) {
|
|
@@ -4827,9 +5222,9 @@ async function readPersonalSpendFromSql(email, nowMs = Date.now()) {
|
|
|
4827
5222
|
let thirtyDaysUsd = 0;
|
|
4828
5223
|
for (const row of rows) {
|
|
4829
5224
|
if (row.costUsd === null) continue;
|
|
4830
|
-
thirtyDaysUsd =
|
|
5225
|
+
thirtyDaysUsd = addUsd3(thirtyDaysUsd, row.costUsd);
|
|
4831
5226
|
if (row.date >= sevenDayStartDate) {
|
|
4832
|
-
sevenDaysUsd =
|
|
5227
|
+
sevenDaysUsd = addUsd3(sevenDaysUsd, row.costUsd);
|
|
4833
5228
|
}
|
|
4834
5229
|
}
|
|
4835
5230
|
return {
|
|
@@ -5389,7 +5784,7 @@ function readDescriptionText(home) {
|
|
|
5389
5784
|
}
|
|
5390
5785
|
}
|
|
5391
5786
|
async function readSkillReports() {
|
|
5392
|
-
const { discoverSkills } = await import("./skills-
|
|
5787
|
+
const { discoverSkills } = await import("./skills-DXP2RCJF.js");
|
|
5393
5788
|
const skills = await discoverSkills();
|
|
5394
5789
|
return skillReportsSchema.parse(
|
|
5395
5790
|
skills.map((skill) => ({
|
|
@@ -5399,7 +5794,7 @@ async function readSkillReports() {
|
|
|
5399
5794
|
);
|
|
5400
5795
|
}
|
|
5401
5796
|
async function readPlugins() {
|
|
5402
|
-
const { pluginCatalogRuntime } = await import("./catalog-runtime-
|
|
5797
|
+
const { pluginCatalogRuntime } = await import("./catalog-runtime-5JVLWXRY.js");
|
|
5403
5798
|
return pluginsSchema.parse(
|
|
5404
5799
|
pluginCatalogRuntime.getProviders().map((plugin) => ({
|
|
5405
5800
|
configKeys: plugin.manifest.configKeys ?? [],
|
|
@@ -5412,7 +5807,7 @@ async function readPlugins() {
|
|
|
5412
5807
|
async function readRuntimeInfoReport() {
|
|
5413
5808
|
const [{ homeDir }, { pluginCatalogRuntime }, plugins, skills] = await Promise.all([
|
|
5414
5809
|
import("./discovery-DWVDM7UK.js"),
|
|
5415
|
-
import("./catalog-runtime-
|
|
5810
|
+
import("./catalog-runtime-5JVLWXRY.js"),
|
|
5416
5811
|
readPlugins(),
|
|
5417
5812
|
readSkillReports()
|
|
5418
5813
|
]);
|
|
@@ -5428,7 +5823,7 @@ async function readRuntimeInfoReport() {
|
|
|
5428
5823
|
}
|
|
5429
5824
|
async function readPluginOperationalReportFeed() {
|
|
5430
5825
|
const nowMs = Date.now();
|
|
5431
|
-
const { getPluginOperationalReports } = await import("./agent-hooks-
|
|
5826
|
+
const { getPluginOperationalReports } = await import("./agent-hooks-3JY76L5X.js");
|
|
5432
5827
|
return pluginOperationalReportFeedSchema.parse({
|
|
5433
5828
|
source: "plugins",
|
|
5434
5829
|
generatedAt: new Date(nowMs).toISOString(),
|