@sentry/junior 0.106.0 → 0.107.1
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-KR5BCWOK.js → agent-hooks-ICPIJAFY.js} +9 -7
- package/dist/api/conversations/detail.d.ts +1 -1
- package/dist/api/conversations/events.d.ts +14 -0
- package/dist/api/conversations/schema.d.ts +196 -463
- package/dist/api/schema.d.ts +2 -7
- package/dist/api/schema.js +10 -8
- package/dist/api.js +377 -810
- package/dist/app.js +3586 -3614
- package/dist/{catalog-runtime-5CVM2DOF.js → catalog-runtime-FOFNPR3P.js} +3 -2
- package/dist/chat/agent/prompt.d.ts +1 -1
- package/dist/chat/agent/request.d.ts +28 -29
- package/dist/chat/agent/resume.d.ts +7 -7
- package/dist/chat/agent/session.d.ts +5 -6
- package/dist/chat/agent/tools.d.ts +3 -3
- package/dist/chat/agent-dispatch/runner.d.ts +2 -0
- package/dist/chat/config.d.ts +2 -2
- package/dist/chat/conversations/history.d.ts +582 -167
- package/dist/chat/conversations/message-projection.d.ts +6 -0
- package/dist/chat/conversations/message-summaries.d.ts +9 -0
- package/dist/chat/conversations/messages.d.ts +13 -27
- package/dist/chat/conversations/projection.d.ts +30 -53
- package/dist/chat/conversations/provenance.d.ts +42 -0
- package/dist/chat/conversations/search.d.ts +2 -2
- package/dist/chat/conversations/sql/conversation-row.d.ts +1 -1
- package/dist/chat/conversations/sql/event-lock.d.ts +3 -0
- package/dist/chat/conversations/sql/history.d.ts +3 -3
- package/dist/chat/conversations/sql/privacy.d.ts +27 -0
- package/dist/chat/conversations/sql/purge.d.ts +2 -10
- package/dist/chat/conversations/sql/store.d.ts +0 -5
- package/dist/chat/conversations/store.d.ts +8 -13
- package/dist/chat/conversations/turn-lifecycle.d.ts +41 -0
- package/dist/chat/db.d.ts +4 -10
- package/dist/chat/model-profile.d.ts +10 -0
- package/dist/chat/oauth-flow.d.ts +0 -5
- package/dist/chat/pi/conversation-events.d.ts +33 -0
- package/dist/chat/pi/sql-model-usage.d.ts +10 -0
- package/dist/chat/plugins/agent-hooks.d.ts +4 -2
- package/dist/chat/resource-events/ingest.d.ts +0 -13
- package/dist/chat/runtime/delivered-turn-state.d.ts +1 -1
- package/dist/chat/runtime/generated-artifacts.d.ts +1 -1
- package/dist/chat/runtime/reply-executor.d.ts +2 -0
- package/dist/chat/runtime/slack-resume.d.ts +23 -28
- package/dist/chat/runtime/slack-runtime.d.ts +2 -0
- package/dist/chat/runtime/turn.d.ts +14 -1
- package/dist/chat/services/context-compaction-marker.d.ts +0 -1
- package/dist/chat/services/context-compaction.d.ts +1 -0
- package/dist/chat/services/conversation-memory.d.ts +9 -0
- package/dist/chat/services/plugin-auth-orchestration.d.ts +1 -4
- package/dist/chat/services/subscribed-decision.d.ts +1 -1
- package/dist/chat/services/turn-failure-response.d.ts +10 -3
- package/dist/chat/services/turn-result.d.ts +7 -12
- package/dist/chat/services/{turn-reasoning-level.d.ts → turn-router.d.ts} +12 -8
- package/dist/chat/services/turn-session-record.d.ts +15 -16
- package/dist/chat/slack/adapter.d.ts +2 -2
- package/dist/chat/slack/errors.d.ts +2 -0
- package/dist/chat/slack/outbound.d.ts +0 -1
- package/dist/chat/slack/reply.d.ts +2 -8
- package/dist/chat/slack/tools/channel-capabilities.d.ts +2 -2
- package/dist/chat/slack/tools/{send-message.d.ts → send-files.d.ts} +27 -19
- package/dist/chat/state/conversation.d.ts +4 -4
- package/dist/chat/state/turn-id.d.ts +2 -0
- package/dist/chat/state/turn-session-keys.d.ts +6 -0
- package/dist/chat/state/turn-session.d.ts +11 -9
- package/dist/chat/task-execution/state.d.ts +6 -1
- package/dist/chat/task-execution/store.d.ts +1 -1
- package/dist/chat/tool-support/pi-tool-adapter.d.ts +1 -1
- package/dist/chat/tool-support/tool-execution-report.d.ts +1 -0
- package/dist/chat/tools/handoff/tool.d.ts +2 -2
- package/dist/chat/tools/sandbox/file-uploads.d.ts +28 -6
- package/dist/chat/tools/types.d.ts +6 -9
- package/dist/chat/tools/web/image-generate.d.ts +4 -6
- package/dist/{chunk-DDRQ4U7I.js → chunk-4YF7Z6IA.js} +390 -270
- package/dist/{chunk-AZ5OMSN5.js → chunk-AUUOHQAT.js} +2 -2
- package/dist/chunk-B2Z2H66D.js +250 -0
- package/dist/{chunk-4W4O4DCV.js → chunk-CQ7KSO2B.js} +75 -45
- package/dist/{chunk-MJSJAHBW.js → chunk-DY7TRYB5.js} +1 -1
- package/dist/{chunk-GPPUTY5M.js → chunk-EDLNHZH3.js} +861 -891
- package/dist/{chunk-R5BFYK2O.js → chunk-IGHMVDWI.js} +134 -18
- package/dist/chunk-MU6HHZEN.js +99 -0
- package/dist/{chunk-XTKJPSMF.js → chunk-NVOTGWYX.js} +458 -684
- package/dist/{chunk-AEWZ7F65.js → chunk-O24R4DCK.js} +2 -179
- package/dist/{chunk-CCFROYAV.js → chunk-PUAMO4PI.js} +115 -125
- package/dist/{chunk-ZMRLBBD5.js → chunk-RMVOAJRL.js} +30 -13
- package/dist/{chunk-3NYUCBLE.js → chunk-SPUAJVVH.js} +6 -4
- package/dist/{chunk-4UYIRWDW.js → chunk-SS67LUOK.js} +41 -290
- package/dist/{chunk-FXFQNHRU.js → chunk-VFUK3X5B.js} +4 -2
- package/dist/{chunk-3MPPVPGZ.js → chunk-VH6KWKG2.js} +2 -2
- package/dist/chunk-VIXFG2VC.js +182 -0
- package/dist/{chunk-BKM4UXUD.js → chunk-YFQ7CQDE.js} +669 -18
- package/dist/{chunk-77LHNQK4.js → chunk-YIPD3L6L.js} +4 -2
- package/dist/{chunk-3OUSJPR7.js → chunk-YNP2ATQX.js} +6 -4
- package/dist/{chunk-WR7H7VLJ.js → chunk-YT72TOEK.js} +2 -2
- package/dist/cli/chat.js +21 -20
- package/dist/cli/check.js +4 -3
- package/dist/cli/plugins.js +11 -9
- package/dist/cli/snapshot-warmup.js +7 -5
- package/dist/cli/upgrade.js +2041 -105
- package/dist/db/schema/{agent-steps.d.ts → conversation-events.d.ts} +37 -21
- package/dist/db/schema.d.ts +28 -159
- package/dist/{db-S33LFWG2.js → db-DIGO4TGW.js} +6 -8
- package/dist/{runner-HA5XAL6K.js → runner-ACR2HAIC.js} +209 -101
- package/dist/{skills-722AXRV5.js → skills-ITNHBARB.js} +4 -3
- package/dist/{validation-EUI2UFRM.js → validation-AGQ46ZGV.js} +4 -3
- package/migrations/0005_conversation_events.sql +122 -0
- package/migrations/README.md +23 -10
- package/migrations/meta/0005_snapshot.json +948 -0
- package/migrations/meta/_journal.json +7 -0
- package/package.json +5 -5
- package/dist/api/conversations/activity.d.ts +0 -40
- package/dist/api/conversations/detail-projection.d.ts +0 -11
- package/dist/api/conversations/detail.query.d.ts +0 -3
- package/dist/api/conversations/subagent.d.ts +0 -10
- package/dist/api/conversations/transcript.d.ts +0 -28
- package/dist/chat/conversations/legacy-advisor-session.d.ts +0 -7
- package/dist/chat/conversations/legacy-import.d.ts +0 -38
- package/dist/chat/conversations/sql/legacy-history-import.d.ts +0 -55
- package/dist/chat/conversations/sql/messages.d.ts +0 -4
- package/dist/chat/conversations/visible-compactions.d.ts +0 -11
- package/dist/chat/conversations/visible-messages.d.ts +0 -47
- package/dist/chat/services/reply-delivery-plan.d.ts +0 -5
- package/dist/chat/state/session-log.d.ts +0 -384
- package/dist/chunk-P4P7O5WG.js +0 -1072
- package/dist/chunk-XIMUQ4IU.js +0 -147
- package/dist/db/schema/conversation-messages.d.ts +0 -153
- package/dist/handlers/github-webhook/check-suite.d.ts +0 -3
- package/dist/handlers/github-webhook/issue-comment.d.ts +0 -3
- package/dist/handlers/github-webhook/pull-request-review-comment.d.ts +0 -3
- package/dist/handlers/github-webhook/pull-request-review.d.ts +0 -3
- package/dist/handlers/github-webhook/pull-request.d.ts +0 -3
- package/dist/handlers/github-webhook/resource.d.ts +0 -10
- package/dist/handlers/github-webhook.d.ts +0 -15
- package/dist/legacy-import-TMJISRKO.js +0 -18
package/dist/api.js
CHANGED
|
@@ -6,21 +6,20 @@ import {
|
|
|
6
6
|
conversationFeedQuerySchema,
|
|
7
7
|
conversationFeedSchema,
|
|
8
8
|
conversationParamsSchema,
|
|
9
|
+
conversationReportEventSchema,
|
|
9
10
|
conversationStatsReportSchema,
|
|
10
|
-
conversationSubagentTranscriptReportSchema,
|
|
11
11
|
locationDetailReportSchema,
|
|
12
12
|
locationDirectoryReportSchema,
|
|
13
13
|
locationParamsSchema,
|
|
14
|
-
personParamsSchema
|
|
15
|
-
|
|
16
|
-
} from "./chunk-CCFROYAV.js";
|
|
14
|
+
personParamsSchema
|
|
15
|
+
} from "./chunk-PUAMO4PI.js";
|
|
17
16
|
import {
|
|
18
17
|
buildSentryConversationUrl,
|
|
19
|
-
buildSentryTraceUrl,
|
|
20
18
|
formatSlackConversationRedactedLabel,
|
|
19
|
+
readConversationEventPrivacySnapshot,
|
|
21
20
|
readHealthReport,
|
|
22
21
|
resolveSlackConversationContextFromThreadId
|
|
23
|
-
} from "./chunk-
|
|
22
|
+
} from "./chunk-IGHMVDWI.js";
|
|
24
23
|
import {
|
|
25
24
|
pluginOperationalReportFeedSchema,
|
|
26
25
|
pluginReportsSchema,
|
|
@@ -28,42 +27,33 @@ import {
|
|
|
28
27
|
skillReportsSchema
|
|
29
28
|
} from "./chunk-CEA3A3UA.js";
|
|
30
29
|
import {
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
} from "./chunk-DDRQ4U7I.js";
|
|
35
|
-
import "./chunk-P4P7O5WG.js";
|
|
30
|
+
agentTurnUsageSchema,
|
|
31
|
+
hasAgentTurnUsage
|
|
32
|
+
} from "./chunk-MU6HHZEN.js";
|
|
36
33
|
import "./chunk-PDO5BLNM.js";
|
|
37
|
-
import "./chunk-
|
|
34
|
+
import "./chunk-VH6KWKG2.js";
|
|
38
35
|
import {
|
|
39
|
-
|
|
40
|
-
getConversationMessageStore,
|
|
36
|
+
decodeStoredConversationEvent,
|
|
41
37
|
getDb,
|
|
38
|
+
getSqlExecutor,
|
|
39
|
+
juniorConversationEvents,
|
|
42
40
|
juniorConversations,
|
|
43
41
|
juniorIdentities,
|
|
44
42
|
juniorUsers
|
|
45
|
-
} from "./chunk-
|
|
43
|
+
} from "./chunk-NVOTGWYX.js";
|
|
46
44
|
import "./chunk-4ZNGQH7C.js";
|
|
47
|
-
import
|
|
48
|
-
stripRuntimeTurnContext,
|
|
49
|
-
unescapeXml,
|
|
50
|
-
unwrapCurrentInstruction
|
|
51
|
-
} from "./chunk-4UYIRWDW.js";
|
|
45
|
+
import "./chunk-SS67LUOK.js";
|
|
52
46
|
import {
|
|
53
47
|
juniorDestinations
|
|
54
|
-
} from "./chunk-
|
|
48
|
+
} from "./chunk-VFUK3X5B.js";
|
|
55
49
|
import {
|
|
56
50
|
canExposeConversationPayload,
|
|
57
51
|
parseSlackThreadId,
|
|
58
52
|
resolveConversationPrivacy
|
|
59
53
|
} from "./chunk-RT5BUHR5.js";
|
|
60
54
|
import "./chunk-B7PUBQQM.js";
|
|
61
|
-
import
|
|
62
|
-
|
|
63
|
-
} from "./chunk-AEWZ7F65.js";
|
|
64
|
-
import {
|
|
65
|
-
isRecord
|
|
66
|
-
} from "./chunk-OB42YVAE.js";
|
|
55
|
+
import "./chunk-O24R4DCK.js";
|
|
56
|
+
import "./chunk-OB42YVAE.js";
|
|
67
57
|
import "./chunk-6GWA276C.js";
|
|
68
58
|
import "./chunk-7FBGKXPE.js";
|
|
69
59
|
import "./chunk-MLKGABMK.js";
|
|
@@ -159,387 +149,223 @@ var archive_default = {
|
|
|
159
149
|
}
|
|
160
150
|
};
|
|
161
151
|
|
|
162
|
-
// src/
|
|
163
|
-
import {
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
var
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
}
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
}
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
${
|
|
193
|
-
}
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
}
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
}
|
|
209
|
-
function isDisplayableTranscriptPart(part) {
|
|
210
|
-
if (part.type !== "thinking") return true;
|
|
211
|
-
return typeof part.output === "string" && part.output.trim().length > 0;
|
|
212
|
-
}
|
|
213
|
-
function normalizeTranscriptPart(part, options = {}) {
|
|
214
|
-
const displayText = (text) => {
|
|
215
|
-
if (options.unwrapCurrentTask) {
|
|
216
|
-
const instruction = unwrapCurrentInstruction(text);
|
|
217
|
-
if (instruction !== void 0) return instruction;
|
|
218
|
-
}
|
|
219
|
-
if (options.unwrapLegacyAdvisorTask) {
|
|
220
|
-
return unwrapLegacyAdvisorTask(text) ?? text;
|
|
221
|
-
}
|
|
222
|
-
return text;
|
|
223
|
-
};
|
|
224
|
-
if (typeof part === "string") {
|
|
225
|
-
return textPart(displayText(part));
|
|
226
|
-
}
|
|
227
|
-
if (!isRecord(part)) {
|
|
228
|
-
return { type: "unknown", output: part };
|
|
229
|
-
}
|
|
230
|
-
const rawType = typeof part.type === "string" ? part.type : "unknown";
|
|
231
|
-
if (rawType === "text") {
|
|
232
|
-
const text = recordField(part, ["text", "content"]);
|
|
233
|
-
return textPart(
|
|
234
|
-
typeof text === "string" ? displayText(text) : JSON.stringify(text) ?? ""
|
|
235
|
-
);
|
|
236
|
-
}
|
|
237
|
-
if (rawType === "toolCall") {
|
|
238
|
-
return {
|
|
239
|
-
type: "tool_call",
|
|
240
|
-
...typeof part.id === "string" ? { id: part.id } : {},
|
|
241
|
-
...typeof part.name === "string" ? { name: part.name } : {},
|
|
242
|
-
input: recordField(part, ["arguments", "input", "args"])
|
|
243
|
-
};
|
|
244
|
-
}
|
|
245
|
-
if (rawType === "toolResult") {
|
|
246
|
-
return {
|
|
247
|
-
type: "tool_result",
|
|
248
|
-
...typeof part.id === "string" ? { id: part.id } : {},
|
|
249
|
-
...typeof part.name === "string" ? { name: part.name } : {},
|
|
250
|
-
output: recordField(part, ["result", "output", "content"])
|
|
251
|
-
};
|
|
252
|
-
}
|
|
253
|
-
if (rawType === "thinking") {
|
|
254
|
-
return {
|
|
255
|
-
type: "thinking",
|
|
256
|
-
output: thinkingOutput(part)
|
|
257
|
-
};
|
|
258
|
-
}
|
|
259
|
-
return {
|
|
260
|
-
type: "unknown",
|
|
261
|
-
...rawType !== "unknown" ? { sourceType: rawType } : {},
|
|
262
|
-
output: part
|
|
263
|
-
};
|
|
264
|
-
}
|
|
265
|
-
function normalizeToolResultMessage(record) {
|
|
266
|
-
const content = record.content;
|
|
267
|
-
let output = content;
|
|
268
|
-
if (Array.isArray(content) && content.length === 1 && isRecord(content[0])) {
|
|
269
|
-
const extracted = recordField(content[0], [
|
|
270
|
-
"text",
|
|
271
|
-
"content",
|
|
272
|
-
"output",
|
|
273
|
-
"result"
|
|
274
|
-
]);
|
|
275
|
-
output = extracted !== void 0 ? extracted : content;
|
|
276
|
-
}
|
|
277
|
-
return {
|
|
278
|
-
type: "tool_result",
|
|
279
|
-
...typeof record.toolCallId === "string" ? { id: record.toolCallId } : {},
|
|
280
|
-
...typeof record.name === "string" ? { name: record.name } : typeof record.toolName === "string" ? { name: record.toolName } : {},
|
|
281
|
-
output
|
|
152
|
+
// src/chat/pi/sql-model-usage.ts
|
|
153
|
+
import { and as and2, eq as eq2, sql } from "drizzle-orm";
|
|
154
|
+
var message = sql`${juniorConversationEvents.payload}->'message'`;
|
|
155
|
+
var usage = sql`${message}->'usage'`;
|
|
156
|
+
var cost = sql`${usage}->'cost'`;
|
|
157
|
+
function nonnegativeNumber(source, field, fallbackField, floor = false) {
|
|
158
|
+
const value = (name) => sql`case
|
|
159
|
+
when jsonb_typeof(${source}->${name}) = 'number'
|
|
160
|
+
and (${source}->>${name})::numeric >= 0
|
|
161
|
+
then ${floor ? sql`floor((${source}->>${name})::numeric)` : sql`(${source}->>${name})::numeric`}
|
|
162
|
+
end`;
|
|
163
|
+
const primary = value(field);
|
|
164
|
+
return fallbackField ? sql`coalesce(${primary}, ${value(fallbackField)})` : sql`${primary}`;
|
|
165
|
+
}
|
|
166
|
+
function token(field, fallbackField) {
|
|
167
|
+
return nonnegativeNumber(usage, field, fallbackField, true);
|
|
168
|
+
}
|
|
169
|
+
function summed(value) {
|
|
170
|
+
return sql`sum(${value})::double precision`;
|
|
171
|
+
}
|
|
172
|
+
function summedCost(value) {
|
|
173
|
+
return sql`round(sum(${value}), 12)::double precision`;
|
|
174
|
+
}
|
|
175
|
+
function messageTotalTokens(args) {
|
|
176
|
+
const { input, output, cacheRead, cacheWrite } = args;
|
|
177
|
+
return sql`case
|
|
178
|
+
when ${input} is not null
|
|
179
|
+
or ${output} is not null
|
|
180
|
+
or ${cacheRead} is not null
|
|
181
|
+
or ${cacheWrite} is not null
|
|
182
|
+
then coalesce(${input}, 0)
|
|
183
|
+
+ coalesce(${output}, 0)
|
|
184
|
+
+ coalesce(${cacheRead}, 0)
|
|
185
|
+
+ coalesce(${cacheWrite}, 0)
|
|
186
|
+
else ${token("totalTokens")}
|
|
187
|
+
end`;
|
|
188
|
+
}
|
|
189
|
+
function definedNumber(value) {
|
|
190
|
+
return value === null ? void 0 : value;
|
|
191
|
+
}
|
|
192
|
+
function usageFromRow(row) {
|
|
193
|
+
const components = {
|
|
194
|
+
inputTokens: definedNumber(row.inputTokens),
|
|
195
|
+
outputTokens: definedNumber(row.outputTokens),
|
|
196
|
+
cachedInputTokens: definedNumber(row.cachedInputTokens),
|
|
197
|
+
cacheCreationTokens: definedNumber(row.cacheCreationTokens)
|
|
282
198
|
};
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
unwrapLegacyAdvisorTask: subagentKind === "advisor"
|
|
290
|
-
});
|
|
291
|
-
}
|
|
292
|
-
function normalizeMessage(message, options = {}) {
|
|
293
|
-
const record = message;
|
|
294
|
-
const content = record.content;
|
|
295
|
-
const role = transcriptRole(record.role);
|
|
296
|
-
return {
|
|
297
|
-
role,
|
|
298
|
-
...role === "assistant" && (record.stopReason === "error" || record.stopReason === "aborted") ? { outcome: record.stopReason } : {},
|
|
299
|
-
...typeof record.timestamp === "number" ? { timestamp: record.timestamp } : {},
|
|
300
|
-
parts: role === "toolResult" ? [normalizeToolResultMessage(record)] : Array.isArray(content) ? content.map(
|
|
301
|
-
(part) => normalizeTranscriptPart(part, {
|
|
302
|
-
unwrapCurrentTask: role === "user",
|
|
303
|
-
unwrapLegacyAdvisorTask: options.unwrapLegacyAdvisorTask && role === "user"
|
|
304
|
-
})
|
|
305
|
-
).filter(isDisplayableTranscriptPart) : [
|
|
306
|
-
normalizeTranscriptPart(content, {
|
|
307
|
-
unwrapCurrentTask: role === "user",
|
|
308
|
-
unwrapLegacyAdvisorTask: options.unwrapLegacyAdvisorTask && role === "user"
|
|
309
|
-
})
|
|
310
|
-
]
|
|
199
|
+
const costFields = {
|
|
200
|
+
input: definedNumber(row.costInput),
|
|
201
|
+
output: definedNumber(row.costOutput),
|
|
202
|
+
cacheRead: definedNumber(row.costCacheRead),
|
|
203
|
+
cacheWrite: definedNumber(row.costCacheWrite),
|
|
204
|
+
total: definedNumber(row.costTotal)
|
|
311
205
|
};
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
return role === "assistant" || role === "system" || role === "tool" || role === "toolResult" || role === "user" ? role : "unknown";
|
|
315
|
-
}
|
|
316
|
-
function serializedChars(value) {
|
|
317
|
-
if (typeof value === "string") return value.length;
|
|
318
|
-
return JSON.stringify(value)?.length ?? 0;
|
|
319
|
-
}
|
|
320
|
-
function serializedBytes(value) {
|
|
321
|
-
const serialized = typeof value === "string" ? value : JSON.stringify(value);
|
|
322
|
-
return new TextEncoder().encode(serialized ?? "").byteLength;
|
|
323
|
-
}
|
|
324
|
-
function payloadType(value) {
|
|
325
|
-
return Array.isArray(value) ? "array" : typeof value;
|
|
326
|
-
}
|
|
327
|
-
function payloadKeys(value) {
|
|
328
|
-
if (!value || typeof value !== "object" || Array.isArray(value)) {
|
|
329
|
-
return void 0;
|
|
330
|
-
}
|
|
331
|
-
const keys = Object.keys(value).slice(
|
|
332
|
-
0,
|
|
333
|
-
SAFE_METADATA_KEY_LIMIT
|
|
206
|
+
const definedCost = Object.fromEntries(
|
|
207
|
+
Object.entries(costFields).filter(([, value]) => value !== void 0)
|
|
334
208
|
);
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
[`${prefix}SizeChars`]: serializedChars(value),
|
|
343
|
-
...keys ? { [`${prefix}Keys`]: keys } : {}
|
|
344
|
-
};
|
|
345
|
-
}
|
|
346
|
-
function redactTranscriptPart(part) {
|
|
347
|
-
if (part.type === "text") {
|
|
348
|
-
return {
|
|
349
|
-
type: "text",
|
|
350
|
-
redacted: true,
|
|
351
|
-
bytes: serializedBytes(part.text ?? ""),
|
|
352
|
-
chars: serializedChars(part.text ?? "")
|
|
353
|
-
};
|
|
354
|
-
}
|
|
355
|
-
if (part.type === "thinking") {
|
|
356
|
-
return {
|
|
357
|
-
type: "thinking",
|
|
358
|
-
redacted: true,
|
|
359
|
-
...redactedPayloadFields("output", part.output)
|
|
360
|
-
};
|
|
361
|
-
}
|
|
362
|
-
if (part.type === "tool_call") {
|
|
363
|
-
return {
|
|
364
|
-
type: "tool_call",
|
|
365
|
-
redacted: true,
|
|
366
|
-
...part.id ? { id: part.id } : {},
|
|
367
|
-
...part.name ? { name: part.name } : {},
|
|
368
|
-
...redactedPayloadFields("input", part.input)
|
|
369
|
-
};
|
|
370
|
-
}
|
|
371
|
-
if (part.type === "tool_result") {
|
|
372
|
-
return {
|
|
373
|
-
type: "tool_result",
|
|
374
|
-
redacted: true,
|
|
375
|
-
...part.id ? { id: part.id } : {},
|
|
376
|
-
...part.name ? { name: part.name } : {},
|
|
377
|
-
...redactedPayloadFields("output", part.output)
|
|
378
|
-
};
|
|
379
|
-
}
|
|
380
|
-
return {
|
|
381
|
-
type: "unknown",
|
|
382
|
-
redacted: true,
|
|
383
|
-
...part.sourceType ? { sourceType: part.sourceType } : {},
|
|
384
|
-
...redactedPayloadFields("output", part.output ?? part.input ?? part.text)
|
|
385
|
-
};
|
|
386
|
-
}
|
|
387
|
-
function redactTranscriptMessage(message) {
|
|
388
|
-
return {
|
|
389
|
-
role: message.role,
|
|
390
|
-
...message.outcome ? { outcome: message.outcome } : {},
|
|
391
|
-
...typeof message.timestamp === "number" ? { timestamp: message.timestamp } : {},
|
|
392
|
-
parts: message.parts.map(redactTranscriptPart)
|
|
209
|
+
const result = {
|
|
210
|
+
...Object.fromEntries(
|
|
211
|
+
Object.entries(components).filter(([, value]) => value !== void 0)
|
|
212
|
+
),
|
|
213
|
+
...row.reasoningTokens === null ? {} : { reasoningTokens: row.reasoningTokens },
|
|
214
|
+
...row.totalTokens === null ? {} : { totalTokens: row.totalTokens },
|
|
215
|
+
...Object.keys(definedCost).length > 0 ? { cost: definedCost } : {}
|
|
393
216
|
};
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
}
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
217
|
+
return hasAgentTurnUsage(result) ? agentTurnUsageSchema.parse(result) : void 0;
|
|
218
|
+
}
|
|
219
|
+
async function readConversationModelUsageFromSql(executor, conversationId) {
|
|
220
|
+
const modelId = sql`concat(${message}->>'provider', '/', ${message}->>'model')`;
|
|
221
|
+
const inputTokens = token("input", "inputTokens");
|
|
222
|
+
const outputTokens = token("output", "outputTokens");
|
|
223
|
+
const cachedInputTokens = token("cacheRead", "cachedInputTokens");
|
|
224
|
+
const cacheCreationTokens = token("cacheWrite", "cacheCreationTokens");
|
|
225
|
+
const rows = await executor.db().select({
|
|
226
|
+
modelId,
|
|
227
|
+
inputTokens: summed(inputTokens),
|
|
228
|
+
outputTokens: summed(outputTokens),
|
|
229
|
+
cachedInputTokens: summed(cachedInputTokens),
|
|
230
|
+
cacheCreationTokens: summed(cacheCreationTokens),
|
|
231
|
+
reasoningTokens: summed(token("reasoning", "reasoningTokens")),
|
|
232
|
+
totalTokens: summed(
|
|
233
|
+
messageTotalTokens({
|
|
234
|
+
input: inputTokens,
|
|
235
|
+
output: outputTokens,
|
|
236
|
+
cacheRead: cachedInputTokens,
|
|
237
|
+
cacheWrite: cacheCreationTokens
|
|
238
|
+
})
|
|
239
|
+
),
|
|
240
|
+
costInput: summedCost(nonnegativeNumber(cost, "input")),
|
|
241
|
+
costOutput: summedCost(nonnegativeNumber(cost, "output")),
|
|
242
|
+
costCacheRead: summedCost(nonnegativeNumber(cost, "cacheRead")),
|
|
243
|
+
costCacheWrite: summedCost(nonnegativeNumber(cost, "cacheWrite")),
|
|
244
|
+
costTotal: summedCost(nonnegativeNumber(cost, "total"))
|
|
245
|
+
}).from(juniorConversationEvents).where(
|
|
246
|
+
and2(
|
|
247
|
+
eq2(juniorConversationEvents.conversationId, conversationId),
|
|
248
|
+
eq2(juniorConversationEvents.type, "agent_step"),
|
|
249
|
+
sql`${message}->>'role' = 'assistant'`,
|
|
250
|
+
sql`jsonb_typeof(${message}->'provider') = 'string'`,
|
|
251
|
+
sql`jsonb_typeof(${message}->'model') = 'string'`,
|
|
252
|
+
sql`coalesce(${message}->>'provider', '') <> ''`,
|
|
253
|
+
sql`coalesce(${message}->>'model', '') <> ''`
|
|
254
|
+
)
|
|
255
|
+
).groupBy(modelId).orderBy(modelId);
|
|
256
|
+
return rows.flatMap((row) => {
|
|
257
|
+
const modelUsage = usageFromRow(row);
|
|
258
|
+
return modelUsage ? [{ modelId: row.modelId, usage: modelUsage }] : [];
|
|
403
259
|
});
|
|
404
260
|
}
|
|
405
|
-
function isConversationMessage(message) {
|
|
406
|
-
if (!isConversationMessageRole(message.role)) return false;
|
|
407
|
-
if (message.role === "assistant") return hasTextPart(message);
|
|
408
|
-
return message.parts.length > 0;
|
|
409
|
-
}
|
|
410
|
-
function countConversationMessages(transcript) {
|
|
411
|
-
return transcript.filter(isConversationMessage).length;
|
|
412
|
-
}
|
|
413
|
-
function traceIdFromTranscript(transcript) {
|
|
414
|
-
for (const message of transcript) {
|
|
415
|
-
for (const part of message.parts) {
|
|
416
|
-
const text = part.text ?? (typeof part.output === "string" ? part.output : typeof part.input === "string" ? part.input : void 0);
|
|
417
|
-
const match = text?.match(
|
|
418
|
-
/\btrace[_-]?id["']?\s*[:=]\s*["']?([a-f0-9]{16,32})\b/i
|
|
419
|
-
);
|
|
420
|
-
if (match?.[1]) {
|
|
421
|
-
return match[1];
|
|
422
|
-
}
|
|
423
|
-
}
|
|
424
|
-
}
|
|
425
|
-
return void 0;
|
|
426
|
-
}
|
|
427
|
-
function subagentTranscriptReport(activity, options = {}) {
|
|
428
|
-
return {
|
|
429
|
-
type: "subagent",
|
|
430
|
-
...options.subagentConversationId ? { subagentConversationId: options.subagentConversationId } : {},
|
|
431
|
-
createdAt: activity.createdAt,
|
|
432
|
-
id: activity.id,
|
|
433
|
-
...activity.modelId ? { modelId: activity.modelId } : {},
|
|
434
|
-
status: activity.status,
|
|
435
|
-
...options.subagentSentryConversationUrl ? { subagentSentryConversationUrl: options.subagentSentryConversationUrl } : {},
|
|
436
|
-
subagentKind: activity.subagentKind,
|
|
437
|
-
transcript: options.transcript ?? [],
|
|
438
|
-
transcriptAvailable: Boolean(options.transcript?.length),
|
|
439
|
-
...activity.endedAt ? { endedAt: activity.endedAt } : {},
|
|
440
|
-
...activity.outcome ? { outcome: activity.outcome } : {},
|
|
441
|
-
...activity.parentToolCallId ? { parentToolCallId: activity.parentToolCallId } : {},
|
|
442
|
-
...activity.reasoningLevel ? { reasoningLevel: activity.reasoningLevel } : {},
|
|
443
|
-
...options.transcriptMessageCount !== void 0 ? { transcriptMessageCount: options.transcriptMessageCount } : {},
|
|
444
|
-
...options.transcriptRedacted ? { transcriptRedacted: options.transcriptRedacted } : {},
|
|
445
|
-
...options.transcriptRedactionReason ? { transcriptRedactionReason: options.transcriptRedactionReason } : {},
|
|
446
|
-
...options.transcriptExpired ? { transcriptExpired: options.transcriptExpired } : {},
|
|
447
|
-
...options.transcriptExpiredAt ? { transcriptExpiredAt: options.transcriptExpiredAt } : {},
|
|
448
|
-
...options.unavailableReason ? { unavailableReason: options.unavailableReason } : {}
|
|
449
|
-
};
|
|
450
|
-
}
|
|
451
261
|
|
|
452
|
-
// src/api/conversations/
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
262
|
+
// src/api/conversations/events.ts
|
|
263
|
+
var conversationReportSourceEventTypes = [
|
|
264
|
+
"message",
|
|
265
|
+
"message_handled",
|
|
266
|
+
"tool_execution_started",
|
|
267
|
+
"turn_started",
|
|
268
|
+
"turn_completed",
|
|
269
|
+
"turn_failed",
|
|
270
|
+
"compaction",
|
|
271
|
+
"handoff",
|
|
272
|
+
"subagent_started",
|
|
273
|
+
"subagent_ended"
|
|
274
|
+
];
|
|
275
|
+
function reportEventData(args) {
|
|
276
|
+
const { data } = args;
|
|
277
|
+
switch (data.type) {
|
|
278
|
+
case "message":
|
|
279
|
+
return {
|
|
280
|
+
type: "message",
|
|
281
|
+
messageId: data.messageId,
|
|
282
|
+
role: data.role,
|
|
283
|
+
...args.canExposePayload ? { text: data.text } : { redacted: true }
|
|
284
|
+
};
|
|
285
|
+
case "message_handled":
|
|
286
|
+
return {
|
|
287
|
+
type: "message_handled",
|
|
288
|
+
messageId: data.messageId
|
|
289
|
+
};
|
|
290
|
+
case "turn_started":
|
|
291
|
+
return {
|
|
292
|
+
type: "turn_lifecycle",
|
|
293
|
+
turnId: data.turnId,
|
|
294
|
+
state: "started"
|
|
295
|
+
};
|
|
296
|
+
case "turn_completed":
|
|
297
|
+
return {
|
|
298
|
+
type: "turn_lifecycle",
|
|
299
|
+
turnId: data.turnId,
|
|
300
|
+
state: data.outcome === "success" ? "succeeded" : "no_reply"
|
|
301
|
+
};
|
|
302
|
+
case "turn_failed":
|
|
303
|
+
return {
|
|
304
|
+
type: "turn_lifecycle",
|
|
305
|
+
turnId: data.turnId,
|
|
306
|
+
state: "failed",
|
|
307
|
+
failureKind: data.failureCode === "delivery_failed" ? "delivery" : "agent"
|
|
308
|
+
};
|
|
309
|
+
case "compaction":
|
|
310
|
+
return { type: "compaction" };
|
|
311
|
+
default:
|
|
312
|
+
return void 0;
|
|
313
|
+
}
|
|
314
|
+
}
|
|
315
|
+
function projectConversationReportEvents(args) {
|
|
316
|
+
const subagentStarts = /* @__PURE__ */ new Map();
|
|
317
|
+
const toolStarts = /* @__PURE__ */ new Map();
|
|
318
|
+
const projected = [];
|
|
319
|
+
for (const event of args.events) {
|
|
320
|
+
let data;
|
|
321
|
+
if (event.data.type === "tool_execution_started") {
|
|
322
|
+
toolStarts.set(event.data.toolCallId, event.seq);
|
|
323
|
+
data = { type: "tool_started", name: event.data.toolName };
|
|
324
|
+
} else if (event.data.type === "subagent_started") {
|
|
325
|
+
subagentStarts.set(event.data.subagentInvocationId, event.seq);
|
|
326
|
+
const toolStartedSeq = event.data.parentToolCallId ? toolStarts.get(event.data.parentToolCallId) : void 0;
|
|
327
|
+
data = {
|
|
328
|
+
type: "subagent_started",
|
|
329
|
+
childConversationId: event.data.childConversationId,
|
|
330
|
+
subagentKind: event.data.subagentKind,
|
|
331
|
+
...toolStartedSeq === void 0 ? {} : { toolStartedSeq }
|
|
332
|
+
};
|
|
333
|
+
} else if (event.data.type === "subagent_ended") {
|
|
334
|
+
const startedSeq = subagentStarts.get(event.data.subagentInvocationId);
|
|
335
|
+
if (startedSeq !== void 0) {
|
|
336
|
+
data = {
|
|
337
|
+
type: "subagent_ended",
|
|
338
|
+
startedSeq,
|
|
339
|
+
outcome: event.data.outcome
|
|
340
|
+
};
|
|
341
|
+
}
|
|
342
|
+
} else if (event.data.type === "handoff") {
|
|
343
|
+
const toolStartedSeq = event.data.triggeringToolCallId ? toolStarts.get(event.data.triggeringToolCallId) : void 0;
|
|
344
|
+
data = {
|
|
345
|
+
type: "handoff",
|
|
346
|
+
...toolStartedSeq === void 0 ? {} : { toolStartedSeq }
|
|
347
|
+
};
|
|
348
|
+
} else {
|
|
349
|
+
data = reportEventData({
|
|
350
|
+
canExposePayload: args.canExposePayload,
|
|
351
|
+
data: event.data
|
|
352
|
+
});
|
|
486
353
|
}
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
354
|
+
if (!data) continue;
|
|
355
|
+
projected.push(
|
|
356
|
+
conversationReportEventSchema.parse({
|
|
357
|
+
seq: event.seq,
|
|
358
|
+
createdAt: new Date(event.createdAtMs).toISOString(),
|
|
359
|
+
data
|
|
360
|
+
})
|
|
493
361
|
);
|
|
494
|
-
if (start.entry.parentToolCallId) {
|
|
495
|
-
subagentsByToolCallId.set(start.entry.parentToolCallId, [
|
|
496
|
-
...subagentsByToolCallId.get(start.entry.parentToolCallId) ?? [],
|
|
497
|
-
activity
|
|
498
|
-
]);
|
|
499
|
-
continue;
|
|
500
|
-
}
|
|
501
|
-
orphanSubagents.push(activity);
|
|
502
|
-
}
|
|
503
|
-
const rows = [];
|
|
504
|
-
for (const step of args.steps) {
|
|
505
|
-
if (step.entry.type !== "tool_execution_started") {
|
|
506
|
-
continue;
|
|
507
|
-
}
|
|
508
|
-
rows.push({
|
|
509
|
-
type: "tool_execution",
|
|
510
|
-
id: step.entry.toolCallId,
|
|
511
|
-
toolCallId: step.entry.toolCallId,
|
|
512
|
-
toolName: step.entry.toolName,
|
|
513
|
-
createdAt: new Date(step.createdAtMs).toISOString(),
|
|
514
|
-
status: toolStatuses.get(step.entry.toolCallId) ?? "running",
|
|
515
|
-
subagents: subagentsByToolCallId.get(step.entry.toolCallId) ?? [],
|
|
516
|
-
...activityPayloadFields(step.entry.args, args.canExposePayload)
|
|
517
|
-
});
|
|
518
362
|
}
|
|
519
|
-
return
|
|
520
|
-
(left, right) => Date.parse(left.createdAt) - Date.parse(right.createdAt) || left.id.localeCompare(right.id)
|
|
521
|
-
);
|
|
522
|
-
}
|
|
523
|
-
function subagentActivityFromSteps(start, end, options = {}) {
|
|
524
|
-
return {
|
|
525
|
-
type: "subagent",
|
|
526
|
-
id: start.entry.subagentInvocationId,
|
|
527
|
-
subagentKind: start.entry.subagentKind,
|
|
528
|
-
...start.entry.modelId ? { modelId: start.entry.modelId } : {},
|
|
529
|
-
...start.entry.parentToolCallId ? { parentToolCallId: start.entry.parentToolCallId } : {},
|
|
530
|
-
...start.entry.reasoningLevel ? { reasoningLevel: start.entry.reasoningLevel } : {},
|
|
531
|
-
createdAt: new Date(start.createdAtMs).toISOString(),
|
|
532
|
-
...end ? {
|
|
533
|
-
endedAt: new Date(end.createdAtMs).toISOString(),
|
|
534
|
-
outcome: end.entry.outcome,
|
|
535
|
-
status: end.entry.outcome,
|
|
536
|
-
// Every subagent is a child conversation whose transcript loads on
|
|
537
|
-
// demand; expose the affordance only when the parent is public.
|
|
538
|
-
...options.canExposeTranscript ? { transcriptAvailable: true } : {}
|
|
539
|
-
} : { status: options.parentStatus ?? "running" }
|
|
540
|
-
};
|
|
363
|
+
return projected;
|
|
541
364
|
}
|
|
542
365
|
|
|
366
|
+
// src/api/conversations/list.ts
|
|
367
|
+
import { and as and3, asc, desc, eq as eq3, isNull } from "drizzle-orm";
|
|
368
|
+
|
|
543
369
|
// src/api/conversations/shared.ts
|
|
544
370
|
function slackStatsLocationLabel(input) {
|
|
545
371
|
const channelId = input.channel;
|
|
@@ -648,7 +474,7 @@ function channelNameRedactedFromConversation(conversation) {
|
|
|
648
474
|
}) !== "public";
|
|
649
475
|
}
|
|
650
476
|
function conversationSummaryFromStoredConversation(args) {
|
|
651
|
-
const { conversation, durationMs, usage } = args;
|
|
477
|
+
const { conversation, durationMs, usage: usage2 } = args;
|
|
652
478
|
const surface = surfaceFromSource(
|
|
653
479
|
conversation.source,
|
|
654
480
|
conversation.conversationId
|
|
@@ -668,7 +494,7 @@ function conversationSummaryFromStoredConversation(args) {
|
|
|
668
494
|
startedAt: new Date(conversation.createdAtMs).toISOString(),
|
|
669
495
|
status: statusFromConversation(conversation),
|
|
670
496
|
surface,
|
|
671
|
-
...
|
|
497
|
+
...usage2 ? { cumulativeUsage: usage2 } : {},
|
|
672
498
|
...actorIdentity ? { actorIdentity } : {},
|
|
673
499
|
...conversation.archivedAtMs ? { archivedAt: new Date(conversation.archivedAtMs).toISOString() } : {},
|
|
674
500
|
...slackThread ? { channel: slackThread.channelId } : {},
|
|
@@ -678,269 +504,7 @@ function conversationSummaryFromStoredConversation(args) {
|
|
|
678
504
|
};
|
|
679
505
|
}
|
|
680
506
|
|
|
681
|
-
// src/api/conversations/detail-projection.ts
|
|
682
|
-
var COMPACTION_SUMMARY_PREFIXES = [
|
|
683
|
-
"Context compaction summary for future Junior turns:",
|
|
684
|
-
"Context handoff summary for future Junior turns:"
|
|
685
|
-
];
|
|
686
|
-
var MODEL_HANDOFF_SUMMARY_PREFIX = "Model handoff checkpoint. Continue the outstanding request now using this summary as the complete prior context:";
|
|
687
|
-
function messageText(message) {
|
|
688
|
-
return normalizeTranscriptMessage(message).parts.filter((part) => part.type === "text").map((part) => part.text ?? "").join("\n").trim();
|
|
689
|
-
}
|
|
690
|
-
function summaryAfterPrefix(message, prefixes) {
|
|
691
|
-
const text = messageText(message);
|
|
692
|
-
const prefix = prefixes.find((candidate) => text.startsWith(candidate));
|
|
693
|
-
if (!prefix) return void 0;
|
|
694
|
-
return text.slice(prefix.length).trim();
|
|
695
|
-
}
|
|
696
|
-
function summaryIndex(messages, provenance, prefixes) {
|
|
697
|
-
for (let index = messages.length - 1; index >= 0; index -= 1) {
|
|
698
|
-
if (provenance[index]?.authority === "context" && summaryAfterPrefix(messages[index], prefixes) !== void 0) {
|
|
699
|
-
return index;
|
|
700
|
-
}
|
|
701
|
-
}
|
|
702
|
-
return -1;
|
|
703
|
-
}
|
|
704
|
-
function matchingPrefix(left, right) {
|
|
705
|
-
const limit = Math.min(left.length, right.length);
|
|
706
|
-
for (let index = 0; index < limit; index += 1) {
|
|
707
|
-
if (!isDeepStrictEqual(left[index], right[index])) return index;
|
|
708
|
-
}
|
|
709
|
-
return limit;
|
|
710
|
-
}
|
|
711
|
-
function historyContent(args) {
|
|
712
|
-
const contextEvents = [];
|
|
713
|
-
const messages = [];
|
|
714
|
-
const epochs = /* @__PURE__ */ new Map();
|
|
715
|
-
for (const step of args.steps) {
|
|
716
|
-
const epoch = epochs.get(step.contextEpoch);
|
|
717
|
-
if (epoch) epoch.push(step);
|
|
718
|
-
else epochs.set(step.contextEpoch, [step]);
|
|
719
|
-
}
|
|
720
|
-
let previousModelId;
|
|
721
|
-
let previousProjection = [];
|
|
722
|
-
for (const steps of epochs.values()) {
|
|
723
|
-
const marker = steps.find(
|
|
724
|
-
(step) => step.entry.type === "context_epoch_started"
|
|
725
|
-
);
|
|
726
|
-
const projection = projectSteps(steps);
|
|
727
|
-
const projected = [];
|
|
728
|
-
const projectedProvenance = [];
|
|
729
|
-
projection.messages.forEach((message, index) => {
|
|
730
|
-
for (const retained of stripRuntimeTurnContext([message])) {
|
|
731
|
-
projected.push(retained);
|
|
732
|
-
projectedProvenance.push(projection.provenance[index]);
|
|
733
|
-
}
|
|
734
|
-
});
|
|
735
|
-
const replacementSummaryIndex = marker?.entry.reason === "compaction" ? summaryIndex(
|
|
736
|
-
projected,
|
|
737
|
-
projectedProvenance,
|
|
738
|
-
COMPACTION_SUMMARY_PREFIXES
|
|
739
|
-
) : marker?.entry.reason === "handoff" ? summaryIndex(projected, projectedProvenance, [
|
|
740
|
-
MODEL_HANDOFF_SUMMARY_PREFIX
|
|
741
|
-
]) : -1;
|
|
742
|
-
const summary = marker?.entry.reason === "compaction" && replacementSummaryIndex >= 0 ? summaryAfterPrefix(
|
|
743
|
-
projected[replacementSummaryIndex],
|
|
744
|
-
COMPACTION_SUMMARY_PREFIXES
|
|
745
|
-
) : void 0;
|
|
746
|
-
const handoffMessage = marker?.entry.reason === "handoff" && replacementSummaryIndex >= 0 ? messageText(projected[replacementSummaryIndex]) || void 0 : void 0;
|
|
747
|
-
if (marker?.entry.reason === "compaction") {
|
|
748
|
-
contextEvents.push({
|
|
749
|
-
type: "context_compacted",
|
|
750
|
-
createdAt: new Date(marker.createdAtMs).toISOString(),
|
|
751
|
-
...marker.entry.modelId ? { modelId: marker.entry.modelId } : {},
|
|
752
|
-
...args.canExposePayload && summary ? { summary } : {},
|
|
753
|
-
transcriptIndex: messages.length
|
|
754
|
-
});
|
|
755
|
-
} else if (marker?.entry.reason === "handoff") {
|
|
756
|
-
contextEvents.push({
|
|
757
|
-
type: "model_handoff",
|
|
758
|
-
createdAt: new Date(marker.createdAtMs).toISOString(),
|
|
759
|
-
...previousModelId ? { fromModelId: previousModelId } : {},
|
|
760
|
-
toModelId: marker.entry.modelId,
|
|
761
|
-
...args.canExposePayload && handoffMessage ? { message: handoffMessage } : {},
|
|
762
|
-
transcriptIndex: messages.length
|
|
763
|
-
});
|
|
764
|
-
}
|
|
765
|
-
if (marker?.entry.reason === "rollback") {
|
|
766
|
-
messages.push(
|
|
767
|
-
...projected.slice(matchingPrefix(previousProjection, projected))
|
|
768
|
-
);
|
|
769
|
-
} else {
|
|
770
|
-
const copiedMessageIndexes = /* @__PURE__ */ new Set();
|
|
771
|
-
projected.forEach((message, index) => {
|
|
772
|
-
if (index === replacementSummaryIndex) return;
|
|
773
|
-
let copiedCompactionMessage = false;
|
|
774
|
-
if (marker?.entry.reason === "compaction" && replacementSummaryIndex >= 0 && index < replacementSummaryIndex) {
|
|
775
|
-
const copiedIndex = messages.findIndex(
|
|
776
|
-
(candidate, candidateIndex) => !copiedMessageIndexes.has(candidateIndex) && isDeepStrictEqual(candidate, message)
|
|
777
|
-
);
|
|
778
|
-
copiedCompactionMessage = copiedIndex >= 0;
|
|
779
|
-
if (copiedCompactionMessage) copiedMessageIndexes.add(copiedIndex);
|
|
780
|
-
}
|
|
781
|
-
if (!copiedCompactionMessage) messages.push(message);
|
|
782
|
-
});
|
|
783
|
-
}
|
|
784
|
-
previousModelId = marker?.entry.modelId ?? previousModelId;
|
|
785
|
-
previousProjection = projected;
|
|
786
|
-
}
|
|
787
|
-
return { contextEvents, messages };
|
|
788
|
-
}
|
|
789
|
-
async function conversationContent(args) {
|
|
790
|
-
const steps = await args.stepStore.loadHistory(args.conversationId);
|
|
791
|
-
const history = historyContent({
|
|
792
|
-
canExposePayload: args.canExposePayload,
|
|
793
|
-
steps
|
|
794
|
-
});
|
|
795
|
-
const messages = history.messages;
|
|
796
|
-
const transcript = messages.length > 0 ? messages.map((message) => normalizeTranscriptMessage(message)) : (await args.messageStore.list(args.conversationId)).map(
|
|
797
|
-
visibleMessageTranscript
|
|
798
|
-
);
|
|
799
|
-
return {
|
|
800
|
-
activity: buildConversationActivityFromSteps({
|
|
801
|
-
canExposePayload: args.canExposePayload,
|
|
802
|
-
steps,
|
|
803
|
-
messages
|
|
804
|
-
}),
|
|
805
|
-
contextEvents: history.contextEvents,
|
|
806
|
-
transcript
|
|
807
|
-
};
|
|
808
|
-
}
|
|
809
|
-
function visibleMessageTranscript(message) {
|
|
810
|
-
return {
|
|
811
|
-
role: message.role,
|
|
812
|
-
timestamp: message.createdAtMs,
|
|
813
|
-
parts: [{ type: "text", text: message.text }]
|
|
814
|
-
};
|
|
815
|
-
}
|
|
816
|
-
async function buildConversationDetail(args) {
|
|
817
|
-
const { conversation } = args;
|
|
818
|
-
const conversationId = conversation.conversationId;
|
|
819
|
-
const nowMs = Date.now();
|
|
820
|
-
const stepStore = getAgentStepStore();
|
|
821
|
-
const messageStore = getConversationMessageStore();
|
|
822
|
-
const transcriptPurgedAtMs = conversation.transcriptPurgedAtMs;
|
|
823
|
-
const transcriptExpiredAt = transcriptPurgedAtMs !== void 0 ? new Date(transcriptPurgedAtMs).toISOString() : void 0;
|
|
824
|
-
const canExposeSqlContent = canExposeConversationPayload({
|
|
825
|
-
conversationId,
|
|
826
|
-
visibility: conversation.visibility
|
|
827
|
-
});
|
|
828
|
-
const currentContent = transcriptPurgedAtMs === void 0 ? await conversationContent({
|
|
829
|
-
conversationId,
|
|
830
|
-
messageStore,
|
|
831
|
-
stepStore,
|
|
832
|
-
canExposePayload: canExposeSqlContent
|
|
833
|
-
}) : { activity: [], contextEvents: [], transcript: [] };
|
|
834
|
-
const currentTranscript = currentContent.transcript;
|
|
835
|
-
const traceId = canExposeSqlContent ? traceIdFromTranscript(currentTranscript) : void 0;
|
|
836
|
-
const sentryTraceUrl = traceId ? buildSentryTraceUrl(traceId) : void 0;
|
|
837
|
-
const sentryConversationUrl = buildSentryConversationUrl(conversationId);
|
|
838
|
-
return {
|
|
839
|
-
...conversationSummaryFromStoredConversation({
|
|
840
|
-
conversation,
|
|
841
|
-
durationMs: args.durationMs,
|
|
842
|
-
...args.locationId ? { locationId: args.locationId } : {},
|
|
843
|
-
usage: args.usage
|
|
844
|
-
}),
|
|
845
|
-
...traceId ? { traceId } : {},
|
|
846
|
-
...sentryTraceUrl ? { sentryTraceUrl } : {},
|
|
847
|
-
activity: currentContent.activity,
|
|
848
|
-
contextEvents: currentContent.contextEvents,
|
|
849
|
-
transcriptAvailable: transcriptExpiredAt === void 0 && canExposeSqlContent && currentTranscript.length > 0,
|
|
850
|
-
...currentTranscript.length > 0 ? {
|
|
851
|
-
transcriptMessageCount: countConversationMessages(currentTranscript)
|
|
852
|
-
} : {},
|
|
853
|
-
...!canExposeSqlContent && transcriptExpiredAt === void 0 ? {
|
|
854
|
-
transcriptMetadata: currentTranscript.map(redactTranscriptMessage),
|
|
855
|
-
transcriptRedacted: true,
|
|
856
|
-
transcriptRedactionReason: "non_public_conversation"
|
|
857
|
-
} : {},
|
|
858
|
-
...transcriptExpiredAt !== void 0 ? {
|
|
859
|
-
transcriptExpired: true,
|
|
860
|
-
transcriptExpiredAt,
|
|
861
|
-
transcriptMetadata: []
|
|
862
|
-
} : {},
|
|
863
|
-
transcript: transcriptExpiredAt === void 0 && canExposeSqlContent ? currentTranscript : [],
|
|
864
|
-
generatedAt: new Date(nowMs).toISOString(),
|
|
865
|
-
...sentryConversationUrl ? { sentryConversationUrl } : {}
|
|
866
|
-
};
|
|
867
|
-
}
|
|
868
|
-
async function buildConversationSubagent(conversation, subagentId) {
|
|
869
|
-
const conversationId = conversation.conversationId;
|
|
870
|
-
const stepStore = getAgentStepStore();
|
|
871
|
-
const parentSteps = await stepStore.loadHistory(conversationId);
|
|
872
|
-
if (conversation?.transcriptPurgedAtMs !== void 0) {
|
|
873
|
-
return {
|
|
874
|
-
type: "subagent",
|
|
875
|
-
createdAt: (/* @__PURE__ */ new Date(0)).toISOString(),
|
|
876
|
-
id: subagentId,
|
|
877
|
-
status: "completed",
|
|
878
|
-
subagentKind: "unknown",
|
|
879
|
-
transcript: [],
|
|
880
|
-
transcriptAvailable: false,
|
|
881
|
-
transcriptExpired: true,
|
|
882
|
-
transcriptExpiredAt: new Date(
|
|
883
|
-
conversation.transcriptPurgedAtMs
|
|
884
|
-
).toISOString()
|
|
885
|
-
};
|
|
886
|
-
}
|
|
887
|
-
const start = parentSteps.find(
|
|
888
|
-
(step) => step.entry.type === "subagent_started" && step.entry.subagentInvocationId === subagentId
|
|
889
|
-
);
|
|
890
|
-
if (!start) {
|
|
891
|
-
return {
|
|
892
|
-
type: "subagent",
|
|
893
|
-
createdAt: (/* @__PURE__ */ new Date(0)).toISOString(),
|
|
894
|
-
id: subagentId,
|
|
895
|
-
status: "error",
|
|
896
|
-
subagentKind: "unknown",
|
|
897
|
-
transcript: [],
|
|
898
|
-
transcriptAvailable: false,
|
|
899
|
-
unavailableReason: "not_found"
|
|
900
|
-
};
|
|
901
|
-
}
|
|
902
|
-
const end = parentSteps.find(
|
|
903
|
-
(step) => step.entry.type === "subagent_ended" && step.entry.subagentInvocationId === subagentId
|
|
904
|
-
);
|
|
905
|
-
const childConversationId = start.entry.childConversationId;
|
|
906
|
-
const activity = subagentActivityFromSteps(start, end);
|
|
907
|
-
const subagentSentryConversationUrl = buildSentryConversationUrl(childConversationId);
|
|
908
|
-
const conversationFields = {
|
|
909
|
-
subagentConversationId: childConversationId,
|
|
910
|
-
...subagentSentryConversationUrl ? { subagentSentryConversationUrl } : {}
|
|
911
|
-
};
|
|
912
|
-
const canExposeTranscript = canExposeConversationPayload({
|
|
913
|
-
conversationId,
|
|
914
|
-
visibility: conversation?.visibility
|
|
915
|
-
});
|
|
916
|
-
if (!canExposeTranscript) {
|
|
917
|
-
return subagentTranscriptReport(activity, {
|
|
918
|
-
...conversationFields,
|
|
919
|
-
transcriptRedacted: true,
|
|
920
|
-
transcriptRedactionReason: "non_public_conversation"
|
|
921
|
-
});
|
|
922
|
-
}
|
|
923
|
-
const childMessages = await loadProjection({
|
|
924
|
-
conversationId: childConversationId
|
|
925
|
-
});
|
|
926
|
-
if (childMessages.length === 0) {
|
|
927
|
-
return subagentTranscriptReport(activity, {
|
|
928
|
-
...conversationFields,
|
|
929
|
-
unavailableReason: "missing_transcript_ref"
|
|
930
|
-
});
|
|
931
|
-
}
|
|
932
|
-
const transcript = childMessages.map(
|
|
933
|
-
(message) => normalizeSubagentTranscriptMessage(message, activity.subagentKind)
|
|
934
|
-
);
|
|
935
|
-
return subagentTranscriptReport(activity, {
|
|
936
|
-
...conversationFields,
|
|
937
|
-
transcript,
|
|
938
|
-
transcriptMessageCount: countConversationMessages(transcript)
|
|
939
|
-
});
|
|
940
|
-
}
|
|
941
|
-
|
|
942
507
|
// src/api/conversations/list.ts
|
|
943
|
-
import { and as and2, asc, desc, eq as eq2, isNull } from "drizzle-orm";
|
|
944
508
|
var CONVERSATION_FEED_LIMIT = 50;
|
|
945
509
|
async function conversationRows(db, limit, actorEmail) {
|
|
946
510
|
return db.select({
|
|
@@ -955,17 +519,17 @@ async function conversationRows(db, limit, actorEmail) {
|
|
|
955
519
|
identityTenantId: juniorIdentities.providerTenantId
|
|
956
520
|
}).from(juniorConversations).leftJoin(
|
|
957
521
|
juniorDestinations,
|
|
958
|
-
|
|
522
|
+
eq3(juniorDestinations.id, juniorConversations.destinationId)
|
|
959
523
|
).leftJoin(
|
|
960
524
|
juniorIdentities,
|
|
961
|
-
|
|
525
|
+
eq3(juniorIdentities.id, juniorConversations.actorIdentityId)
|
|
962
526
|
).where(
|
|
963
|
-
|
|
527
|
+
and3(
|
|
964
528
|
isNull(juniorConversations.parentConversationId),
|
|
965
529
|
isNull(juniorConversations.archivedAt),
|
|
966
|
-
actorEmail ?
|
|
967
|
-
|
|
968
|
-
|
|
530
|
+
actorEmail ? and3(
|
|
531
|
+
eq3(juniorIdentities.emailNormalized, actorEmail),
|
|
532
|
+
eq3(juniorIdentities.emailVerified, true)
|
|
969
533
|
) : void 0
|
|
970
534
|
)
|
|
971
535
|
).orderBy(
|
|
@@ -1019,11 +583,11 @@ async function readConversationRecordFromSql(conversationId) {
|
|
|
1019
583
|
identityTenantId: juniorIdentities.providerTenantId
|
|
1020
584
|
}).from(juniorConversations).leftJoin(
|
|
1021
585
|
juniorDestinations,
|
|
1022
|
-
|
|
586
|
+
eq3(juniorDestinations.id, juniorConversations.destinationId)
|
|
1023
587
|
).leftJoin(
|
|
1024
588
|
juniorIdentities,
|
|
1025
|
-
|
|
1026
|
-
).where(
|
|
589
|
+
eq3(juniorIdentities.id, juniorConversations.actorIdentityId)
|
|
590
|
+
).where(eq3(juniorConversations.conversationId, conversationId)).limit(1);
|
|
1027
591
|
const row = rows[0];
|
|
1028
592
|
return row ? {
|
|
1029
593
|
conversation: conversationFromRow(row),
|
|
@@ -1069,35 +633,76 @@ var list_default = {
|
|
|
1069
633
|
}
|
|
1070
634
|
};
|
|
1071
635
|
|
|
1072
|
-
// src/api/conversations/detail.
|
|
1073
|
-
|
|
1074
|
-
|
|
1075
|
-
|
|
1076
|
-
|
|
1077
|
-
|
|
1078
|
-
|
|
1079
|
-
|
|
1080
|
-
|
|
1081
|
-
}
|
|
636
|
+
// src/api/conversations/detail.ts
|
|
637
|
+
function projectConversationDetail(args) {
|
|
638
|
+
const { conversation } = args;
|
|
639
|
+
const conversationId = conversation.conversationId;
|
|
640
|
+
const transcriptPurgedAtMs = conversation.transcriptPurgedAtMs;
|
|
641
|
+
const { visibility: _storedVisibility, ...conversationWithoutVisibility } = conversation;
|
|
642
|
+
const authorizedConversation = {
|
|
643
|
+
...conversationWithoutVisibility,
|
|
644
|
+
...args.effectiveVisibility ? { visibility: args.effectiveVisibility } : {}
|
|
645
|
+
};
|
|
646
|
+
const canExposePayload = canExposeConversationPayload({
|
|
647
|
+
conversationId: args.privacyConversationId ?? conversationId,
|
|
648
|
+
visibility: args.effectiveVisibility
|
|
649
|
+
});
|
|
650
|
+
const events = transcriptPurgedAtMs === void 0 ? args.events : [];
|
|
651
|
+
const modelUsage = transcriptPurgedAtMs === void 0 ? args.modelUsage : [];
|
|
652
|
+
const sentryConversationUrl = buildSentryConversationUrl(conversationId);
|
|
653
|
+
return {
|
|
654
|
+
...conversationSummaryFromStoredConversation({
|
|
655
|
+
conversation: authorizedConversation,
|
|
656
|
+
durationMs: args.durationMs,
|
|
657
|
+
...args.locationId ? { locationId: args.locationId } : {},
|
|
658
|
+
usage: args.usage
|
|
659
|
+
}),
|
|
660
|
+
events: projectConversationReportEvents({ canExposePayload, events }),
|
|
661
|
+
...modelUsage.length > 0 ? { modelUsage } : {},
|
|
662
|
+
eventHistory: transcriptPurgedAtMs !== void 0 ? {
|
|
663
|
+
status: "expired",
|
|
664
|
+
expiredAt: new Date(transcriptPurgedAtMs).toISOString()
|
|
665
|
+
} : canExposePayload ? { status: "available" } : {
|
|
666
|
+
status: "redacted",
|
|
667
|
+
reason: "non_public_conversation"
|
|
668
|
+
},
|
|
669
|
+
generatedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
670
|
+
...sentryConversationUrl ? { sentryConversationUrl } : {}
|
|
671
|
+
};
|
|
1082
672
|
}
|
|
1083
673
|
async function readConversationDetailFromSql(conversationId) {
|
|
1084
674
|
const record = await readConversationRecordFromSql(conversationId);
|
|
1085
675
|
if (!record) return void 0;
|
|
1086
|
-
const
|
|
1087
|
-
|
|
1088
|
-
|
|
1089
|
-
|
|
676
|
+
const executor = getSqlExecutor();
|
|
677
|
+
const [snapshot, modelUsage] = await Promise.all([
|
|
678
|
+
readConversationEventPrivacySnapshot(executor, {
|
|
679
|
+
conversationId,
|
|
680
|
+
eventTypes: conversationReportSourceEventTypes
|
|
1090
681
|
}),
|
|
1091
|
-
|
|
682
|
+
record.conversation.transcriptPurgedAtMs === void 0 ? readConversationModelUsageFromSql(executor, conversationId) : Promise.resolve([])
|
|
1092
683
|
]);
|
|
1093
|
-
return
|
|
1094
|
-
|
|
1095
|
-
|
|
1096
|
-
|
|
1097
|
-
|
|
684
|
+
if (!snapshot) return void 0;
|
|
685
|
+
const events = snapshot.events.map(
|
|
686
|
+
(row) => decodeStoredConversationEvent({
|
|
687
|
+
schemaVersion: row.schemaVersion,
|
|
688
|
+
seq: row.seq,
|
|
689
|
+
historyVersion: row.historyVersion,
|
|
690
|
+
...row.idempotencyKey ? { idempotencyKey: row.idempotencyKey } : {},
|
|
691
|
+
createdAtMs: row.createdAt.getTime(),
|
|
692
|
+
type: row.type,
|
|
693
|
+
payload: row.payload
|
|
694
|
+
})
|
|
695
|
+
);
|
|
696
|
+
const effectiveVisibility = snapshot.visibility === "public" || snapshot.visibility === "private" ? snapshot.visibility : void 0;
|
|
697
|
+
return projectConversationDetail({
|
|
698
|
+
...record,
|
|
699
|
+
effectiveVisibility,
|
|
700
|
+
events,
|
|
701
|
+
modelUsage,
|
|
702
|
+
privacyConversationId: snapshot.rootConversationId,
|
|
703
|
+
usage: record.usage ?? void 0
|
|
704
|
+
});
|
|
1098
705
|
}
|
|
1099
|
-
|
|
1100
|
-
// src/api/conversations/detail.ts
|
|
1101
706
|
async function readConversationDetail(conversationId) {
|
|
1102
707
|
const report = await readConversationDetailFromSql(conversationId);
|
|
1103
708
|
return report ? conversationDetailReportSchema.parse(report) : void 0;
|
|
@@ -1116,12 +721,12 @@ var detail_default = {
|
|
|
1116
721
|
};
|
|
1117
722
|
|
|
1118
723
|
// src/api/conversations/stats.query.ts
|
|
1119
|
-
import { and as
|
|
724
|
+
import { and as and4, eq as eq4, gte, isNull as isNull2, lte, sql as sql3 } from "drizzle-orm";
|
|
1120
725
|
|
|
1121
726
|
// src/api/conversations/aggregate.ts
|
|
1122
|
-
import { sql } from "drizzle-orm";
|
|
727
|
+
import { sql as sql2 } from "drizzle-orm";
|
|
1123
728
|
function tokenValue() {
|
|
1124
|
-
return
|
|
729
|
+
return sql2`
|
|
1125
730
|
CASE
|
|
1126
731
|
WHEN ${juniorConversations.usage}->>'totalTokens' IS NOT NULL
|
|
1127
732
|
THEN (${juniorConversations.usage}->>'totalTokens')::double precision
|
|
@@ -1140,7 +745,7 @@ function tokenValue() {
|
|
|
1140
745
|
`;
|
|
1141
746
|
}
|
|
1142
747
|
function costValue() {
|
|
1143
|
-
return
|
|
748
|
+
return sql2`
|
|
1144
749
|
CASE
|
|
1145
750
|
WHEN ${juniorConversations.usage}->'cost'->>'total' IS NOT NULL
|
|
1146
751
|
THEN (${juniorConversations.usage}->'cost'->>'total')::double precision
|
|
@@ -1160,30 +765,30 @@ function costValue() {
|
|
|
1160
765
|
}
|
|
1161
766
|
function conversationAggregateColumns() {
|
|
1162
767
|
return {
|
|
1163
|
-
active:
|
|
768
|
+
active: sql2`COUNT(*) FILTER (
|
|
1164
769
|
WHERE ${juniorConversations.executionStatus} NOT IN ('idle', 'failed')
|
|
1165
770
|
)::integer`,
|
|
1166
|
-
conversations:
|
|
1167
|
-
costUsd:
|
|
1168
|
-
durationMs:
|
|
1169
|
-
failed:
|
|
771
|
+
conversations: sql2`COUNT(*)::integer`,
|
|
772
|
+
costUsd: sql2`SUM(${costValue()})::double precision`,
|
|
773
|
+
durationMs: sql2`COALESCE(SUM(${juniorConversations.durationMs}), 0)::double precision`,
|
|
774
|
+
failed: sql2`COUNT(*) FILTER (
|
|
1170
775
|
WHERE ${juniorConversations.executionStatus} = 'failed'
|
|
1171
776
|
)::integer`,
|
|
1172
|
-
tokens:
|
|
777
|
+
tokens: sql2`SUM(${tokenValue()})::double precision`
|
|
1173
778
|
};
|
|
1174
779
|
}
|
|
1175
780
|
function conversationRangeColumns() {
|
|
1176
781
|
return {
|
|
1177
|
-
firstSeenAt:
|
|
782
|
+
firstSeenAt: sql2`MIN(${juniorConversations.createdAt})`.mapWith(
|
|
1178
783
|
juniorConversations.createdAt
|
|
1179
784
|
),
|
|
1180
|
-
lastSeenAt:
|
|
785
|
+
lastSeenAt: sql2`MAX(${juniorConversations.lastActivityAt})`.mapWith(
|
|
1181
786
|
juniorConversations.lastActivityAt
|
|
1182
787
|
)
|
|
1183
788
|
};
|
|
1184
789
|
}
|
|
1185
790
|
function conversationActiveDaysColumn() {
|
|
1186
|
-
return
|
|
791
|
+
return sql2`COUNT(DISTINCT (${juniorConversations.lastActivityAt} AT TIME ZONE 'UTC')::date)::integer`;
|
|
1187
792
|
}
|
|
1188
793
|
|
|
1189
794
|
// src/api/conversations/stats.query.ts
|
|
@@ -1242,7 +847,7 @@ function statsItems(map) {
|
|
|
1242
847
|
);
|
|
1243
848
|
}
|
|
1244
849
|
function statsWhere(start, end) {
|
|
1245
|
-
return
|
|
850
|
+
return and4(
|
|
1246
851
|
isNull2(juniorConversations.parentConversationId),
|
|
1247
852
|
gte(juniorConversations.lastActivityAt, start),
|
|
1248
853
|
lte(juniorConversations.lastActivityAt, end)
|
|
@@ -1276,7 +881,7 @@ function metricDays(rows, endMs) {
|
|
|
1276
881
|
}
|
|
1277
882
|
async function aggregateStats(db, start, end) {
|
|
1278
883
|
const where = statsWhere(start, end);
|
|
1279
|
-
const activityDate =
|
|
884
|
+
const activityDate = sql3`TO_CHAR(
|
|
1280
885
|
${juniorConversations.lastActivityAt} AT TIME ZONE 'UTC',
|
|
1281
886
|
'YYYY-MM-DD'
|
|
1282
887
|
)`;
|
|
@@ -1292,8 +897,8 @@ async function aggregateStats(db, start, end) {
|
|
|
1292
897
|
...conversationAggregateColumns()
|
|
1293
898
|
}).from(juniorConversations).leftJoin(
|
|
1294
899
|
juniorIdentities,
|
|
1295
|
-
|
|
1296
|
-
).leftJoin(juniorUsers,
|
|
900
|
+
eq4(juniorIdentities.id, juniorConversations.actorIdentityId)
|
|
901
|
+
).leftJoin(juniorUsers, eq4(juniorUsers.id, juniorIdentities.userId)).where(where).groupBy(
|
|
1297
902
|
juniorIdentities.displayName,
|
|
1298
903
|
juniorIdentities.emailNormalized,
|
|
1299
904
|
juniorIdentities.handle,
|
|
@@ -1311,7 +916,7 @@ async function aggregateStats(db, start, end) {
|
|
|
1311
916
|
...conversationAggregateColumns()
|
|
1312
917
|
}).from(juniorConversations).leftJoin(
|
|
1313
918
|
juniorDestinations,
|
|
1314
|
-
|
|
919
|
+
eq4(juniorDestinations.id, juniorConversations.destinationId)
|
|
1315
920
|
).where(where).groupBy(
|
|
1316
921
|
juniorConversations.channelName,
|
|
1317
922
|
juniorConversations.source,
|
|
@@ -1374,46 +979,8 @@ var stats_default = {
|
|
|
1374
979
|
handler: async () => Response.json(await readConversationStats())
|
|
1375
980
|
};
|
|
1376
981
|
|
|
1377
|
-
// src/api/conversations/subagent.ts
|
|
1378
|
-
async function readConversationSubagent(conversationId, subagentId) {
|
|
1379
|
-
const record = await readConversationRecordFromSql(conversationId);
|
|
1380
|
-
if (!record) {
|
|
1381
|
-
return conversationSubagentTranscriptReportSchema.parse({
|
|
1382
|
-
type: "subagent",
|
|
1383
|
-
createdAt: (/* @__PURE__ */ new Date(0)).toISOString(),
|
|
1384
|
-
id: subagentId,
|
|
1385
|
-
status: "error",
|
|
1386
|
-
subagentKind: "unknown",
|
|
1387
|
-
transcript: [],
|
|
1388
|
-
transcriptAvailable: false,
|
|
1389
|
-
unavailableReason: "not_found"
|
|
1390
|
-
});
|
|
1391
|
-
}
|
|
1392
|
-
return conversationSubagentTranscriptReportSchema.parse(
|
|
1393
|
-
await buildConversationSubagent(record.conversation, subagentId)
|
|
1394
|
-
);
|
|
1395
|
-
}
|
|
1396
|
-
var subagent_default = {
|
|
1397
|
-
method: "get",
|
|
1398
|
-
path: "/:conversationId/subagents/:subagentId",
|
|
1399
|
-
handler: async (c) => {
|
|
1400
|
-
const { conversationId, subagentId } = parseParams(
|
|
1401
|
-
subagentParamsSchema,
|
|
1402
|
-
c.req.param()
|
|
1403
|
-
);
|
|
1404
|
-
const report = await readConversationSubagent(conversationId, subagentId);
|
|
1405
|
-
return report.unavailableReason === "not_found" ? Response.json(report, { status: 404 }) : Response.json(report);
|
|
1406
|
-
}
|
|
1407
|
-
};
|
|
1408
|
-
|
|
1409
982
|
// src/api/conversations/routes.ts
|
|
1410
|
-
var routes = [
|
|
1411
|
-
list_default,
|
|
1412
|
-
stats_default,
|
|
1413
|
-
archive_default,
|
|
1414
|
-
detail_default,
|
|
1415
|
-
subagent_default
|
|
1416
|
-
];
|
|
983
|
+
var routes = [list_default, stats_default, archive_default, detail_default];
|
|
1417
984
|
function createConversationRoutes() {
|
|
1418
985
|
const app = new Hono();
|
|
1419
986
|
for (const route of routes) app.on(route.method, route.path, route.handler);
|
|
@@ -1424,7 +991,7 @@ function createConversationRoutes() {
|
|
|
1424
991
|
import { Hono as Hono2 } from "hono";
|
|
1425
992
|
|
|
1426
993
|
// src/api/locations/query.ts
|
|
1427
|
-
import { and as
|
|
994
|
+
import { and as and5, asc as asc2, desc as desc2, eq as eq5, gte as gte2, isNull as isNull3, sql as sql4 } from "drizzle-orm";
|
|
1428
995
|
|
|
1429
996
|
// src/api/conversations/reporting.ts
|
|
1430
997
|
var PRIVATE_CONVERSATION_LABEL2 = "Private Conversation";
|
|
@@ -1558,10 +1125,10 @@ function topLevelWhere() {
|
|
|
1558
1125
|
return isNull3(juniorConversations.parentConversationId);
|
|
1559
1126
|
}
|
|
1560
1127
|
function publicLocationWhere(destinationId) {
|
|
1561
|
-
return
|
|
1128
|
+
return and5(
|
|
1562
1129
|
topLevelWhere(),
|
|
1563
|
-
|
|
1564
|
-
|
|
1130
|
+
eq5(juniorDestinations.id, destinationId),
|
|
1131
|
+
eq5(juniorDestinations.visibility, "public")
|
|
1565
1132
|
);
|
|
1566
1133
|
}
|
|
1567
1134
|
function locationColumns() {
|
|
@@ -1612,22 +1179,22 @@ async function directoryRows(db) {
|
|
|
1612
1179
|
...conversationRangeColumns()
|
|
1613
1180
|
}).from(juniorConversations).leftJoin(
|
|
1614
1181
|
juniorDestinations,
|
|
1615
|
-
|
|
1182
|
+
eq5(juniorDestinations.id, juniorConversations.destinationId)
|
|
1616
1183
|
).where(topLevelWhere()).groupBy(...locationGroupBy());
|
|
1617
1184
|
}
|
|
1618
1185
|
async function directoryActivityRows(db, start) {
|
|
1619
|
-
const date =
|
|
1186
|
+
const date = sql4`TO_CHAR(
|
|
1620
1187
|
${juniorConversations.lastActivityAt} AT TIME ZONE 'UTC',
|
|
1621
1188
|
'YYYY-MM-DD'
|
|
1622
1189
|
)`;
|
|
1623
1190
|
return db.select({
|
|
1624
|
-
conversations:
|
|
1191
|
+
conversations: sql4`COUNT(*)::integer`,
|
|
1625
1192
|
date,
|
|
1626
1193
|
visibility: juniorDestinations.visibility
|
|
1627
1194
|
}).from(juniorConversations).leftJoin(
|
|
1628
1195
|
juniorDestinations,
|
|
1629
|
-
|
|
1630
|
-
).where(
|
|
1196
|
+
eq5(juniorDestinations.id, juniorConversations.destinationId)
|
|
1197
|
+
).where(and5(topLevelWhere(), gte2(juniorConversations.lastActivityAt, start))).groupBy(date, juniorDestinations.visibility);
|
|
1631
1198
|
}
|
|
1632
1199
|
function directoryActivityDays(rows, nowMs) {
|
|
1633
1200
|
const days = /* @__PURE__ */ new Map();
|
|
@@ -1701,7 +1268,7 @@ async function recentLocationRows(db, locationId) {
|
|
|
1701
1268
|
destinationId: juniorDestinations.id,
|
|
1702
1269
|
destinationVisibility: juniorDestinations.visibility,
|
|
1703
1270
|
durationMs: juniorConversations.durationMs,
|
|
1704
|
-
email:
|
|
1271
|
+
email: sql4`COALESCE(
|
|
1705
1272
|
${juniorUsers.primaryEmailNormalized},
|
|
1706
1273
|
${juniorIdentities.email}
|
|
1707
1274
|
)`,
|
|
@@ -1710,7 +1277,7 @@ async function recentLocationRows(db, locationId) {
|
|
|
1710
1277
|
fullName: juniorUsers.displayName,
|
|
1711
1278
|
handle: juniorIdentities.handle,
|
|
1712
1279
|
lastActivityAt: juniorConversations.lastActivityAt,
|
|
1713
|
-
providerSubjectId:
|
|
1280
|
+
providerSubjectId: sql4`CASE
|
|
1714
1281
|
WHEN ${juniorIdentities.provider} = 'slack'
|
|
1715
1282
|
THEN ${juniorIdentities.providerSubjectId}
|
|
1716
1283
|
ELSE NULL
|
|
@@ -1721,12 +1288,12 @@ async function recentLocationRows(db, locationId) {
|
|
|
1721
1288
|
usage: juniorConversations.usage
|
|
1722
1289
|
}).from(juniorConversations).innerJoin(
|
|
1723
1290
|
juniorDestinations,
|
|
1724
|
-
|
|
1291
|
+
eq5(juniorDestinations.id, juniorConversations.destinationId)
|
|
1725
1292
|
).leftJoin(
|
|
1726
1293
|
juniorIdentities,
|
|
1727
|
-
|
|
1728
|
-
).leftJoin(juniorUsers,
|
|
1729
|
-
|
|
1294
|
+
eq5(juniorIdentities.id, juniorConversations.actorIdentityId)
|
|
1295
|
+
).leftJoin(juniorUsers, eq5(juniorUsers.id, juniorIdentities.userId)).where(
|
|
1296
|
+
and5(
|
|
1730
1297
|
publicLocationWhere(locationId),
|
|
1731
1298
|
isNull3(juniorConversations.archivedAt)
|
|
1732
1299
|
)
|
|
@@ -1742,7 +1309,7 @@ async function readLocationDetailFromSql(locationId) {
|
|
|
1742
1309
|
const start = new Date(end);
|
|
1743
1310
|
start.setUTCDate(start.getUTCDate() - (ACTIVITY_DAYS - 1));
|
|
1744
1311
|
const where = publicLocationWhere(locationId);
|
|
1745
|
-
const activityDate =
|
|
1312
|
+
const activityDate = sql4`TO_CHAR(
|
|
1746
1313
|
${juniorConversations.lastActivityAt} AT TIME ZONE 'UTC',
|
|
1747
1314
|
'YYYY-MM-DD'
|
|
1748
1315
|
)`;
|
|
@@ -1753,12 +1320,12 @@ async function readLocationDetailFromSql(locationId) {
|
|
|
1753
1320
|
...conversationRangeColumns()
|
|
1754
1321
|
}).from(juniorConversations).innerJoin(
|
|
1755
1322
|
juniorDestinations,
|
|
1756
|
-
|
|
1323
|
+
eq5(juniorDestinations.id, juniorConversations.destinationId)
|
|
1757
1324
|
).where(where).groupBy(...locationGroupBy()),
|
|
1758
1325
|
getDb().select({ date: activityDate, ...conversationAggregateColumns() }).from(juniorConversations).innerJoin(
|
|
1759
1326
|
juniorDestinations,
|
|
1760
|
-
|
|
1761
|
-
).where(
|
|
1327
|
+
eq5(juniorDestinations.id, juniorConversations.destinationId)
|
|
1328
|
+
).where(and5(where, gte2(juniorConversations.lastActivityAt, start))).groupBy(activityDate),
|
|
1762
1329
|
getDb().select({
|
|
1763
1330
|
actorIdentityId: juniorConversations.actorIdentityId,
|
|
1764
1331
|
email: juniorUsers.primaryEmailNormalized,
|
|
@@ -1770,11 +1337,11 @@ async function readLocationDetailFromSql(locationId) {
|
|
|
1770
1337
|
...conversationAggregateColumns()
|
|
1771
1338
|
}).from(juniorConversations).innerJoin(
|
|
1772
1339
|
juniorDestinations,
|
|
1773
|
-
|
|
1340
|
+
eq5(juniorDestinations.id, juniorConversations.destinationId)
|
|
1774
1341
|
).leftJoin(
|
|
1775
1342
|
juniorIdentities,
|
|
1776
|
-
|
|
1777
|
-
).leftJoin(juniorUsers,
|
|
1343
|
+
eq5(juniorIdentities.id, juniorConversations.actorIdentityId)
|
|
1344
|
+
).leftJoin(juniorUsers, eq5(juniorUsers.id, juniorIdentities.userId)).where(where).groupBy(
|
|
1778
1345
|
juniorConversations.actorIdentityId,
|
|
1779
1346
|
juniorUsers.primaryEmailNormalized,
|
|
1780
1347
|
juniorUsers.displayName,
|
|
@@ -1867,10 +1434,10 @@ function createLocationRoutes() {
|
|
|
1867
1434
|
import { Hono as Hono3 } from "hono";
|
|
1868
1435
|
|
|
1869
1436
|
// src/api/people/list.query.ts
|
|
1870
|
-
import { and as
|
|
1437
|
+
import { and as and7, eq as eq7, gte as gte3, sql as sql6 } from "drizzle-orm";
|
|
1871
1438
|
|
|
1872
1439
|
// src/api/people/shared.ts
|
|
1873
|
-
import { and as
|
|
1440
|
+
import { and as and6, asc as asc3, desc as desc3, eq as eq6, isNull as isNull4, sql as sql5 } from "drizzle-orm";
|
|
1874
1441
|
var RECENT_LIMIT2 = 25;
|
|
1875
1442
|
var ACTIVITY_DAYS2 = 365;
|
|
1876
1443
|
function normalizeEmail(email) {
|
|
@@ -1914,11 +1481,11 @@ function statsItems2(map) {
|
|
|
1914
1481
|
}
|
|
1915
1482
|
function verifiedActorWhere(email) {
|
|
1916
1483
|
const normalizedEmail = normalizeEmail(email);
|
|
1917
|
-
return
|
|
1918
|
-
|
|
1919
|
-
|
|
1920
|
-
|
|
1921
|
-
normalizedEmail ?
|
|
1484
|
+
return and6(
|
|
1485
|
+
eq6(juniorIdentities.provider, "slack"),
|
|
1486
|
+
eq6(juniorIdentities.emailVerified, true),
|
|
1487
|
+
sql5`${juniorUsers.primaryEmailNormalized} IS NOT NULL`,
|
|
1488
|
+
normalizedEmail ? eq6(juniorUsers.primaryEmailNormalized, normalizedEmail) : void 0
|
|
1922
1489
|
);
|
|
1923
1490
|
}
|
|
1924
1491
|
async function recentActorRows(email) {
|
|
@@ -1942,12 +1509,12 @@ async function recentActorRows(email) {
|
|
|
1942
1509
|
usage: juniorConversations.usage
|
|
1943
1510
|
}).from(juniorConversations).innerJoin(
|
|
1944
1511
|
juniorIdentities,
|
|
1945
|
-
|
|
1946
|
-
).innerJoin(juniorUsers,
|
|
1512
|
+
eq6(juniorIdentities.id, juniorConversations.actorIdentityId)
|
|
1513
|
+
).innerJoin(juniorUsers, eq6(juniorUsers.id, juniorIdentities.userId)).leftJoin(
|
|
1947
1514
|
juniorDestinations,
|
|
1948
|
-
|
|
1515
|
+
eq6(juniorDestinations.id, juniorConversations.destinationId)
|
|
1949
1516
|
).where(
|
|
1950
|
-
|
|
1517
|
+
and6(verifiedActorWhere(email), isNull4(juniorConversations.archivedAt))
|
|
1951
1518
|
).orderBy(
|
|
1952
1519
|
desc3(juniorConversations.lastActivityAt),
|
|
1953
1520
|
asc3(juniorConversations.conversationId)
|
|
@@ -1976,7 +1543,7 @@ function directoryActivityDays2(rows, nowMs) {
|
|
|
1976
1543
|
async function readPeopleListFromSql() {
|
|
1977
1544
|
const nowMs = Date.now();
|
|
1978
1545
|
const { end, start } = activityWindow(nowMs);
|
|
1979
|
-
const activityDate =
|
|
1546
|
+
const activityDate = sql6`TO_CHAR(
|
|
1980
1547
|
${juniorConversations.lastActivityAt} AT TIME ZONE 'UTC',
|
|
1981
1548
|
'YYYY-MM-DD'
|
|
1982
1549
|
)`;
|
|
@@ -1984,24 +1551,24 @@ async function readPeopleListFromSql() {
|
|
|
1984
1551
|
getDb().select({
|
|
1985
1552
|
email: juniorUsers.primaryEmailNormalized,
|
|
1986
1553
|
fullName: juniorUsers.displayName,
|
|
1987
|
-
slackUserId:
|
|
1988
|
-
slackUserName:
|
|
1554
|
+
slackUserId: sql6`MAX(${juniorIdentities.providerSubjectId})`,
|
|
1555
|
+
slackUserName: sql6`MAX(${juniorIdentities.handle})`,
|
|
1989
1556
|
activeDays: conversationActiveDaysColumn(),
|
|
1990
1557
|
...conversationAggregateColumns(),
|
|
1991
1558
|
...conversationRangeColumns()
|
|
1992
1559
|
}).from(juniorConversations).innerJoin(
|
|
1993
1560
|
juniorIdentities,
|
|
1994
|
-
|
|
1995
|
-
).innerJoin(juniorUsers,
|
|
1561
|
+
eq7(juniorIdentities.id, juniorConversations.actorIdentityId)
|
|
1562
|
+
).innerJoin(juniorUsers, eq7(juniorUsers.id, juniorIdentities.userId)).where(verifiedActorWhere()).groupBy(juniorUsers.primaryEmailNormalized, juniorUsers.displayName),
|
|
1996
1563
|
getDb().select({
|
|
1997
|
-
activePeople:
|
|
1998
|
-
conversations:
|
|
1564
|
+
activePeople: sql6`COUNT(DISTINCT ${juniorUsers.id})::int`,
|
|
1565
|
+
conversations: sql6`COUNT(*)::int`,
|
|
1999
1566
|
date: activityDate
|
|
2000
1567
|
}).from(juniorConversations).innerJoin(
|
|
2001
1568
|
juniorIdentities,
|
|
2002
|
-
|
|
2003
|
-
).innerJoin(juniorUsers,
|
|
2004
|
-
|
|
1569
|
+
eq7(juniorIdentities.id, juniorConversations.actorIdentityId)
|
|
1570
|
+
).innerJoin(juniorUsers, eq7(juniorUsers.id, juniorIdentities.userId)).where(
|
|
1571
|
+
and7(
|
|
2005
1572
|
verifiedActorWhere(),
|
|
2006
1573
|
gte3(juniorConversations.lastActivityAt, start)
|
|
2007
1574
|
)
|
|
@@ -2049,7 +1616,7 @@ var list_default3 = {
|
|
|
2049
1616
|
};
|
|
2050
1617
|
|
|
2051
1618
|
// src/api/people/profile.query.ts
|
|
2052
|
-
import { and as
|
|
1619
|
+
import { and as and8, eq as eq8, gte as gte4, sql as sql7 } from "drizzle-orm";
|
|
2053
1620
|
function emptyProfile(email, nowMs) {
|
|
2054
1621
|
const end = new Date(nowMs);
|
|
2055
1622
|
end.setUTCHours(0, 0, 0, 0);
|
|
@@ -2084,7 +1651,7 @@ function addAggregate2(map, label, row) {
|
|
|
2084
1651
|
map.set(label, item);
|
|
2085
1652
|
}
|
|
2086
1653
|
function surfaceExpression() {
|
|
2087
|
-
return
|
|
1654
|
+
return sql7`CASE
|
|
2088
1655
|
WHEN ${juniorConversations.source} IN ('api', 'scheduler', 'slack')
|
|
2089
1656
|
THEN ${juniorConversations.source}
|
|
2090
1657
|
WHEN ${juniorConversations.conversationId} LIKE 'slack:%' THEN 'slack'
|
|
@@ -2112,30 +1679,30 @@ async function readPeopleProfileFromSql(email) {
|
|
|
2112
1679
|
start.setUTCDate(start.getUTCDate() - (ACTIVITY_DAYS2 - 1));
|
|
2113
1680
|
const where = verifiedActorWhere(normalizedEmail);
|
|
2114
1681
|
const surface = surfaceExpression();
|
|
2115
|
-
const activityDate =
|
|
1682
|
+
const activityDate = sql7`TO_CHAR(
|
|
2116
1683
|
${juniorConversations.lastActivityAt} AT TIME ZONE 'UTC',
|
|
2117
1684
|
'YYYY-MM-DD'
|
|
2118
1685
|
)`;
|
|
2119
|
-
const channel =
|
|
1686
|
+
const channel = sql7`SPLIT_PART(${juniorConversations.conversationId}, ':', 2)`;
|
|
2120
1687
|
const [totalsRows, dayRows, locationRows, surfaceRows, recentRows] = await Promise.all([
|
|
2121
1688
|
getDb().select({
|
|
2122
1689
|
email: juniorUsers.primaryEmailNormalized,
|
|
2123
1690
|
fullName: juniorUsers.displayName,
|
|
2124
|
-
slackUserId:
|
|
2125
|
-
slackUserName:
|
|
1691
|
+
slackUserId: sql7`MAX(${juniorIdentities.providerSubjectId})`,
|
|
1692
|
+
slackUserName: sql7`MAX(${juniorIdentities.handle})`,
|
|
2126
1693
|
activeDays: conversationActiveDaysColumn(),
|
|
2127
1694
|
...conversationAggregateColumns()
|
|
2128
1695
|
}).from(juniorConversations).innerJoin(
|
|
2129
1696
|
juniorIdentities,
|
|
2130
|
-
|
|
2131
|
-
).innerJoin(juniorUsers,
|
|
1697
|
+
eq8(juniorIdentities.id, juniorConversations.actorIdentityId)
|
|
1698
|
+
).innerJoin(juniorUsers, eq8(juniorUsers.id, juniorIdentities.userId)).where(where).groupBy(juniorUsers.primaryEmailNormalized, juniorUsers.displayName),
|
|
2132
1699
|
getDb().select({
|
|
2133
1700
|
date: activityDate,
|
|
2134
1701
|
...conversationAggregateColumns()
|
|
2135
1702
|
}).from(juniorConversations).innerJoin(
|
|
2136
1703
|
juniorIdentities,
|
|
2137
|
-
|
|
2138
|
-
).innerJoin(juniorUsers,
|
|
1704
|
+
eq8(juniorIdentities.id, juniorConversations.actorIdentityId)
|
|
1705
|
+
).innerJoin(juniorUsers, eq8(juniorUsers.id, juniorIdentities.userId)).where(and8(where, gte4(juniorConversations.lastActivityAt, start))).groupBy(activityDate),
|
|
2139
1706
|
getDb().select({
|
|
2140
1707
|
channel,
|
|
2141
1708
|
channelName: juniorConversations.channelName,
|
|
@@ -2144,10 +1711,10 @@ async function readPeopleProfileFromSql(email) {
|
|
|
2144
1711
|
...conversationAggregateColumns()
|
|
2145
1712
|
}).from(juniorConversations).innerJoin(
|
|
2146
1713
|
juniorIdentities,
|
|
2147
|
-
|
|
2148
|
-
).innerJoin(juniorUsers,
|
|
1714
|
+
eq8(juniorIdentities.id, juniorConversations.actorIdentityId)
|
|
1715
|
+
).innerJoin(juniorUsers, eq8(juniorUsers.id, juniorIdentities.userId)).leftJoin(
|
|
2149
1716
|
juniorDestinations,
|
|
2150
|
-
|
|
1717
|
+
eq8(juniorDestinations.id, juniorConversations.destinationId)
|
|
2151
1718
|
).where(where).groupBy(
|
|
2152
1719
|
channel,
|
|
2153
1720
|
juniorConversations.channelName,
|
|
@@ -2156,8 +1723,8 @@ async function readPeopleProfileFromSql(email) {
|
|
|
2156
1723
|
),
|
|
2157
1724
|
getDb().select({ surface, ...conversationAggregateColumns() }).from(juniorConversations).innerJoin(
|
|
2158
1725
|
juniorIdentities,
|
|
2159
|
-
|
|
2160
|
-
).innerJoin(juniorUsers,
|
|
1726
|
+
eq8(juniorIdentities.id, juniorConversations.actorIdentityId)
|
|
1727
|
+
).innerJoin(juniorUsers, eq8(juniorUsers.id, juniorIdentities.userId)).where(where).groupBy(surface),
|
|
2161
1728
|
recentActorRows(normalizedEmail)
|
|
2162
1729
|
]);
|
|
2163
1730
|
const totalsRow = totalsRows[0];
|
|
@@ -2245,7 +1812,7 @@ function readDescriptionText(home) {
|
|
|
2245
1812
|
}
|
|
2246
1813
|
}
|
|
2247
1814
|
async function readSkillReports() {
|
|
2248
|
-
const { discoverSkills } = await import("./skills-
|
|
1815
|
+
const { discoverSkills } = await import("./skills-ITNHBARB.js");
|
|
2249
1816
|
const skills = await discoverSkills();
|
|
2250
1817
|
return skillReportsSchema.parse(
|
|
2251
1818
|
skills.map((skill) => ({
|
|
@@ -2255,7 +1822,7 @@ async function readSkillReports() {
|
|
|
2255
1822
|
);
|
|
2256
1823
|
}
|
|
2257
1824
|
async function readPluginReports() {
|
|
2258
|
-
const { pluginCatalogRuntime } = await import("./catalog-runtime-
|
|
1825
|
+
const { pluginCatalogRuntime } = await import("./catalog-runtime-FOFNPR3P.js");
|
|
2259
1826
|
return pluginReportsSchema.parse(
|
|
2260
1827
|
pluginCatalogRuntime.getProviders().map((plugin) => ({
|
|
2261
1828
|
name: plugin.manifest.name
|
|
@@ -2265,7 +1832,7 @@ async function readPluginReports() {
|
|
|
2265
1832
|
async function readRuntimeInfoReport() {
|
|
2266
1833
|
const [{ homeDir }, { pluginCatalogRuntime }, plugins, skills] = await Promise.all([
|
|
2267
1834
|
import("./discovery-RMHYSRL7.js"),
|
|
2268
|
-
import("./catalog-runtime-
|
|
1835
|
+
import("./catalog-runtime-FOFNPR3P.js"),
|
|
2269
1836
|
readPluginReports(),
|
|
2270
1837
|
readSkillReports()
|
|
2271
1838
|
]);
|
|
@@ -2281,7 +1848,7 @@ async function readRuntimeInfoReport() {
|
|
|
2281
1848
|
}
|
|
2282
1849
|
async function readPluginOperationalReportFeed() {
|
|
2283
1850
|
const nowMs = Date.now();
|
|
2284
|
-
const { getPluginOperationalReports } = await import("./agent-hooks-
|
|
1851
|
+
const { getPluginOperationalReports } = await import("./agent-hooks-ICPIJAFY.js");
|
|
2285
1852
|
return pluginOperationalReportFeedSchema.parse({
|
|
2286
1853
|
source: "plugins",
|
|
2287
1854
|
generatedAt: new Date(nowMs).toISOString(),
|