@sentry/junior 0.177.0 → 0.179.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-IYHCN7CO.js → agent-hooks-32IDCLMW.js} +12 -12
- package/dist/api/conversations/archive.d.ts +5 -2
- package/dist/api/conversations/list.d.ts +0 -1
- package/dist/api/conversations/membership.d.ts +14 -0
- package/dist/api/conversations/projection.d.ts +2 -1
- package/dist/api/locations/detail.d.ts +1 -1
- package/dist/api/people/shared.d.ts +2 -2
- package/dist/api/schema/conversation.d.ts +4 -4
- package/dist/api/schema/location.d.ts +1 -1
- package/dist/api/schema/person.d.ts +1 -1
- package/dist/api/schema.js +1 -1
- package/dist/api.js +399 -287
- package/dist/app.js +573 -198
- package/dist/{catalog-runtime-2TD4CXSB.js → catalog-runtime-FBVA6WAQ.js} +5 -5
- package/dist/chat/agent/sandbox.d.ts +2 -0
- package/dist/chat/conversations/sql/participants.d.ts +1 -0
- package/dist/chat/conversations/store.d.ts +0 -1
- package/dist/chat/sandbox/errors.d.ts +4 -0
- package/dist/chat/sandbox/noninteractive-command.d.ts +1 -0
- package/dist/chat/sandbox/prepare-workspace.d.ts +27 -3
- package/dist/chat/sandbox/sandbox.d.ts +2 -0
- package/dist/chat/sandbox/session.d.ts +2 -0
- package/dist/chat/sandbox/snapshot/builder-sandbox.d.ts +5 -0
- package/dist/chat/sandbox/snapshot/install.d.ts +2 -2
- package/dist/chat/sandbox/snapshot/span.d.ts +3 -0
- package/dist/chat/sandbox/snapshot/store.d.ts +20 -17
- package/dist/chat/sandbox/snapshot/waiting-error.d.ts +15 -0
- package/dist/chat/sandbox/snapshot/workspace.d.ts +17 -0
- package/dist/chat/scheduled-tasks/personal.d.ts +5 -8
- package/dist/chat/scheduled-tasks/runs.d.ts +49 -0
- package/dist/chat/scheduled-tasks/schedule-intent.d.ts +1 -1
- package/dist/chat/scheduled-tasks/tasks.d.ts +27 -0
- package/dist/chat/scheduled-tasks/tool-support.d.ts +0 -4
- package/dist/chat/scheduled-tasks/tools/create.d.ts +1 -1
- package/dist/chat/scheduled-tasks/tools/update.d.ts +1 -1
- package/dist/chat/scheduled-tasks/types.d.ts +127 -78
- package/dist/chat/services/workspace-snapshot-wait.d.ts +27 -0
- package/dist/chat/workspaces/types.d.ts +1 -0
- package/dist/{chunk-CAWBLVBY.js → chunk-2HIPYNQI.js} +6 -6
- package/dist/{chunk-ZCYABD7N.js → chunk-3AFVR5UC.js} +5 -5
- package/dist/{chunk-PA7QDS7P.js → chunk-3I7XE3PA.js} +204 -100
- package/dist/{chunk-VGDOEKO2.js → chunk-3TM3FYLQ.js} +1 -1
- package/dist/{chunk-6NZRKJWU.js → chunk-4GWXAILB.js} +1 -1
- package/dist/{chunk-LFZODSAY.js → chunk-5IRROPA5.js} +4 -4
- package/dist/{chunk-N4YEVOEC.js → chunk-B6ECUSVX.js} +45 -276
- package/dist/{chunk-4TWDRU64.js → chunk-CJLBLELR.js} +5 -5
- package/dist/{chunk-3FWXQZJJ.js → chunk-FAS6AIMF.js} +1 -1
- package/dist/{chunk-I7PKGMKI.js → chunk-FIDMHAO6.js} +6 -6
- package/dist/{chunk-4SVAFAI2.js → chunk-FTGD2FBP.js} +1 -1
- package/dist/{chunk-LVL5NG5G.js → chunk-G2CAC4CV.js} +19 -19
- package/dist/{chunk-DLTP6TUJ.js → chunk-GENV6KF2.js} +2 -2
- package/dist/{chunk-FVVYHML7.js → chunk-GPLAT6H7.js} +6 -6
- package/dist/{chunk-7CVYXUOJ.js → chunk-HQNE5APD.js} +1 -1
- package/dist/{chunk-Q362TECJ.js → chunk-JMJNFEDC.js} +331 -2
- package/dist/{chunk-AFOFVEXP.js → chunk-JT4WMD3C.js} +124 -13
- package/dist/{chunk-7ZFESKJ2.js → chunk-KJLHIHFF.js} +9 -9
- package/dist/{chunk-QLLOX7JY.js → chunk-Q5B3WTGG.js} +8 -8
- package/dist/{chunk-DGGIKWYQ.js → chunk-R5NWWYIS.js} +1 -1
- package/dist/{chunk-WCQUKX74.js → chunk-R6U7N4FS.js} +14 -5
- package/dist/{chunk-WYO2HXY5.js → chunk-RTRBYSF3.js} +1 -1
- package/dist/{chunk-2IMQLZHS.js → chunk-RZRYOLCE.js} +1144 -136
- package/dist/{chunk-7B6NW4P7.js → chunk-SLGGOASN.js} +1 -1
- package/dist/{chunk-SNPQGTHJ.js → chunk-TIEKUH4Q.js} +1 -1
- package/dist/{chunk-ELEAIRTG.js → chunk-TKB25A3L.js} +2 -2
- package/dist/{chunk-UB5YB2ED.js → chunk-U4TKB6F6.js} +6 -6
- package/dist/{chunk-ORMJY4RG.js → chunk-UT6X7XN7.js} +1 -1
- package/dist/{chunk-LPMLAJYR.js → chunk-VP4OVRDD.js} +11 -17
- package/dist/{chunk-7PZDAXIK.js → chunk-XSPSCWLH.js} +1 -1
- package/dist/chunk-XZY6G5YZ.js +1088 -0
- package/dist/{chunk-J2EWL6GJ.js → chunk-YFNAMRGE.js} +1 -1
- package/dist/{chunk-6KGMMVHF.js → chunk-ZQMG3CL5.js} +2 -2
- package/dist/cli/chat.js +31 -30
- package/dist/cli/check.js +6 -6
- package/dist/cli/plugins.js +13 -13
- package/dist/cli/snapshot-create.js +10 -10
- package/dist/cli/upgrade.js +7 -7
- package/dist/db/schema/conversation-participants.d.ts +17 -0
- package/dist/db/schema/conversations.d.ts +629 -1
- package/dist/db/schema/scheduled-tasks.d.ts +29 -5
- package/dist/db/schema/snapshots.d.ts +1 -1
- package/dist/db/schema.d.ts +46 -5
- package/dist/{db-A3CB76US.js → db-EJAV7JL6.js} +7 -7
- package/dist/instrumentation.js +4 -4
- package/dist/nitro.js +2 -2
- package/dist/{oauth-callback-server-64QMI3IB.js → oauth-callback-server-GAVSUBTQ.js} +23 -23
- package/dist/{runner-EIAE2BGD.js → runner-34JL64JF.js} +15 -15
- package/dist/{skills-ZADWFKDG.js → skills-U545HALM.js} +6 -6
- package/dist/spawn-I2S4IDUQ.js +37 -0
- package/dist/{validation-4I6AF4CV.js → validation-EVXVGA44.js} +6 -6
- package/dist/version.js +1 -1
- package/dist/{work-BS6BZ66U.js → work-QOAUPDBU.js} +18 -18
- package/dist/worker-5GX2IKLZ.js +24 -0
- package/migrations/0033_workspace_snapshot_active_build.sql +1 -0
- package/migrations/0034_strong_randall.sql +31 -0
- package/migrations/meta/0033_snapshot.json +2914 -0
- package/migrations/meta/0034_snapshot.json +3038 -0
- package/migrations/meta/_journal.json +15 -1
- package/package.json +4 -4
- package/dist/chat/scheduled-tasks/store.d.ts +0 -78
- package/dist/chunk-4TRHPYTL.js +0 -1944
- package/dist/spawn-DVUOUFFC.js +0 -37
- package/dist/worker-RS5PWTCE.js +0 -24
package/dist/api.js
CHANGED
|
@@ -41,12 +41,17 @@ import {
|
|
|
41
41
|
workspaceListSchema,
|
|
42
42
|
workspaceParamsSchema,
|
|
43
43
|
workspaceSchema
|
|
44
|
-
} from "./chunk-
|
|
44
|
+
} from "./chunk-TKB25A3L.js";
|
|
45
45
|
import {
|
|
46
46
|
appendAndEnqueueApiConversationMessage,
|
|
47
47
|
authenticatePersonalToken,
|
|
48
|
+
conversationArchiveTimes,
|
|
49
|
+
conversationArchivedForEmail,
|
|
50
|
+
conversationArchivedForUser,
|
|
48
51
|
conversationHasParticipantEmail,
|
|
49
52
|
conversationHasParticipantUser,
|
|
53
|
+
conversationNotArchivedForEmail,
|
|
54
|
+
conversationNotArchivedForUser,
|
|
50
55
|
createAndEnqueueApiConversation,
|
|
51
56
|
createPersonalToken,
|
|
52
57
|
createVercelAttachmentStorage,
|
|
@@ -59,15 +64,15 @@ import {
|
|
|
59
64
|
revokePersonalToken,
|
|
60
65
|
viewerConversationMembership,
|
|
61
66
|
webActorFromEmail
|
|
62
|
-
} from "./chunk-
|
|
67
|
+
} from "./chunk-JT4WMD3C.js";
|
|
63
68
|
import {
|
|
64
69
|
buildSentryConversationUrl,
|
|
65
70
|
getWebAuthorization
|
|
66
|
-
} from "./chunk-
|
|
71
|
+
} from "./chunk-FTGD2FBP.js";
|
|
67
72
|
import {
|
|
68
73
|
cancelHumanFacingPendingMessages,
|
|
69
74
|
getConversation
|
|
70
|
-
} from "./chunk-
|
|
75
|
+
} from "./chunk-5IRROPA5.js";
|
|
71
76
|
import {
|
|
72
77
|
readTaskExecutionByConversationId,
|
|
73
78
|
readTaskExecutionDays,
|
|
@@ -75,8 +80,8 @@ import {
|
|
|
75
80
|
readTaskExecutionSummaries,
|
|
76
81
|
readTaskExecutions,
|
|
77
82
|
readTaskRuns
|
|
78
|
-
} from "./chunk-
|
|
79
|
-
import "./chunk-
|
|
83
|
+
} from "./chunk-KJLHIHFF.js";
|
|
84
|
+
import "./chunk-CJLBLELR.js";
|
|
80
85
|
import {
|
|
81
86
|
healthReportSchema,
|
|
82
87
|
pluginOperationalReportFeedSchema,
|
|
@@ -90,30 +95,33 @@ import {
|
|
|
90
95
|
import "./chunk-JAL3CH4G.js";
|
|
91
96
|
import "./chunk-5I6ORJUY.js";
|
|
92
97
|
import {
|
|
93
|
-
createSchedulerSqlStore,
|
|
94
98
|
deleteEventTask,
|
|
95
99
|
eventTaskBelongsToUser,
|
|
96
100
|
eventTaskTriggerAvailable,
|
|
97
101
|
getEventTask,
|
|
98
102
|
getResourceEventCatalog,
|
|
103
|
+
isListedScheduledTask,
|
|
99
104
|
listEventTasksCreatedBy,
|
|
100
105
|
listPublicEventTasksForTeams,
|
|
101
106
|
listPublicScheduledTasksForTeams,
|
|
107
|
+
parseScheduledTaskRow,
|
|
102
108
|
readLiveAttachment,
|
|
103
|
-
|
|
104
|
-
|
|
109
|
+
readScheduledTask,
|
|
110
|
+
readStats,
|
|
111
|
+
saveScheduledTask
|
|
112
|
+
} from "./chunk-XZY6G5YZ.js";
|
|
105
113
|
import {
|
|
106
114
|
parseSlackThreadId
|
|
107
|
-
} from "./chunk-
|
|
115
|
+
} from "./chunk-FAS6AIMF.js";
|
|
108
116
|
import {
|
|
109
117
|
agentTurnUsageSchema,
|
|
110
118
|
fallbackShortTitle,
|
|
111
119
|
hasAgentTurnUsage,
|
|
112
120
|
renderJuniorNativeConversationEvent
|
|
113
|
-
} from "./chunk-
|
|
121
|
+
} from "./chunk-FIDMHAO6.js";
|
|
114
122
|
import {
|
|
115
123
|
getCachedSnapshot
|
|
116
|
-
} from "./chunk-
|
|
124
|
+
} from "./chunk-B6ECUSVX.js";
|
|
117
125
|
import "./chunk-PDO5BLNM.js";
|
|
118
126
|
import {
|
|
119
127
|
SANDBOX_RUNTIME,
|
|
@@ -134,7 +142,7 @@ import {
|
|
|
134
142
|
updateWorkspace,
|
|
135
143
|
withSlackRetries,
|
|
136
144
|
workspaceRepoCheckoutPath
|
|
137
|
-
} from "./chunk-
|
|
145
|
+
} from "./chunk-3I7XE3PA.js";
|
|
138
146
|
import "./chunk-3Y47VMHV.js";
|
|
139
147
|
import {
|
|
140
148
|
decodeStoredConversationEvent,
|
|
@@ -142,26 +150,30 @@ import {
|
|
|
142
150
|
getDb,
|
|
143
151
|
getSqlExecutor,
|
|
144
152
|
locationFromRow,
|
|
145
|
-
parseSessionSource
|
|
146
|
-
|
|
153
|
+
parseSessionSource,
|
|
154
|
+
resolveRootConversationId
|
|
155
|
+
} from "./chunk-VP4OVRDD.js";
|
|
147
156
|
import {
|
|
157
|
+
conversationReadColumns,
|
|
148
158
|
juniorConversationEvents,
|
|
159
|
+
juniorConversationParticipants,
|
|
149
160
|
juniorConversations,
|
|
150
161
|
juniorIdentities,
|
|
162
|
+
juniorSchedulerTasks,
|
|
151
163
|
juniorUsers
|
|
152
|
-
} from "./chunk-
|
|
164
|
+
} from "./chunk-R6U7N4FS.js";
|
|
153
165
|
import {
|
|
154
166
|
create,
|
|
155
167
|
hash
|
|
156
|
-
} from "./chunk-
|
|
157
|
-
import "./chunk-
|
|
158
|
-
import "./chunk-
|
|
168
|
+
} from "./chunk-JMJNFEDC.js";
|
|
169
|
+
import "./chunk-3TM3FYLQ.js";
|
|
170
|
+
import "./chunk-GENV6KF2.js";
|
|
159
171
|
import {
|
|
160
172
|
juniorDestinations
|
|
161
173
|
} from "./chunk-VFUK3X5B.js";
|
|
162
|
-
import "./chunk-
|
|
163
|
-
import "./chunk-
|
|
164
|
-
import "./chunk-
|
|
174
|
+
import "./chunk-XSPSCWLH.js";
|
|
175
|
+
import "./chunk-YFNAMRGE.js";
|
|
176
|
+
import "./chunk-SLGGOASN.js";
|
|
165
177
|
import "./chunk-CGA4ERJ5.js";
|
|
166
178
|
import {
|
|
167
179
|
parseSlackChannelId,
|
|
@@ -171,12 +183,12 @@ import {
|
|
|
171
183
|
import {
|
|
172
184
|
logException,
|
|
173
185
|
logWarn
|
|
174
|
-
} from "./chunk-
|
|
186
|
+
} from "./chunk-HQNE5APD.js";
|
|
175
187
|
import "./chunk-6GWA276C.js";
|
|
176
188
|
import "./chunk-OOUNJNMR.js";
|
|
177
189
|
import "./chunk-H4HBKISO.js";
|
|
178
|
-
import "./chunk-
|
|
179
|
-
import "./chunk-
|
|
190
|
+
import "./chunk-UT6X7XN7.js";
|
|
191
|
+
import "./chunk-TIEKUH4Q.js";
|
|
180
192
|
import "./chunk-MLKGABMK.js";
|
|
181
193
|
|
|
182
194
|
// src/api.ts
|
|
@@ -231,33 +243,91 @@ var requireViewer = createMiddleware(
|
|
|
231
243
|
);
|
|
232
244
|
|
|
233
245
|
// src/api/conversations/archive.ts
|
|
234
|
-
import { and, eq, isNotNull } from "drizzle-orm";
|
|
235
|
-
async function
|
|
236
|
-
const
|
|
237
|
-
|
|
246
|
+
import { and, eq, isNotNull, sql } from "drizzle-orm";
|
|
247
|
+
async function setViewerArchive(args) {
|
|
248
|
+
const executor = getSqlExecutor();
|
|
249
|
+
return await executor.transaction(async () => {
|
|
250
|
+
const db = executor.db();
|
|
251
|
+
const [root] = await db.select({ lastActivityAt: juniorConversations.lastActivityAt }).from(juniorConversations).where(eq(juniorConversations.conversationId, args.rootConversationId)).limit(1).for("update");
|
|
252
|
+
if (!root) return { status: "missing" };
|
|
253
|
+
if (args.archived) {
|
|
254
|
+
if (root.lastActivityAt.getTime() !== Date.parse(args.lastSeenAt)) {
|
|
255
|
+
return { status: "conflict" };
|
|
256
|
+
}
|
|
257
|
+
const archivedAt = /* @__PURE__ */ new Date();
|
|
258
|
+
const lastMessageAt = new Date(args.lastSeenAt);
|
|
259
|
+
await db.insert(juniorConversationParticipants).values({
|
|
260
|
+
archivedAt,
|
|
261
|
+
lastMessageAt,
|
|
262
|
+
rootConversationId: args.rootConversationId,
|
|
263
|
+
userId: args.userId
|
|
264
|
+
}).onConflictDoUpdate({
|
|
265
|
+
target: [
|
|
266
|
+
juniorConversationParticipants.userId,
|
|
267
|
+
juniorConversationParticipants.rootConversationId
|
|
268
|
+
],
|
|
269
|
+
set: {
|
|
270
|
+
archivedAt,
|
|
271
|
+
lastMessageAt: sql`greatest(${juniorConversationParticipants.lastMessageAt}, excluded.last_message_at)`
|
|
272
|
+
}
|
|
273
|
+
});
|
|
274
|
+
return { archivedAt: archivedAt.toISOString(), status: "updated" };
|
|
275
|
+
}
|
|
276
|
+
await db.update(juniorConversationParticipants).set({ archivedAt: null }).where(
|
|
277
|
+
and(
|
|
278
|
+
eq(juniorConversationParticipants.userId, args.userId),
|
|
279
|
+
eq(
|
|
280
|
+
juniorConversationParticipants.rootConversationId,
|
|
281
|
+
args.rootConversationId
|
|
282
|
+
),
|
|
283
|
+
isNotNull(juniorConversationParticipants.archivedAt)
|
|
284
|
+
)
|
|
285
|
+
);
|
|
286
|
+
return { archivedAt: null, status: "updated" };
|
|
287
|
+
});
|
|
288
|
+
}
|
|
289
|
+
async function readConversationArchivedAt(viewer, conversationId) {
|
|
290
|
+
const rootConversationId = await resolveRootConversationId(
|
|
291
|
+
getSqlExecutor(),
|
|
292
|
+
conversationId
|
|
293
|
+
);
|
|
294
|
+
const [row] = await getDb().select({ archivedAt: juniorConversationParticipants.archivedAt }).from(juniorConversationParticipants).where(
|
|
238
295
|
and(
|
|
239
|
-
eq(
|
|
240
|
-
|
|
296
|
+
eq(juniorConversationParticipants.userId, viewer.id),
|
|
297
|
+
eq(
|
|
298
|
+
juniorConversationParticipants.rootConversationId,
|
|
299
|
+
rootConversationId
|
|
300
|
+
)
|
|
241
301
|
)
|
|
242
|
-
).
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
async function archiveConversation(conversationId, body) {
|
|
253
|
-
const result = await archiveIfUnchanged({ ...body, conversationId });
|
|
254
|
-
if (result === "not_found") {
|
|
302
|
+
).limit(1);
|
|
303
|
+
return row?.archivedAt?.getTime();
|
|
304
|
+
}
|
|
305
|
+
async function archiveConversation(viewer, conversationId, body) {
|
|
306
|
+
const access = await readConversationAccessFromSql(
|
|
307
|
+
getDb(),
|
|
308
|
+
[conversationId],
|
|
309
|
+
viewer
|
|
310
|
+
);
|
|
311
|
+
if (!access.get(conversationId)?.isParticipant) {
|
|
255
312
|
throwApiError(404, "Conversation not found.");
|
|
256
313
|
}
|
|
257
|
-
|
|
258
|
-
|
|
314
|
+
const rootConversationId = await resolveRootConversationId(
|
|
315
|
+
getSqlExecutor(),
|
|
316
|
+
conversationId
|
|
317
|
+
);
|
|
318
|
+
const result = await setViewerArchive({
|
|
319
|
+
archived: body.archived,
|
|
320
|
+
lastSeenAt: body.lastSeenAt,
|
|
321
|
+
rootConversationId,
|
|
322
|
+
userId: viewer.id
|
|
323
|
+
});
|
|
324
|
+
if (result.status === "updated") {
|
|
325
|
+
return { archivedAt: result.archivedAt };
|
|
259
326
|
}
|
|
260
|
-
|
|
327
|
+
if (result.status === "missing") {
|
|
328
|
+
throwApiError(404, "Conversation not found.");
|
|
329
|
+
}
|
|
330
|
+
throwApiError(409, "Conversation received new activity.");
|
|
261
331
|
}
|
|
262
332
|
|
|
263
333
|
// src/api/conversations/attachments.ts
|
|
@@ -480,31 +550,31 @@ async function resolveSlackTeamDomains(teamIds) {
|
|
|
480
550
|
}
|
|
481
551
|
|
|
482
552
|
// src/chat/pi/sql-model-usage.ts
|
|
483
|
-
import { and as and2, eq as eq2, sql } from "drizzle-orm";
|
|
484
|
-
var message =
|
|
485
|
-
var usage =
|
|
486
|
-
var cost =
|
|
553
|
+
import { and as and2, eq as eq2, sql as sql2 } from "drizzle-orm";
|
|
554
|
+
var message = sql2`${juniorConversationEvents.payload}`;
|
|
555
|
+
var usage = sql2`${message}->'usage'`;
|
|
556
|
+
var cost = sql2`${usage}->'cost'`;
|
|
487
557
|
function nonnegativeNumber(source, field, fallbackField, floor = false) {
|
|
488
|
-
const value = (name) =>
|
|
558
|
+
const value = (name) => sql2`case
|
|
489
559
|
when jsonb_typeof(${source}->${name}) = 'number'
|
|
490
560
|
and (${source}->>${name})::numeric >= 0
|
|
491
|
-
then ${floor ?
|
|
561
|
+
then ${floor ? sql2`floor((${source}->>${name})::numeric)` : sql2`(${source}->>${name})::numeric`}
|
|
492
562
|
end`;
|
|
493
563
|
const primary = value(field);
|
|
494
|
-
return fallbackField ?
|
|
564
|
+
return fallbackField ? sql2`coalesce(${primary}, ${value(fallbackField)})` : sql2`${primary}`;
|
|
495
565
|
}
|
|
496
566
|
function token(field, fallbackField) {
|
|
497
567
|
return nonnegativeNumber(usage, field, fallbackField, true);
|
|
498
568
|
}
|
|
499
569
|
function summed(value) {
|
|
500
|
-
return
|
|
570
|
+
return sql2`sum(${value})::double precision`;
|
|
501
571
|
}
|
|
502
572
|
function summedCost(value) {
|
|
503
|
-
return
|
|
573
|
+
return sql2`round(sum(${value}), 12)::double precision`;
|
|
504
574
|
}
|
|
505
575
|
function messageTotalTokens(args) {
|
|
506
576
|
const { input, output, cacheRead, cacheWrite } = args;
|
|
507
|
-
return
|
|
577
|
+
return sql2`case
|
|
508
578
|
when ${input} is not null
|
|
509
579
|
or ${output} is not null
|
|
510
580
|
or ${cacheRead} is not null
|
|
@@ -547,7 +617,7 @@ function usageFromRow(row) {
|
|
|
547
617
|
return hasAgentTurnUsage(result) ? agentTurnUsageSchema.parse(result) : void 0;
|
|
548
618
|
}
|
|
549
619
|
async function readConversationModelUsageFromSql(executor, options) {
|
|
550
|
-
const modelId =
|
|
620
|
+
const modelId = sql2`case
|
|
551
621
|
when position('/' in coalesce(${message}->>'model', '')) > 0
|
|
552
622
|
then ${message}->>'model'
|
|
553
623
|
else concat(${message}->>'provider', '/', ${message}->>'model')
|
|
@@ -586,10 +656,10 @@ async function readConversationModelUsageFromSql(executor, options) {
|
|
|
586
656
|
and2(
|
|
587
657
|
options.includeDescendants ? eq2(juniorConversations.rootConversationId, options.conversationId) : eq2(juniorConversationEvents.conversationId, options.conversationId),
|
|
588
658
|
eq2(juniorConversationEvents.type, "assistant_message"),
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
659
|
+
sql2`jsonb_typeof(${message}->'provider') = 'string'`,
|
|
660
|
+
sql2`jsonb_typeof(${message}->'model') = 'string'`,
|
|
661
|
+
sql2`coalesce(${message}->>'provider', '') <> ''`,
|
|
662
|
+
sql2`coalesce(${message}->>'model', '') <> ''`
|
|
593
663
|
)
|
|
594
664
|
).groupBy(modelId).orderBy(modelId);
|
|
595
665
|
return rows.flatMap((row) => {
|
|
@@ -654,7 +724,7 @@ import {
|
|
|
654
724
|
getTableColumns,
|
|
655
725
|
inArray,
|
|
656
726
|
lt,
|
|
657
|
-
sql as
|
|
727
|
+
sql as sql3
|
|
658
728
|
} from "drizzle-orm";
|
|
659
729
|
|
|
660
730
|
// src/api/conversations/events.ts
|
|
@@ -1065,7 +1135,7 @@ async function readConversationEventRows(executor, args) {
|
|
|
1065
1135
|
return executor.db().select({
|
|
1066
1136
|
...conversationEventColumns,
|
|
1067
1137
|
// Replacement history is model context, never dashboard report data.
|
|
1068
|
-
payload:
|
|
1138
|
+
payload: sql3`case
|
|
1069
1139
|
when ${juniorConversationEvents.type} in ('compaction', 'handoff')
|
|
1070
1140
|
then jsonb_set(
|
|
1071
1141
|
${juniorConversationEvents.payload},
|
|
@@ -1083,11 +1153,11 @@ async function readConversationEventRows(executor, args) {
|
|
|
1083
1153
|
args.types ?? [...conversationReportSourceEventTypes]
|
|
1084
1154
|
),
|
|
1085
1155
|
args.subagentInvocationIds === void 0 ? void 0 : inArray(
|
|
1086
|
-
|
|
1156
|
+
sql3`${juniorConversationEvents.payload}->>'subagentInvocationId'`,
|
|
1087
1157
|
args.subagentInvocationIds
|
|
1088
1158
|
),
|
|
1089
1159
|
args.toolCallIds === void 0 ? void 0 : inArray(
|
|
1090
|
-
|
|
1160
|
+
sql3`${juniorConversationEvents.payload}->>'toolCallId'`,
|
|
1091
1161
|
args.toolCallIds
|
|
1092
1162
|
)
|
|
1093
1163
|
)
|
|
@@ -1167,7 +1237,7 @@ async function readConversationEventPage(executor, args) {
|
|
|
1167
1237
|
}
|
|
1168
1238
|
|
|
1169
1239
|
// src/api/conversations/list.ts
|
|
1170
|
-
import { and as and7, asc as asc2, desc as desc2, eq as eq7,
|
|
1240
|
+
import { and as and7, asc as asc2, desc as desc2, eq as eq7, isNull as isNull3, sql as sql7 } from "drizzle-orm";
|
|
1171
1241
|
|
|
1172
1242
|
// src/api/conversations/shared.ts
|
|
1173
1243
|
function slackStatsLocationLabel(input) {
|
|
@@ -1341,7 +1411,7 @@ function conversationSummaryFromStoredConversation(args) {
|
|
|
1341
1411
|
...usage3 ? { cumulativeUsage: usage3 } : {},
|
|
1342
1412
|
...actorIdentity ? { actorIdentity } : {},
|
|
1343
1413
|
...sourceUrl ? { sourceUrl } : {},
|
|
1344
|
-
|
|
1414
|
+
archivedAt: args.archivedAtMs === void 0 ? null : new Date(args.archivedAtMs).toISOString(),
|
|
1345
1415
|
...slackThread ? { channel: slackThread.channelId } : {},
|
|
1346
1416
|
...channelName ? { channelName } : {},
|
|
1347
1417
|
...channelNameRedacted ? { channelNameRedacted: true } : {},
|
|
@@ -1350,7 +1420,7 @@ function conversationSummaryFromStoredConversation(args) {
|
|
|
1350
1420
|
}
|
|
1351
1421
|
|
|
1352
1422
|
// src/api/conversations/usage.ts
|
|
1353
|
-
import { and as and4, eq as eq4, inArray as inArray2, isNull, sql as
|
|
1423
|
+
import { and as and4, eq as eq4, inArray as inArray2, isNull, sql as sql4 } from "drizzle-orm";
|
|
1354
1424
|
import { alias } from "drizzle-orm/pg-core";
|
|
1355
1425
|
var usage2 = juniorConversations.usage;
|
|
1356
1426
|
var metricRootConversation = alias(
|
|
@@ -1364,10 +1434,10 @@ var componentFields = [
|
|
|
1364
1434
|
"cacheCreationTokens"
|
|
1365
1435
|
];
|
|
1366
1436
|
function summedUsageNumber(field) {
|
|
1367
|
-
return
|
|
1437
|
+
return sql4`sum((${usage2}->>${field})::double precision)::double precision`;
|
|
1368
1438
|
}
|
|
1369
1439
|
function summedCostNumber(field) {
|
|
1370
|
-
return
|
|
1440
|
+
return sql4`round(
|
|
1371
1441
|
sum((${usage2}->'cost'->>${field})::numeric),
|
|
1372
1442
|
12
|
|
1373
1443
|
)::double precision`;
|
|
@@ -1397,7 +1467,7 @@ function usageFromAggregate(row) {
|
|
|
1397
1467
|
}
|
|
1398
1468
|
async function readRootConversationMetricsFromSql(db, rootConversationIds) {
|
|
1399
1469
|
if (rootConversationIds.length === 0) return /* @__PURE__ */ new Map();
|
|
1400
|
-
const hasComponents =
|
|
1470
|
+
const hasComponents = sql4`coalesce(
|
|
1401
1471
|
${usage2}->>'inputTokens',
|
|
1402
1472
|
${usage2}->>'outputTokens',
|
|
1403
1473
|
${usage2}->>'cachedInputTokens',
|
|
@@ -1405,12 +1475,12 @@ async function readRootConversationMetricsFromSql(db, rootConversationIds) {
|
|
|
1405
1475
|
) is not null`;
|
|
1406
1476
|
const rows = await db.select({
|
|
1407
1477
|
rootConversationId: juniorConversations.rootConversationId,
|
|
1408
|
-
durationMs:
|
|
1478
|
+
durationMs: sql4`coalesce(sum(${juniorConversations.durationMs}), 0)::double precision`,
|
|
1409
1479
|
inputTokens: summedUsageNumber("inputTokens"),
|
|
1410
1480
|
outputTokens: summedUsageNumber("outputTokens"),
|
|
1411
1481
|
cachedInputTokens: summedUsageNumber("cachedInputTokens"),
|
|
1412
1482
|
cacheCreationTokens: summedUsageNumber("cacheCreationTokens"),
|
|
1413
|
-
totalOnlyTokens:
|
|
1483
|
+
totalOnlyTokens: sql4`sum(
|
|
1414
1484
|
case
|
|
1415
1485
|
when not (${hasComponents})
|
|
1416
1486
|
then (${usage2}->>'totalTokens')::double precision
|
|
@@ -1460,7 +1530,7 @@ import {
|
|
|
1460
1530
|
isNotNull as isNotNull2,
|
|
1461
1531
|
isNull as isNull2,
|
|
1462
1532
|
or,
|
|
1463
|
-
sql as
|
|
1533
|
+
sql as sql5
|
|
1464
1534
|
} from "drizzle-orm";
|
|
1465
1535
|
import { alias as alias2 } from "drizzle-orm/pg-core";
|
|
1466
1536
|
var auxiliaryRootConversation = alias2(
|
|
@@ -1468,7 +1538,7 @@ var auxiliaryRootConversation = alias2(
|
|
|
1468
1538
|
"auxiliary_root_conversation"
|
|
1469
1539
|
);
|
|
1470
1540
|
function eventCost() {
|
|
1471
|
-
return
|
|
1541
|
+
return sql5`CASE
|
|
1472
1542
|
WHEN ${juniorConversationEvents.type} = 'structured_event'
|
|
1473
1543
|
AND jsonb_typeof(${juniorConversationEvents.payload}->'content'->'costUsd') = 'number'
|
|
1474
1544
|
THEN (${juniorConversationEvents.payload}->'content'->>'costUsd')::numeric
|
|
@@ -1481,16 +1551,16 @@ function eventCost() {
|
|
|
1481
1551
|
async function readConversationAuxiliaryCostsFromSql(db, conversationIds, options) {
|
|
1482
1552
|
if (conversationIds.length === 0) return /* @__PURE__ */ new Map();
|
|
1483
1553
|
const selectedIds = [...conversationIds];
|
|
1484
|
-
const conversationId = options.includeDescendants ?
|
|
1554
|
+
const conversationId = options.includeDescendants ? sql5`coalesce(
|
|
1485
1555
|
${auxiliaryRootConversation.conversationId},
|
|
1486
1556
|
${juniorConversations.conversationId}
|
|
1487
|
-
)` :
|
|
1488
|
-
const namespace =
|
|
1557
|
+
)` : sql5`${juniorConversations.conversationId}`;
|
|
1558
|
+
const namespace = sql5`CASE
|
|
1489
1559
|
WHEN ${juniorConversationEvents.type} = 'structured_event'
|
|
1490
1560
|
THEN ${juniorConversationEvents.payload}->>'namespace'
|
|
1491
1561
|
ELSE 'junior'
|
|
1492
1562
|
END`;
|
|
1493
|
-
const name =
|
|
1563
|
+
const name = sql5`CASE
|
|
1494
1564
|
WHEN ${juniorConversationEvents.type} = 'structured_event'
|
|
1495
1565
|
THEN ${juniorConversationEvents.payload}->>'name'
|
|
1496
1566
|
ELSE ${juniorConversationEvents.type}
|
|
@@ -1505,10 +1575,10 @@ async function readConversationAuxiliaryCostsFromSql(db, conversationIds, option
|
|
|
1505
1575
|
) : inArray3(juniorConversations.conversationId, selectedIds);
|
|
1506
1576
|
const rows = await db.select({
|
|
1507
1577
|
conversationId,
|
|
1508
|
-
costUsd:
|
|
1578
|
+
costUsd: sql5`round(sum(${cost2}), 12)::double precision`.mapWith(
|
|
1509
1579
|
Number
|
|
1510
1580
|
),
|
|
1511
|
-
events:
|
|
1581
|
+
events: sql5`count(*)::integer`.mapWith(Number),
|
|
1512
1582
|
name,
|
|
1513
1583
|
namespace
|
|
1514
1584
|
}).from(juniorConversationEvents).innerJoin(
|
|
@@ -1540,7 +1610,7 @@ async function readConversationAuxiliaryCostsFromSql(db, conversationIds, option
|
|
|
1540
1610
|
"turn_routed"
|
|
1541
1611
|
])
|
|
1542
1612
|
),
|
|
1543
|
-
|
|
1613
|
+
sql5`${cost2} >= 0`
|
|
1544
1614
|
)
|
|
1545
1615
|
).groupBy(conversationId, namespace, name).orderBy(conversationId, namespace, name);
|
|
1546
1616
|
const result = /* @__PURE__ */ new Map();
|
|
@@ -1687,15 +1757,15 @@ function isConversationPriority(conversation, nowMs) {
|
|
|
1687
1757
|
}
|
|
1688
1758
|
|
|
1689
1759
|
// src/api/conversations/user-message-activity.ts
|
|
1690
|
-
import { and as and6, eq as eq6, inArray as inArray4, isNotNull as isNotNull3, or as or2, sql as
|
|
1760
|
+
import { and as and6, eq as eq6, inArray as inArray4, isNotNull as isNotNull3, or as or2, sql as sql6 } from "drizzle-orm";
|
|
1691
1761
|
async function readLastUserMessageAtByConversation(db, conversationIds) {
|
|
1692
1762
|
if (conversationIds.length === 0) return /* @__PURE__ */ new Map();
|
|
1693
|
-
const authority =
|
|
1694
|
-
const actorPlatform =
|
|
1695
|
-
const role =
|
|
1763
|
+
const authority = sql6`${juniorConversationEvents.payload}->'provenance'->>'authority'`;
|
|
1764
|
+
const actorPlatform = sql6`${juniorConversationEvents.payload}->'provenance'->'actor'->>'platform'`;
|
|
1765
|
+
const role = sql6`${juniorConversationEvents.payload}->>'role'`;
|
|
1696
1766
|
const rows = await db.select({
|
|
1697
1767
|
conversationId: juniorConversationEvents.conversationId,
|
|
1698
|
-
lastUserMessageAt:
|
|
1768
|
+
lastUserMessageAt: sql6`max(${juniorConversationEvents.createdAt})`
|
|
1699
1769
|
}).from(juniorConversationEvents).where(
|
|
1700
1770
|
and6(
|
|
1701
1771
|
inArray4(juniorConversationEvents.conversationId, conversationIds),
|
|
@@ -1703,7 +1773,7 @@ async function readLastUserMessageAtByConversation(db, conversationIds) {
|
|
|
1703
1773
|
and6(
|
|
1704
1774
|
eq6(juniorConversationEvents.type, "user_message"),
|
|
1705
1775
|
eq6(authority, "instruction"),
|
|
1706
|
-
|
|
1776
|
+
sql6`${actorPlatform} in ('slack', 'local', 'web')`
|
|
1707
1777
|
),
|
|
1708
1778
|
and6(
|
|
1709
1779
|
eq6(juniorConversationEvents.type, "message"),
|
|
@@ -1723,22 +1793,28 @@ async function readLastUserMessageAtByConversation(db, conversationIds) {
|
|
|
1723
1793
|
|
|
1724
1794
|
// src/api/conversations/list.ts
|
|
1725
1795
|
var CONVERSATION_FEED_LIMIT = 50;
|
|
1726
|
-
function conversationFeedMembershipFilter(filter) {
|
|
1727
|
-
if (!filter) return void 0;
|
|
1796
|
+
function conversationFeedMembershipFilter(status, filter) {
|
|
1797
|
+
if (!filter) return status === "archived" ? sql7`false` : void 0;
|
|
1728
1798
|
if (filter.kind === "viewer") {
|
|
1729
|
-
return
|
|
1730
|
-
|
|
1731
|
-
|
|
1732
|
-
|
|
1799
|
+
return and7(
|
|
1800
|
+
viewerConversationMembership({
|
|
1801
|
+
actorMatch: eq7(juniorIdentities.userId, filter.userId),
|
|
1802
|
+
participantMatch: conversationHasParticipantUser(filter.userId)
|
|
1803
|
+
}),
|
|
1804
|
+
status === "archived" ? conversationArchivedForUser(filter.userId) : conversationNotArchivedForUser(filter.userId)
|
|
1805
|
+
);
|
|
1733
1806
|
}
|
|
1734
|
-
return
|
|
1735
|
-
|
|
1736
|
-
|
|
1737
|
-
|
|
1807
|
+
return and7(
|
|
1808
|
+
viewerConversationMembership({
|
|
1809
|
+
actorMatch: eq7(juniorUsers.primaryEmailNormalized, filter.email),
|
|
1810
|
+
participantMatch: conversationHasParticipantEmail(filter.email)
|
|
1811
|
+
}),
|
|
1812
|
+
status === "archived" ? conversationArchivedForEmail(filter.email) : conversationNotArchivedForEmail(filter.email)
|
|
1813
|
+
);
|
|
1738
1814
|
}
|
|
1739
1815
|
async function conversationRows(db, limit, status, filter) {
|
|
1740
1816
|
return db.select({
|
|
1741
|
-
conversation:
|
|
1817
|
+
conversation: conversationReadColumns(),
|
|
1742
1818
|
destination: juniorDestinations,
|
|
1743
1819
|
identityDisplayName: juniorIdentities.displayName,
|
|
1744
1820
|
identityEmail: juniorIdentities.email,
|
|
@@ -1756,8 +1832,7 @@ async function conversationRows(db, limit, status, filter) {
|
|
|
1756
1832
|
).leftJoin(juniorUsers, eq7(juniorUsers.id, juniorIdentities.userId)).where(
|
|
1757
1833
|
and7(
|
|
1758
1834
|
isNull3(juniorConversations.parentConversationId),
|
|
1759
|
-
status
|
|
1760
|
-
conversationFeedMembershipFilter(filter)
|
|
1835
|
+
conversationFeedMembershipFilter(status, filter)
|
|
1761
1836
|
)
|
|
1762
1837
|
).orderBy(
|
|
1763
1838
|
desc2(juniorConversations.lastActivityAt),
|
|
@@ -1793,7 +1868,6 @@ function conversationFromRow(row) {
|
|
|
1793
1868
|
},
|
|
1794
1869
|
...actor ? { actor } : {},
|
|
1795
1870
|
...location ? { location } : {},
|
|
1796
|
-
...value.archivedAt ? { archivedAtMs: value.archivedAt.getTime() } : {},
|
|
1797
1871
|
...value.channelName ? { channelName: value.channelName } : {},
|
|
1798
1872
|
...value.source ? { source: value.source } : {},
|
|
1799
1873
|
...sessionSource ? { sessionSource } : {},
|
|
@@ -1804,7 +1878,7 @@ function conversationFromRow(row) {
|
|
|
1804
1878
|
async function readConversationRecordFromSql(conversationId) {
|
|
1805
1879
|
const db = getDb();
|
|
1806
1880
|
const rows = await db.select({
|
|
1807
|
-
conversation:
|
|
1881
|
+
conversation: conversationReadColumns(),
|
|
1808
1882
|
destination: juniorDestinations,
|
|
1809
1883
|
identityDisplayName: juniorIdentities.displayName,
|
|
1810
1884
|
identityEmail: juniorIdentities.email,
|
|
@@ -1847,11 +1921,12 @@ function conversationFeedFilter(options) {
|
|
|
1847
1921
|
async function readConversationFeedFromSql(options = {}) {
|
|
1848
1922
|
const nowMs = Date.now();
|
|
1849
1923
|
const db = getDb();
|
|
1924
|
+
const filter = conversationFeedFilter(options);
|
|
1850
1925
|
const rows = await conversationRows(
|
|
1851
1926
|
db,
|
|
1852
1927
|
options.limit ?? CONVERSATION_FEED_LIMIT,
|
|
1853
1928
|
options.status ?? "active",
|
|
1854
|
-
|
|
1929
|
+
filter
|
|
1855
1930
|
);
|
|
1856
1931
|
const conversations = rows.map((row) => conversationFromRow(row));
|
|
1857
1932
|
const conversationIds = conversations.map(
|
|
@@ -1859,6 +1934,7 @@ async function readConversationFeedFromSql(options = {}) {
|
|
|
1859
1934
|
);
|
|
1860
1935
|
const [
|
|
1861
1936
|
accessByConversation,
|
|
1937
|
+
archiveTimesByConversation,
|
|
1862
1938
|
annotationsByConversation,
|
|
1863
1939
|
auxiliaryCostsByRoot,
|
|
1864
1940
|
metricsByRoot,
|
|
@@ -1867,6 +1943,11 @@ async function readConversationFeedFromSql(options = {}) {
|
|
|
1867
1943
|
lastUserMessageAtByConversation
|
|
1868
1944
|
] = await Promise.all([
|
|
1869
1945
|
readConversationAccessFromSql(db, conversationIds, options.viewer),
|
|
1946
|
+
conversationArchiveTimes(
|
|
1947
|
+
db,
|
|
1948
|
+
conversationIds,
|
|
1949
|
+
filter?.kind === "viewer" ? { userId: filter.userId } : filter?.kind === "actorEmail" ? { email: filter.email } : void 0
|
|
1950
|
+
),
|
|
1870
1951
|
listConversationAnnotationsById(db, conversationIds),
|
|
1871
1952
|
readConversationAuxiliaryCostsFromSql(db, conversationIds, {
|
|
1872
1953
|
includeDescendants: true
|
|
@@ -1897,7 +1978,11 @@ async function readConversationFeedFromSql(options = {}) {
|
|
|
1897
1978
|
const row = rows[index];
|
|
1898
1979
|
const access = accessByConversation.get(conversation.conversationId);
|
|
1899
1980
|
const metrics = metricsByRoot.get(conversation.conversationId);
|
|
1981
|
+
const archivedAtMs = archiveTimesByConversation.get(
|
|
1982
|
+
conversation.conversationId
|
|
1983
|
+
);
|
|
1900
1984
|
const summary = conversationSummaryFromStoredConversation({
|
|
1985
|
+
...archivedAtMs === void 0 ? {} : { archivedAtMs },
|
|
1901
1986
|
conversation,
|
|
1902
1987
|
access,
|
|
1903
1988
|
auxiliaryCosts: auxiliaryCostsByRoot.get(conversation.conversationId),
|
|
@@ -1944,9 +2029,10 @@ async function readConversationFeed(options = {}) {
|
|
|
1944
2029
|
}
|
|
1945
2030
|
|
|
1946
2031
|
// src/chat/tasks/read.ts
|
|
1947
|
-
import { and as
|
|
2032
|
+
import { and as and9, eq as eq9, or as or4 } from "drizzle-orm";
|
|
1948
2033
|
|
|
1949
2034
|
// src/chat/scheduled-tasks/personal.ts
|
|
2035
|
+
import { and as and8, desc as desc3, eq as eq8, inArray as inArray5, lt as lt2, notInArray, or as or3, sql as sql8 } from "drizzle-orm";
|
|
1950
2036
|
import { z as z3 } from "zod";
|
|
1951
2037
|
var cursorSchema = z3.object({
|
|
1952
2038
|
createdAtMs: z3.number().finite(),
|
|
@@ -1994,37 +2080,71 @@ function encodeCursor(task, query) {
|
|
|
1994
2080
|
"utf8"
|
|
1995
2081
|
).toString("base64url");
|
|
1996
2082
|
}
|
|
1997
|
-
function
|
|
2083
|
+
async function deleteViewerScheduledTask(db, user, id, nowMs = Date.now()) {
|
|
1998
2084
|
const identityIds = new Set(user.identities.map((identity) => identity.id));
|
|
2085
|
+
const task = await readScheduledTask(db, id);
|
|
2086
|
+
if (!task || task.status === "deleted" || !identityIds.has(task.creatorIdentityId)) {
|
|
2087
|
+
throw new PersonalScheduledTaskNotFoundError();
|
|
2088
|
+
}
|
|
2089
|
+
await saveScheduledTask(db, {
|
|
2090
|
+
...task,
|
|
2091
|
+
nextRunAtMs: void 0,
|
|
2092
|
+
runNowAtMs: void 0,
|
|
2093
|
+
status: "deleted",
|
|
2094
|
+
updatedAtMs: nowMs
|
|
2095
|
+
});
|
|
2096
|
+
}
|
|
2097
|
+
async function listViewerScheduledTasks(db, user, input) {
|
|
2098
|
+
const identityIds = user.identities.map((identity) => identity.id);
|
|
2099
|
+
if (identityIds.length === 0) return { tasks: [] };
|
|
2100
|
+
const query = normalizeQuery(input.query);
|
|
2101
|
+
const cursor = decodeCursor(input.cursor, query);
|
|
2102
|
+
const tasks = [];
|
|
2103
|
+
let before = cursor;
|
|
2104
|
+
const fetchLimit = input.limit + 1;
|
|
2105
|
+
while (tasks.length < fetchLimit) {
|
|
2106
|
+
const cursorFilter = before ? or3(
|
|
2107
|
+
lt2(juniorSchedulerTasks.createdAtMs, before.createdAtMs),
|
|
2108
|
+
and8(
|
|
2109
|
+
eq8(juniorSchedulerTasks.createdAtMs, before.createdAtMs),
|
|
2110
|
+
lt2(juniorSchedulerTasks.id, before.id)
|
|
2111
|
+
)
|
|
2112
|
+
) : void 0;
|
|
2113
|
+
const search = query ? or3(
|
|
2114
|
+
sql8`strpos(lower(${juniorSchedulerTasks.title}), ${query}) > 0`,
|
|
2115
|
+
sql8`strpos(lower(${juniorSchedulerTasks.record}->'task'->>'text'), ${query}) > 0`,
|
|
2116
|
+
sql8`strpos(lower(${juniorSchedulerTasks.record}->'schedule'->>'description'), ${query}) > 0`,
|
|
2117
|
+
sql8`strpos(lower(${juniorSchedulerTasks.record}->'schedule'->>'timezone'), ${query}) > 0`,
|
|
2118
|
+
sql8`strpos(lower(${juniorSchedulerTasks.status}), ${query}) > 0`
|
|
2119
|
+
) : void 0;
|
|
2120
|
+
const rows = await db.select({
|
|
2121
|
+
createdAtMs: juniorSchedulerTasks.createdAtMs,
|
|
2122
|
+
creatorIdentityId: juniorSchedulerTasks.creatorIdentityId,
|
|
2123
|
+
id: juniorSchedulerTasks.id,
|
|
2124
|
+
record: juniorSchedulerTasks.record,
|
|
2125
|
+
title: juniorSchedulerTasks.title
|
|
2126
|
+
}).from(juniorSchedulerTasks).where(
|
|
2127
|
+
and8(
|
|
2128
|
+
notInArray(juniorSchedulerTasks.status, ["deleted", "paused"]),
|
|
2129
|
+
inArray5(juniorSchedulerTasks.creatorIdentityId, identityIds),
|
|
2130
|
+
cursorFilter,
|
|
2131
|
+
search
|
|
2132
|
+
)
|
|
2133
|
+
).orderBy(
|
|
2134
|
+
desc3(juniorSchedulerTasks.createdAtMs),
|
|
2135
|
+
desc3(juniorSchedulerTasks.id)
|
|
2136
|
+
).limit(fetchLimit);
|
|
2137
|
+
tasks.push(
|
|
2138
|
+
...rows.map(parseScheduledTaskRow).filter(isListedScheduledTask)
|
|
2139
|
+
);
|
|
2140
|
+
if (rows.length < fetchLimit) break;
|
|
2141
|
+
const last = rows.at(-1);
|
|
2142
|
+
before = { createdAtMs: last.createdAtMs, id: last.id };
|
|
2143
|
+
}
|
|
2144
|
+
const page = tasks.slice(0, input.limit);
|
|
1999
2145
|
return {
|
|
2000
|
-
|
|
2001
|
-
|
|
2002
|
-
if (!task || task.status === "deleted" || !identityIds.has(task.creatorIdentityId)) {
|
|
2003
|
-
throw new PersonalScheduledTaskNotFoundError();
|
|
2004
|
-
}
|
|
2005
|
-
await store.saveTask({
|
|
2006
|
-
...task,
|
|
2007
|
-
nextRunAtMs: void 0,
|
|
2008
|
-
runNowAtMs: void 0,
|
|
2009
|
-
status: "deleted",
|
|
2010
|
-
updatedAtMs: nowMs
|
|
2011
|
-
});
|
|
2012
|
-
},
|
|
2013
|
-
async list(input) {
|
|
2014
|
-
const query = normalizeQuery(input.query);
|
|
2015
|
-
const cursor = decodeCursor(input.cursor, query);
|
|
2016
|
-
const matching = await store.listTasksCreatedBy({
|
|
2017
|
-
...cursor ? { before: cursor } : {},
|
|
2018
|
-
identityIds: [...identityIds],
|
|
2019
|
-
limit: input.limit + 1,
|
|
2020
|
-
...query ? { query } : {}
|
|
2021
|
-
});
|
|
2022
|
-
const tasks = matching.slice(0, input.limit);
|
|
2023
|
-
return {
|
|
2024
|
-
tasks,
|
|
2025
|
-
...matching.length > input.limit && tasks.length > 0 ? { nextCursor: encodeCursor(tasks.at(-1), query) } : {}
|
|
2026
|
-
};
|
|
2027
|
-
}
|
|
2146
|
+
tasks: page,
|
|
2147
|
+
...tasks.length > input.limit && page.length > 0 ? { nextCursor: encodeCursor(page.at(-1), query) } : {}
|
|
2028
2148
|
};
|
|
2029
2149
|
}
|
|
2030
2150
|
|
|
@@ -2054,16 +2174,16 @@ async function creatorProfileEmails(candidates) {
|
|
|
2054
2174
|
email: juniorUsers.primaryEmailNormalized,
|
|
2055
2175
|
slackUserId: juniorIdentities.providerSubjectId,
|
|
2056
2176
|
teamId: juniorIdentities.providerTenantId
|
|
2057
|
-
}).from(juniorIdentities).innerJoin(juniorUsers,
|
|
2058
|
-
|
|
2059
|
-
|
|
2060
|
-
|
|
2061
|
-
|
|
2062
|
-
|
|
2177
|
+
}).from(juniorIdentities).innerJoin(juniorUsers, eq9(juniorUsers.id, juniorIdentities.userId)).where(
|
|
2178
|
+
and9(
|
|
2179
|
+
eq9(juniorIdentities.kind, "user"),
|
|
2180
|
+
eq9(juniorIdentities.provider, "slack"),
|
|
2181
|
+
eq9(juniorIdentities.emailVerified, true),
|
|
2182
|
+
or4(
|
|
2063
2183
|
...[...selectors.values()].map(
|
|
2064
|
-
(selector) =>
|
|
2065
|
-
|
|
2066
|
-
|
|
2184
|
+
(selector) => and9(
|
|
2185
|
+
eq9(juniorIdentities.providerTenantId, selector.teamId),
|
|
2186
|
+
eq9(juniorIdentities.providerSubjectId, selector.slackUserId)
|
|
2067
2187
|
)
|
|
2068
2188
|
)
|
|
2069
2189
|
)
|
|
@@ -2099,12 +2219,12 @@ async function destinationDetails(destinations) {
|
|
|
2099
2219
|
providerTenantId: juniorDestinations.providerTenantId,
|
|
2100
2220
|
visibility: juniorDestinations.visibility
|
|
2101
2221
|
}).from(juniorDestinations).where(
|
|
2102
|
-
|
|
2222
|
+
or4(
|
|
2103
2223
|
...[...selectors.values()].map(
|
|
2104
|
-
(destination) =>
|
|
2105
|
-
|
|
2106
|
-
|
|
2107
|
-
|
|
2224
|
+
(destination) => and9(
|
|
2225
|
+
eq9(juniorDestinations.provider, "slack"),
|
|
2226
|
+
eq9(juniorDestinations.providerTenantId, destination.teamId),
|
|
2227
|
+
eq9(juniorDestinations.providerDestinationId, destination.channelId)
|
|
2108
2228
|
)
|
|
2109
2229
|
)
|
|
2110
2230
|
)
|
|
@@ -2197,7 +2317,7 @@ async function resolveViewerTaskCandidate(user, kind, id) {
|
|
|
2197
2317
|
const identityIds = new Set(user.identities.map((identity) => identity.id));
|
|
2198
2318
|
const teamIds = viewerTeamIds(user);
|
|
2199
2319
|
if (kind === "scheduled") {
|
|
2200
|
-
const task2 = await
|
|
2320
|
+
const task2 = await readScheduledTask(db, id);
|
|
2201
2321
|
if (!task2 || task2.status === "deleted") return void 0;
|
|
2202
2322
|
const ownedByViewer2 = identityIds.has(task2.creatorIdentityId);
|
|
2203
2323
|
const destinations2 = await destinationDetails([task2.destination]);
|
|
@@ -2262,13 +2382,10 @@ async function taskSummaryForCandidate(candidate) {
|
|
|
2262
2382
|
}
|
|
2263
2383
|
async function readViewerTasks(user) {
|
|
2264
2384
|
const db = getDb();
|
|
2265
|
-
const schedulerStore = createSchedulerSqlStore(db);
|
|
2266
2385
|
const identityIds = new Set(user.identities.map((identity) => identity.id));
|
|
2267
2386
|
const teamIds = viewerTeamIds(user);
|
|
2268
2387
|
const [scheduledPage, publicScheduled, eventTasks, publicEventTasks] = await Promise.all([
|
|
2269
|
-
|
|
2270
|
-
limit: TASK_FETCH_LIMIT
|
|
2271
|
-
}),
|
|
2388
|
+
listViewerScheduledTasks(db, user, { limit: TASK_FETCH_LIMIT }),
|
|
2272
2389
|
listPublicScheduledTasksForTeams(db, teamIds, TASK_FETCH_LIMIT),
|
|
2273
2390
|
listEventTasksCreatedBy(db, user, TASK_FETCH_LIMIT),
|
|
2274
2391
|
listPublicEventTasksForTeams(db, teamIds, TASK_FETCH_LIMIT)
|
|
@@ -2450,10 +2567,7 @@ async function readConversationSourceTask(args) {
|
|
|
2450
2567
|
async function deleteViewerTask(user, kind, id) {
|
|
2451
2568
|
if (kind === "scheduled") {
|
|
2452
2569
|
try {
|
|
2453
|
-
await
|
|
2454
|
-
createSchedulerSqlStore(getDb()),
|
|
2455
|
-
user
|
|
2456
|
-
).delete(id);
|
|
2570
|
+
await deleteViewerScheduledTask(getDb(), user, id);
|
|
2457
2571
|
return;
|
|
2458
2572
|
} catch (error) {
|
|
2459
2573
|
if (error instanceof PersonalScheduledTaskNotFoundError) {
|
|
@@ -2480,6 +2594,7 @@ function projectConversationDetail(args) {
|
|
|
2480
2594
|
return {
|
|
2481
2595
|
...conversationSummaryFromStoredConversation({
|
|
2482
2596
|
access: args.access,
|
|
2597
|
+
...args.archivedAtMs === void 0 ? {} : { archivedAtMs: args.archivedAtMs },
|
|
2483
2598
|
auxiliaryCosts: args.auxiliaryCosts,
|
|
2484
2599
|
conversation,
|
|
2485
2600
|
durationMs: args.durationMs,
|
|
@@ -2508,6 +2623,7 @@ function projectConversationDetail(args) {
|
|
|
2508
2623
|
async function readConversationDetailFromSql(conversationId, options) {
|
|
2509
2624
|
const record = await readConversationRecordFromSql(conversationId);
|
|
2510
2625
|
if (!record) return void 0;
|
|
2626
|
+
const archivedAtMs = options.viewer ? await readConversationArchivedAt(options.viewer, conversationId) : void 0;
|
|
2511
2627
|
const executor = getSqlExecutor();
|
|
2512
2628
|
const includeDescendantMetrics = record.rootConversationId === conversationId;
|
|
2513
2629
|
const [
|
|
@@ -2550,6 +2666,7 @@ async function readConversationDetailFromSql(conversationId, options) {
|
|
|
2550
2666
|
return projectConversationDetail({
|
|
2551
2667
|
...record,
|
|
2552
2668
|
access,
|
|
2669
|
+
...archivedAtMs === void 0 ? {} : { archivedAtMs },
|
|
2553
2670
|
annotations,
|
|
2554
2671
|
auxiliaryCosts: auxiliaryCostsByConversation.get(conversationId),
|
|
2555
2672
|
durationMs: metrics?.durationMs ?? record.durationMs,
|
|
@@ -2791,20 +2908,20 @@ async function requireConversationPendingMessages(conversationId, options = {})
|
|
|
2791
2908
|
}
|
|
2792
2909
|
|
|
2793
2910
|
// src/api/conversations/stats.query.ts
|
|
2794
|
-
import { and as
|
|
2911
|
+
import { and as and10, eq as eq10, gte, isNull as isNull4, lte, sql as sql10 } from "drizzle-orm";
|
|
2795
2912
|
import { alias as alias3 } from "drizzle-orm/pg-core";
|
|
2796
2913
|
|
|
2797
2914
|
// src/api/conversations/aggregate.ts
|
|
2798
|
-
import { sql as
|
|
2915
|
+
import { sql as sql9 } from "drizzle-orm";
|
|
2799
2916
|
function usageTokenValue(source, field) {
|
|
2800
|
-
return
|
|
2917
|
+
return sql9`CASE
|
|
2801
2918
|
WHEN ${source.usage}->>${field} IS NOT NULL
|
|
2802
2919
|
THEN (${source.usage}->>${field})::double precision
|
|
2803
2920
|
ELSE NULL
|
|
2804
2921
|
END`;
|
|
2805
2922
|
}
|
|
2806
2923
|
function tokenValue(source) {
|
|
2807
|
-
return
|
|
2924
|
+
return sql9`
|
|
2808
2925
|
CASE
|
|
2809
2926
|
WHEN COALESCE(
|
|
2810
2927
|
${source.usage}->>'inputTokens',
|
|
@@ -2823,7 +2940,7 @@ function tokenValue(source) {
|
|
|
2823
2940
|
`;
|
|
2824
2941
|
}
|
|
2825
2942
|
function costValue(source) {
|
|
2826
|
-
return
|
|
2943
|
+
return sql9`
|
|
2827
2944
|
CASE
|
|
2828
2945
|
WHEN ${source.usage}->'cost'->>'total' IS NOT NULL
|
|
2829
2946
|
THEN (${source.usage}->'cost'->>'total')::double precision
|
|
@@ -2844,34 +2961,34 @@ function costValue(source) {
|
|
|
2844
2961
|
function conversationAggregateColumns(sources) {
|
|
2845
2962
|
const metrics = sources?.metrics ?? juniorConversations;
|
|
2846
2963
|
const roots = sources?.roots ?? juniorConversations;
|
|
2847
|
-
const conversationCount = sources ?
|
|
2964
|
+
const conversationCount = sources ? sql9`COUNT(DISTINCT ${roots.conversationId})` : sql9`COUNT(*)`;
|
|
2848
2965
|
return {
|
|
2849
|
-
active:
|
|
2966
|
+
active: sql9`${conversationCount} FILTER (
|
|
2850
2967
|
WHERE ${roots.executionStatus} NOT IN ('idle', 'failed')
|
|
2851
2968
|
)::integer`,
|
|
2852
|
-
conversations:
|
|
2853
|
-
cachedInputTokens:
|
|
2854
|
-
costUsd:
|
|
2855
|
-
durationMs:
|
|
2856
|
-
failed:
|
|
2969
|
+
conversations: sql9`${conversationCount}::integer`,
|
|
2970
|
+
cachedInputTokens: sql9`SUM(${usageTokenValue(metrics, "cachedInputTokens")})::double precision`,
|
|
2971
|
+
costUsd: sql9`SUM(${costValue(metrics)})::double precision`,
|
|
2972
|
+
durationMs: sql9`COALESCE(SUM(${metrics.durationMs}), 0)::double precision`,
|
|
2973
|
+
failed: sql9`${conversationCount} FILTER (
|
|
2857
2974
|
WHERE ${roots.executionStatus} = 'failed'
|
|
2858
2975
|
)::integer`,
|
|
2859
|
-
inputTokens:
|
|
2860
|
-
tokens:
|
|
2976
|
+
inputTokens: sql9`SUM(${usageTokenValue(metrics, "inputTokens")})::double precision`,
|
|
2977
|
+
tokens: sql9`SUM(${tokenValue(metrics)})::double precision`
|
|
2861
2978
|
};
|
|
2862
2979
|
}
|
|
2863
2980
|
function conversationRangeColumns() {
|
|
2864
2981
|
return {
|
|
2865
|
-
firstSeenAt:
|
|
2982
|
+
firstSeenAt: sql9`MIN(${juniorConversations.createdAt})`.mapWith(
|
|
2866
2983
|
juniorConversations.createdAt
|
|
2867
2984
|
),
|
|
2868
|
-
lastSeenAt:
|
|
2985
|
+
lastSeenAt: sql9`MAX(${juniorConversations.lastActivityAt})`.mapWith(
|
|
2869
2986
|
juniorConversations.lastActivityAt
|
|
2870
2987
|
)
|
|
2871
2988
|
};
|
|
2872
2989
|
}
|
|
2873
2990
|
function conversationActiveDaysColumn() {
|
|
2874
|
-
return
|
|
2991
|
+
return sql9`COUNT(DISTINCT (${juniorConversations.lastActivityAt} AT TIME ZONE 'UTC')::date)::integer`;
|
|
2875
2992
|
}
|
|
2876
2993
|
|
|
2877
2994
|
// src/api/conversations/stats.query.ts
|
|
@@ -2935,7 +3052,7 @@ function statsItems(map) {
|
|
|
2935
3052
|
);
|
|
2936
3053
|
}
|
|
2937
3054
|
function statsWhere(start, end) {
|
|
2938
|
-
return
|
|
3055
|
+
return and10(
|
|
2939
3056
|
isNull4(juniorConversations.parentConversationId),
|
|
2940
3057
|
gte(juniorConversations.lastActivityAt, start),
|
|
2941
3058
|
lte(juniorConversations.lastActivityAt, end)
|
|
@@ -3012,14 +3129,14 @@ function guardianStats(rows, endMs) {
|
|
|
3012
3129
|
}
|
|
3013
3130
|
async function aggregateStats(db, start, end) {
|
|
3014
3131
|
const where = statsWhere(start, end);
|
|
3015
|
-
const activityDate =
|
|
3132
|
+
const activityDate = sql10`TO_CHAR(
|
|
3016
3133
|
${juniorConversations.lastActivityAt} AT TIME ZONE 'UTC',
|
|
3017
3134
|
'YYYY-MM-DD'
|
|
3018
3135
|
)`;
|
|
3019
3136
|
const [totalsRows, actorRows, locationRows, metricRows] = await Promise.all([
|
|
3020
3137
|
db.select(treeAggregateColumns).from(juniorConversations).innerJoin(
|
|
3021
3138
|
treeConversation,
|
|
3022
|
-
|
|
3139
|
+
eq10(
|
|
3023
3140
|
treeConversation.rootConversationId,
|
|
3024
3141
|
juniorConversations.conversationId
|
|
3025
3142
|
)
|
|
@@ -3034,14 +3151,14 @@ async function aggregateStats(db, start, end) {
|
|
|
3034
3151
|
...treeAggregateColumns
|
|
3035
3152
|
}).from(juniorConversations).innerJoin(
|
|
3036
3153
|
treeConversation,
|
|
3037
|
-
|
|
3154
|
+
eq10(
|
|
3038
3155
|
treeConversation.rootConversationId,
|
|
3039
3156
|
juniorConversations.conversationId
|
|
3040
3157
|
)
|
|
3041
3158
|
).leftJoin(
|
|
3042
3159
|
juniorIdentities,
|
|
3043
|
-
|
|
3044
|
-
).leftJoin(juniorUsers,
|
|
3160
|
+
eq10(juniorIdentities.id, juniorConversations.actorIdentityId)
|
|
3161
|
+
).leftJoin(juniorUsers, eq10(juniorUsers.id, juniorIdentities.userId)).where(where).groupBy(
|
|
3045
3162
|
juniorIdentities.displayName,
|
|
3046
3163
|
juniorIdentities.emailNormalized,
|
|
3047
3164
|
juniorIdentities.handle,
|
|
@@ -3059,13 +3176,13 @@ async function aggregateStats(db, start, end) {
|
|
|
3059
3176
|
...treeAggregateColumns
|
|
3060
3177
|
}).from(juniorConversations).innerJoin(
|
|
3061
3178
|
treeConversation,
|
|
3062
|
-
|
|
3179
|
+
eq10(
|
|
3063
3180
|
treeConversation.rootConversationId,
|
|
3064
3181
|
juniorConversations.conversationId
|
|
3065
3182
|
)
|
|
3066
3183
|
).leftJoin(
|
|
3067
3184
|
juniorDestinations,
|
|
3068
|
-
|
|
3185
|
+
eq10(juniorDestinations.id, juniorConversations.destinationId)
|
|
3069
3186
|
).where(where).groupBy(
|
|
3070
3187
|
juniorConversations.channelName,
|
|
3071
3188
|
juniorConversations.source,
|
|
@@ -3084,7 +3201,7 @@ async function aggregateStats(db, start, end) {
|
|
|
3084
3201
|
tokens: treeAggregateColumns.tokens
|
|
3085
3202
|
}).from(juniorConversations).innerJoin(
|
|
3086
3203
|
treeConversation,
|
|
3087
|
-
|
|
3204
|
+
eq10(
|
|
3088
3205
|
treeConversation.rootConversationId,
|
|
3089
3206
|
juniorConversations.conversationId
|
|
3090
3207
|
)
|
|
@@ -3093,26 +3210,26 @@ async function aggregateStats(db, start, end) {
|
|
|
3093
3210
|
return { actorRows, locationRows, metricRows, totals: totalsRows[0] };
|
|
3094
3211
|
}
|
|
3095
3212
|
async function aggregateGuardianStats(db, start, end) {
|
|
3096
|
-
const date =
|
|
3213
|
+
const date = sql10`TO_CHAR(
|
|
3097
3214
|
${juniorConversationEvents.createdAt} AT TIME ZONE 'UTC',
|
|
3098
3215
|
'YYYY-MM-DD'
|
|
3099
3216
|
)`;
|
|
3100
|
-
const decision =
|
|
3101
|
-
const cost2 =
|
|
3217
|
+
const decision = sql10`${juniorConversationEvents.payload}->>'decision'`;
|
|
3218
|
+
const cost2 = sql10`CASE
|
|
3102
3219
|
WHEN jsonb_typeof(${juniorConversationEvents.payload}->'costUsd') = 'number'
|
|
3103
3220
|
THEN (${juniorConversationEvents.payload}->>'costUsd')::double precision
|
|
3104
3221
|
ELSE NULL
|
|
3105
3222
|
END`;
|
|
3106
3223
|
return await db.select({
|
|
3107
|
-
allow:
|
|
3108
|
-
ask:
|
|
3109
|
-
costUsd:
|
|
3224
|
+
allow: sql10`COUNT(*) FILTER (WHERE ${decision} = 'allow')::integer`,
|
|
3225
|
+
ask: sql10`COUNT(*) FILTER (WHERE ${decision} = 'ask')::integer`,
|
|
3226
|
+
costUsd: sql10`SUM(${cost2})::double precision`,
|
|
3110
3227
|
date,
|
|
3111
|
-
deny:
|
|
3112
|
-
requests:
|
|
3228
|
+
deny: sql10`COUNT(*) FILTER (WHERE ${decision} = 'deny')::integer`,
|
|
3229
|
+
requests: sql10`COUNT(*)::integer`
|
|
3113
3230
|
}).from(juniorConversationEvents).where(
|
|
3114
|
-
|
|
3115
|
-
|
|
3231
|
+
and10(
|
|
3232
|
+
eq10(juniorConversationEvents.type, "guardian_action_reviewed"),
|
|
3116
3233
|
gte(juniorConversationEvents.createdAt, start),
|
|
3117
3234
|
lte(juniorConversationEvents.createdAt, end)
|
|
3118
3235
|
)
|
|
@@ -3230,6 +3347,7 @@ function createConversationRoutes(options) {
|
|
|
3230
3347
|
);
|
|
3231
3348
|
app.patch(
|
|
3232
3349
|
"/:conversationId/archive",
|
|
3350
|
+
requireViewer,
|
|
3233
3351
|
validateRequest(
|
|
3234
3352
|
"param",
|
|
3235
3353
|
conversationParamsSchema,
|
|
@@ -3241,11 +3359,12 @@ function createConversationRoutes(options) {
|
|
|
3241
3359
|
"Invalid request body."
|
|
3242
3360
|
),
|
|
3243
3361
|
async (context) => {
|
|
3362
|
+
const viewer = context.get("viewer");
|
|
3244
3363
|
const { conversationId } = context.req.valid("param");
|
|
3245
3364
|
const body = context.req.valid("json");
|
|
3246
3365
|
return jsonResponse(
|
|
3247
3366
|
archiveConversationResponseSchema,
|
|
3248
|
-
await archiveConversation(conversationId, body)
|
|
3367
|
+
await archiveConversation(viewer, conversationId, body)
|
|
3249
3368
|
);
|
|
3250
3369
|
}
|
|
3251
3370
|
);
|
|
@@ -3374,7 +3493,7 @@ function createConversationRoutes(options) {
|
|
|
3374
3493
|
import { Hono as Hono2 } from "hono";
|
|
3375
3494
|
|
|
3376
3495
|
// src/api/locations/query.ts
|
|
3377
|
-
import { and as
|
|
3496
|
+
import { and as and11, asc as asc3, desc as desc4, eq as eq11, gte as gte2, isNull as isNull5, sql as sql11 } from "drizzle-orm";
|
|
3378
3497
|
import { alias as alias4 } from "drizzle-orm/pg-core";
|
|
3379
3498
|
|
|
3380
3499
|
// src/api/conversations/reporting.ts
|
|
@@ -3482,10 +3601,10 @@ function topLevelWhere() {
|
|
|
3482
3601
|
return isNull5(juniorConversations.parentConversationId);
|
|
3483
3602
|
}
|
|
3484
3603
|
function publicLocationWhere(destinationId) {
|
|
3485
|
-
return
|
|
3604
|
+
return and11(
|
|
3486
3605
|
topLevelWhere(),
|
|
3487
|
-
|
|
3488
|
-
|
|
3606
|
+
eq11(juniorDestinations.id, destinationId),
|
|
3607
|
+
eq11(juniorDestinations.visibility, "public")
|
|
3489
3608
|
);
|
|
3490
3609
|
}
|
|
3491
3610
|
function locationColumns() {
|
|
@@ -3536,28 +3655,28 @@ async function directoryRows(db) {
|
|
|
3536
3655
|
...conversationRangeColumns()
|
|
3537
3656
|
}).from(juniorConversations).innerJoin(
|
|
3538
3657
|
treeConversation2,
|
|
3539
|
-
|
|
3658
|
+
eq11(
|
|
3540
3659
|
treeConversation2.rootConversationId,
|
|
3541
3660
|
juniorConversations.conversationId
|
|
3542
3661
|
)
|
|
3543
3662
|
).leftJoin(
|
|
3544
3663
|
juniorDestinations,
|
|
3545
|
-
|
|
3664
|
+
eq11(juniorDestinations.id, juniorConversations.destinationId)
|
|
3546
3665
|
).where(topLevelWhere()).groupBy(...locationGroupBy());
|
|
3547
3666
|
}
|
|
3548
3667
|
async function directoryActivityRows(db, start) {
|
|
3549
|
-
const date =
|
|
3668
|
+
const date = sql11`TO_CHAR(
|
|
3550
3669
|
${juniorConversations.lastActivityAt} AT TIME ZONE 'UTC',
|
|
3551
3670
|
'YYYY-MM-DD'
|
|
3552
3671
|
)`;
|
|
3553
3672
|
return db.select({
|
|
3554
|
-
conversations:
|
|
3673
|
+
conversations: sql11`COUNT(*)::integer`,
|
|
3555
3674
|
date,
|
|
3556
3675
|
visibility: juniorDestinations.visibility
|
|
3557
3676
|
}).from(juniorConversations).leftJoin(
|
|
3558
3677
|
juniorDestinations,
|
|
3559
|
-
|
|
3560
|
-
).where(
|
|
3678
|
+
eq11(juniorDestinations.id, juniorConversations.destinationId)
|
|
3679
|
+
).where(and11(topLevelWhere(), gte2(juniorConversations.lastActivityAt, start))).groupBy(date, juniorDestinations.visibility);
|
|
3561
3680
|
}
|
|
3562
3681
|
function directoryActivityDays(rows, nowMs) {
|
|
3563
3682
|
const days = /* @__PURE__ */ new Map();
|
|
@@ -3630,7 +3749,7 @@ async function recentLocationRows(db, locationId) {
|
|
|
3630
3749
|
createdAt: juniorConversations.createdAt,
|
|
3631
3750
|
destinationId: juniorDestinations.id,
|
|
3632
3751
|
durationMs: juniorConversations.durationMs,
|
|
3633
|
-
email:
|
|
3752
|
+
email: sql11`COALESCE(
|
|
3634
3753
|
${juniorUsers.primaryEmailNormalized},
|
|
3635
3754
|
${juniorIdentities.email}
|
|
3636
3755
|
)`,
|
|
@@ -3639,7 +3758,7 @@ async function recentLocationRows(db, locationId) {
|
|
|
3639
3758
|
fullName: juniorUsers.displayName,
|
|
3640
3759
|
handle: juniorIdentities.handle,
|
|
3641
3760
|
lastActivityAt: juniorConversations.lastActivityAt,
|
|
3642
|
-
providerSubjectId:
|
|
3761
|
+
providerSubjectId: sql11`CASE
|
|
3643
3762
|
WHEN ${juniorIdentities.provider} = 'slack'
|
|
3644
3763
|
THEN ${juniorIdentities.providerSubjectId}
|
|
3645
3764
|
ELSE NULL
|
|
@@ -3650,17 +3769,12 @@ async function recentLocationRows(db, locationId) {
|
|
|
3650
3769
|
usage: juniorConversations.usage
|
|
3651
3770
|
}).from(juniorConversations).innerJoin(
|
|
3652
3771
|
juniorDestinations,
|
|
3653
|
-
|
|
3772
|
+
eq11(juniorDestinations.id, juniorConversations.destinationId)
|
|
3654
3773
|
).leftJoin(
|
|
3655
3774
|
juniorIdentities,
|
|
3656
|
-
|
|
3657
|
-
).leftJoin(juniorUsers,
|
|
3658
|
-
|
|
3659
|
-
publicLocationWhere(locationId),
|
|
3660
|
-
isNull5(juniorConversations.archivedAt)
|
|
3661
|
-
)
|
|
3662
|
-
).orderBy(
|
|
3663
|
-
desc3(juniorConversations.lastActivityAt),
|
|
3775
|
+
eq11(juniorIdentities.id, juniorConversations.actorIdentityId)
|
|
3776
|
+
).leftJoin(juniorUsers, eq11(juniorUsers.id, juniorIdentities.userId)).where(publicLocationWhere(locationId)).orderBy(
|
|
3777
|
+
desc4(juniorConversations.lastActivityAt),
|
|
3664
3778
|
asc3(juniorConversations.conversationId)
|
|
3665
3779
|
).limit(RECENT_LIMIT);
|
|
3666
3780
|
}
|
|
@@ -3671,7 +3785,7 @@ async function readLocationDetailFromSql(locationId, options = {}) {
|
|
|
3671
3785
|
const start = new Date(end);
|
|
3672
3786
|
start.setUTCDate(start.getUTCDate() - (ACTIVITY_DAYS - 1));
|
|
3673
3787
|
const where = publicLocationWhere(locationId);
|
|
3674
|
-
const activityDate =
|
|
3788
|
+
const activityDate = sql11`TO_CHAR(
|
|
3675
3789
|
${juniorConversations.lastActivityAt} AT TIME ZONE 'UTC',
|
|
3676
3790
|
'YYYY-MM-DD'
|
|
3677
3791
|
)`;
|
|
@@ -3682,27 +3796,27 @@ async function readLocationDetailFromSql(locationId, options = {}) {
|
|
|
3682
3796
|
...conversationRangeColumns()
|
|
3683
3797
|
}).from(juniorConversations).innerJoin(
|
|
3684
3798
|
treeConversation2,
|
|
3685
|
-
|
|
3799
|
+
eq11(
|
|
3686
3800
|
treeConversation2.rootConversationId,
|
|
3687
3801
|
juniorConversations.conversationId
|
|
3688
3802
|
)
|
|
3689
3803
|
).innerJoin(
|
|
3690
3804
|
juniorDestinations,
|
|
3691
|
-
|
|
3805
|
+
eq11(juniorDestinations.id, juniorConversations.destinationId)
|
|
3692
3806
|
).where(where).groupBy(...locationGroupBy()),
|
|
3693
3807
|
getDb().select({
|
|
3694
3808
|
date: activityDate,
|
|
3695
3809
|
...treeAggregateColumns2
|
|
3696
3810
|
}).from(juniorConversations).innerJoin(
|
|
3697
3811
|
treeConversation2,
|
|
3698
|
-
|
|
3812
|
+
eq11(
|
|
3699
3813
|
treeConversation2.rootConversationId,
|
|
3700
3814
|
juniorConversations.conversationId
|
|
3701
3815
|
)
|
|
3702
3816
|
).innerJoin(
|
|
3703
3817
|
juniorDestinations,
|
|
3704
|
-
|
|
3705
|
-
).where(
|
|
3818
|
+
eq11(juniorDestinations.id, juniorConversations.destinationId)
|
|
3819
|
+
).where(and11(where, gte2(juniorConversations.lastActivityAt, start))).groupBy(activityDate),
|
|
3706
3820
|
getDb().select({
|
|
3707
3821
|
actorIdentityId: juniorConversations.actorIdentityId,
|
|
3708
3822
|
email: juniorUsers.primaryEmailNormalized,
|
|
@@ -3714,17 +3828,17 @@ async function readLocationDetailFromSql(locationId, options = {}) {
|
|
|
3714
3828
|
...treeAggregateColumns2
|
|
3715
3829
|
}).from(juniorConversations).innerJoin(
|
|
3716
3830
|
treeConversation2,
|
|
3717
|
-
|
|
3831
|
+
eq11(
|
|
3718
3832
|
treeConversation2.rootConversationId,
|
|
3719
3833
|
juniorConversations.conversationId
|
|
3720
3834
|
)
|
|
3721
3835
|
).innerJoin(
|
|
3722
3836
|
juniorDestinations,
|
|
3723
|
-
|
|
3837
|
+
eq11(juniorDestinations.id, juniorConversations.destinationId)
|
|
3724
3838
|
).leftJoin(
|
|
3725
3839
|
juniorIdentities,
|
|
3726
|
-
|
|
3727
|
-
).leftJoin(juniorUsers,
|
|
3840
|
+
eq11(juniorIdentities.id, juniorConversations.actorIdentityId)
|
|
3841
|
+
).leftJoin(juniorUsers, eq11(juniorUsers.id, juniorIdentities.userId)).where(where).groupBy(
|
|
3728
3842
|
juniorConversations.actorIdentityId,
|
|
3729
3843
|
juniorUsers.primaryEmailNormalized,
|
|
3730
3844
|
juniorUsers.displayName,
|
|
@@ -3837,10 +3951,10 @@ function createLocationRoutes() {
|
|
|
3837
3951
|
import { Hono as Hono3 } from "hono";
|
|
3838
3952
|
|
|
3839
3953
|
// src/api/people/list.query.ts
|
|
3840
|
-
import { and as
|
|
3954
|
+
import { and as and13, eq as eq13, gte as gte3, sql as sql13 } from "drizzle-orm";
|
|
3841
3955
|
|
|
3842
3956
|
// src/api/people/shared.ts
|
|
3843
|
-
import { and as
|
|
3957
|
+
import { and as and12, asc as asc4, desc as desc5, eq as eq12, isNull as isNull6, notExists, or as or5, sql as sql12 } from "drizzle-orm";
|
|
3844
3958
|
import { alias as alias5 } from "drizzle-orm/pg-core";
|
|
3845
3959
|
var RECENT_LIMIT2 = 25;
|
|
3846
3960
|
var ACTIVITY_DAYS2 = 365;
|
|
@@ -3860,37 +3974,37 @@ var peopleTreeAggregateColumns = conversationAggregateColumns({
|
|
|
3860
3974
|
function peopleTreeMetricsJoin() {
|
|
3861
3975
|
const rootOwnedByActor = getDb().select({ conversationId: peopleRootConversation.conversationId }).from(peopleRootConversation).innerJoin(
|
|
3862
3976
|
peopleRootIdentity,
|
|
3863
|
-
|
|
3977
|
+
eq12(peopleRootIdentity.id, peopleRootConversation.actorIdentityId)
|
|
3864
3978
|
).where(
|
|
3865
|
-
|
|
3866
|
-
|
|
3979
|
+
and12(
|
|
3980
|
+
eq12(
|
|
3867
3981
|
peopleRootConversation.conversationId,
|
|
3868
3982
|
juniorConversations.rootConversationId
|
|
3869
3983
|
),
|
|
3870
3984
|
isNull6(peopleRootConversation.parentConversationId),
|
|
3871
|
-
|
|
3985
|
+
eq12(
|
|
3872
3986
|
peopleRootConversation.rootConversationId,
|
|
3873
3987
|
peopleRootConversation.conversationId
|
|
3874
3988
|
),
|
|
3875
|
-
|
|
3989
|
+
eq12(
|
|
3876
3990
|
peopleRootIdentity.emailNormalized,
|
|
3877
3991
|
juniorUsers.primaryEmailNormalized
|
|
3878
3992
|
),
|
|
3879
|
-
|
|
3993
|
+
eq12(peopleRootIdentity.emailVerified, true)
|
|
3880
3994
|
)
|
|
3881
3995
|
);
|
|
3882
|
-
return
|
|
3883
|
-
|
|
3996
|
+
return and12(
|
|
3997
|
+
eq12(
|
|
3884
3998
|
peopleTreeConversation.rootConversationId,
|
|
3885
3999
|
juniorConversations.rootConversationId
|
|
3886
4000
|
),
|
|
3887
|
-
|
|
3888
|
-
|
|
4001
|
+
or5(
|
|
4002
|
+
eq12(
|
|
3889
4003
|
juniorConversations.rootConversationId,
|
|
3890
4004
|
juniorConversations.conversationId
|
|
3891
4005
|
),
|
|
3892
|
-
|
|
3893
|
-
|
|
4006
|
+
and12(
|
|
4007
|
+
eq12(
|
|
3894
4008
|
peopleTreeConversation.conversationId,
|
|
3895
4009
|
juniorConversations.conversationId
|
|
3896
4010
|
),
|
|
@@ -3940,11 +4054,11 @@ function statsItems2(map) {
|
|
|
3940
4054
|
}
|
|
3941
4055
|
function verifiedActorWhere(email) {
|
|
3942
4056
|
const normalizedEmail = normalizeEmail(email);
|
|
3943
|
-
return
|
|
3944
|
-
|
|
3945
|
-
|
|
3946
|
-
|
|
3947
|
-
normalizedEmail ?
|
|
4057
|
+
return and12(
|
|
4058
|
+
eq12(juniorIdentities.provider, "slack"),
|
|
4059
|
+
eq12(juniorIdentities.emailVerified, true),
|
|
4060
|
+
sql12`${juniorUsers.primaryEmailNormalized} IS NOT NULL`,
|
|
4061
|
+
normalizedEmail ? eq12(juniorUsers.primaryEmailNormalized, normalizedEmail) : void 0
|
|
3948
4062
|
);
|
|
3949
4063
|
}
|
|
3950
4064
|
async function recentActorRows(email) {
|
|
@@ -3967,14 +4081,12 @@ async function recentActorRows(email) {
|
|
|
3967
4081
|
usage: juniorConversations.usage
|
|
3968
4082
|
}).from(juniorConversations).innerJoin(
|
|
3969
4083
|
juniorIdentities,
|
|
3970
|
-
|
|
3971
|
-
).innerJoin(juniorUsers,
|
|
4084
|
+
eq12(juniorIdentities.id, juniorConversations.actorIdentityId)
|
|
4085
|
+
).innerJoin(juniorUsers, eq12(juniorUsers.id, juniorIdentities.userId)).leftJoin(
|
|
3972
4086
|
juniorDestinations,
|
|
3973
|
-
|
|
3974
|
-
).where(
|
|
3975
|
-
|
|
3976
|
-
).orderBy(
|
|
3977
|
-
desc4(juniorConversations.lastActivityAt),
|
|
4087
|
+
eq12(juniorDestinations.id, juniorConversations.destinationId)
|
|
4088
|
+
).where(verifiedActorWhere(email)).orderBy(
|
|
4089
|
+
desc5(juniorConversations.lastActivityAt),
|
|
3978
4090
|
asc4(juniorConversations.conversationId)
|
|
3979
4091
|
).limit(RECENT_LIMIT2);
|
|
3980
4092
|
}
|
|
@@ -4001,7 +4113,7 @@ function directoryActivityDays2(rows, nowMs) {
|
|
|
4001
4113
|
async function readPeopleListFromSql() {
|
|
4002
4114
|
const nowMs = Date.now();
|
|
4003
4115
|
const { end, start } = activityWindow(nowMs);
|
|
4004
|
-
const activityDate =
|
|
4116
|
+
const activityDate = sql13`TO_CHAR(
|
|
4005
4117
|
${juniorConversations.lastActivityAt} AT TIME ZONE 'UTC',
|
|
4006
4118
|
'YYYY-MM-DD'
|
|
4007
4119
|
)`;
|
|
@@ -4009,24 +4121,24 @@ async function readPeopleListFromSql() {
|
|
|
4009
4121
|
getDb().select({
|
|
4010
4122
|
email: juniorUsers.primaryEmailNormalized,
|
|
4011
4123
|
fullName: juniorUsers.displayName,
|
|
4012
|
-
slackUserId:
|
|
4013
|
-
slackUserName:
|
|
4124
|
+
slackUserId: sql13`MAX(${juniorIdentities.providerSubjectId})`,
|
|
4125
|
+
slackUserName: sql13`MAX(${juniorIdentities.handle})`,
|
|
4014
4126
|
activeDays: conversationActiveDaysColumn(),
|
|
4015
4127
|
...peopleTreeAggregateColumns,
|
|
4016
4128
|
...conversationRangeColumns()
|
|
4017
4129
|
}).from(juniorConversations).innerJoin(
|
|
4018
4130
|
juniorIdentities,
|
|
4019
|
-
|
|
4020
|
-
).innerJoin(juniorUsers,
|
|
4131
|
+
eq13(juniorIdentities.id, juniorConversations.actorIdentityId)
|
|
4132
|
+
).innerJoin(juniorUsers, eq13(juniorUsers.id, juniorIdentities.userId)).leftJoin(peopleTreeConversation, peopleTreeMetricsJoin()).where(verifiedActorWhere()).groupBy(juniorUsers.primaryEmailNormalized, juniorUsers.displayName),
|
|
4021
4133
|
getDb().select({
|
|
4022
|
-
activePeople:
|
|
4023
|
-
conversations:
|
|
4134
|
+
activePeople: sql13`COUNT(DISTINCT ${juniorUsers.id})::int`,
|
|
4135
|
+
conversations: sql13`COUNT(*)::int`,
|
|
4024
4136
|
date: activityDate
|
|
4025
4137
|
}).from(juniorConversations).innerJoin(
|
|
4026
4138
|
juniorIdentities,
|
|
4027
|
-
|
|
4028
|
-
).innerJoin(juniorUsers,
|
|
4029
|
-
|
|
4139
|
+
eq13(juniorIdentities.id, juniorConversations.actorIdentityId)
|
|
4140
|
+
).innerJoin(juniorUsers, eq13(juniorUsers.id, juniorIdentities.userId)).where(
|
|
4141
|
+
and13(
|
|
4030
4142
|
verifiedActorWhere(),
|
|
4031
4143
|
gte3(juniorConversations.lastActivityAt, start)
|
|
4032
4144
|
)
|
|
@@ -4079,7 +4191,7 @@ async function readPeoplePluginReports(args) {
|
|
|
4079
4191
|
source: "plugins"
|
|
4080
4192
|
});
|
|
4081
4193
|
}
|
|
4082
|
-
const { getPluginProfileReports } = await import("./agent-hooks-
|
|
4194
|
+
const { getPluginProfileReports } = await import("./agent-hooks-32IDCLMW.js");
|
|
4083
4195
|
return pluginOperationalReportFeedSchema.parse({
|
|
4084
4196
|
generatedAt: new Date(nowMs).toISOString(),
|
|
4085
4197
|
reports: await getPluginProfileReports({
|
|
@@ -4092,7 +4204,7 @@ async function readPeoplePluginReports(args) {
|
|
|
4092
4204
|
}
|
|
4093
4205
|
|
|
4094
4206
|
// src/api/people/profile.query.ts
|
|
4095
|
-
import { and as
|
|
4207
|
+
import { and as and14, eq as eq14, gte as gte4, sql as sql14 } from "drizzle-orm";
|
|
4096
4208
|
function emptyProfile(email, nowMs) {
|
|
4097
4209
|
const end = new Date(nowMs);
|
|
4098
4210
|
end.setUTCHours(0, 0, 0, 0);
|
|
@@ -4127,7 +4239,7 @@ function addAggregate2(map, label, row) {
|
|
|
4127
4239
|
map.set(label, item);
|
|
4128
4240
|
}
|
|
4129
4241
|
function surfaceExpression() {
|
|
4130
|
-
return
|
|
4242
|
+
return sql14`CASE
|
|
4131
4243
|
WHEN ${juniorConversations.source} IN ('api', 'scheduler', 'slack')
|
|
4132
4244
|
THEN ${juniorConversations.source}
|
|
4133
4245
|
WHEN ${juniorConversations.conversationId} LIKE 'slack:%' THEN 'slack'
|
|
@@ -4156,30 +4268,30 @@ async function readPeopleProfileFromSql(email, options = {}) {
|
|
|
4156
4268
|
const where = verifiedActorWhere(normalizedEmail);
|
|
4157
4269
|
const metricsJoin = peopleTreeMetricsJoin();
|
|
4158
4270
|
const surface = surfaceExpression();
|
|
4159
|
-
const activityDate =
|
|
4271
|
+
const activityDate = sql14`TO_CHAR(
|
|
4160
4272
|
${juniorConversations.lastActivityAt} AT TIME ZONE 'UTC',
|
|
4161
4273
|
'YYYY-MM-DD'
|
|
4162
4274
|
)`;
|
|
4163
|
-
const channel =
|
|
4275
|
+
const channel = sql14`SPLIT_PART(${juniorConversations.conversationId}, ':', 2)`;
|
|
4164
4276
|
const [totalsRows, dayRows, locationRows, surfaceRows, recentRows] = await Promise.all([
|
|
4165
4277
|
getDb().select({
|
|
4166
4278
|
email: juniorUsers.primaryEmailNormalized,
|
|
4167
4279
|
fullName: juniorUsers.displayName,
|
|
4168
|
-
slackUserId:
|
|
4169
|
-
slackUserName:
|
|
4280
|
+
slackUserId: sql14`MAX(${juniorIdentities.providerSubjectId})`,
|
|
4281
|
+
slackUserName: sql14`MAX(${juniorIdentities.handle})`,
|
|
4170
4282
|
activeDays: conversationActiveDaysColumn(),
|
|
4171
4283
|
...peopleTreeAggregateColumns
|
|
4172
4284
|
}).from(juniorConversations).innerJoin(
|
|
4173
4285
|
juniorIdentities,
|
|
4174
|
-
|
|
4175
|
-
).innerJoin(juniorUsers,
|
|
4286
|
+
eq14(juniorIdentities.id, juniorConversations.actorIdentityId)
|
|
4287
|
+
).innerJoin(juniorUsers, eq14(juniorUsers.id, juniorIdentities.userId)).leftJoin(peopleTreeConversation, metricsJoin).where(where).groupBy(juniorUsers.primaryEmailNormalized, juniorUsers.displayName),
|
|
4176
4288
|
getDb().select({
|
|
4177
4289
|
date: activityDate,
|
|
4178
4290
|
...peopleTreeAggregateColumns
|
|
4179
4291
|
}).from(juniorConversations).innerJoin(
|
|
4180
4292
|
juniorIdentities,
|
|
4181
|
-
|
|
4182
|
-
).innerJoin(juniorUsers,
|
|
4293
|
+
eq14(juniorIdentities.id, juniorConversations.actorIdentityId)
|
|
4294
|
+
).innerJoin(juniorUsers, eq14(juniorUsers.id, juniorIdentities.userId)).leftJoin(peopleTreeConversation, metricsJoin).where(and14(where, gte4(juniorConversations.lastActivityAt, start))).groupBy(activityDate),
|
|
4183
4295
|
getDb().select({
|
|
4184
4296
|
channel,
|
|
4185
4297
|
channelName: juniorConversations.channelName,
|
|
@@ -4188,10 +4300,10 @@ async function readPeopleProfileFromSql(email, options = {}) {
|
|
|
4188
4300
|
...peopleTreeAggregateColumns
|
|
4189
4301
|
}).from(juniorConversations).innerJoin(
|
|
4190
4302
|
juniorIdentities,
|
|
4191
|
-
|
|
4192
|
-
).innerJoin(juniorUsers,
|
|
4303
|
+
eq14(juniorIdentities.id, juniorConversations.actorIdentityId)
|
|
4304
|
+
).innerJoin(juniorUsers, eq14(juniorUsers.id, juniorIdentities.userId)).leftJoin(peopleTreeConversation, metricsJoin).leftJoin(
|
|
4193
4305
|
juniorDestinations,
|
|
4194
|
-
|
|
4306
|
+
eq14(juniorDestinations.id, juniorConversations.destinationId)
|
|
4195
4307
|
).where(where).groupBy(
|
|
4196
4308
|
channel,
|
|
4197
4309
|
juniorConversations.channelName,
|
|
@@ -4200,8 +4312,8 @@ async function readPeopleProfileFromSql(email, options = {}) {
|
|
|
4200
4312
|
),
|
|
4201
4313
|
getDb().select({ surface, ...peopleTreeAggregateColumns }).from(juniorConversations).innerJoin(
|
|
4202
4314
|
juniorIdentities,
|
|
4203
|
-
|
|
4204
|
-
).innerJoin(juniorUsers,
|
|
4315
|
+
eq14(juniorIdentities.id, juniorConversations.actorIdentityId)
|
|
4316
|
+
).innerJoin(juniorUsers, eq14(juniorUsers.id, juniorIdentities.userId)).leftJoin(peopleTreeConversation, metricsJoin).where(where).groupBy(surface),
|
|
4205
4317
|
recentActorRows(normalizedEmail)
|
|
4206
4318
|
]);
|
|
4207
4319
|
const totalsRow = totalsRows[0];
|
|
@@ -4279,7 +4391,7 @@ async function readPeopleProfile(email, options = {}) {
|
|
|
4279
4391
|
}
|
|
4280
4392
|
|
|
4281
4393
|
// src/api/people/spend.query.ts
|
|
4282
|
-
import { and as
|
|
4394
|
+
import { and as and15, eq as eq15, gte as gte5, lte as lte2, sql as sql15 } from "drizzle-orm";
|
|
4283
4395
|
var SEVEN_DAY_OFFSET = 6;
|
|
4284
4396
|
var THIRTY_DAY_OFFSET = 29;
|
|
4285
4397
|
function addUsd2(current, next) {
|
|
@@ -4298,7 +4410,7 @@ function spendWindow(nowMs) {
|
|
|
4298
4410
|
async function readPersonalSpendFromSql(email, nowMs = Date.now()) {
|
|
4299
4411
|
const normalizedEmail = normalizeEmail(email);
|
|
4300
4412
|
const { end, sevenDayStart, thirtyDayStart } = spendWindow(nowMs);
|
|
4301
|
-
const activityDate =
|
|
4413
|
+
const activityDate = sql15`TO_CHAR(
|
|
4302
4414
|
${juniorConversations.lastActivityAt} AT TIME ZONE 'UTC',
|
|
4303
4415
|
'YYYY-MM-DD'
|
|
4304
4416
|
)`;
|
|
@@ -4308,9 +4420,9 @@ async function readPersonalSpendFromSql(email, nowMs = Date.now()) {
|
|
|
4308
4420
|
date: activityDate
|
|
4309
4421
|
}).from(juniorConversations).innerJoin(
|
|
4310
4422
|
juniorIdentities,
|
|
4311
|
-
|
|
4312
|
-
).innerJoin(juniorUsers,
|
|
4313
|
-
|
|
4423
|
+
eq15(juniorIdentities.id, juniorConversations.actorIdentityId)
|
|
4424
|
+
).innerJoin(juniorUsers, eq15(juniorUsers.id, juniorIdentities.userId)).leftJoin(peopleTreeConversation, metricsJoin).where(
|
|
4425
|
+
and15(
|
|
4314
4426
|
verifiedActorWhere(normalizedEmail),
|
|
4315
4427
|
gte5(juniorConversations.lastActivityAt, thirtyDayStart),
|
|
4316
4428
|
lte2(juniorConversations.lastActivityAt, end)
|
|
@@ -4798,7 +4910,7 @@ function readDescriptionText(home) {
|
|
|
4798
4910
|
}
|
|
4799
4911
|
}
|
|
4800
4912
|
async function readSkillReports() {
|
|
4801
|
-
const { discoverSkills } = await import("./skills-
|
|
4913
|
+
const { discoverSkills } = await import("./skills-U545HALM.js");
|
|
4802
4914
|
const skills = await discoverSkills();
|
|
4803
4915
|
return skillReportsSchema.parse(
|
|
4804
4916
|
skills.map((skill) => ({
|
|
@@ -4808,7 +4920,7 @@ async function readSkillReports() {
|
|
|
4808
4920
|
);
|
|
4809
4921
|
}
|
|
4810
4922
|
async function readPlugins() {
|
|
4811
|
-
const { pluginCatalogRuntime } = await import("./catalog-runtime-
|
|
4923
|
+
const { pluginCatalogRuntime } = await import("./catalog-runtime-FBVA6WAQ.js");
|
|
4812
4924
|
return pluginsSchema.parse(
|
|
4813
4925
|
pluginCatalogRuntime.getProviders().map((plugin) => ({
|
|
4814
4926
|
configKeys: plugin.manifest.configKeys ?? [],
|
|
@@ -4821,7 +4933,7 @@ async function readPlugins() {
|
|
|
4821
4933
|
async function readRuntimeInfoReport() {
|
|
4822
4934
|
const [{ homeDir }, { pluginCatalogRuntime }, plugins, skills] = await Promise.all([
|
|
4823
4935
|
import("./discovery-GUFTFBTL.js"),
|
|
4824
|
-
import("./catalog-runtime-
|
|
4936
|
+
import("./catalog-runtime-FBVA6WAQ.js"),
|
|
4825
4937
|
readPlugins(),
|
|
4826
4938
|
readSkillReports()
|
|
4827
4939
|
]);
|
|
@@ -4837,7 +4949,7 @@ async function readRuntimeInfoReport() {
|
|
|
4837
4949
|
}
|
|
4838
4950
|
async function readPluginOperationalReportFeed() {
|
|
4839
4951
|
const nowMs = Date.now();
|
|
4840
|
-
const { getPluginOperationalReports } = await import("./agent-hooks-
|
|
4952
|
+
const { getPluginOperationalReports } = await import("./agent-hooks-32IDCLMW.js");
|
|
4841
4953
|
return pluginOperationalReportFeedSchema.parse({
|
|
4842
4954
|
source: "plugins",
|
|
4843
4955
|
generatedAt: new Date(nowMs).toISOString(),
|