@dudousxd/nestjs-agent-store-drizzle 0.7.1 → 0.8.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/index.cjs +225 -60
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +39 -3
- package/dist/index.d.ts +39 -3
- package/dist/index.js +227 -62
- package/dist/index.js.map +1 -1
- package/package.json +3 -3
package/dist/index.cjs
CHANGED
|
@@ -543,8 +543,8 @@ var DrizzleAgentStore = class {
|
|
|
543
543
|
const start = /* @__PURE__ */ new Date(`${day}T00:00:00.000Z`);
|
|
544
544
|
const end = /* @__PURE__ */ new Date(`${day}T23:59:59.999Z`);
|
|
545
545
|
const rows = await this.db.select().from(agentTokenUsage).where((0, import_drizzle_orm2.and)((0, import_drizzle_orm2.eq)(agentTokenUsage.actorRef, actorRef), (0, import_drizzle_orm2.gte)(agentTokenUsage.createdAt, start), (0, import_drizzle_orm2.lte)(agentTokenUsage.createdAt, end)));
|
|
546
|
-
const usedTokens = rows.reduce((
|
|
547
|
-
const costUsd = rows.reduce((
|
|
546
|
+
const usedTokens = rows.reduce((sum2, row) => sum2 + row.inputTokens + row.outputTokens, 0);
|
|
547
|
+
const costUsd = rows.reduce((sum2, row) => sum2 + (row.costUsd ?? 0), 0);
|
|
548
548
|
return {
|
|
549
549
|
usedTokens,
|
|
550
550
|
costUsd
|
|
@@ -644,6 +644,35 @@ function emptyPage(query) {
|
|
|
644
644
|
};
|
|
645
645
|
}
|
|
646
646
|
__name(emptyPage, "emptyPage");
|
|
647
|
+
function toRecentRunRow(run) {
|
|
648
|
+
return {
|
|
649
|
+
runId: run.id,
|
|
650
|
+
threadId: run.threadId,
|
|
651
|
+
actorRef: run.actorRef,
|
|
652
|
+
agentName: run.agentName ?? null,
|
|
653
|
+
status: run.status,
|
|
654
|
+
durationMs: run.durationMs ?? null,
|
|
655
|
+
errorCode: run.errorCode ?? null,
|
|
656
|
+
errorMessage: run.errorMessage ?? null,
|
|
657
|
+
retries: run.retries,
|
|
658
|
+
startedAt: run.startedAt.toISOString(),
|
|
659
|
+
promptHash: run.promptHash ?? null
|
|
660
|
+
};
|
|
661
|
+
}
|
|
662
|
+
__name(toRecentRunRow, "toRecentRunRow");
|
|
663
|
+
function toRunToolCallRow(toolCall) {
|
|
664
|
+
return {
|
|
665
|
+
toolCallId: toolCall.id,
|
|
666
|
+
toolName: toolCall.toolName,
|
|
667
|
+
toolType: toolCall.toolType,
|
|
668
|
+
status: toolCall.status,
|
|
669
|
+
executionMs: toolCall.executionMs ?? null,
|
|
670
|
+
executedByRef: toolCall.executedByRef ?? null,
|
|
671
|
+
error: toolCall.error ?? null,
|
|
672
|
+
createdAt: toolCall.createdAt.toISOString()
|
|
673
|
+
};
|
|
674
|
+
}
|
|
675
|
+
__name(toRunToolCallRow, "toRunToolCallRow");
|
|
647
676
|
function toUsageInput(row) {
|
|
648
677
|
return {
|
|
649
678
|
modelId: row.modelId,
|
|
@@ -753,25 +782,63 @@ var DrizzleGovernanceQueries = class {
|
|
|
753
782
|
runId: row.runId
|
|
754
783
|
}));
|
|
755
784
|
}
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
785
|
+
/**
|
|
786
|
+
* Message counts and token totals for a whole set of threads in TWO grouped queries, not two per
|
|
787
|
+
* thread — a 200-row page used to cost four hundred round trips. Mirrors the MikroORM adapter's
|
|
788
|
+
* `threadRollups`, which reaches the same numbers without a QueryBuilder.
|
|
789
|
+
*/
|
|
790
|
+
async threadRollups(threadIds) {
|
|
791
|
+
const rollups = new Map(threadIds.map((threadId) => [
|
|
792
|
+
threadId,
|
|
793
|
+
{
|
|
794
|
+
messageCount: 0,
|
|
795
|
+
totalTokens: 0
|
|
796
|
+
}
|
|
797
|
+
]));
|
|
798
|
+
if (threadIds.length === 0) {
|
|
799
|
+
return rollups;
|
|
800
|
+
}
|
|
801
|
+
const messageCounts = await this.db.select({
|
|
802
|
+
threadId: agentMessage.threadId,
|
|
803
|
+
value: (0, import_drizzle_orm3.count)()
|
|
804
|
+
}).from(agentMessage).where((0, import_drizzle_orm3.inArray)(agentMessage.threadId, threadIds)).groupBy(agentMessage.threadId);
|
|
805
|
+
for (const row of messageCounts) {
|
|
806
|
+
const bucket = rollups.get(row.threadId);
|
|
807
|
+
if (bucket !== void 0) {
|
|
808
|
+
bucket.messageCount = row.value;
|
|
809
|
+
}
|
|
810
|
+
}
|
|
811
|
+
const usageTotals = await this.db.select({
|
|
812
|
+
threadId: agentTokenUsage.threadId,
|
|
813
|
+
inputTokens: (0, import_drizzle_orm3.sum)(agentTokenUsage.inputTokens),
|
|
814
|
+
outputTokens: (0, import_drizzle_orm3.sum)(agentTokenUsage.outputTokens)
|
|
815
|
+
}).from(agentTokenUsage).where((0, import_drizzle_orm3.inArray)(agentTokenUsage.threadId, threadIds)).groupBy(agentTokenUsage.threadId);
|
|
816
|
+
for (const row of usageTotals) {
|
|
817
|
+
const bucket = rollups.get(row.threadId);
|
|
818
|
+
if (bucket !== void 0) {
|
|
819
|
+
bucket.totalTokens = Number(row.inputTokens ?? 0) + Number(row.outputTokens ?? 0);
|
|
820
|
+
}
|
|
821
|
+
}
|
|
822
|
+
return rollups;
|
|
823
|
+
}
|
|
824
|
+
/** Decorate an ordered thread list with its batched rollups, preserving the incoming order. */
|
|
825
|
+
async toThreadActivityRows(threads) {
|
|
826
|
+
const rollups = await this.threadRollups(threads.map((thread) => thread.id));
|
|
827
|
+
return threads.map((thread) => {
|
|
828
|
+
const rollup = rollups.get(thread.id);
|
|
829
|
+
return {
|
|
766
830
|
threadId: thread.id,
|
|
767
831
|
title: thread.title,
|
|
768
832
|
actorRef: thread.actorRef,
|
|
769
|
-
messageCount:
|
|
770
|
-
totalTokens,
|
|
833
|
+
messageCount: rollup?.messageCount ?? 0,
|
|
834
|
+
totalTokens: rollup?.totalTokens ?? 0,
|
|
771
835
|
lastActivityAt: thread.updatedAt.toISOString()
|
|
772
|
-
}
|
|
773
|
-
}
|
|
774
|
-
|
|
836
|
+
};
|
|
837
|
+
});
|
|
838
|
+
}
|
|
839
|
+
async recentThreads(limit) {
|
|
840
|
+
const threads = await this.db.select().from(agentThread).where((0, import_drizzle_orm3.isNull)(agentThread.deletedAt)).orderBy((0, import_drizzle_orm3.desc)(agentThread.updatedAt), (0, import_drizzle_orm3.desc)(agentThread.id)).limit(limit);
|
|
841
|
+
return this.toThreadActivityRows(threads);
|
|
775
842
|
}
|
|
776
843
|
async runsInRange(range) {
|
|
777
844
|
const { start, end } = (0, import_nestjs_agent_core.dayBoundsUtc)(range);
|
|
@@ -873,19 +940,7 @@ var DrizzleGovernanceQueries = class {
|
|
|
873
940
|
}
|
|
874
941
|
async recentRuns(limit) {
|
|
875
942
|
const runs = await this.db.select().from(agentRun).orderBy((0, import_drizzle_orm3.desc)(agentRun.startedAt), (0, import_drizzle_orm3.desc)(agentRun.id)).limit(limit);
|
|
876
|
-
return runs.map(
|
|
877
|
-
runId: run.id,
|
|
878
|
-
threadId: run.threadId,
|
|
879
|
-
actorRef: run.actorRef,
|
|
880
|
-
agentName: run.agentName ?? null,
|
|
881
|
-
status: run.status,
|
|
882
|
-
durationMs: run.durationMs ?? null,
|
|
883
|
-
errorCode: run.errorCode ?? null,
|
|
884
|
-
errorMessage: run.errorMessage ?? null,
|
|
885
|
-
retries: run.retries,
|
|
886
|
-
startedAt: run.startedAt.toISOString(),
|
|
887
|
-
promptHash: run.promptHash ?? null
|
|
888
|
-
}));
|
|
943
|
+
return runs.map(toRecentRunRow);
|
|
889
944
|
}
|
|
890
945
|
/**
|
|
891
946
|
* Tool calls sitting `pending_approval`, oldest first (an inbox drains from the back), joined
|
|
@@ -918,8 +973,10 @@ var DrizzleGovernanceQueries = class {
|
|
|
918
973
|
}
|
|
919
974
|
/**
|
|
920
975
|
* Per-tool call/failure/rejection/latency rollup over the range, highest call count first.
|
|
921
|
-
* `p95ExecutionMs`
|
|
922
|
-
* their final status); `null` when none did.
|
|
976
|
+
* `p50ExecutionMs`/`p95ExecutionMs` are computed over calls that recorded a non-null `executionMs`
|
|
977
|
+
* (regardless of their final status); both `null` when none did. Percentiles are taken in-process
|
|
978
|
+
* off the sorted sample rather than in SQL, matching the MikroORM adapter — MySQL has no
|
|
979
|
+
* `PERCENTILE_CONT` and one portable implementation beats three dialect-specific ones.
|
|
923
980
|
*/
|
|
924
981
|
async toolStats(range) {
|
|
925
982
|
const { start, end } = (0, import_nestjs_agent_core.dayBoundsUtc)(range);
|
|
@@ -952,6 +1009,7 @@ var DrizzleGovernanceQueries = class {
|
|
|
952
1009
|
calls: bucket.calls,
|
|
953
1010
|
failed: bucket.failed,
|
|
954
1011
|
rejected: bucket.rejected,
|
|
1012
|
+
p50ExecutionMs: percentileMs(bucket.executionMs, 0.5),
|
|
955
1013
|
p95ExecutionMs: percentileMs(bucket.executionMs, 0.95)
|
|
956
1014
|
});
|
|
957
1015
|
}
|
|
@@ -1013,22 +1071,7 @@ var DrizzleGovernanceQueries = class {
|
|
|
1013
1071
|
value: (0, import_drizzle_orm3.count)()
|
|
1014
1072
|
}).from(agentThread).where(whereClause);
|
|
1015
1073
|
const threads = await this.db.select().from(agentThread).where(whereClause).orderBy((0, import_drizzle_orm3.desc)(agentThread.updatedAt), (0, import_drizzle_orm3.desc)(agentThread.id)).limit(query.pageSize).offset((query.page - 1) * query.pageSize);
|
|
1016
|
-
const rows =
|
|
1017
|
-
for (const thread of threads) {
|
|
1018
|
-
const [messageCountRow] = await this.db.select({
|
|
1019
|
-
value: (0, import_drizzle_orm3.count)()
|
|
1020
|
-
}).from(agentMessage).where((0, import_drizzle_orm3.eq)(agentMessage.threadId, thread.id));
|
|
1021
|
-
const usageRows = await this.db.select().from(agentTokenUsage).where((0, import_drizzle_orm3.eq)(agentTokenUsage.threadId, thread.id));
|
|
1022
|
-
const totalTokens = usageRows.reduce((sum, row) => sum + row.inputTokens + row.outputTokens, 0);
|
|
1023
|
-
rows.push({
|
|
1024
|
-
threadId: thread.id,
|
|
1025
|
-
title: thread.title,
|
|
1026
|
-
actorRef: thread.actorRef,
|
|
1027
|
-
messageCount: messageCountRow?.value ?? 0,
|
|
1028
|
-
totalTokens,
|
|
1029
|
-
lastActivityAt: thread.updatedAt.toISOString()
|
|
1030
|
-
});
|
|
1031
|
-
}
|
|
1074
|
+
const rows = await this.toThreadActivityRows(threads);
|
|
1032
1075
|
return {
|
|
1033
1076
|
rows,
|
|
1034
1077
|
total: totalRow?.value ?? 0,
|
|
@@ -1051,24 +1094,146 @@ var DrizzleGovernanceQueries = class {
|
|
|
1051
1094
|
}).from(agentRun).where(whereClause);
|
|
1052
1095
|
const runs = await this.db.select().from(agentRun).where(whereClause).orderBy((0, import_drizzle_orm3.desc)(agentRun.startedAt), (0, import_drizzle_orm3.desc)(agentRun.id)).limit(query.pageSize).offset((query.page - 1) * query.pageSize);
|
|
1053
1096
|
return {
|
|
1054
|
-
rows: runs.map(
|
|
1055
|
-
|
|
1056
|
-
|
|
1057
|
-
|
|
1058
|
-
|
|
1059
|
-
|
|
1060
|
-
|
|
1061
|
-
|
|
1062
|
-
|
|
1063
|
-
|
|
1064
|
-
|
|
1065
|
-
|
|
1097
|
+
rows: runs.map(toRecentRunRow),
|
|
1098
|
+
total: totalRow?.value ?? 0,
|
|
1099
|
+
page: query.page,
|
|
1100
|
+
pageSize: query.pageSize
|
|
1101
|
+
};
|
|
1102
|
+
}
|
|
1103
|
+
/**
|
|
1104
|
+
* Paged, filterable approvals inbox, oldest first — the same ordering as {@link pendingApprovals},
|
|
1105
|
+
* now with the `total` that method structurally cannot report. The join to `agent_message` /
|
|
1106
|
+
* `agent_thread` is unconditional (it already resolves title/actor/agentName), so the `threadId`/
|
|
1107
|
+
* `actorRef`/`agentName` filters cost nothing extra.
|
|
1108
|
+
*
|
|
1109
|
+
* The order is TOTAL (`created_at asc, id asc`, and `id` is the primary key), so no row can land on
|
|
1110
|
+
* two pages or on none for a given snapshot. Ascending order also means a newly requested approval
|
|
1111
|
+
* appends past the last page instead of shifting the page an operator is currently reading.
|
|
1112
|
+
*/
|
|
1113
|
+
async approvalsPage(query) {
|
|
1114
|
+
const filters = query.where;
|
|
1115
|
+
const whereClause = (0, import_drizzle_orm3.and)((0, import_drizzle_orm3.eq)(agentToolCall.status, "pending_approval"), filters?.toolName !== void 0 ? (0, import_drizzle_orm3.eq)(agentToolCall.toolName, filters.toolName) : void 0, filters?.threadId !== void 0 ? (0, import_drizzle_orm3.eq)(agentThread.id, filters.threadId) : void 0, filters?.actorRef !== void 0 ? (0, import_drizzle_orm3.eq)(agentThread.actorRef, filters.actorRef) : void 0, filters?.agentName !== void 0 ? (0, import_drizzle_orm3.eq)(agentMessage.agentName, filters.agentName) : void 0, filters?.fromDay !== void 0 ? (0, import_drizzle_orm3.gte)(agentToolCall.createdAt, dayStartUtc(filters.fromDay)) : void 0, filters?.toDay !== void 0 ? (0, import_drizzle_orm3.lte)(agentToolCall.createdAt, dayEndUtc(filters.toDay)) : void 0);
|
|
1116
|
+
const [totalRow] = await this.db.select({
|
|
1117
|
+
value: (0, import_drizzle_orm3.count)()
|
|
1118
|
+
}).from(agentToolCall).innerJoin(agentMessage, (0, import_drizzle_orm3.eq)(agentToolCall.messageId, agentMessage.id)).innerJoin(agentThread, (0, import_drizzle_orm3.eq)(agentMessage.threadId, agentThread.id)).where(whereClause);
|
|
1119
|
+
const rows = await this.db.select({
|
|
1120
|
+
toolCallId: agentToolCall.id,
|
|
1121
|
+
toolName: agentToolCall.toolName,
|
|
1122
|
+
input: agentToolCall.input,
|
|
1123
|
+
threadId: agentThread.id,
|
|
1124
|
+
threadTitle: agentThread.title,
|
|
1125
|
+
actorRef: agentThread.actorRef,
|
|
1126
|
+
agentName: agentMessage.agentName,
|
|
1127
|
+
requestedAt: agentToolCall.createdAt,
|
|
1128
|
+
runId: agentToolCall.runId
|
|
1129
|
+
}).from(agentToolCall).innerJoin(agentMessage, (0, import_drizzle_orm3.eq)(agentToolCall.messageId, agentMessage.id)).innerJoin(agentThread, (0, import_drizzle_orm3.eq)(agentMessage.threadId, agentThread.id)).where(whereClause).orderBy((0, import_drizzle_orm3.asc)(agentToolCall.createdAt), (0, import_drizzle_orm3.asc)(agentToolCall.id)).limit(query.pageSize).offset((query.page - 1) * query.pageSize);
|
|
1130
|
+
return {
|
|
1131
|
+
rows: rows.map((row) => ({
|
|
1132
|
+
toolCallId: row.toolCallId,
|
|
1133
|
+
toolName: row.toolName,
|
|
1134
|
+
input: row.input,
|
|
1135
|
+
threadId: row.threadId,
|
|
1136
|
+
threadTitle: row.threadTitle,
|
|
1137
|
+
actorRef: row.actorRef,
|
|
1138
|
+
agentName: row.agentName ?? null,
|
|
1139
|
+
requestedAt: row.requestedAt.toISOString(),
|
|
1140
|
+
runId: row.runId
|
|
1066
1141
|
})),
|
|
1067
1142
|
total: totalRow?.value ?? 0,
|
|
1068
1143
|
page: query.page,
|
|
1069
1144
|
pageSize: query.pageSize
|
|
1070
1145
|
};
|
|
1071
1146
|
}
|
|
1147
|
+
/**
|
|
1148
|
+
* One run, its owning thread's headline and its tool calls — TWO queries regardless of how many
|
|
1149
|
+
* tools the run called. `toolCalls` comes off `agent_tool_call.run_id`, so a run recorded before
|
|
1150
|
+
* that column was written reports none.
|
|
1151
|
+
*/
|
|
1152
|
+
async runDetail(runId) {
|
|
1153
|
+
const [row] = await this.db.select({
|
|
1154
|
+
run: agentRun,
|
|
1155
|
+
thread: agentThread
|
|
1156
|
+
}).from(agentRun).innerJoin(agentThread, (0, import_drizzle_orm3.eq)(agentRun.threadId, agentThread.id)).where((0, import_drizzle_orm3.eq)(agentRun.id, runId)).limit(1);
|
|
1157
|
+
if (row === void 0) {
|
|
1158
|
+
return null;
|
|
1159
|
+
}
|
|
1160
|
+
const toolCalls = await this.db.select().from(agentToolCall).where((0, import_drizzle_orm3.eq)(agentToolCall.runId, runId)).orderBy((0, import_drizzle_orm3.asc)(agentToolCall.createdAt), (0, import_drizzle_orm3.asc)(agentToolCall.id));
|
|
1161
|
+
return {
|
|
1162
|
+
run: toRecentRunRow(row.run),
|
|
1163
|
+
thread: {
|
|
1164
|
+
threadId: row.thread.id,
|
|
1165
|
+
title: row.thread.title,
|
|
1166
|
+
actorRef: row.thread.actorRef,
|
|
1167
|
+
deleted: row.thread.deletedAt != null
|
|
1168
|
+
},
|
|
1169
|
+
toolCalls: toolCalls.map(toRunToolCallRow)
|
|
1170
|
+
};
|
|
1171
|
+
}
|
|
1172
|
+
/**
|
|
1173
|
+
* One thread with its lifetime usage rollup, its newest runs and its newest messages. A fixed six
|
|
1174
|
+
* queries (thread, usage, message count, message page, that page's tool-call counts, runs+count) —
|
|
1175
|
+
* the per-message tool-call counts are ONE grouped read over the returned message ids, not one per
|
|
1176
|
+
* message. Soft-deleted threads are returned with `deleted: true`; an audit still needs them.
|
|
1177
|
+
*/
|
|
1178
|
+
async threadDetail(query) {
|
|
1179
|
+
const [thread] = await this.db.select().from(agentThread).where((0, import_drizzle_orm3.eq)(agentThread.id, query.threadId)).limit(1);
|
|
1180
|
+
if (thread === void 0) {
|
|
1181
|
+
return null;
|
|
1182
|
+
}
|
|
1183
|
+
const pricing = await this.loadPricing();
|
|
1184
|
+
const usageRows = await this.db.select().from(agentTokenUsage).where((0, import_drizzle_orm3.eq)(agentTokenUsage.threadId, thread.id));
|
|
1185
|
+
const usage = (0, import_nestjs_agent_core.rollupThreadUsage)(usageRows.map(toUsageInput), pricing);
|
|
1186
|
+
const [messageCountRow] = await this.db.select({
|
|
1187
|
+
value: (0, import_drizzle_orm3.count)()
|
|
1188
|
+
}).from(agentMessage).where((0, import_drizzle_orm3.eq)(agentMessage.threadId, thread.id));
|
|
1189
|
+
const messages = await this.db.select().from(agentMessage).where((0, import_drizzle_orm3.eq)(agentMessage.threadId, thread.id)).orderBy((0, import_drizzle_orm3.desc)(agentMessage.createdAt), (0, import_drizzle_orm3.desc)(agentMessage.id)).limit(query.messageLimit);
|
|
1190
|
+
const toolCallCounts = await this.toolCallCountsByMessage(messages.map((message) => message.id));
|
|
1191
|
+
const [runTotalRow] = await this.db.select({
|
|
1192
|
+
value: (0, import_drizzle_orm3.count)()
|
|
1193
|
+
}).from(agentRun).where((0, import_drizzle_orm3.eq)(agentRun.threadId, thread.id));
|
|
1194
|
+
const runs = await this.db.select().from(agentRun).where((0, import_drizzle_orm3.eq)(agentRun.threadId, thread.id)).orderBy((0, import_drizzle_orm3.desc)(agentRun.startedAt), (0, import_drizzle_orm3.desc)(agentRun.id)).limit(query.runLimit);
|
|
1195
|
+
return {
|
|
1196
|
+
thread: {
|
|
1197
|
+
threadId: thread.id,
|
|
1198
|
+
title: thread.title,
|
|
1199
|
+
actorRef: thread.actorRef,
|
|
1200
|
+
messageCount: messageCountRow?.value ?? 0,
|
|
1201
|
+
totalTokens: usage.totalTokens,
|
|
1202
|
+
lastActivityAt: thread.updatedAt.toISOString()
|
|
1203
|
+
},
|
|
1204
|
+
deleted: thread.deletedAt != null,
|
|
1205
|
+
usage,
|
|
1206
|
+
runs: runs.map(toRecentRunRow),
|
|
1207
|
+
runTotal: runTotalRow?.value ?? 0,
|
|
1208
|
+
messages: messages.map((message) => {
|
|
1209
|
+
const { content, truncated } = (0, import_nestjs_agent_core.truncateDetailContent)(message.content);
|
|
1210
|
+
return {
|
|
1211
|
+
messageId: message.id,
|
|
1212
|
+
role: message.role,
|
|
1213
|
+
content,
|
|
1214
|
+
truncated,
|
|
1215
|
+
agentName: message.agentName ?? null,
|
|
1216
|
+
toolCallCount: toolCallCounts.get(message.id) ?? 0,
|
|
1217
|
+
createdAt: message.createdAt.toISOString()
|
|
1218
|
+
};
|
|
1219
|
+
})
|
|
1220
|
+
};
|
|
1221
|
+
}
|
|
1222
|
+
/** Tool-call counts for a set of messages in ONE grouped query — the detail view's no-N+1 guarantee. */
|
|
1223
|
+
async toolCallCountsByMessage(messageIds) {
|
|
1224
|
+
const counts = /* @__PURE__ */ new Map();
|
|
1225
|
+
if (messageIds.length === 0) {
|
|
1226
|
+
return counts;
|
|
1227
|
+
}
|
|
1228
|
+
const rows = await this.db.select({
|
|
1229
|
+
messageId: agentToolCall.messageId,
|
|
1230
|
+
value: (0, import_drizzle_orm3.count)()
|
|
1231
|
+
}).from(agentToolCall).where((0, import_drizzle_orm3.inArray)(agentToolCall.messageId, messageIds)).groupBy(agentToolCall.messageId);
|
|
1232
|
+
for (const row of rows) {
|
|
1233
|
+
counts.set(row.messageId, row.value);
|
|
1234
|
+
}
|
|
1235
|
+
return counts;
|
|
1236
|
+
}
|
|
1072
1237
|
};
|
|
1073
1238
|
|
|
1074
1239
|
// src/drizzle-pricing-store.ts
|