@sentry/junior 0.112.0 → 0.113.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-6MVTPKP4.js → agent-hooks-BKEMWR3Z.js} +8 -8
- package/dist/api/conversations/cursor.d.ts +17 -0
- package/dist/api/conversations/detail.d.ts +16 -18
- package/dist/api/conversations/event-list.d.ts +91 -0
- package/dist/api/conversations/event-page.d.ts +18 -0
- package/dist/api/conversations/events.d.ts +5 -1
- package/dist/api/conversations/projection.d.ts +6 -1
- package/dist/api/schema/conversation.d.ts +132 -51
- package/dist/api/schema.d.ts +2 -2
- package/dist/api/schema.js +7 -1
- package/dist/api.js +444 -138
- package/dist/app.js +20 -20
- package/dist/{catalog-runtime-UEO25P2J.js → catalog-runtime-6XYOUVRZ.js} +5 -5
- package/dist/chat/pi/transcript.d.ts +2 -0
- package/dist/chat/services/provider-error.d.ts +39 -0
- package/dist/chat/services/provider-retry.d.ts +3 -6
- package/dist/chat/task-execution/state.d.ts +2 -2
- package/dist/chat/task-execution/store.d.ts +1 -1
- package/dist/{chunk-CSS7JHEM.js → chunk-36UJA3OD.js} +1 -1
- package/dist/{chunk-4EJO4HIC.js → chunk-3CTIAKSS.js} +1 -1
- package/dist/{chunk-66IP6WED.js → chunk-4VKFQPCW.js} +4 -4
- package/dist/{chunk-GJG67YFS.js → chunk-4WZ7YKDF.js} +2 -2
- package/dist/{chunk-SKEMI4IF.js → chunk-DXRPHBOU.js} +132 -23
- package/dist/{chunk-GR4IB6OQ.js → chunk-H5ON7XTE.js} +73 -28
- package/dist/{chunk-X3SP5RDW.js → chunk-HMRVILWZ.js} +1 -1
- package/dist/{chunk-2FJ6WEYV.js → chunk-K5BXPM74.js} +1 -1
- package/dist/{chunk-QIALGHRN.js → chunk-LLKDNPYV.js} +2 -2
- package/dist/{chunk-ZHP4KNF7.js → chunk-LR2SKL5Y.js} +1 -1
- package/dist/{chunk-AU2JVUDF.js → chunk-NP7TYFYR.js} +1 -1
- package/dist/{chunk-TZU3R5OC.js → chunk-OXE5ZUTS.js} +1 -1
- package/dist/{chunk-NDQL4ESR.js → chunk-QTS66GMR.js} +2 -2
- package/dist/{chunk-PK4ETCUQ.js → chunk-RCBUZGIT.js} +217 -199
- package/dist/{chunk-JE23YR3X.js → chunk-UKGNSJQQ.js} +50 -42
- package/dist/{chunk-AWNDKI5K.js → chunk-WBB22ANL.js} +20 -15
- package/dist/{chunk-VBSVNOLA.js → chunk-YJ44UT7D.js} +5 -5
- package/dist/{chunk-IV2O4HQJ.js → chunk-ZRSUCJGA.js} +1 -1
- package/dist/cli/chat.js +19 -19
- package/dist/cli/check.js +6 -6
- package/dist/cli/plugins.js +11 -11
- package/dist/cli/snapshot-warmup.js +8 -8
- package/dist/cli/upgrade.js +5 -5
- package/dist/{db-P5H5RVQV.js → db-2ASK6MV6.js} +5 -5
- package/dist/instrumentation.js +2 -2
- package/dist/nitro.js +2 -2
- package/dist/{runner-B4ZDUO3R.js → runner-L363K62Z.js} +12 -13
- package/dist/{skills-GWTOZ3XV.js → skills-VCPG3NOO.js} +6 -6
- package/dist/{validation-QFIC6XH6.js → validation-GY7AJBLC.js} +6 -6
- package/dist/version.js +1 -1
- package/package.json +6 -6
package/dist/api.js
CHANGED
|
@@ -5,7 +5,10 @@ import {
|
|
|
5
5
|
apiErrorSchema,
|
|
6
6
|
archiveConversationBodySchema,
|
|
7
7
|
archiveConversationResponseSchema,
|
|
8
|
+
conversationDetailQuerySchema,
|
|
8
9
|
conversationDetailReportSchema,
|
|
10
|
+
conversationEventPageSchema,
|
|
11
|
+
conversationEventsQuerySchema,
|
|
9
12
|
conversationFeedQuerySchema,
|
|
10
13
|
conversationFeedSchema,
|
|
11
14
|
conversationParamsSchema,
|
|
@@ -15,13 +18,13 @@ import {
|
|
|
15
18
|
locationDirectoryReportSchema,
|
|
16
19
|
locationParamsSchema,
|
|
17
20
|
personParamsSchema
|
|
18
|
-
} from "./chunk-
|
|
21
|
+
} from "./chunk-UKGNSJQQ.js";
|
|
19
22
|
import {
|
|
20
23
|
buildSentryConversationUrl,
|
|
21
24
|
formatSlackConversationRedactedLabel,
|
|
22
25
|
readHealthReport,
|
|
23
26
|
resolveSlackConversationContextFromThreadId
|
|
24
|
-
} from "./chunk-
|
|
27
|
+
} from "./chunk-K5BXPM74.js";
|
|
25
28
|
import {
|
|
26
29
|
healthReportSchema,
|
|
27
30
|
pluginOperationalReportFeedSchema,
|
|
@@ -34,12 +37,12 @@ import {
|
|
|
34
37
|
hasAgentTurnUsage
|
|
35
38
|
} from "./chunk-MU6HHZEN.js";
|
|
36
39
|
import "./chunk-PDO5BLNM.js";
|
|
37
|
-
import "./chunk-
|
|
40
|
+
import "./chunk-QTS66GMR.js";
|
|
38
41
|
import {
|
|
39
42
|
decodeStoredConversationEvent,
|
|
40
43
|
getDb,
|
|
41
44
|
getSqlExecutor
|
|
42
|
-
} from "./chunk-
|
|
45
|
+
} from "./chunk-LLKDNPYV.js";
|
|
43
46
|
import {
|
|
44
47
|
juniorConversationEvents,
|
|
45
48
|
juniorConversations,
|
|
@@ -47,7 +50,7 @@ import {
|
|
|
47
50
|
juniorUsers
|
|
48
51
|
} from "./chunk-JQFJO5WH.js";
|
|
49
52
|
import "./chunk-4ZNGQH7C.js";
|
|
50
|
-
import "./chunk-
|
|
53
|
+
import "./chunk-RCBUZGIT.js";
|
|
51
54
|
import {
|
|
52
55
|
juniorDestinations
|
|
53
56
|
} from "./chunk-VFUK3X5B.js";
|
|
@@ -55,11 +58,11 @@ import {
|
|
|
55
58
|
canExposeConversationPayload,
|
|
56
59
|
parseSlackThreadId
|
|
57
60
|
} from "./chunk-6Y5L4BOM.js";
|
|
58
|
-
import "./chunk-
|
|
61
|
+
import "./chunk-36UJA3OD.js";
|
|
59
62
|
import "./chunk-42WRQLJ6.js";
|
|
60
63
|
import "./chunk-6GWA276C.js";
|
|
61
|
-
import "./chunk-
|
|
62
|
-
import "./chunk-
|
|
64
|
+
import "./chunk-NP7TYFYR.js";
|
|
65
|
+
import "./chunk-ZRSUCJGA.js";
|
|
63
66
|
import "./chunk-MLKGABMK.js";
|
|
64
67
|
|
|
65
68
|
// src/api.ts
|
|
@@ -156,9 +159,6 @@ var archive_default = defineApiRoute({
|
|
|
156
159
|
}
|
|
157
160
|
});
|
|
158
161
|
|
|
159
|
-
// src/api/conversations/detail.ts
|
|
160
|
-
import { and as and5, asc as asc2, eq as eq6, getTableColumns, inArray as inArray3, sql as sql3 } from "drizzle-orm";
|
|
161
|
-
|
|
162
162
|
// src/chat/pi/sql-model-usage.ts
|
|
163
163
|
import { and as and2, eq as eq2, sql } from "drizzle-orm";
|
|
164
164
|
var message = sql`${juniorConversationEvents.payload}->'message'`;
|
|
@@ -275,8 +275,67 @@ async function readConversationModelUsageFromSql(executor, options) {
|
|
|
275
275
|
});
|
|
276
276
|
}
|
|
277
277
|
|
|
278
|
-
// src/api/conversations/
|
|
278
|
+
// src/api/conversations/cursor.ts
|
|
279
|
+
import { createHmac, timingSafeEqual } from "crypto";
|
|
279
280
|
import { z } from "zod";
|
|
281
|
+
var CURSOR_CONTEXT = "junior-conversation-report-cursor";
|
|
282
|
+
var conversationCursorPayloadSchema = z.object({
|
|
283
|
+
conversationId: z.string().min(1),
|
|
284
|
+
seq: z.number().int().min(-1),
|
|
285
|
+
version: z.literal(1)
|
|
286
|
+
}).strict();
|
|
287
|
+
function cursorSecret() {
|
|
288
|
+
const secret = process.env.JUNIOR_SECRET?.trim();
|
|
289
|
+
if (!secret) {
|
|
290
|
+
throw new Error("Cannot sign conversation cursor without JUNIOR_SECRET");
|
|
291
|
+
}
|
|
292
|
+
return secret;
|
|
293
|
+
}
|
|
294
|
+
function signature(payload) {
|
|
295
|
+
return createHmac("sha256", cursorSecret()).update(`${CURSOR_CONTEXT}:${payload}`).digest("base64url");
|
|
296
|
+
}
|
|
297
|
+
function encodeConversationCursor(payload) {
|
|
298
|
+
const encoded = Buffer.from(
|
|
299
|
+
JSON.stringify({ ...payload, version: 1 }),
|
|
300
|
+
"utf8"
|
|
301
|
+
).toString("base64url");
|
|
302
|
+
return `${encoded}.${signature(encoded)}`;
|
|
303
|
+
}
|
|
304
|
+
function decodeConversationCursor(args) {
|
|
305
|
+
const [encoded, actualSignature, extra] = args.cursor.split(".");
|
|
306
|
+
if (!encoded || !actualSignature || extra !== void 0) return void 0;
|
|
307
|
+
const expected = Buffer.from(signature(encoded));
|
|
308
|
+
const actual = Buffer.from(actualSignature);
|
|
309
|
+
if (expected.length !== actual.length || !timingSafeEqual(expected, actual)) {
|
|
310
|
+
return void 0;
|
|
311
|
+
}
|
|
312
|
+
try {
|
|
313
|
+
const parsed = conversationCursorPayloadSchema.parse(
|
|
314
|
+
JSON.parse(Buffer.from(encoded, "base64url").toString("utf8"))
|
|
315
|
+
);
|
|
316
|
+
if (parsed.conversationId !== args.conversationId) {
|
|
317
|
+
return void 0;
|
|
318
|
+
}
|
|
319
|
+
return { seq: parsed.seq };
|
|
320
|
+
} catch {
|
|
321
|
+
return void 0;
|
|
322
|
+
}
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
// src/api/conversations/event-page.ts
|
|
326
|
+
import {
|
|
327
|
+
and as and3,
|
|
328
|
+
asc,
|
|
329
|
+
desc,
|
|
330
|
+
eq as eq3,
|
|
331
|
+
getTableColumns,
|
|
332
|
+
inArray,
|
|
333
|
+
lt,
|
|
334
|
+
sql as sql2
|
|
335
|
+
} from "drizzle-orm";
|
|
336
|
+
|
|
337
|
+
// src/api/conversations/events.ts
|
|
338
|
+
import { z as z2 } from "zod";
|
|
280
339
|
var conversationReportSourceEventTypes = [
|
|
281
340
|
"message",
|
|
282
341
|
"message_handled",
|
|
@@ -290,31 +349,33 @@ var conversationReportSourceEventTypes = [
|
|
|
290
349
|
"subagent_started",
|
|
291
350
|
"subagent_ended"
|
|
292
351
|
];
|
|
293
|
-
var reportingAssistantMessageSchema =
|
|
294
|
-
role:
|
|
295
|
-
content:
|
|
352
|
+
var reportingAssistantMessageSchema = z2.object({
|
|
353
|
+
role: z2.literal("assistant"),
|
|
354
|
+
content: z2.array(z2.unknown())
|
|
296
355
|
}).passthrough();
|
|
297
|
-
var reportingToolCallPartSchema =
|
|
298
|
-
type:
|
|
299
|
-
id:
|
|
300
|
-
name:
|
|
301
|
-
arguments:
|
|
356
|
+
var reportingToolCallPartSchema = z2.object({
|
|
357
|
+
type: z2.literal("toolCall"),
|
|
358
|
+
id: z2.string().min(1),
|
|
359
|
+
name: z2.string().min(1),
|
|
360
|
+
arguments: z2.unknown()
|
|
302
361
|
}).passthrough();
|
|
303
|
-
var reportingToolResultMessageSchema =
|
|
304
|
-
role:
|
|
305
|
-
toolCallId:
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
362
|
+
var reportingToolResultMessageSchema = z2.object({
|
|
363
|
+
role: z2.literal("toolResult"),
|
|
364
|
+
toolCallId: z2.string().min(1),
|
|
365
|
+
toolName: z2.string().min(1).optional(),
|
|
366
|
+
name: z2.string().min(1).optional(),
|
|
367
|
+
content: z2.array(z2.unknown()),
|
|
368
|
+
details: z2.unknown().optional(),
|
|
369
|
+
isError: z2.boolean().optional()
|
|
309
370
|
}).passthrough();
|
|
310
|
-
var reportingToolResultDetailsSchema =
|
|
311
|
-
ok:
|
|
312
|
-
status:
|
|
371
|
+
var reportingToolResultDetailsSchema = z2.object({
|
|
372
|
+
ok: z2.boolean().optional(),
|
|
373
|
+
status: z2.string().optional()
|
|
313
374
|
}).passthrough();
|
|
314
|
-
var reportingTextPartSchema =
|
|
315
|
-
var reportingMediaPartSchema =
|
|
316
|
-
type:
|
|
317
|
-
mimeType:
|
|
375
|
+
var reportingTextPartSchema = z2.object({ type: z2.literal("text"), text: z2.string() }).passthrough();
|
|
376
|
+
var reportingMediaPartSchema = z2.object({
|
|
377
|
+
type: z2.enum(["image", "audio"]),
|
|
378
|
+
mimeType: z2.string().min(1).optional()
|
|
318
379
|
}).passthrough();
|
|
319
380
|
function sanitizeModelContentPart(value) {
|
|
320
381
|
const text = reportingTextPartSchema.safeParse(value);
|
|
@@ -343,6 +404,9 @@ function reportToolCalls(args) {
|
|
|
343
404
|
{
|
|
344
405
|
toolCallId: call.data.id,
|
|
345
406
|
name: call.data.name,
|
|
407
|
+
status: "running",
|
|
408
|
+
startedAt: new Date(args.createdAtMs).toISOString(),
|
|
409
|
+
startedSeq: args.seq,
|
|
346
410
|
...args.canExposePayload && call.data.arguments !== void 0 ? { input: call.data.arguments } : {}
|
|
347
411
|
}
|
|
348
412
|
];
|
|
@@ -357,13 +421,37 @@ function reportToolResult(args) {
|
|
|
357
421
|
);
|
|
358
422
|
const outcome = message2.data.isError === true || details.success && (details.data.ok === false || details.data.status === "error") ? "error" : "completed";
|
|
359
423
|
const output = modelVisibleToolOutput(message2.data.content);
|
|
424
|
+
const name = message2.data.toolName ?? message2.data.name ?? args.start?.name;
|
|
425
|
+
if (!name) return void 0;
|
|
360
426
|
return {
|
|
361
|
-
type: "
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
427
|
+
type: "tool_calls",
|
|
428
|
+
calls: [
|
|
429
|
+
{
|
|
430
|
+
toolCallId: message2.data.toolCallId,
|
|
431
|
+
name,
|
|
432
|
+
status: outcome,
|
|
433
|
+
...args.start ? {
|
|
434
|
+
startedAt: new Date(args.start.createdAtMs).toISOString(),
|
|
435
|
+
startedSeq: args.start.seq
|
|
436
|
+
} : {},
|
|
437
|
+
...args.canExposePayload && output !== void 0 ? { output } : {}
|
|
438
|
+
}
|
|
439
|
+
]
|
|
365
440
|
};
|
|
366
441
|
}
|
|
442
|
+
function conversationReportToolResultIds(events) {
|
|
443
|
+
return [
|
|
444
|
+
...new Set(
|
|
445
|
+
events.flatMap((event) => {
|
|
446
|
+
if (event.data.type !== "agent_step") return [];
|
|
447
|
+
const result = reportingToolResultMessageSchema.safeParse(
|
|
448
|
+
event.data.message
|
|
449
|
+
);
|
|
450
|
+
return result.success ? [result.data.toolCallId] : [];
|
|
451
|
+
})
|
|
452
|
+
)
|
|
453
|
+
];
|
|
454
|
+
}
|
|
367
455
|
function reportEventData(args) {
|
|
368
456
|
const { data } = args;
|
|
369
457
|
switch (data.type) {
|
|
@@ -405,39 +493,95 @@ function reportEventData(args) {
|
|
|
405
493
|
return void 0;
|
|
406
494
|
}
|
|
407
495
|
}
|
|
408
|
-
function
|
|
496
|
+
function projectConversationReportEventPage(args) {
|
|
409
497
|
const subagentStarts = /* @__PURE__ */ new Map();
|
|
498
|
+
for (const event of args.subagentStartEvents ?? []) {
|
|
499
|
+
if (event.data.type === "subagent_started") {
|
|
500
|
+
subagentStarts.set(event.data.subagentInvocationId, {
|
|
501
|
+
createdAtMs: event.createdAtMs,
|
|
502
|
+
data: event.data,
|
|
503
|
+
seq: event.seq
|
|
504
|
+
});
|
|
505
|
+
}
|
|
506
|
+
}
|
|
507
|
+
const toolStarts = /* @__PURE__ */ new Map();
|
|
508
|
+
for (const event of args.toolStartEvents ?? []) {
|
|
509
|
+
if (event.data.type === "tool_execution_started") {
|
|
510
|
+
const current = toolStarts.get(event.data.toolCallId);
|
|
511
|
+
if (!current || event.seq < current.seq) {
|
|
512
|
+
toolStarts.set(event.data.toolCallId, {
|
|
513
|
+
createdAtMs: event.createdAtMs,
|
|
514
|
+
name: event.data.toolName,
|
|
515
|
+
seq: event.seq
|
|
516
|
+
});
|
|
517
|
+
}
|
|
518
|
+
}
|
|
519
|
+
}
|
|
410
520
|
const projected = [];
|
|
411
521
|
for (const event of args.events) {
|
|
412
522
|
let data;
|
|
413
523
|
if (event.data.type === "agent_step") {
|
|
414
524
|
const reportArgs = {
|
|
415
525
|
canExposePayload: args.canExposePayload,
|
|
416
|
-
|
|
526
|
+
createdAtMs: event.createdAtMs,
|
|
527
|
+
message: event.data.message,
|
|
528
|
+
seq: event.seq
|
|
417
529
|
};
|
|
418
|
-
|
|
530
|
+
const result = reportingToolResultMessageSchema.safeParse(
|
|
531
|
+
event.data.message
|
|
532
|
+
);
|
|
533
|
+
const start = result.success ? toolStarts.get(result.data.toolCallId) : void 0;
|
|
534
|
+
data = reportToolCalls(reportArgs) ?? reportToolResult({
|
|
535
|
+
canExposePayload: args.canExposePayload,
|
|
536
|
+
message: event.data.message,
|
|
537
|
+
...start && start.seq < event.seq ? { start } : {}
|
|
538
|
+
});
|
|
419
539
|
} else if (event.data.type === "tool_execution_started") {
|
|
540
|
+
toolStarts.set(event.data.toolCallId, {
|
|
541
|
+
createdAtMs: event.createdAtMs,
|
|
542
|
+
name: event.data.toolName,
|
|
543
|
+
seq: event.seq
|
|
544
|
+
});
|
|
420
545
|
data = {
|
|
421
|
-
type: "
|
|
422
|
-
|
|
423
|
-
|
|
546
|
+
type: "tool_calls",
|
|
547
|
+
calls: [
|
|
548
|
+
{
|
|
549
|
+
toolCallId: event.data.toolCallId,
|
|
550
|
+
name: event.data.toolName,
|
|
551
|
+
status: "running",
|
|
552
|
+
startedAt: new Date(event.createdAtMs).toISOString(),
|
|
553
|
+
startedSeq: event.seq
|
|
554
|
+
}
|
|
555
|
+
]
|
|
424
556
|
};
|
|
425
557
|
} else if (event.data.type === "subagent_started") {
|
|
426
|
-
subagentStarts.set(event.data.subagentInvocationId,
|
|
558
|
+
subagentStarts.set(event.data.subagentInvocationId, {
|
|
559
|
+
createdAtMs: event.createdAtMs,
|
|
560
|
+
data: event.data,
|
|
561
|
+
seq: event.seq
|
|
562
|
+
});
|
|
427
563
|
data = {
|
|
428
|
-
type: "
|
|
564
|
+
type: "subagent",
|
|
565
|
+
startedSeq: event.seq,
|
|
566
|
+
startedAt: new Date(event.createdAtMs).toISOString(),
|
|
429
567
|
childConversationId: event.data.childConversationId,
|
|
430
568
|
subagentKind: event.data.subagentKind,
|
|
569
|
+
status: "running",
|
|
431
570
|
...event.data.parentToolCallId ? { parentToolCallId: event.data.parentToolCallId } : {}
|
|
432
571
|
};
|
|
433
572
|
} else if (event.data.type === "subagent_ended") {
|
|
434
|
-
const
|
|
435
|
-
if (
|
|
573
|
+
const started = subagentStarts.get(event.data.subagentInvocationId);
|
|
574
|
+
if (started && started.seq < event.seq) {
|
|
436
575
|
data = {
|
|
437
|
-
type: "
|
|
438
|
-
startedSeq,
|
|
439
|
-
|
|
576
|
+
type: "subagent",
|
|
577
|
+
startedSeq: started.seq,
|
|
578
|
+
startedAt: new Date(started.createdAtMs).toISOString(),
|
|
579
|
+
childConversationId: started.data.childConversationId,
|
|
580
|
+
subagentKind: started.data.subagentKind,
|
|
581
|
+
...started.data.parentToolCallId ? { parentToolCallId: started.data.parentToolCallId } : {},
|
|
582
|
+
status: event.data.outcome === "success" ? "completed" : event.data.outcome
|
|
440
583
|
};
|
|
584
|
+
subagentStarts.delete(event.data.subagentInvocationId);
|
|
441
585
|
}
|
|
442
586
|
} else if (event.data.type === "handoff") {
|
|
443
587
|
data = {
|
|
@@ -465,8 +609,116 @@ function projectConversationReportEvents(args) {
|
|
|
465
609
|
return projected;
|
|
466
610
|
}
|
|
467
611
|
|
|
612
|
+
// src/api/conversations/event-page.ts
|
|
613
|
+
var conversationEventColumns = getTableColumns(juniorConversationEvents);
|
|
614
|
+
var MIN_SCAN_SIZE = 64;
|
|
615
|
+
async function readConversationEventRows(executor, args) {
|
|
616
|
+
return executor.db().select({
|
|
617
|
+
...conversationEventColumns,
|
|
618
|
+
// Replacement history is model context, never dashboard report data.
|
|
619
|
+
payload: sql2`case
|
|
620
|
+
when ${juniorConversationEvents.type} in ('compaction', 'handoff')
|
|
621
|
+
then jsonb_set(
|
|
622
|
+
${juniorConversationEvents.payload},
|
|
623
|
+
'{replacementHistory}',
|
|
624
|
+
'[]'::jsonb
|
|
625
|
+
)
|
|
626
|
+
else ${juniorConversationEvents.payload}
|
|
627
|
+
end`
|
|
628
|
+
}).from(juniorConversationEvents).where(
|
|
629
|
+
and3(
|
|
630
|
+
eq3(juniorConversationEvents.conversationId, args.conversationId),
|
|
631
|
+
args.beforeSeq === void 0 ? void 0 : lt(juniorConversationEvents.seq, args.beforeSeq),
|
|
632
|
+
inArray(
|
|
633
|
+
juniorConversationEvents.type,
|
|
634
|
+
args.types ?? [...conversationReportSourceEventTypes]
|
|
635
|
+
),
|
|
636
|
+
args.subagentInvocationIds === void 0 ? void 0 : inArray(
|
|
637
|
+
sql2`${juniorConversationEvents.payload}->>'subagentInvocationId'`,
|
|
638
|
+
args.subagentInvocationIds
|
|
639
|
+
),
|
|
640
|
+
args.toolCallIds === void 0 ? void 0 : inArray(
|
|
641
|
+
sql2`${juniorConversationEvents.payload}->>'toolCallId'`,
|
|
642
|
+
args.toolCallIds
|
|
643
|
+
)
|
|
644
|
+
)
|
|
645
|
+
).orderBy(
|
|
646
|
+
args.direction === "forward" ? asc(juniorConversationEvents.seq) : desc(juniorConversationEvents.seq)
|
|
647
|
+
).limit(args.limit);
|
|
648
|
+
}
|
|
649
|
+
function decodeConversationEventRow(row) {
|
|
650
|
+
return decodeStoredConversationEvent({
|
|
651
|
+
schemaVersion: row.schemaVersion,
|
|
652
|
+
seq: row.seq,
|
|
653
|
+
historyVersion: row.historyVersion,
|
|
654
|
+
...row.idempotencyKey ? { idempotencyKey: row.idempotencyKey } : {},
|
|
655
|
+
createdAtMs: row.createdAt.getTime(),
|
|
656
|
+
type: row.type,
|
|
657
|
+
payload: row.payload
|
|
658
|
+
});
|
|
659
|
+
}
|
|
660
|
+
async function projectConversationEventRows(executor, args) {
|
|
661
|
+
const events = args.rows.map(decodeConversationEventRow).sort((left, right) => left.seq - right.seq);
|
|
662
|
+
const endedInvocationIds = [
|
|
663
|
+
...new Set(
|
|
664
|
+
events.flatMap(
|
|
665
|
+
(event) => event.data.type === "subagent_ended" ? [event.data.subagentInvocationId] : []
|
|
666
|
+
)
|
|
667
|
+
)
|
|
668
|
+
];
|
|
669
|
+
const subagentStartRows = endedInvocationIds.length === 0 ? [] : await readConversationEventRows(executor, {
|
|
670
|
+
conversationId: args.conversationId,
|
|
671
|
+
direction: "forward",
|
|
672
|
+
limit: endedInvocationIds.length,
|
|
673
|
+
subagentInvocationIds: endedInvocationIds,
|
|
674
|
+
types: ["subagent_started"]
|
|
675
|
+
});
|
|
676
|
+
const toolResultIds = conversationReportToolResultIds(events);
|
|
677
|
+
const toolStartRows = toolResultIds.length === 0 ? [] : await readConversationEventRows(executor, {
|
|
678
|
+
conversationId: args.conversationId,
|
|
679
|
+
direction: "forward",
|
|
680
|
+
limit: toolResultIds.length,
|
|
681
|
+
toolCallIds: toolResultIds,
|
|
682
|
+
types: ["tool_execution_started"]
|
|
683
|
+
});
|
|
684
|
+
return projectConversationReportEventPage({
|
|
685
|
+
canExposePayload: args.canExposePayload,
|
|
686
|
+
events,
|
|
687
|
+
subagentStartEvents: subagentStartRows.map(decodeConversationEventRow),
|
|
688
|
+
toolStartEvents: toolStartRows.map(decodeConversationEventRow)
|
|
689
|
+
});
|
|
690
|
+
}
|
|
691
|
+
async function readConversationEventPage(executor, args) {
|
|
692
|
+
const scanSize = Math.max(args.limit + 1, MIN_SCAN_SIZE);
|
|
693
|
+
const rows = [];
|
|
694
|
+
let beforeSeq = args.beforeSeq;
|
|
695
|
+
let projected = [];
|
|
696
|
+
while (projected.length <= args.limit) {
|
|
697
|
+
const batch = await readConversationEventRows(executor, {
|
|
698
|
+
beforeSeq,
|
|
699
|
+
conversationId: args.conversationId,
|
|
700
|
+
direction: "backward",
|
|
701
|
+
limit: scanSize
|
|
702
|
+
});
|
|
703
|
+
if (batch.length === 0) break;
|
|
704
|
+
rows.push(...batch);
|
|
705
|
+
projected = await projectConversationEventRows(executor, {
|
|
706
|
+
canExposePayload: args.canExposePayload,
|
|
707
|
+
conversationId: args.conversationId,
|
|
708
|
+
rows
|
|
709
|
+
});
|
|
710
|
+
if (projected.length > args.limit || batch.length < scanSize) break;
|
|
711
|
+
beforeSeq = batch.at(-1).seq;
|
|
712
|
+
}
|
|
713
|
+
const events = projected.slice(-args.limit);
|
|
714
|
+
return {
|
|
715
|
+
events,
|
|
716
|
+
...projected.length > events.length && events[0] ? { previousSeq: events[0].seq } : {}
|
|
717
|
+
};
|
|
718
|
+
}
|
|
719
|
+
|
|
468
720
|
// src/api/conversations/list.ts
|
|
469
|
-
import { and as
|
|
721
|
+
import { and as and5, asc as asc2, desc as desc2, eq as eq6, isNull as isNull2 } from "drizzle-orm";
|
|
470
722
|
|
|
471
723
|
// src/api/conversations/shared.ts
|
|
472
724
|
function slackStatsLocationLabel(input) {
|
|
@@ -566,6 +818,15 @@ function channelNameRedactedFromConversation(conversation, canViewPrivateContent
|
|
|
566
818
|
}
|
|
567
819
|
return !canViewPrivateContent;
|
|
568
820
|
}
|
|
821
|
+
function conversationEventHistory(args) {
|
|
822
|
+
if (args.transcriptPurgedAtMs !== void 0) {
|
|
823
|
+
return {
|
|
824
|
+
status: "expired",
|
|
825
|
+
expiredAt: new Date(args.transcriptPurgedAtMs).toISOString()
|
|
826
|
+
};
|
|
827
|
+
}
|
|
828
|
+
return args.canExposePayload ? { status: "available" } : { status: "redacted", reason: "non_public_conversation" };
|
|
829
|
+
}
|
|
569
830
|
function conversationSummaryFromStoredConversation(args) {
|
|
570
831
|
const { conversation, durationMs, usage: usage3 } = args;
|
|
571
832
|
const canViewPrivateContent = args.access?.canViewPrivateContent ?? false;
|
|
@@ -610,7 +871,7 @@ function conversationSummaryFromStoredConversation(args) {
|
|
|
610
871
|
}
|
|
611
872
|
|
|
612
873
|
// src/api/conversations/access.ts
|
|
613
|
-
import { eq as
|
|
874
|
+
import { eq as eq4, inArray as inArray2 } from "drizzle-orm";
|
|
614
875
|
import { alias } from "drizzle-orm/pg-core";
|
|
615
876
|
var rootConversation = alias(juniorConversations, "access_root_conversation");
|
|
616
877
|
var rootDestination = alias(juniorDestinations, "access_root_destination");
|
|
@@ -630,17 +891,17 @@ async function readConversationAccessFromSql(db, conversationIds, verifiedViewer
|
|
|
630
891
|
rootEmailVerified: rootIdentity.emailVerified
|
|
631
892
|
}).from(juniorConversations).leftJoin(
|
|
632
893
|
rootConversation,
|
|
633
|
-
|
|
894
|
+
eq4(
|
|
634
895
|
rootConversation.conversationId,
|
|
635
896
|
juniorConversations.rootConversationId
|
|
636
897
|
)
|
|
637
898
|
).leftJoin(
|
|
638
899
|
rootDestination,
|
|
639
|
-
|
|
900
|
+
eq4(rootDestination.id, rootConversation.destinationId)
|
|
640
901
|
).leftJoin(
|
|
641
902
|
rootIdentity,
|
|
642
|
-
|
|
643
|
-
).where(
|
|
903
|
+
eq4(rootIdentity.id, rootConversation.actorIdentityId)
|
|
904
|
+
).where(inArray2(juniorConversations.conversationId, [...conversationIds]));
|
|
644
905
|
return new Map(
|
|
645
906
|
rows.map((row) => {
|
|
646
907
|
const hasValidRoot = row.rootConversationId !== null && row.rootConversationId === row.storedRootConversationId && row.rootRootConversationId === row.rootConversationId && row.rootParentConversationId === null && (row.parentConversationId !== null || row.storedRootConversationId === row.conversationId);
|
|
@@ -664,7 +925,7 @@ async function readConversationAccessFromSql(db, conversationIds, verifiedViewer
|
|
|
664
925
|
}
|
|
665
926
|
|
|
666
927
|
// src/api/conversations/usage.ts
|
|
667
|
-
import { and as
|
|
928
|
+
import { and as and4, eq as eq5, inArray as inArray3, isNull, sql as sql3 } from "drizzle-orm";
|
|
668
929
|
import { alias as alias2 } from "drizzle-orm/pg-core";
|
|
669
930
|
var usage2 = juniorConversations.usage;
|
|
670
931
|
var metricRootConversation = alias2(
|
|
@@ -678,10 +939,10 @@ var componentFields = [
|
|
|
678
939
|
"cacheCreationTokens"
|
|
679
940
|
];
|
|
680
941
|
function summedUsageNumber(field) {
|
|
681
|
-
return
|
|
942
|
+
return sql3`sum((${usage2}->>${field})::double precision)::double precision`;
|
|
682
943
|
}
|
|
683
944
|
function summedCostNumber(field) {
|
|
684
|
-
return
|
|
945
|
+
return sql3`round(
|
|
685
946
|
sum((${usage2}->'cost'->>${field})::numeric),
|
|
686
947
|
12
|
|
687
948
|
)::double precision`;
|
|
@@ -711,7 +972,7 @@ function usageFromAggregate(row) {
|
|
|
711
972
|
}
|
|
712
973
|
async function readRootConversationMetricsFromSql(db, rootConversationIds) {
|
|
713
974
|
if (rootConversationIds.length === 0) return /* @__PURE__ */ new Map();
|
|
714
|
-
const hasComponents =
|
|
975
|
+
const hasComponents = sql3`coalesce(
|
|
715
976
|
${usage2}->>'inputTokens',
|
|
716
977
|
${usage2}->>'outputTokens',
|
|
717
978
|
${usage2}->>'cachedInputTokens',
|
|
@@ -719,12 +980,12 @@ async function readRootConversationMetricsFromSql(db, rootConversationIds) {
|
|
|
719
980
|
) is not null`;
|
|
720
981
|
const rows = await db.select({
|
|
721
982
|
rootConversationId: juniorConversations.rootConversationId,
|
|
722
|
-
durationMs:
|
|
983
|
+
durationMs: sql3`coalesce(sum(${juniorConversations.durationMs}), 0)::double precision`,
|
|
723
984
|
inputTokens: summedUsageNumber("inputTokens"),
|
|
724
985
|
outputTokens: summedUsageNumber("outputTokens"),
|
|
725
986
|
cachedInputTokens: summedUsageNumber("cachedInputTokens"),
|
|
726
987
|
cacheCreationTokens: summedUsageNumber("cacheCreationTokens"),
|
|
727
|
-
totalOnlyTokens:
|
|
988
|
+
totalOnlyTokens: sql3`sum(
|
|
728
989
|
case
|
|
729
990
|
when not (${hasComponents})
|
|
730
991
|
then (${usage2}->>'totalTokens')::double precision
|
|
@@ -738,19 +999,19 @@ async function readRootConversationMetricsFromSql(db, rootConversationIds) {
|
|
|
738
999
|
costTotal: summedCostNumber("total")
|
|
739
1000
|
}).from(juniorConversations).innerJoin(
|
|
740
1001
|
metricRootConversation,
|
|
741
|
-
|
|
742
|
-
|
|
1002
|
+
and4(
|
|
1003
|
+
eq5(
|
|
743
1004
|
metricRootConversation.conversationId,
|
|
744
1005
|
juniorConversations.rootConversationId
|
|
745
1006
|
),
|
|
746
1007
|
isNull(metricRootConversation.parentConversationId),
|
|
747
|
-
|
|
1008
|
+
eq5(
|
|
748
1009
|
metricRootConversation.rootConversationId,
|
|
749
1010
|
metricRootConversation.conversationId
|
|
750
1011
|
)
|
|
751
1012
|
)
|
|
752
1013
|
).where(
|
|
753
|
-
|
|
1014
|
+
inArray3(juniorConversations.rootConversationId, [...rootConversationIds])
|
|
754
1015
|
).groupBy(juniorConversations.rootConversationId);
|
|
755
1016
|
return new Map(
|
|
756
1017
|
rows.flatMap((row) => {
|
|
@@ -782,22 +1043,22 @@ async function conversationRows(db, limit, actorEmail) {
|
|
|
782
1043
|
userDisplayName: juniorUsers.displayName
|
|
783
1044
|
}).from(juniorConversations).leftJoin(
|
|
784
1045
|
juniorDestinations,
|
|
785
|
-
|
|
1046
|
+
eq6(juniorDestinations.id, juniorConversations.destinationId)
|
|
786
1047
|
).leftJoin(
|
|
787
1048
|
juniorIdentities,
|
|
788
|
-
|
|
789
|
-
).leftJoin(juniorUsers,
|
|
790
|
-
|
|
1049
|
+
eq6(juniorIdentities.id, juniorConversations.actorIdentityId)
|
|
1050
|
+
).leftJoin(juniorUsers, eq6(juniorUsers.id, juniorIdentities.userId)).where(
|
|
1051
|
+
and5(
|
|
791
1052
|
isNull2(juniorConversations.parentConversationId),
|
|
792
1053
|
isNull2(juniorConversations.archivedAt),
|
|
793
|
-
actorEmail ?
|
|
794
|
-
|
|
795
|
-
|
|
1054
|
+
actorEmail ? and5(
|
|
1055
|
+
eq6(juniorIdentities.emailNormalized, actorEmail),
|
|
1056
|
+
eq6(juniorIdentities.emailVerified, true)
|
|
796
1057
|
) : void 0
|
|
797
1058
|
)
|
|
798
1059
|
).orderBy(
|
|
799
|
-
|
|
800
|
-
|
|
1060
|
+
desc2(juniorConversations.lastActivityAt),
|
|
1061
|
+
asc2(juniorConversations.conversationId)
|
|
801
1062
|
).limit(limit);
|
|
802
1063
|
}
|
|
803
1064
|
function conversationFromRow(row) {
|
|
@@ -845,11 +1106,11 @@ async function readConversationRecordFromSql(conversationId) {
|
|
|
845
1106
|
userDisplayName: juniorUsers.displayName
|
|
846
1107
|
}).from(juniorConversations).leftJoin(
|
|
847
1108
|
juniorDestinations,
|
|
848
|
-
|
|
1109
|
+
eq6(juniorDestinations.id, juniorConversations.destinationId)
|
|
849
1110
|
).leftJoin(
|
|
850
1111
|
juniorIdentities,
|
|
851
|
-
|
|
852
|
-
).leftJoin(juniorUsers,
|
|
1112
|
+
eq6(juniorIdentities.id, juniorConversations.actorIdentityId)
|
|
1113
|
+
).leftJoin(juniorUsers, eq6(juniorUsers.id, juniorIdentities.userId)).where(eq6(juniorConversations.conversationId, conversationId)).limit(1);
|
|
853
1114
|
const row = rows[0];
|
|
854
1115
|
return row ? {
|
|
855
1116
|
conversation: conversationFromRow(row),
|
|
@@ -914,35 +1175,11 @@ var list_default = defineApiRoute({
|
|
|
914
1175
|
});
|
|
915
1176
|
|
|
916
1177
|
// src/api/conversations/detail.ts
|
|
917
|
-
var conversationEventColumns = getTableColumns(juniorConversationEvents);
|
|
918
|
-
async function readConversationReportEventRows(executor, conversationId) {
|
|
919
|
-
return executor.db().select({
|
|
920
|
-
...conversationEventColumns,
|
|
921
|
-
// Replacement history is model context, never dashboard report data.
|
|
922
|
-
payload: sql3`case
|
|
923
|
-
when ${juniorConversationEvents.type} in ('compaction', 'handoff')
|
|
924
|
-
then jsonb_set(
|
|
925
|
-
${juniorConversationEvents.payload},
|
|
926
|
-
'{replacementHistory}',
|
|
927
|
-
'[]'::jsonb
|
|
928
|
-
)
|
|
929
|
-
else ${juniorConversationEvents.payload}
|
|
930
|
-
end`
|
|
931
|
-
}).from(juniorConversationEvents).where(
|
|
932
|
-
and5(
|
|
933
|
-
eq6(juniorConversationEvents.conversationId, conversationId),
|
|
934
|
-
inArray3(juniorConversationEvents.type, [
|
|
935
|
-
...conversationReportSourceEventTypes
|
|
936
|
-
])
|
|
937
|
-
)
|
|
938
|
-
).orderBy(asc2(juniorConversationEvents.seq));
|
|
939
|
-
}
|
|
940
1178
|
function projectConversationDetail(args) {
|
|
941
1179
|
const { conversation } = args;
|
|
942
1180
|
const conversationId = conversation.conversationId;
|
|
943
1181
|
const transcriptPurgedAtMs = conversation.transcriptPurgedAtMs;
|
|
944
1182
|
const canExposePayload = args.access?.canViewPrivateContent ?? false;
|
|
945
|
-
const events = transcriptPurgedAtMs === void 0 ? args.events : [];
|
|
946
1183
|
const modelUsage = transcriptPurgedAtMs === void 0 ? args.modelUsage : [];
|
|
947
1184
|
const sentryConversationUrl = buildSentryConversationUrl(conversationId);
|
|
948
1185
|
return {
|
|
@@ -953,15 +1190,18 @@ function projectConversationDetail(args) {
|
|
|
953
1190
|
...args.locationId ? { locationId: args.locationId } : {},
|
|
954
1191
|
usage: args.usage
|
|
955
1192
|
}),
|
|
956
|
-
events:
|
|
1193
|
+
events: args.events,
|
|
1194
|
+
...args.previousSeq !== void 0 ? {
|
|
1195
|
+
previousCursor: encodeConversationCursor({
|
|
1196
|
+
conversationId,
|
|
1197
|
+
seq: args.previousSeq
|
|
1198
|
+
})
|
|
1199
|
+
} : {},
|
|
957
1200
|
...modelUsage.length > 0 ? { modelUsage } : {},
|
|
958
|
-
eventHistory:
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
}
|
|
962
|
-
status: "redacted",
|
|
963
|
-
reason: "non_public_conversation"
|
|
964
|
-
},
|
|
1201
|
+
eventHistory: conversationEventHistory({
|
|
1202
|
+
canExposePayload,
|
|
1203
|
+
...transcriptPurgedAtMs === void 0 ? {} : { transcriptPurgedAtMs }
|
|
1204
|
+
}),
|
|
965
1205
|
generatedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
966
1206
|
...sentryConversationUrl ? { sentryConversationUrl } : {}
|
|
967
1207
|
};
|
|
@@ -971,13 +1211,12 @@ async function readConversationDetailFromSql(conversationId, options) {
|
|
|
971
1211
|
if (!record) return void 0;
|
|
972
1212
|
const executor = getSqlExecutor();
|
|
973
1213
|
const includeDescendantMetrics = record.rootConversationId === conversationId;
|
|
974
|
-
const [accessByConversation,
|
|
1214
|
+
const [accessByConversation, modelUsage, metricsByRoot] = await Promise.all([
|
|
975
1215
|
readConversationAccessFromSql(
|
|
976
1216
|
getDb(),
|
|
977
1217
|
[conversationId],
|
|
978
1218
|
options.verifiedViewerEmail
|
|
979
1219
|
),
|
|
980
|
-
readConversationReportEventRows(executor, conversationId),
|
|
981
1220
|
record.conversation.transcriptPurgedAtMs === void 0 ? readConversationModelUsageFromSql(executor, {
|
|
982
1221
|
conversationId,
|
|
983
1222
|
includeDescendants: includeDescendantMetrics
|
|
@@ -987,29 +1226,28 @@ async function readConversationDetailFromSql(conversationId, options) {
|
|
|
987
1226
|
includeDescendantMetrics ? [conversationId] : []
|
|
988
1227
|
)
|
|
989
1228
|
]);
|
|
990
|
-
const
|
|
991
|
-
|
|
992
|
-
|
|
993
|
-
|
|
994
|
-
|
|
995
|
-
|
|
996
|
-
createdAtMs: row.createdAt.getTime(),
|
|
997
|
-
type: row.type,
|
|
998
|
-
payload: row.payload
|
|
999
|
-
})
|
|
1000
|
-
);
|
|
1229
|
+
const access = accessByConversation.get(conversationId);
|
|
1230
|
+
const page = record.conversation.transcriptPurgedAtMs === void 0 ? await readConversationEventPage(executor, {
|
|
1231
|
+
canExposePayload: access?.canViewPrivateContent ?? false,
|
|
1232
|
+
conversationId,
|
|
1233
|
+
limit: options.limit
|
|
1234
|
+
}) : { events: [] };
|
|
1001
1235
|
const metrics = metricsByRoot.get(conversationId);
|
|
1002
1236
|
return projectConversationDetail({
|
|
1003
1237
|
...record,
|
|
1004
|
-
access
|
|
1238
|
+
access,
|
|
1005
1239
|
durationMs: metrics?.durationMs ?? record.durationMs,
|
|
1006
|
-
events,
|
|
1240
|
+
events: page.events,
|
|
1007
1241
|
modelUsage,
|
|
1242
|
+
...page.previousSeq === void 0 ? {} : { previousSeq: page.previousSeq },
|
|
1008
1243
|
usage: metrics?.usage ?? record.usage ?? void 0
|
|
1009
1244
|
});
|
|
1010
1245
|
}
|
|
1011
1246
|
async function readConversationDetail(conversationId, options = {}) {
|
|
1012
|
-
const report = await readConversationDetailFromSql(conversationId,
|
|
1247
|
+
const report = await readConversationDetailFromSql(conversationId, {
|
|
1248
|
+
...options,
|
|
1249
|
+
limit: options.limit ?? 500
|
|
1250
|
+
});
|
|
1013
1251
|
return report ? conversationDetailReportSchema.parse(report) : void 0;
|
|
1014
1252
|
}
|
|
1015
1253
|
var detail_default = defineApiRoute({
|
|
@@ -1021,11 +1259,73 @@ var detail_default = defineApiRoute({
|
|
|
1021
1259
|
conversationParamsSchema,
|
|
1022
1260
|
c.req.param()
|
|
1023
1261
|
);
|
|
1262
|
+
const query = parseQuery(conversationDetailQuerySchema, c.req.query());
|
|
1024
1263
|
const verifiedViewerEmail = c.get("verifiedViewerEmail");
|
|
1025
|
-
const report = await readConversationDetail(
|
|
1026
|
-
|
|
1027
|
-
verifiedViewerEmail ? { verifiedViewerEmail } : {}
|
|
1264
|
+
const report = await readConversationDetail(conversationId, {
|
|
1265
|
+
...query,
|
|
1266
|
+
...verifiedViewerEmail ? { verifiedViewerEmail } : {}
|
|
1267
|
+
});
|
|
1268
|
+
if (!report) throwApiError(404, "Conversation not found.");
|
|
1269
|
+
return report;
|
|
1270
|
+
}
|
|
1271
|
+
});
|
|
1272
|
+
|
|
1273
|
+
// src/api/conversations/event-list.ts
|
|
1274
|
+
async function readConversationEvents(conversationId, beforeValue, options = {}) {
|
|
1275
|
+
const record = await readConversationRecordFromSql(conversationId);
|
|
1276
|
+
if (!record) return void 0;
|
|
1277
|
+
const before = decodeConversationCursor({
|
|
1278
|
+
conversationId,
|
|
1279
|
+
cursor: beforeValue
|
|
1280
|
+
});
|
|
1281
|
+
if (!before) throwApiError(400, "Invalid conversation cursor.");
|
|
1282
|
+
const accessByConversation = await readConversationAccessFromSql(
|
|
1283
|
+
getDb(),
|
|
1284
|
+
[conversationId],
|
|
1285
|
+
options.verifiedViewerEmail
|
|
1286
|
+
);
|
|
1287
|
+
const access = accessByConversation.get(conversationId);
|
|
1288
|
+
const canExposePayload = access?.canViewPrivateContent ?? false;
|
|
1289
|
+
const transcriptPurgedAtMs = record.conversation.transcriptPurgedAtMs;
|
|
1290
|
+
const page = transcriptPurgedAtMs === void 0 ? await readConversationEventPage(getSqlExecutor(), {
|
|
1291
|
+
beforeSeq: before.seq,
|
|
1292
|
+
canExposePayload,
|
|
1293
|
+
conversationId,
|
|
1294
|
+
limit: options.limit ?? 500
|
|
1295
|
+
}) : { events: [] };
|
|
1296
|
+
return conversationEventPageSchema.parse({
|
|
1297
|
+
events: page.events,
|
|
1298
|
+
eventHistory: conversationEventHistory({
|
|
1299
|
+
canExposePayload,
|
|
1300
|
+
...transcriptPurgedAtMs === void 0 ? {} : { transcriptPurgedAtMs }
|
|
1301
|
+
}),
|
|
1302
|
+
...page.previousSeq === void 0 ? {} : {
|
|
1303
|
+
previousCursor: encodeConversationCursor({
|
|
1304
|
+
conversationId,
|
|
1305
|
+
seq: page.previousSeq
|
|
1306
|
+
})
|
|
1307
|
+
},
|
|
1308
|
+
generatedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
1309
|
+
});
|
|
1310
|
+
}
|
|
1311
|
+
var event_list_default = defineApiRoute({
|
|
1312
|
+
method: "get",
|
|
1313
|
+
path: "/:conversationId/events",
|
|
1314
|
+
responseSchema: conversationEventPageSchema,
|
|
1315
|
+
handler: async (c) => {
|
|
1316
|
+
const { conversationId } = parseParams(
|
|
1317
|
+
conversationParamsSchema,
|
|
1318
|
+
c.req.param()
|
|
1028
1319
|
);
|
|
1320
|
+
const { before, limit } = parseQuery(
|
|
1321
|
+
conversationEventsQuerySchema,
|
|
1322
|
+
c.req.query()
|
|
1323
|
+
);
|
|
1324
|
+
const verifiedViewerEmail = c.get("verifiedViewerEmail");
|
|
1325
|
+
const report = await readConversationEvents(conversationId, before, {
|
|
1326
|
+
limit,
|
|
1327
|
+
...verifiedViewerEmail ? { verifiedViewerEmail } : {}
|
|
1328
|
+
});
|
|
1029
1329
|
if (!report) throwApiError(404, "Conversation not found.");
|
|
1030
1330
|
return report;
|
|
1031
1331
|
}
|
|
@@ -1325,7 +1625,13 @@ var stats_default = defineApiRoute({
|
|
|
1325
1625
|
});
|
|
1326
1626
|
|
|
1327
1627
|
// src/api/conversations/routes.ts
|
|
1328
|
-
var routes = [
|
|
1628
|
+
var routes = [
|
|
1629
|
+
list_default,
|
|
1630
|
+
stats_default,
|
|
1631
|
+
archive_default,
|
|
1632
|
+
event_list_default,
|
|
1633
|
+
detail_default
|
|
1634
|
+
];
|
|
1329
1635
|
function createConversationRoutes() {
|
|
1330
1636
|
const app = new Hono();
|
|
1331
1637
|
registerApiRoutes(app, routes);
|
|
@@ -1336,7 +1642,7 @@ function createConversationRoutes() {
|
|
|
1336
1642
|
import { Hono as Hono2 } from "hono";
|
|
1337
1643
|
|
|
1338
1644
|
// src/api/locations/query.ts
|
|
1339
|
-
import { and as and7, asc as asc3, desc as
|
|
1645
|
+
import { and as and7, asc as asc3, desc as desc3, eq as eq8, gte as gte2, isNull as isNull4, sql as sql6 } from "drizzle-orm";
|
|
1340
1646
|
import { alias as alias4 } from "drizzle-orm/pg-core";
|
|
1341
1647
|
|
|
1342
1648
|
// src/api/conversations/reporting.ts
|
|
@@ -1622,7 +1928,7 @@ async function recentLocationRows(db, locationId) {
|
|
|
1622
1928
|
isNull4(juniorConversations.archivedAt)
|
|
1623
1929
|
)
|
|
1624
1930
|
).orderBy(
|
|
1625
|
-
|
|
1931
|
+
desc3(juniorConversations.lastActivityAt),
|
|
1626
1932
|
asc3(juniorConversations.conversationId)
|
|
1627
1933
|
).limit(RECENT_LIMIT);
|
|
1628
1934
|
}
|
|
@@ -1803,7 +2109,7 @@ import { Hono as Hono3 } from "hono";
|
|
|
1803
2109
|
import { and as and9, eq as eq10, gte as gte3, sql as sql8 } from "drizzle-orm";
|
|
1804
2110
|
|
|
1805
2111
|
// src/api/people/shared.ts
|
|
1806
|
-
import { and as and8, asc as asc4, desc as
|
|
2112
|
+
import { and as and8, asc as asc4, desc as desc4, eq as eq9, isNull as isNull5, notExists, or, sql as sql7 } from "drizzle-orm";
|
|
1807
2113
|
import { alias as alias5 } from "drizzle-orm/pg-core";
|
|
1808
2114
|
var RECENT_LIMIT2 = 25;
|
|
1809
2115
|
var ACTIVITY_DAYS2 = 365;
|
|
@@ -1937,7 +2243,7 @@ async function recentActorRows(email) {
|
|
|
1937
2243
|
).where(
|
|
1938
2244
|
and8(verifiedActorWhere(email), isNull5(juniorConversations.archivedAt))
|
|
1939
2245
|
).orderBy(
|
|
1940
|
-
|
|
2246
|
+
desc4(juniorConversations.lastActivityAt),
|
|
1941
2247
|
asc4(juniorConversations.conversationId)
|
|
1942
2248
|
).limit(RECENT_LIMIT2);
|
|
1943
2249
|
}
|
|
@@ -2257,7 +2563,7 @@ function readDescriptionText(home) {
|
|
|
2257
2563
|
}
|
|
2258
2564
|
}
|
|
2259
2565
|
async function readSkillReports() {
|
|
2260
|
-
const { discoverSkills } = await import("./skills-
|
|
2566
|
+
const { discoverSkills } = await import("./skills-VCPG3NOO.js");
|
|
2261
2567
|
const skills = await discoverSkills();
|
|
2262
2568
|
return skillReportsSchema.parse(
|
|
2263
2569
|
skills.map((skill) => ({
|
|
@@ -2267,7 +2573,7 @@ async function readSkillReports() {
|
|
|
2267
2573
|
);
|
|
2268
2574
|
}
|
|
2269
2575
|
async function readPluginReports() {
|
|
2270
|
-
const { pluginCatalogRuntime } = await import("./catalog-runtime-
|
|
2576
|
+
const { pluginCatalogRuntime } = await import("./catalog-runtime-6XYOUVRZ.js");
|
|
2271
2577
|
return pluginReportsSchema.parse(
|
|
2272
2578
|
pluginCatalogRuntime.getProviders().map((plugin) => ({
|
|
2273
2579
|
name: plugin.manifest.name
|
|
@@ -2277,7 +2583,7 @@ async function readPluginReports() {
|
|
|
2277
2583
|
async function readRuntimeInfoReport() {
|
|
2278
2584
|
const [{ homeDir }, { pluginCatalogRuntime }, plugins, skills] = await Promise.all([
|
|
2279
2585
|
import("./discovery-RMHYSRL7.js"),
|
|
2280
|
-
import("./catalog-runtime-
|
|
2586
|
+
import("./catalog-runtime-6XYOUVRZ.js"),
|
|
2281
2587
|
readPluginReports(),
|
|
2282
2588
|
readSkillReports()
|
|
2283
2589
|
]);
|
|
@@ -2293,7 +2599,7 @@ async function readRuntimeInfoReport() {
|
|
|
2293
2599
|
}
|
|
2294
2600
|
async function readPluginOperationalReportFeed() {
|
|
2295
2601
|
const nowMs = Date.now();
|
|
2296
|
-
const { getPluginOperationalReports } = await import("./agent-hooks-
|
|
2602
|
+
const { getPluginOperationalReports } = await import("./agent-hooks-BKEMWR3Z.js");
|
|
2297
2603
|
return pluginOperationalReportFeedSchema.parse({
|
|
2298
2604
|
source: "plugins",
|
|
2299
2605
|
generatedAt: new Date(nowMs).toISOString(),
|