perf(database): replace listSnapshot+JS filter with scoped SQL in getCompanyMetrics

Replace 17-table snapshot fetch + 50+ JS filters per agent with five
scoped aggregation queries:

  - tasks GROUP BY assignee_agent_id with conditional sums for done /
    assigned / cancelled counts
  - runs (within cutoff) GROUP BY agent_id with conditional sums for
    succeeded / failed counts
  - runs GROUP BY agent_id over started_at/finished_at for avg duration
    + max(created_at) as last active
  - cost_entries GROUP BY agent_id for total cost
  - activity GROUP BY actor restricted to status-change actions for
    review cycle count

Company-level totals also collapse to single COUNT/SUM queries instead
of in-memory reductions over the full snapshot. Return shape unchanged.
This commit is contained in:
ZacharyZhang-NY committed 2026-04-16 22:18:52 -04:00
1 parent 47731f61a0
commit 659a2026de
1 file changed
+143 -82
+143 -82
View File
@@ -2,6 +2,7 @@ import type { DatabaseSync } from "node:sqlite";
import type {
CompanyMetrics,
AgentMetrics,
InboxItem,
ProfileSnapshot,
RunStatus,
StandupReport,
@@ -21,104 +22,164 @@ export function buildCompanySettingsMethods(
) {
return {
getCompanyMetrics(companyId: string, days: number = 30): CompanyMetrics {
const snapshot = deps.listSnapshot({ companyId });
const agents = snapshot.agents;
const tasks = snapshot.tasks;
const runs = snapshot.runs;
const costs = snapshot.costs;
const cutoff = new Date(Date.now() - days * 24 * 60 * 60 * 1000).toISOString();
const recentRuns = runs.filter((r) => r.createdAt > cutoff);
const recentTasks = tasks.filter((t) => t.status === "done" && t.updatedAt > cutoff);
const db = getDb();
const successfulRuns = recentRuns.filter((r) => r.status === "succeeded").length;
const failedRuns = recentRuns.filter(
(r) => r.status === "failed" || r.status === "timed_out",
const agentRows = readAll<{
id: string; name: string; status: string;
}>(
`select id, name, status from agents where company_id = ? order by created_at asc`,
companyId,
);
const activeAgentRows = agentRows.filter(
(a) => a.status !== "pending_approval" && a.status !== "terminated",
);
const totalAgents = activeAgentRows.length;
const activeAgents = agentRows.filter(
(a) => a.status === "active" || a.status === "running",
).length;
const totalCost = costs.reduce((sum, c) => sum + (c.amountUsd ?? 0), 0);
const completedTasks = tasks.filter((t) => t.status === "done").length;
const agentMetrics: AgentMetrics[] = agents
.filter((a) => a.status !== "pending_approval" && a.status !== "terminated")
.map((agent) => {
const agentTasks = tasks.filter((t) => t.assigneeAgentId === agent.id);
const agentRuns = runs.filter((r) => r.agentId === agent.id);
const agentRecentRuns = agentRuns.filter((r) => r.createdAt > cutoff);
const agentCosts = costs.filter((c) => c.agentId === agent.id);
const totalTasks = (db.prepare(
"select count(*) as c from tasks where company_id = ?",
).get(companyId) as { c: number }).c;
const completedTasks = (db.prepare(
"select count(*) as c from tasks where company_id = ? and status = 'done'",
).get(companyId) as { c: number }).c;
const blockedTasks = (db.prepare(
"select count(*) as c from tasks where company_id = ? and status = 'blocked'",
).get(companyId) as { c: number }).c;
const agentSucceeded = agentRecentRuns.filter((r) => r.status === "succeeded").length;
const agentFailed = agentRecentRuns.filter(
(r) => r.status === "failed" || r.status === "timed_out",
).length;
const recentRunStats = db.prepare(
`select
count(*) as totalRuns,
sum(case when status = 'succeeded' then 1 else 0 end) as successful,
sum(case when status = 'failed' or status = 'timed_out' then 1 else 0 end) as failed
from runs where company_id = ? and created_at > ?`,
).get(companyId, cutoff) as { totalRuns: number; successful: number | null; failed: number | null };
const totalRuns = recentRunStats.totalRuns ?? 0;
const successfulRuns = recentRunStats.successful ?? 0;
const failedRuns = recentRunStats.failed ?? 0;
// Avg run duration
const finishedRuns = agentRuns.filter(
(r): r is typeof r & { startedAt: string; finishedAt: string } =>
Boolean(r.startedAt && r.finishedAt),
);
const avgDuration =
finishedRuns.length > 0
? finishedRuns.reduce(
(sum, r) =>
sum +
(new Date(r.finishedAt).getTime() - new Date(r.startedAt).getTime()) / 1000,
0,
) / finishedRuns.length
: 0;
const totalCost = (db.prepare(
"select coalesce(sum(amount_usd), 0) as s from cost_entries where company_id = ?",
).get(companyId) as { s: number }).s;
// Review cycles: count task status transitions by this agent
// Actual action strings: "task.status_changed" (api-server), "task.updated" (index.ts), "task.auto_assigned" (database)
const reviewCycles = snapshot.activity.filter(
(a) =>
a.companyId === companyId &&
a.actor === agent.id &&
(a.action === "task.status_changed" ||
a.action === "task.updated" ||
a.action === "task.auto_assigned"),
).length;
const recentTasksDone = (db.prepare(
"select count(*) as c from tasks where company_id = ? and status = 'done' and updated_at > ?",
).get(companyId, cutoff) as { c: number }).c;
const lastRun = agentRuns.sort(
(a, b) => new Date(b.createdAt).getTime() - new Date(a.createdAt).getTime(),
)[0];
const taskAggRows = readAll<{
agentId: string;
done: number;
assigned: number;
cancelled: number;
}>(
`select assignee_agent_id as agentId,
sum(case when status = 'done' then 1 else 0 end) as done,
sum(case when status != 'done' and status != 'cancelled' then 1 else 0 end) as assigned,
sum(case when status = 'cancelled' then 1 else 0 end) as cancelled
from tasks
where company_id = ? and assignee_agent_id is not null
group by assignee_agent_id`,
companyId,
);
const taskAggMap = new Map(taskAggRows.map((row) => [row.agentId, row]));
return {
agentId: agent.id,
agentName: agent.name,
tasksCompleted: agentTasks.filter((t) => t.status === "done").length,
tasksAssigned: agentTasks.filter(
(t) => t.status !== "done" && t.status !== "cancelled",
).length,
tasksFailed: agentTasks.filter((t) => t.status === "cancelled").length,
successRate:
agentRecentRuns.length > 0
? Math.round((agentSucceeded / agentRecentRuns.length) * 100)
: 0,
avgRunDurationSec: Math.round(avgDuration),
totalCostUsd: agentCosts.reduce((sum, c) => sum + (c.amountUsd ?? 0), 0),
runsTotal: agentRecentRuns.length,
runsSucceeded: agentSucceeded,
runsFailed: agentFailed,
reviewCycles,
lastActiveAt: lastRun?.createdAt ?? null,
};
});
const runRecentAggRows = readAll<{
agentId: string;
total: number;
succeeded: number;
failed: number;
}>(
`select agent_id as agentId,
count(*) as total,
sum(case when status = 'succeeded' then 1 else 0 end) as succeeded,
sum(case when status = 'failed' or status = 'timed_out' then 1 else 0 end) as failed
from runs
where company_id = ? and created_at > ?
group by agent_id`,
companyId,
cutoff,
);
const runRecentAggMap = new Map(runRecentAggRows.map((row) => [row.agentId, row]));
const runDurationRows = readAll<{
agentId: string;
avgDurationSec: number | null;
lastActiveAt: string | null;
}>(
`select agent_id as agentId,
avg((julianday(finished_at) - julianday(started_at)) * 86400.0) as avgDurationSec,
max(created_at) as lastActiveAt
from runs
where company_id = ? and started_at is not null and finished_at is not null
group by agent_id`,
companyId,
);
const runDurationMap = new Map(runDurationRows.map((row) => [row.agentId, row]));
const lastActiveRows = readAll<{ agentId: string; lastActiveAt: string }>(
`select agent_id as agentId, max(created_at) as lastActiveAt
from runs where company_id = ? group by agent_id`,
companyId,
);
const lastActiveMap = new Map(lastActiveRows.map((row) => [row.agentId, row.lastActiveAt]));
const costAggRows = readAll<{ agentId: string; totalCost: number }>(
`select agent_id as agentId, coalesce(sum(amount_usd), 0) as totalCost
from cost_entries where company_id = ? and agent_id is not null
group by agent_id`,
companyId,
);
const costAggMap = new Map(costAggRows.map((row) => [row.agentId, row.totalCost]));
const reviewCycleRows = readAll<{ actor: string; cycles: number }>(
`select actor, count(*) as cycles
from activity
where company_id = ?
and action in ('task.status_changed', 'task.updated', 'task.auto_assigned')
group by actor`,
companyId,
);
const reviewCycleMap = new Map(reviewCycleRows.map((row) => [row.actor, row.cycles]));
const agentMetrics: AgentMetrics[] = activeAgentRows.map((agent) => {
const taskAgg = taskAggMap.get(agent.id);
const runRecent = runRecentAggMap.get(agent.id);
const runDur = runDurationMap.get(agent.id);
const succeeded = runRecent?.succeeded ?? 0;
const total = runRecent?.total ?? 0;
return {
agentId: agent.id,
agentName: agent.name,
tasksCompleted: taskAgg?.done ?? 0,
tasksAssigned: taskAgg?.assigned ?? 0,
tasksFailed: taskAgg?.cancelled ?? 0,
successRate: total > 0 ? Math.round((succeeded / total) * 100) : 0,
avgRunDurationSec: Math.round(runDur?.avgDurationSec ?? 0),
totalCostUsd: costAggMap.get(agent.id) ?? 0,
runsTotal: total,
runsSucceeded: succeeded,
runsFailed: runRecent?.failed ?? 0,
reviewCycles: reviewCycleMap.get(agent.id) ?? 0,
lastActiveAt: lastActiveMap.get(agent.id) ?? null,
};
});
return {
totalAgents: agents.filter(
(a) => a.status !== "pending_approval" && a.status !== "terminated",
).length,
activeAgents: agents.filter((a) => a.status === "active" || a.status === "running").length,
totalTasks: tasks.length,
totalAgents,
activeAgents,
totalTasks,
completedTasks,
blockedTasks: tasks.filter((t) => t.status === "blocked").length,
totalRuns: recentRuns.length,
blockedTasks,
totalRuns,
successfulRuns,
failedRuns,
overallSuccessRate:
recentRuns.length > 0 ? Math.round((successfulRuns / recentRuns.length) * 100) : 0,
overallSuccessRate: totalRuns > 0 ? Math.round((successfulRuns / totalRuns) * 100) : 0,
totalCostUsd: totalCost,
avgCostPerTask: completedTasks > 0 ? totalCost / completedTasks : 0,
throughputTasksPerDay: days > 0 ? recentTasks.length / days : 0,
throughputTasksPerDay: days > 0 ? recentTasksDone / days : 0,
agentMetrics,
};
},