@agent-native/dispatch 0.40.31 → 0.40.34
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/CHANGELOG.md +28 -18
- package/dist/actions/connect-external-agent.d.ts.map +1 -1
- package/dist/actions/connect-external-agent.js +2 -9
- package/dist/actions/connect-external-agent.js.map +1 -1
- package/dist/actions/list-dispatch-usage-metrics.js +1 -1
- package/dist/actions/list-dispatch-usage-metrics.js.map +1 -1
- package/dist/actions/provider-api-register.d.ts +11 -11
- package/dist/actions/provider-api-register.js +2 -14
- package/dist/actions/provider-api-register.js.map +1 -1
- package/dist/db/index.d.ts.map +1 -1
- package/dist/db/index.js +4 -9
- package/dist/db/index.js.map +1 -1
- package/dist/server/lib/admin-config.d.ts.map +1 -1
- package/dist/server/lib/admin-config.js +3 -1
- package/dist/server/lib/admin-config.js.map +1 -1
- package/dist/server/lib/app-creation-store.d.ts.map +1 -1
- package/dist/server/lib/app-creation-store.js +2 -11
- package/dist/server/lib/app-creation-store.js.map +1 -1
- package/dist/server/lib/community-apps.js +1 -1
- package/dist/server/lib/community-apps.js.map +1 -1
- package/dist/server/lib/mcp-access-store.d.ts.map +1 -1
- package/dist/server/lib/mcp-access-store.js +2 -10
- package/dist/server/lib/mcp-access-store.js.map +1 -1
- package/dist/server/lib/thread-debug-store.d.ts.map +1 -1
- package/dist/server/lib/thread-debug-store.js +2 -6
- package/dist/server/lib/thread-debug-store.js.map +1 -1
- package/dist/server/lib/usage-metrics-store.d.ts.map +1 -1
- package/dist/server/lib/usage-metrics-store.js +2 -11
- package/dist/server/lib/usage-metrics-store.js.map +1 -1
- package/dist/server/lib/vault-store.d.ts.map +1 -1
- package/dist/server/lib/vault-store.js +2 -9
- package/dist/server/lib/vault-store.js.map +1 -1
- package/dist/server/lib/workspace-app-action-auth.d.ts.map +1 -1
- package/dist/server/lib/workspace-app-action-auth.js +7 -2
- package/dist/server/lib/workspace-app-action-auth.js.map +1 -1
- package/dist/server/plugins/agent-chat.js +1 -1
- package/dist/server/plugins/agent-chat.js.map +1 -1
- package/package.json +3 -3
- package/src/actions/connect-external-agent.spec.ts +25 -11
- package/src/actions/connect-external-agent.ts +2 -9
- package/src/actions/index.spec.ts +3 -0
- package/src/actions/list-dispatch-usage-metrics.ts +1 -1
- package/src/actions/provider-api-register.spec.ts +15 -9
- package/src/actions/provider-api-register.ts +5 -13
- package/src/db/index.spec.ts +74 -0
- package/src/db/index.ts +4 -9
- package/src/server/lib/admin-config.spec.ts +51 -0
- package/src/server/lib/admin-config.ts +2 -1
- package/src/server/lib/app-creation-store.spec.ts +27 -5
- package/src/server/lib/app-creation-store.ts +2 -10
- package/src/server/lib/community-apps.ts +1 -1
- package/src/server/lib/mcp-access-store.spec.ts +39 -12
- package/src/server/lib/mcp-access-store.ts +3 -10
- package/src/server/lib/thread-debug-store.spec.ts +64 -0
- package/src/server/lib/thread-debug-store.ts +2 -9
- package/src/server/lib/usage-metrics-store.spec.ts +64 -0
- package/src/server/lib/usage-metrics-store.ts +2 -17
- package/src/server/lib/vault-store.spec.ts +26 -9
- package/src/server/lib/vault-store.ts +3 -10
- package/src/server/lib/workspace-app-action-auth.spec.ts +37 -6
- package/src/server/lib/workspace-app-action-auth.ts +12 -2
- package/src/server/plugins/agent-chat.spec.ts +14 -0
- package/src/server/plugins/agent-chat.ts +1 -1
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { detectEngineFromEnv, detectEngineFromUserSecrets, getAgentEngineEntry, isAgentEngineSettingConfigured, isStoredEngineUsable, readDefaultAgentEngineSetting, registerBuiltinEngines, } from "@agent-native/core/agent/engine";
|
|
2
2
|
import { getDbExec } from "@agent-native/core/db";
|
|
3
|
+
import { readOrgMemberRole } from "@agent-native/core/server";
|
|
3
4
|
import { ForbiddenError } from "@agent-native/core/sharing";
|
|
4
5
|
import { builderCreditsFromCostCents, getUsageSummary, isSelfScopedUsageRead, MIXED_USAGE_BILLING, UNKNOWN_USAGE_BILLING, usageBillingForEngine, usageOrgScope, } from "@agent-native/core/usage";
|
|
5
6
|
import { isDispatchEnvironmentAdmin } from "./admin-config.js";
|
|
@@ -201,16 +202,6 @@ async function initializeUsageMetricsTable(sinceMs) {
|
|
|
201
202
|
// stale, or unavailable; each aggregate read below is already best-effort.
|
|
202
203
|
}
|
|
203
204
|
}
|
|
204
|
-
async function getViewerOrgRole(orgId, email) {
|
|
205
|
-
if (!orgId)
|
|
206
|
-
return null;
|
|
207
|
-
const rows = await queryRows(`SELECT role FROM org_members
|
|
208
|
-
WHERE org_id = ? AND LOWER(email) = ?
|
|
209
|
-
AND federation_removal_pending_at IS NULL
|
|
210
|
-
LIMIT 1`, [orgId, email.toLowerCase()]);
|
|
211
|
-
const role = rows[0]?.role;
|
|
212
|
-
return typeof role === "string" ? role : null;
|
|
213
|
-
}
|
|
214
205
|
async function listOrgMembers(orgId) {
|
|
215
206
|
if (!orgId)
|
|
216
207
|
return [];
|
|
@@ -581,7 +572,7 @@ async function loadChatStats(where, args) {
|
|
|
581
572
|
async function assertCanViewMetrics(viewScope) {
|
|
582
573
|
const viewerEmail = currentOwnerEmail();
|
|
583
574
|
const orgId = currentOrgId();
|
|
584
|
-
const role = await
|
|
575
|
+
const role = orgId ? await readOrgMemberRole(orgId, viewerEmail) : null;
|
|
585
576
|
if (viewScope === "me" ||
|
|
586
577
|
isDispatchEnvironmentAdmin(viewerEmail) ||
|
|
587
578
|
role === "owner" ||
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"usage-metrics-store.js","sourceRoot":"","sources":["../../../src/server/lib/usage-metrics-store.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n detectEngineFromEnv,\n detectEngineFromUserSecrets,\n getAgentEngineEntry,\n isAgentEngineSettingConfigured,\n isStoredEngineUsable,\n readDefaultAgentEngineSetting,\n registerBuiltinEngines,\n} from \"@agent-native/core/agent/engine\";\nimport { getDbExec } from \"@agent-native/core/db\";\nimport { ForbiddenError } from \"@agent-native/core/sharing\";\nimport {\n builderCreditsFromCostCents,\n getUsageSummary,\n isSelfScopedUsageRead,\n MIXED_USAGE_BILLING,\n UNKNOWN_USAGE_BILLING,\n usageBillingForEngine,\n usageOrgScope,\n type UsageBillingMode,\n} from \"@agent-native/core/usage\";\n\nimport { isDispatchEnvironmentAdmin } from \"./admin-config.js\";\nimport {\n listWorkspaceApps,\n type WorkspaceAppSummary,\n} from \"./app-creation-store.js\";\nimport { currentOrgId, currentOwnerEmail } from \"./dispatch-store.js\";\n\nconst DAY_MS = 86_400_000;\n\nregisterBuiltinEngines();\n\nexport interface UsageMetricBucket {\n key: string;\n label: string;\n costCents: number;\n calls: number;\n chatCalls: number;\n inputTokens: number;\n outputTokens: number;\n cacheReadTokens: number;\n cacheWriteTokens: number;\n activeUsers: number;\n lastActiveAt: number | null;\n}\n\nexport interface UserUsageMetric extends UsageMetricBucket {\n ownerEmail: string;\n chatThreads: number;\n chatMessages: number;\n lastChatAt: number | null;\n topApp: string | null;\n role: string | null;\n}\n\nexport interface AppAdoptionActionMetric {\n key: string;\n label: string;\n calls: number;\n activeUsers: number;\n lastActiveAt: number | null;\n}\n\nexport interface AppAccessMetric {\n id: string;\n name: string;\n path: string;\n status: WorkspaceAppSummary[\"status\"];\n statusLabel?: string;\n isDispatch: boolean;\n accessModel: \"workspace\" | \"solo\";\n accessLabel: string;\n accessUsers: number;\n ownerEmail: string | null;\n isOwnedByViewer: boolean;\n canViewUsage: boolean;\n usersWithUsage: number;\n dailyActiveUsers: number;\n weeklyActiveUsers: number;\n usageCalls: number;\n chatCalls: number;\n costCents: number;\n lastActiveAt: number | null;\n actionMetrics: AppAdoptionActionMetric[];\n}\n\nexport interface DailyUsageMetric {\n date: string;\n costCents: number;\n calls: number;\n chatCalls: number;\n activeUsers: number;\n dailyActiveUsers: number;\n weeklyActiveUsers: number | null;\n}\n\nexport interface MonthlyUserUsageMetric {\n month: string;\n ownerEmail: string;\n costCents: number;\n credits: number | null;\n calls: number;\n chatCalls: number;\n inputTokens: number;\n outputTokens: number;\n cacheReadTokens: number;\n cacheWriteTokens: number;\n}\n\ntype MonthlyUsageAggregate = Omit<MonthlyUserUsageMetric, \"credits\"> & {\n builderCredits: number;\n builderEstimatedCostX100: number;\n unclassifiedCalls: number;\n unpricedBuilderCalls: number;\n};\n\nexport interface WorkspaceAppCreationMetric {\n month: string;\n ownerEmail: string;\n count: number;\n appIds: string[];\n}\n\nexport interface RecentUsageMetric {\n id: number;\n createdAt: number;\n ownerEmail: string;\n app: string;\n label: string;\n model: string;\n inputTokens: number;\n outputTokens: number;\n cacheReadTokens: number;\n cacheWriteTokens: number;\n costCents: number;\n prompt: string | null;\n promptSource: \"thread\" | \"thread-preview\" | \"not-captured\" | \"unavailable\";\n threadId: string | null;\n runId: string | null;\n taskId: string | null;\n sourcePlatform: string | null;\n sourceId: string | null;\n}\n\nexport type UsageMetricsScope = \"me\" | \"workspace\" | \"app\";\n\nexport interface UsageUserOption {\n email: string;\n role: string | null;\n}\n\nexport interface DispatchUsageMetrics {\n billing: UsageBillingMode;\n viewScope: UsageMetricsScope;\n selectedUserEmail: string | null;\n selectedAppId: string | null;\n availableUsers: UsageUserOption[];\n sinceMs: number;\n sinceDays: number;\n generatedAt: number;\n access: {\n viewerEmail: string;\n orgId: string | null;\n role: string | null;\n scope: \"organization\" | \"solo\";\n totalUsers: number;\n };\n totals: {\n costCents: number;\n calls: number;\n chatCalls: number;\n inputTokens: number;\n outputTokens: number;\n cacheReadTokens: number;\n cacheWriteTokens: number;\n activeUsers: number;\n chatThreads: number;\n chatMessages: number;\n workspaceApps: number;\n };\n byApp: UsageMetricBucket[];\n byUser: UserUsageMetric[];\n byLabel: UsageMetricBucket[];\n byModel: UsageMetricBucket[];\n daily: DailyUsageMetric[];\n dailyAvailable: boolean;\n monthlyByUser: MonthlyUserUsageMetric[];\n workspaceAppCreationsByUserMonth: WorkspaceAppCreationMetric[];\n appAccess: AppAccessMetric[];\n recent: RecentUsageMetric[];\n}\n\ninterface MemberRecord {\n email: string;\n role: string | null;\n joinedAt: number | null;\n}\n\ninterface ChatStats {\n threads: number;\n messages: number;\n lastChatAt: number | null;\n}\n\nfunction numberField(row: Record<string, unknown>, key: string): number {\n return Number(row[key] ?? 0) || 0;\n}\n\nfunction stringField(row: Record<string, unknown>, key: string): string {\n const value = row[key];\n return typeof value === \"string\" || typeof value === \"number\"\n ? String(value)\n : value == null\n ? \"\"\n : JSON.stringify(value);\n}\n\nfunction nullableNumberField(\n row: Record<string, unknown>,\n key: string,\n): number | null {\n const value = row[key];\n if (value == null) return null;\n const numberValue = Number(value);\n return Number.isFinite(numberValue) ? numberValue : null;\n}\n\nfunction nullableStringField(\n row: Record<string, unknown>,\n key: string,\n): string | null {\n const value = row[key];\n if (typeof value !== \"string\") return null;\n const trimmed = value.trim();\n return trimmed || null;\n}\n\ntype ParsedThreadData =\n | { status: \"absent\"; value: null }\n | { status: \"invalid\"; value: null }\n | { status: \"parsed\"; value: Record<string, unknown> };\n\nfunction parseJson(value: unknown): ParsedThreadData {\n if (typeof value !== \"string\" || !value.trim()) {\n return { status: \"absent\", value: null };\n }\n try {\n const parsed = JSON.parse(value);\n return parsed && typeof parsed === \"object\"\n ? { status: \"parsed\", value: parsed as Record<string, unknown> }\n : { status: \"invalid\", value: null };\n } catch {\n return { status: \"invalid\", value: null };\n }\n}\n\nfunction textFromPromptContent(value: unknown): string {\n if (typeof value === \"string\") return value.trim();\n if (!Array.isArray(value)) return \"\";\n return value\n .map((part) => {\n if (!part || typeof part !== \"object\") return \"\";\n const item = part as Record<string, unknown>;\n return item.type === \"text\" && typeof item.text === \"string\"\n ? item.text.trim()\n : \"\";\n })\n .filter(Boolean)\n .join(\"\\n\")\n .trim();\n}\n\nfunction truncatePrompt(value: string, maxLength = 360): string {\n if (value.length <= maxLength) return value;\n return `${value.slice(0, maxLength - 1).trimEnd()}…`;\n}\n\nfunction firstUserPrompt(threadData: unknown): string | null {\n const parsed = parseJson(threadData);\n if (parsed.status !== \"parsed\") return null;\n const messages = parsed.value.messages;\n if (!Array.isArray(messages)) return null;\n\n for (const entry of messages) {\n if (!entry || typeof entry !== \"object\") continue;\n const record = entry as Record<string, unknown>;\n const message =\n record.message && typeof record.message === \"object\"\n ? (record.message as Record<string, unknown>)\n : record;\n const role = typeof message.role === \"string\" ? message.role : \"\";\n if (role !== \"user\" && role !== \"human\") continue;\n const text = textFromPromptContent(message.content);\n if (text) return truncatePrompt(text);\n }\n return null;\n}\n\ninterface ThreadPromptRow {\n id?: unknown;\n preview?: unknown;\n thread_data?: unknown;\n}\n\nasync function hydrateRecentPrompts(\n rows: Array<Record<string, unknown>>,\n): Promise<RecentUsageMetric[]> {\n const threadIds = [\n ...new Set(\n rows\n .map((row) => nullableStringField(row, \"thread_id\"))\n .filter((value): value is string => Boolean(value)),\n ),\n ];\n const threads = new Map<string, ThreadPromptRow>();\n let threadQueryUnavailable = false;\n\n if (threadIds.length > 0) {\n try {\n const result = await getDbExec().execute({\n sql: `SELECT id, preview, thread_data FROM chat_threads WHERE id IN (${threadIds.map(() => \"?\").join(\", \")})`,\n args: threadIds,\n });\n for (const row of result.rows as ThreadPromptRow[]) {\n const id = typeof row.id === \"string\" ? row.id : \"\";\n if (id) threads.set(id, row);\n }\n } catch {\n threadQueryUnavailable = true;\n }\n }\n\n return rows.map((row) => {\n const threadId = nullableStringField(row, \"thread_id\");\n const thread = threadId ? threads.get(threadId) : undefined;\n const prompt = thread ? firstUserPrompt(thread.thread_data) : null;\n const preview =\n typeof thread?.preview === \"string\" ? thread.preview.trim() : \"\";\n const promptSource = prompt\n ? \"thread\"\n : preview\n ? \"thread-preview\"\n : threadQueryUnavailable && threadId\n ? \"unavailable\"\n : \"not-captured\";\n\n return {\n id: numberField(row, \"id\"),\n createdAt: numberField(row, \"created_at\"),\n ownerEmail: stringField(row, \"owner_email\"),\n app: stringField(row, \"app\") || \"unattributed\",\n label: stringField(row, \"label\") || \"chat\",\n model: stringField(row, \"model\") || \"unknown\",\n inputTokens: numberField(row, \"input_tokens\"),\n outputTokens: numberField(row, \"output_tokens\"),\n cacheReadTokens: numberField(row, \"cache_read_tokens\"),\n cacheWriteTokens: numberField(row, \"cache_write_tokens\"),\n costCents: numberField(row, \"cost_cents_x100\") / 100,\n prompt: prompt ?? (preview ? truncatePrompt(preview) : null),\n promptSource,\n threadId,\n runId: nullableStringField(row, \"run_id\"),\n taskId: nullableStringField(row, \"task_id\"),\n sourcePlatform: nullableStringField(row, \"source_platform\"),\n sourceId: nullableStringField(row, \"source_id\"),\n } satisfies RecentUsageMetric;\n });\n}\n\nfunction labelForKey(value: string): string {\n const trimmed = value.trim();\n return trimmed || \"Unattributed\";\n}\n\nfunction appUsageKey(value: string | null | undefined): string {\n const raw = (value ?? \"\").trim().toLowerCase();\n return raw || \"unattributed\";\n}\n\nfunction appOwner(app: WorkspaceAppSummary): string | null {\n const owner = app.owner?.trim();\n return owner || null;\n}\n\nasync function detectUsageEngineName(): Promise<string | null> {\n try {\n const stored = (await readDefaultAgentEngineSetting()) as {\n engine?: string;\n } | null;\n if (isAgentEngineSettingConfigured(stored)) {\n return (stored as { engine: string }).engine;\n }\n if (stored && typeof stored.engine === \"string\") {\n const entry = getAgentEngineEntry(stored.engine);\n if (entry && isStoredEngineUsable(stored, entry)) {\n return stored.engine;\n }\n }\n\n const detectedFromUser = await detectEngineFromUserSecrets();\n if (detectedFromUser) return detectedFromUser.name;\n\n return detectEngineFromEnv()?.name ?? null;\n } catch {\n return null;\n }\n}\n\nasync function queryRows<T extends Record<string, unknown>>(\n sql: string,\n args: unknown[] = [],\n): Promise<T[]> {\n try {\n const result = await getDbExec().execute({ sql, args });\n return result.rows as T[];\n } catch {\n return [];\n }\n}\n\nasync function initializeUsageMetricsTable(sinceMs: number): Promise<void> {\n try {\n await getUsageSummary({ ownerEmail: \"__dispatch_metrics_init__\", sinceMs });\n } catch {\n // Metrics should still render an empty state if usage storage is locked,\n // stale, or unavailable; each aggregate read below is already best-effort.\n }\n}\n\nasync function getViewerOrgRole(\n orgId: string | null,\n email: string,\n): Promise<string | null> {\n if (!orgId) return null;\n const rows = await queryRows<{ role?: string }>(\n `SELECT role FROM org_members\n WHERE org_id = ? AND LOWER(email) = ?\n AND federation_removal_pending_at IS NULL\n LIMIT 1`,\n [orgId, email.toLowerCase()],\n );\n const role = rows[0]?.role;\n return typeof role === \"string\" ? role : null;\n}\n\nasync function listOrgMembers(orgId: string | null): Promise<MemberRecord[]> {\n if (!orgId) return [];\n const result = await getDbExec().execute({\n sql: `SELECT email, role, joined_at AS joined_at FROM org_members\n WHERE org_id = ? AND federation_removal_pending_at IS NULL\n ORDER BY joined_at ASC`,\n args: [orgId],\n });\n const rows = result.rows as Record<string, unknown>[];\n return rows\n .map((row) => ({\n email: stringField(row, \"email\").trim(),\n role: stringField(row, \"role\") || null,\n joinedAt: nullableNumberField(row, \"joined_at\"),\n }))\n .filter((member) => member.email);\n}\n\nfunction usageScope(\n sinceMs: number,\n memberEmails: string[],\n): { where: string; args: unknown[] } {\n if (memberEmails.length === 0) {\n return { where: \"created_at >= ?\", args: [sinceMs] };\n }\n const placeholders = memberEmails.map(() => \"?\").join(\", \");\n return {\n where: `created_at >= ? AND LOWER(owner_email) IN (${placeholders})`,\n args: [sinceMs, ...memberEmails.map((email) => email.toLowerCase())],\n };\n}\n\nfunction withOrgUsageScope(\n scope: { where: string; args: unknown[] },\n orgId: string | null,\n selfScoped: boolean,\n): { where: string; args: unknown[] } {\n const org = usageOrgScope({ orgId, selfScoped });\n return {\n where: `${scope.where} AND ${org.where || \"org_id IS NULL\"}`,\n args: [...scope.args, ...org.args],\n };\n}\n\nfunction threadScope(\n sinceMs: number,\n memberEmails: string[],\n): { where: string; args: unknown[] } {\n if (memberEmails.length === 0) {\n return { where: \"updated_at >= ?\", args: [sinceMs] };\n }\n const placeholders = memberEmails.map(() => \"?\").join(\", \");\n return {\n where: `updated_at >= ? AND LOWER(owner_email) IN (${placeholders})`,\n args: [sinceMs, ...memberEmails.map((email) => email.toLowerCase())],\n };\n}\n\nfunction ownerScope(\n sinceMs: number,\n ownerEmail: string,\n): {\n where: string;\n args: unknown[];\n} {\n return {\n where: \"created_at >= ? AND LOWER(owner_email) = ?\",\n args: [sinceMs, ownerEmail.toLowerCase()],\n };\n}\n\nfunction ownerThreadScope(\n sinceMs: number,\n ownerEmail: string,\n): {\n where: string;\n args: unknown[];\n} {\n return {\n where: \"updated_at >= ? AND LOWER(owner_email) = ?\",\n args: [sinceMs, ownerEmail.toLowerCase()],\n };\n}\n\nfunction appUsageScope(\n sinceMs: number,\n memberEmails: string[],\n appId: string,\n orgId: string | null,\n viewerEmail: string,\n): { where: string; args: unknown[] } {\n const scope = withOrgUsageScope(\n usageScope(sinceMs, memberEmails),\n orgId,\n isSelfScopedUsageRead(memberEmails, viewerEmail),\n );\n return {\n where: `${scope.where} AND LOWER(app) = ?`,\n args: [...scope.args, appUsageKey(appId)],\n };\n}\n\nfunction workspaceAppCreationScope(\n sinceMs: number,\n orgId: string | null,\n memberEmails: string[],\n): { where: string; args: unknown[] } {\n const filters = [\"created_at >= ?\", \"action = ?\"];\n const args: unknown[] = [sinceMs, \"workspace-app.pending\"];\n\n if (orgId) {\n filters.push(\"org_id = ?\");\n args.push(orgId);\n }\n if (memberEmails.length > 0) {\n filters.push(\n `LOWER(owner_email) IN (${memberEmails.map(() => \"?\").join(\", \")})`,\n );\n args.push(...memberEmails.map((email) => email.toLowerCase()));\n }\n\n return { where: filters.join(\" AND \"), args };\n}\n\nfunction bucketFromRow(row: Record<string, unknown>): UsageMetricBucket {\n const key = stringField(row, \"k\");\n return {\n key,\n label: labelForKey(key),\n costCents: numberField(row, \"cost_x100\") / 100,\n calls: numberField(row, \"calls\"),\n chatCalls: numberField(row, \"chat_calls\"),\n inputTokens: numberField(row, \"input_tokens\"),\n outputTokens: numberField(row, \"output_tokens\"),\n cacheReadTokens: numberField(row, \"cache_read_tokens\"),\n cacheWriteTokens: numberField(row, \"cache_write_tokens\"),\n activeUsers: numberField(row, \"active_users\"),\n lastActiveAt: nullableNumberField(row, \"last_active_at\"),\n };\n}\n\nasync function usageBuckets(\n columnExpression: string,\n where: string,\n args: unknown[],\n limit: number,\n): Promise<UsageMetricBucket[]> {\n const rows = await queryRows<Record<string, unknown>>(\n `SELECT ${columnExpression} AS k,\n COALESCE(SUM(cost_cents_x100), 0) AS cost_x100,\n COUNT(*) AS calls,\n SUM(CASE WHEN label = 'chat' THEN 1 ELSE 0 END) AS chat_calls,\n COALESCE(SUM(input_tokens), 0) AS input_tokens,\n COALESCE(SUM(output_tokens), 0) AS output_tokens,\n COALESCE(SUM(cache_read_tokens), 0) AS cache_read_tokens,\n COALESCE(SUM(cache_write_tokens), 0) AS cache_write_tokens,\n COUNT(DISTINCT owner_email) AS active_users,\n MAX(created_at) AS last_active_at\n FROM token_usage\n WHERE ${where}\n GROUP BY ${columnExpression}\n ORDER BY cost_x100 DESC\n LIMIT ?`,\n [...args, limit],\n );\n return rows.map(bucketFromRow);\n}\n\nconst adoptionActionKeySql = `CASE\n WHEN LOWER(TRIM(label)) = 'chat' THEN 'chat'\n WHEN LOWER(TRIM(label)) IN ('automation', 'manual-automation')\n OR LOWER(TRIM(label)) LIKE 'automation:%'\n OR LOWER(TRIM(label)) LIKE 'manual-automation:%'\n OR LOWER(TRIM(label)) LIKE 'recurring-job:%' THEN 'automation'\n WHEN LOWER(TRIM(label)) = 'custom-agent'\n OR LOWER(TRIM(label)) LIKE 'custom-agent:%' THEN 'custom-agent'\n ELSE 'other'\nEND`;\n\ninterface AppAdoptionAggregate {\n calls: number;\n costCents: number;\n chatCalls: number;\n activeUsers: number;\n dailyActiveUsers: number;\n weeklyActiveUsers: number;\n lastActiveAt: number | null;\n actions: Map<\n string,\n { calls: number; activeUsers: number; lastActiveAt: number | null }\n >;\n}\n\nfunction emptyAppAdoptionAggregate(): AppAdoptionAggregate {\n return {\n calls: 0,\n costCents: 0,\n chatCalls: 0,\n activeUsers: 0,\n dailyActiveUsers: 0,\n weeklyActiveUsers: 0,\n lastActiveAt: null,\n actions: new Map(),\n };\n}\n\nasync function loadAppAdoption(\n usage: { where: string; args: unknown[] },\n adoptionUsage: { where: string; args: unknown[] },\n generatedAt: number,\n): Promise<Map<string, AppAdoptionAggregate>> {\n const appExpression = \"COALESCE(NULLIF(app, ''), 'unattributed')\";\n const [selectedRows, adoptionRows, actionRows] = await Promise.all([\n queryRows<Record<string, unknown>>(\n `SELECT ${appExpression} AS app,\n COALESCE(SUM(cost_cents_x100), 0) AS cost_x100,\n COUNT(*) AS calls,\n SUM(CASE WHEN label = 'chat' THEN 1 ELSE 0 END) AS chat_calls,\n COUNT(DISTINCT owner_email) AS active_users,\n MAX(created_at) AS last_active_at\n FROM token_usage\n WHERE ${usage.where}\n GROUP BY ${appExpression}`,\n usage.args,\n ),\n queryRows<Record<string, unknown>>(\n `SELECT ${appExpression} AS app,\n COUNT(DISTINCT CASE WHEN created_at >= ? THEN owner_email END) AS daily_active_users,\n COUNT(DISTINCT CASE WHEN created_at >= ? THEN owner_email END) AS weekly_active_users\n FROM token_usage\n WHERE ${adoptionUsage.where}\n GROUP BY ${appExpression}`,\n [generatedAt - DAY_MS, generatedAt - 7 * DAY_MS, ...adoptionUsage.args],\n ),\n queryRows<Record<string, unknown>>(\n `SELECT ${appExpression} AS app,\n ${adoptionActionKeySql} AS action_key,\n COUNT(*) AS calls,\n COUNT(DISTINCT owner_email) AS active_users,\n MAX(created_at) AS last_active_at\n FROM token_usage\n WHERE ${usage.where}\n GROUP BY ${appExpression}, ${adoptionActionKeySql}`,\n usage.args,\n ),\n ]);\n\n const adoptionByApp = new Map<string, AppAdoptionAggregate>();\n const getAdoption = (app: string): AppAdoptionAggregate => {\n const key = appUsageKey(app);\n const existing = adoptionByApp.get(key);\n if (existing) return existing;\n const created = emptyAppAdoptionAggregate();\n adoptionByApp.set(key, created);\n return created;\n };\n\n for (const row of selectedRows) {\n const adoption = getAdoption(stringField(row, \"app\"));\n adoption.calls = numberField(row, \"calls\");\n adoption.costCents = numberField(row, \"cost_x100\") / 100;\n adoption.chatCalls = numberField(row, \"chat_calls\");\n adoption.activeUsers = numberField(row, \"active_users\");\n adoption.lastActiveAt = nullableNumberField(row, \"last_active_at\");\n }\n for (const row of adoptionRows) {\n const adoption = getAdoption(stringField(row, \"app\"));\n adoption.dailyActiveUsers = numberField(row, \"daily_active_users\");\n adoption.weeklyActiveUsers = numberField(row, \"weekly_active_users\");\n }\n for (const row of actionRows) {\n const adoption = getAdoption(stringField(row, \"app\"));\n adoption.actions.set(stringField(row, \"action_key\"), {\n calls: numberField(row, \"calls\"),\n activeUsers: numberField(row, \"active_users\"),\n lastActiveAt: nullableNumberField(row, \"last_active_at\"),\n });\n }\n\n return adoptionByApp;\n}\n\nasync function loadDailyAndMonthlyUsage(usage: {\n where: string;\n args: unknown[];\n}): Promise<{\n daily: DailyUsageMetric[];\n dailyAvailable: boolean;\n monthlyByUser: MonthlyUsageAggregate[];\n usersByDay: Map<string, Set<string>>;\n}> {\n const dayBucketExpression = `CAST(created_at / ${DAY_MS} AS INTEGER)`;\n let result;\n try {\n result = await getDbExec().execute({\n sql: `SELECT ${dayBucketExpression} AS day_bucket,\n owner_email,\n COALESCE(SUM(cost_cents_x100), 0) AS cost_x100,\n COALESCE(SUM(builder_credits_used), 0) AS builder_credits,\n COALESCE(SUM(CASE\n WHEN engine_name = 'builder' AND builder_credits_used IS NULL\n THEN cost_cents_x100 ELSE 0\n END), 0) AS builder_estimated_cost_x100,\n COUNT(*) FILTER (\n WHERE NULLIF(engine_name, '') IS NULL AND builder_credits_used IS NULL\n ) AS unclassified_calls,\n COUNT(*) FILTER (\n WHERE engine_name = 'builder' AND builder_credits_used IS NULL\n AND cost_source = 'unavailable' AND cost_cents_x100 <= 0\n ) AS unpriced_builder_calls,\n COUNT(*) AS calls,\n SUM(CASE WHEN label = 'chat' THEN 1 ELSE 0 END) AS chat_calls,\n COALESCE(SUM(input_tokens), 0) AS input_tokens,\n COALESCE(SUM(output_tokens), 0) AS output_tokens,\n COALESCE(SUM(cache_read_tokens), 0) AS cache_read_tokens,\n COALESCE(SUM(cache_write_tokens), 0) AS cache_write_tokens\n FROM token_usage\n WHERE ${usage.where}\n GROUP BY ${dayBucketExpression}, owner_email\n ORDER BY ${dayBucketExpression} ASC`,\n args: usage.args,\n });\n } catch {\n return {\n daily: [],\n dailyAvailable: false,\n monthlyByUser: [],\n usersByDay: new Map(),\n };\n }\n const rows = result.rows as Record<string, unknown>[];\n const dailyMap = new Map<\n string,\n { costX100: number; calls: number; chatCalls: number; users: Set<string> }\n >();\n const monthlyByUserMap = new Map<string, MonthlyUsageAggregate>();\n const usersByDay = new Map<string, Set<string>>();\n\n for (const row of rows) {\n const date = new Date(\n numberField(row, \"day_bucket\") * DAY_MS,\n ).toISOString();\n const day = date.slice(0, 10);\n const ownerEmail = stringField(row, \"owner_email\");\n const daily = dailyMap.get(day) ?? {\n costX100: 0,\n calls: 0,\n chatCalls: 0,\n users: new Set<string>(),\n };\n daily.costX100 += numberField(row, \"cost_x100\");\n daily.calls += numberField(row, \"calls\");\n daily.chatCalls += numberField(row, \"chat_calls\");\n daily.users.add(ownerEmail.toLowerCase());\n dailyMap.set(day, daily);\n const users = usersByDay.get(day) ?? new Set<string>();\n users.add(ownerEmail.toLowerCase());\n usersByDay.set(day, users);\n\n const month = day.slice(0, 7);\n const monthlyKey = `${ownerEmail}\\u0000${month}`;\n const monthly = monthlyByUserMap.get(monthlyKey) ?? {\n month,\n ownerEmail,\n costCents: 0,\n builderCredits: 0,\n builderEstimatedCostX100: 0,\n unclassifiedCalls: 0,\n unpricedBuilderCalls: 0,\n calls: 0,\n chatCalls: 0,\n inputTokens: 0,\n outputTokens: 0,\n cacheReadTokens: 0,\n cacheWriteTokens: 0,\n };\n monthly.costCents += numberField(row, \"cost_x100\") / 100;\n monthly.builderCredits += numberField(row, \"builder_credits\");\n monthly.builderEstimatedCostX100 += numberField(\n row,\n \"builder_estimated_cost_x100\",\n );\n monthly.unclassifiedCalls += numberField(row, \"unclassified_calls\");\n monthly.unpricedBuilderCalls += numberField(row, \"unpriced_builder_calls\");\n monthly.calls += numberField(row, \"calls\");\n monthly.chatCalls += numberField(row, \"chat_calls\");\n monthly.inputTokens += numberField(row, \"input_tokens\");\n monthly.outputTokens += numberField(row, \"output_tokens\");\n monthly.cacheReadTokens += numberField(row, \"cache_read_tokens\");\n monthly.cacheWriteTokens += numberField(row, \"cache_write_tokens\");\n monthlyByUserMap.set(monthlyKey, monthly);\n }\n\n return {\n daily: [...dailyMap.entries()]\n .map(([date, value]) => ({\n date,\n costCents: value.costX100 / 100,\n calls: value.calls,\n chatCalls: value.chatCalls,\n activeUsers: value.users.size,\n dailyActiveUsers: value.users.size,\n weeklyActiveUsers: null,\n }))\n .sort((a, b) => a.date.localeCompare(b.date)),\n dailyAvailable: true,\n monthlyByUser: [...monthlyByUserMap.values()].sort(\n (a, b) =>\n a.month.localeCompare(b.month) ||\n a.ownerEmail.localeCompare(b.ownerEmail),\n ),\n usersByDay,\n };\n}\n\nasync function loadWeeklyActiveUsers(\n usage: { where: string; args: unknown[] },\n visibleUsersByDay: Map<string, Set<string>>,\n startDate: string,\n endDate: string,\n): Promise<Map<string, number> | null> {\n const dayBucketExpression = `CAST(created_at / ${DAY_MS} AS INTEGER)`;\n let result;\n try {\n result = await getDbExec().execute({\n sql: `SELECT ${dayBucketExpression} AS day_bucket, owner_email\n FROM token_usage\n WHERE ${usage.where}\n GROUP BY ${dayBucketExpression}, owner_email\n ORDER BY ${dayBucketExpression} ASC`,\n args: usage.args,\n });\n // coercion-ok: null distinguishes an unavailable optional trend from empty activity.\n } catch {\n return null;\n }\n const rows = result.rows as Record<string, unknown>[];\n const usersByDay = new Map(\n [...visibleUsersByDay.entries()].map(([day, users]) => [\n day,\n new Set(users),\n ]),\n );\n for (const row of rows) {\n const day = new Date(numberField(row, \"day_bucket\") * DAY_MS)\n .toISOString()\n .slice(0, 10);\n const users = usersByDay.get(day) ?? new Set<string>();\n users.add(stringField(row, \"owner_email\").toLowerCase());\n usersByDay.set(day, users);\n }\n\n const activityByDay = new Map<string, number>();\n const firstDay = Date.parse(`${startDate}T00:00:00Z`);\n const lastDay = Date.parse(`${endDate}T00:00:00Z`);\n for (let dayStart = firstDay; dayStart <= lastDay; dayStart += DAY_MS) {\n const day = new Date(dayStart).toISOString().slice(0, 10);\n const weeklyUsers = new Set<string>();\n for (\n let previousDayStart = dayStart;\n previousDayStart >= dayStart - 6 * DAY_MS;\n previousDayStart -= DAY_MS\n ) {\n const previousDay = new Date(previousDayStart).toISOString().slice(0, 10);\n for (const user of usersByDay.get(previousDay) ?? []) {\n weeklyUsers.add(user);\n }\n }\n activityByDay.set(day, weeklyUsers.size);\n }\n return activityByDay;\n}\n\nasync function loadChatStats(\n where: string,\n args: unknown[],\n): Promise<Map<string, ChatStats>> {\n const rows = await queryRows<Record<string, unknown>>(\n `SELECT owner_email AS owner_email,\n COUNT(*) AS threads,\n COALESCE(SUM(message_count), 0) AS messages,\n MAX(updated_at) AS last_chat_at\n FROM chat_threads\n WHERE ${where}\n GROUP BY owner_email`,\n args,\n );\n return new Map(\n rows.map((row) => [\n stringField(row, \"owner_email\"),\n {\n threads: numberField(row, \"threads\"),\n messages: numberField(row, \"messages\"),\n lastChatAt: nullableNumberField(row, \"last_chat_at\"),\n },\n ]),\n );\n}\n\nasync function assertCanViewMetrics(viewScope: UsageMetricsScope): Promise<{\n viewerEmail: string;\n orgId: string | null;\n role: string | null;\n}> {\n const viewerEmail = currentOwnerEmail();\n const orgId = currentOrgId();\n const role = await getViewerOrgRole(orgId, viewerEmail);\n if (\n viewScope === \"me\" ||\n isDispatchEnvironmentAdmin(viewerEmail) ||\n role === \"owner\" ||\n role === \"admin\"\n ) {\n return { viewerEmail, orgId, role };\n }\n if (!orgId) {\n return { viewerEmail, orgId, role };\n }\n throw new ForbiddenError(\n \"Only organization owners and admins can view workspace usage metrics.\",\n );\n}\n\nexport async function listDispatchUsageMetrics(input: {\n sinceDays?: number;\n scope?: UsageMetricsScope;\n userEmail?: string | null;\n appId?: string | null;\n}): Promise<DispatchUsageMetrics> {\n const viewScope: UsageMetricsScope =\n input.scope === \"me\" ? \"me\" : input.scope === \"app\" ? \"app\" : \"workspace\";\n const { viewerEmail, orgId, role } = await assertCanViewMetrics(\n viewScope === \"app\" ? \"me\" : viewScope,\n );\n const sinceDays = Math.max(1, Math.min(365, input.sinceDays ?? 30));\n const generatedAt = Date.now();\n const sinceMs = generatedAt - sinceDays * DAY_MS;\n const apps = await listWorkspaceApps({ includeAgentCards: false });\n const requestedAppId = input.appId?.trim() || null;\n const selectedApp =\n viewScope === \"app\" && requestedAppId\n ? apps.find((app) => app.id === requestedAppId)\n : null;\n if (viewScope === \"app\" && !requestedAppId) {\n throw new Error(\"App metrics require an appId.\");\n }\n if (viewScope === \"app\" && !selectedApp) {\n throw new ForbiddenError(\n \"You do not have access to metrics for this workspace app.\",\n );\n }\n const selectedAppOwner = selectedApp ? appOwner(selectedApp) : null;\n const isMetricsAdmin = Boolean(\n isDispatchEnvironmentAdmin(viewerEmail) ||\n role === \"owner\" ||\n role === \"admin\",\n );\n if (\n viewScope === \"app\" &&\n !isMetricsAdmin &&\n selectedAppOwner?.toLowerCase() !== viewerEmail.toLowerCase()\n ) {\n throw new ForbiddenError(\n \"Only the app owner or an organization owner or admin can view app metrics.\",\n );\n }\n\n await initializeUsageMetricsTable(sinceMs);\n\n const rawMembers =\n viewScope === \"me\"\n ? [{ email: viewerEmail, role, joinedAt: null }]\n : orgId\n ? await listOrgMembers(orgId)\n : [{ email: viewerEmail, role: null, joinedAt: null }];\n const members =\n viewScope !== \"me\" && orgId && rawMembers.length === 0\n ? [{ email: viewerEmail, role, joinedAt: null }]\n : rawMembers;\n const requestedUserEmail =\n viewScope === \"app\" ? null : input.userEmail?.trim() || null;\n const selectedUserEmail =\n viewScope === \"me\"\n ? viewerEmail\n : requestedUserEmail\n ? (members.find(\n (member) =>\n member.email.toLowerCase() === requestedUserEmail.toLowerCase(),\n )?.email ?? null)\n : null;\n if (viewScope === \"workspace\" && requestedUserEmail && !selectedUserEmail) {\n throw new ForbiddenError(\n \"The selected user is not available in this workspace.\",\n );\n }\n const memberEmails = selectedUserEmail\n ? [selectedUserEmail]\n : members.map((member) => member.email);\n const selfScopedUsage = isSelfScopedUsageRead(memberEmails, viewerEmail);\n const memberByEmail = new Map(\n members.map((member) => [member.email.toLowerCase(), member]),\n );\n const usage =\n viewScope === \"app\" && selectedApp\n ? appUsageScope(sinceMs, memberEmails, selectedApp.id, orgId, viewerEmail)\n : withOrgUsageScope(\n selectedUserEmail\n ? ownerScope(sinceMs, selectedUserEmail)\n : usageScope(sinceMs, memberEmails),\n orgId,\n selfScopedUsage,\n );\n const visibleSinceMs = Math.floor(sinceMs / DAY_MS) * DAY_MS;\n const adoptionSinceMs = Math.min(\n visibleSinceMs - 6 * DAY_MS,\n generatedAt - 7 * DAY_MS,\n );\n const adoptionUsage =\n viewScope === \"app\" && selectedApp\n ? appUsageScope(\n adoptionSinceMs,\n memberEmails,\n selectedApp.id,\n orgId,\n viewerEmail,\n )\n : withOrgUsageScope(\n selectedUserEmail\n ? ownerScope(adoptionSinceMs, selectedUserEmail)\n : usageScope(adoptionSinceMs, memberEmails),\n orgId,\n selfScopedUsage,\n );\n const weeklyLookbackUsage = {\n where: `${adoptionUsage.where} AND created_at < ?`,\n args: [...adoptionUsage.args, sinceMs],\n };\n const threads = selectedUserEmail\n ? ownerThreadScope(sinceMs, selectedUserEmail)\n : threadScope(sinceMs, memberEmails);\n\n const workspaceAppCreation = workspaceAppCreationScope(\n sinceMs,\n orgId,\n memberEmails,\n );\n\n const [\n totalsRows,\n byApp,\n byUserBase,\n byLabel,\n byModel,\n chatStats,\n workspaceAppCreationRows,\n ] = await Promise.all([\n queryRows<Record<string, unknown>>(\n `SELECT\n COALESCE(SUM(cost_cents_x100), 0) AS cost_x100,\n COUNT(*) AS calls,\n SUM(CASE WHEN label = 'chat' THEN 1 ELSE 0 END) AS chat_calls,\n COALESCE(SUM(input_tokens), 0) AS input_tokens,\n COALESCE(SUM(output_tokens), 0) AS output_tokens,\n COALESCE(SUM(cache_read_tokens), 0) AS cache_read_tokens,\n COALESCE(SUM(cache_write_tokens), 0) AS cache_write_tokens,\n COUNT(*) FILTER (WHERE engine_name = 'builder' OR builder_credits_used IS NOT NULL) AS builder_calls,\n COUNT(*) FILTER (WHERE NULLIF(engine_name, '') IS NOT NULL AND NULLIF(engine_name, '') <> 'builder' AND builder_credits_used IS NULL) AS provider_calls,\n COUNT(*) FILTER (WHERE NULLIF(engine_name, '') IS NULL AND builder_credits_used IS NULL) AS unknown_calls,\n COUNT(DISTINCT owner_email) AS active_users\n FROM token_usage\n WHERE ${usage.where}`,\n usage.args,\n ),\n usageBuckets(\n `COALESCE(NULLIF(app, ''), 'unattributed')`,\n usage.where,\n usage.args,\n 20,\n ),\n viewScope === \"app\"\n ? Promise.resolve([] as UsageMetricBucket[])\n : usageBuckets(\"owner_email\", usage.where, usage.args, 50),\n viewScope === \"app\"\n ? Promise.resolve([] as UsageMetricBucket[])\n : usageBuckets(\n `COALESCE(NULLIF(label, ''), 'chat')`,\n usage.where,\n usage.args,\n 20,\n ),\n usageBuckets(\n `COALESCE(NULLIF(model, ''), 'unknown')`,\n usage.where,\n usage.args,\n 20,\n ),\n viewScope === \"app\"\n ? Promise.resolve(new Map<string, ChatStats>())\n : loadChatStats(threads.where, threads.args),\n viewScope === \"app\"\n ? Promise.resolve([])\n : queryRows<Record<string, unknown>>(\n `SELECT owner_email, actor, target_id, created_at\n FROM dispatch_audit_events\n WHERE ${workspaceAppCreation.where}\n ORDER BY created_at ASC`,\n workspaceAppCreation.args,\n ),\n ]);\n\n const totals = totalsRows[0] ?? {};\n const builderCalls = numberField(totals, \"builder_calls\");\n const providerCalls = numberField(totals, \"provider_calls\");\n const unknownCalls = numberField(totals, \"unknown_calls\");\n const billing = unknownCalls\n ? UNKNOWN_USAGE_BILLING\n : builderCalls > 0 && providerCalls > 0\n ? MIXED_USAGE_BILLING\n : builderCalls > 0\n ? usageBillingForEngine(\"builder\")\n : providerCalls > 0\n ? usageBillingForEngine(\"external\")\n : usageBillingForEngine(await detectUsageEngineName());\n\n const topAppRows =\n viewScope === \"app\"\n ? []\n : await queryRows<Record<string, unknown>>(\n `SELECT owner_email AS owner_email,\n COALESCE(NULLIF(app, ''), 'unattributed') AS app,\n COALESCE(SUM(cost_cents_x100), 0) AS cost_x100\n FROM token_usage\n WHERE ${usage.where}\n GROUP BY owner_email, COALESCE(NULLIF(app, ''), 'unattributed')\n ORDER BY owner_email ASC, cost_x100 DESC`,\n usage.args,\n );\n const topAppByUser = new Map<string, string>();\n for (const row of topAppRows) {\n const email = stringField(row, \"owner_email\");\n if (!topAppByUser.has(email)) {\n topAppByUser.set(email, stringField(row, \"app\"));\n }\n }\n\n const byUserMap = new Map<string, UserUsageMetric>();\n for (const bucket of byUserBase) {\n const ownerEmail = bucket.key;\n const stats = chatStats.get(ownerEmail) ?? {\n threads: 0,\n messages: 0,\n lastChatAt: null,\n };\n const member = memberByEmail.get(ownerEmail.toLowerCase());\n byUserMap.set(ownerEmail, {\n ...bucket,\n ownerEmail,\n chatThreads: stats.threads,\n chatMessages: stats.messages,\n lastChatAt: stats.lastChatAt,\n topApp: topAppByUser.get(ownerEmail) ?? null,\n role: member?.role ?? null,\n });\n }\n for (const [ownerEmail, stats] of chatStats) {\n if (byUserMap.has(ownerEmail)) continue;\n const member = memberByEmail.get(ownerEmail.toLowerCase());\n byUserMap.set(ownerEmail, {\n key: ownerEmail,\n label: ownerEmail,\n ownerEmail,\n costCents: 0,\n calls: 0,\n chatCalls: 0,\n inputTokens: 0,\n outputTokens: 0,\n cacheReadTokens: 0,\n cacheWriteTokens: 0,\n activeUsers: 1,\n lastActiveAt: stats.lastChatAt,\n chatThreads: stats.threads,\n chatMessages: stats.messages,\n lastChatAt: stats.lastChatAt,\n topApp: null,\n role: member?.role ?? null,\n });\n }\n\n const [\n {\n daily: usageDaily,\n dailyAvailable,\n monthlyByUser: monthlyUsage,\n usersByDay,\n },\n appAdoptionMap,\n ] = await Promise.all([\n loadDailyAndMonthlyUsage(usage),\n loadAppAdoption(usage, adoptionUsage, generatedAt),\n ]);\n const usageByDate = new Map(usageDaily.map((row) => [row.date, row]));\n const weeklyActiveUsers = dailyAvailable\n ? await loadWeeklyActiveUsers(\n weeklyLookbackUsage,\n usersByDay,\n new Date(visibleSinceMs).toISOString().slice(0, 10),\n new Date(generatedAt).toISOString().slice(0, 10),\n )\n : null;\n const daily = !dailyAvailable\n ? []\n : weeklyActiveUsers\n ? [...weeklyActiveUsers.entries()].map(([date, weeklyUsers]) => ({\n ...(usageByDate.get(date) ?? {\n date,\n costCents: 0,\n calls: 0,\n chatCalls: 0,\n activeUsers: 0,\n dailyActiveUsers: 0,\n weeklyActiveUsers: 0,\n }),\n weeklyActiveUsers: weeklyUsers,\n }))\n : usageDaily.map((row) => ({ ...row, weeklyActiveUsers: null }));\n\n const monthlyByUser =\n viewScope === \"app\"\n ? []\n : monthlyUsage.map(\n ({\n builderCredits,\n builderEstimatedCostX100,\n unclassifiedCalls,\n unpricedBuilderCalls,\n ...row\n }) => ({\n ...row,\n credits:\n billing.unit === \"usd\" ||\n billing.unit === \"unknown\" ||\n unclassifiedCalls > 0 ||\n unpricedBuilderCalls > 0\n ? null\n : builderCredits +\n builderCreditsFromCostCents(builderEstimatedCostX100 / 100),\n }),\n );\n\n const workspaceAppCreationMap = new Map<\n string,\n { month: string; ownerEmail: string; count: number; appIds: Set<string> }\n >();\n for (const row of workspaceAppCreationRows) {\n const month = new Date(numberField(row, \"created_at\"))\n .toISOString()\n .slice(0, 7);\n const ownerEmail =\n stringField(row, \"owner_email\") || stringField(row, \"actor\");\n if (!ownerEmail) continue;\n const key = `${ownerEmail}\\u0000${month}`;\n const current = workspaceAppCreationMap.get(key) ?? {\n month,\n ownerEmail,\n count: 0,\n appIds: new Set<string>(),\n };\n current.count += 1;\n const appId = stringField(row, \"target_id\");\n if (appId) current.appIds.add(appId);\n workspaceAppCreationMap.set(key, current);\n }\n const workspaceAppCreationsByUserMonth = [...workspaceAppCreationMap.values()]\n .map(({ appIds, ...row }) => ({\n ...row,\n appIds: [...appIds].sort(),\n }))\n .sort(\n (a, b) =>\n a.month.localeCompare(b.month) ||\n a.ownerEmail.localeCompare(b.ownerEmail),\n );\n\n const recentRows =\n viewScope === \"app\"\n ? []\n : await queryRows<Record<string, unknown>>(\n `SELECT id, created_at, owner_email, app, label, model,\n input_tokens, output_tokens, cache_read_tokens, cache_write_tokens,\n cost_cents_x100, thread_id, run_id, task_id, source_platform, source_id\n FROM token_usage\n WHERE ${usage.where}\n ORDER BY created_at DESC\n LIMIT 50`,\n usage.args,\n );\n const recent =\n viewScope === \"app\" ? [] : await hydrateRecentPrompts(recentRows);\n\n const appUsageByKey = new Map(\n byApp.map((bucket) => [appUsageKey(bucket.key), bucket]),\n );\n const accessUsers = members.length || byUserMap.size;\n const accessModel =\n viewScope === \"me\" ? \"solo\" : orgId ? \"workspace\" : \"solo\";\n const accessLabel =\n viewScope === \"me\"\n ? \"Your account\"\n : orgId\n ? \"Workspace members\"\n : \"Signed-in users\";\n const appRows = selectedApp ? [selectedApp] : apps;\n const appAccess = appRows.map((app) => {\n const usageBucket = appUsageByKey.get(appUsageKey(app.id));\n const adoption = appAdoptionMap.get(appUsageKey(app.id));\n const ownerEmail = appOwner(app);\n const isOwnedByViewer =\n ownerEmail?.toLowerCase() === viewerEmail.toLowerCase();\n const canViewUsage = isMetricsAdmin || isOwnedByViewer;\n const visibleUsageBucket = canViewUsage ? usageBucket : undefined;\n const visibleAdoption = canViewUsage ? adoption : undefined;\n return {\n id: app.id,\n name: app.name,\n path: app.path,\n status: app.status,\n statusLabel: app.statusLabel,\n isDispatch: app.isDispatch,\n accessModel,\n accessLabel,\n accessUsers,\n ownerEmail: canViewUsage ? ownerEmail : null,\n isOwnedByViewer,\n canViewUsage,\n usersWithUsage:\n visibleAdoption?.activeUsers ?? visibleUsageBucket?.activeUsers ?? 0,\n dailyActiveUsers: visibleAdoption?.dailyActiveUsers ?? 0,\n weeklyActiveUsers: visibleAdoption?.weeklyActiveUsers ?? 0,\n usageCalls: visibleAdoption?.calls ?? visibleUsageBucket?.calls ?? 0,\n chatCalls:\n visibleAdoption?.chatCalls ?? visibleUsageBucket?.chatCalls ?? 0,\n costCents:\n visibleAdoption?.costCents ?? visibleUsageBucket?.costCents ?? 0,\n lastActiveAt:\n visibleAdoption?.lastActiveAt ??\n visibleUsageBucket?.lastActiveAt ??\n null,\n actionMetrics: visibleAdoption\n ? [...visibleAdoption.actions.entries()]\n .map(([key, action]) => ({\n key,\n label: key,\n calls: action.calls,\n activeUsers: action.activeUsers,\n lastActiveAt: action.lastActiveAt,\n }))\n .sort((a, b) => b.calls - a.calls)\n : [],\n } satisfies AppAccessMetric;\n });\n\n const chatThreadTotals = [...chatStats.values()].reduce(\n (acc, value) => ({\n threads: acc.threads + value.threads,\n messages: acc.messages + value.messages,\n }),\n { threads: 0, messages: 0 },\n );\n\n return {\n billing,\n viewScope,\n selectedUserEmail,\n selectedAppId: selectedApp?.id ?? null,\n availableUsers:\n viewScope === \"app\"\n ? []\n : members\n .map(({ email, role }) => ({ email, role }))\n .sort((a, b) => a.email.localeCompare(b.email)),\n sinceMs,\n sinceDays,\n generatedAt,\n access: {\n viewerEmail,\n orgId,\n role,\n scope: orgId ? \"organization\" : \"solo\",\n totalUsers: accessUsers,\n },\n totals: {\n costCents: numberField(totals, \"cost_x100\") / 100,\n calls: numberField(totals, \"calls\"),\n chatCalls: numberField(totals, \"chat_calls\"),\n inputTokens: numberField(totals, \"input_tokens\"),\n outputTokens: numberField(totals, \"output_tokens\"),\n cacheReadTokens: numberField(totals, \"cache_read_tokens\"),\n cacheWriteTokens: numberField(totals, \"cache_write_tokens\"),\n activeUsers: numberField(totals, \"active_users\"),\n chatThreads: chatThreadTotals.threads,\n chatMessages: chatThreadTotals.messages,\n workspaceApps: apps.filter((app) => !app.isDispatch).length,\n },\n byApp,\n byUser:\n viewScope === \"app\"\n ? []\n : [...byUserMap.values()].sort((a, b) => {\n if (b.costCents !== a.costCents) return b.costCents - a.costCents;\n return (b.lastActiveAt ?? 0) - (a.lastActiveAt ?? 0);\n }),\n byLabel,\n byModel,\n daily,\n dailyAvailable,\n monthlyByUser,\n workspaceAppCreationsByUserMonth,\n appAccess,\n recent,\n };\n}\n"]}
|
|
1
|
+
{"version":3,"file":"usage-metrics-store.js","sourceRoot":"","sources":["../../../src/server/lib/usage-metrics-store.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n detectEngineFromEnv,\n detectEngineFromUserSecrets,\n getAgentEngineEntry,\n isAgentEngineSettingConfigured,\n isStoredEngineUsable,\n readDefaultAgentEngineSetting,\n registerBuiltinEngines,\n} from \"@agent-native/core/agent/engine\";\nimport { getDbExec } from \"@agent-native/core/db\";\nimport { readOrgMemberRole } from \"@agent-native/core/server\";\nimport { ForbiddenError } from \"@agent-native/core/sharing\";\nimport {\n builderCreditsFromCostCents,\n getUsageSummary,\n isSelfScopedUsageRead,\n MIXED_USAGE_BILLING,\n UNKNOWN_USAGE_BILLING,\n usageBillingForEngine,\n usageOrgScope,\n type UsageBillingMode,\n} from \"@agent-native/core/usage\";\n\nimport { isDispatchEnvironmentAdmin } from \"./admin-config.js\";\nimport {\n listWorkspaceApps,\n type WorkspaceAppSummary,\n} from \"./app-creation-store.js\";\nimport { currentOrgId, currentOwnerEmail } from \"./dispatch-store.js\";\n\nconst DAY_MS = 86_400_000;\n\nregisterBuiltinEngines();\n\nexport interface UsageMetricBucket {\n key: string;\n label: string;\n costCents: number;\n calls: number;\n chatCalls: number;\n inputTokens: number;\n outputTokens: number;\n cacheReadTokens: number;\n cacheWriteTokens: number;\n activeUsers: number;\n lastActiveAt: number | null;\n}\n\nexport interface UserUsageMetric extends UsageMetricBucket {\n ownerEmail: string;\n chatThreads: number;\n chatMessages: number;\n lastChatAt: number | null;\n topApp: string | null;\n role: string | null;\n}\n\nexport interface AppAdoptionActionMetric {\n key: string;\n label: string;\n calls: number;\n activeUsers: number;\n lastActiveAt: number | null;\n}\n\nexport interface AppAccessMetric {\n id: string;\n name: string;\n path: string;\n status: WorkspaceAppSummary[\"status\"];\n statusLabel?: string;\n isDispatch: boolean;\n accessModel: \"workspace\" | \"solo\";\n accessLabel: string;\n accessUsers: number;\n ownerEmail: string | null;\n isOwnedByViewer: boolean;\n canViewUsage: boolean;\n usersWithUsage: number;\n dailyActiveUsers: number;\n weeklyActiveUsers: number;\n usageCalls: number;\n chatCalls: number;\n costCents: number;\n lastActiveAt: number | null;\n actionMetrics: AppAdoptionActionMetric[];\n}\n\nexport interface DailyUsageMetric {\n date: string;\n costCents: number;\n calls: number;\n chatCalls: number;\n activeUsers: number;\n dailyActiveUsers: number;\n weeklyActiveUsers: number | null;\n}\n\nexport interface MonthlyUserUsageMetric {\n month: string;\n ownerEmail: string;\n costCents: number;\n credits: number | null;\n calls: number;\n chatCalls: number;\n inputTokens: number;\n outputTokens: number;\n cacheReadTokens: number;\n cacheWriteTokens: number;\n}\n\ntype MonthlyUsageAggregate = Omit<MonthlyUserUsageMetric, \"credits\"> & {\n builderCredits: number;\n builderEstimatedCostX100: number;\n unclassifiedCalls: number;\n unpricedBuilderCalls: number;\n};\n\nexport interface WorkspaceAppCreationMetric {\n month: string;\n ownerEmail: string;\n count: number;\n appIds: string[];\n}\n\nexport interface RecentUsageMetric {\n id: number;\n createdAt: number;\n ownerEmail: string;\n app: string;\n label: string;\n model: string;\n inputTokens: number;\n outputTokens: number;\n cacheReadTokens: number;\n cacheWriteTokens: number;\n costCents: number;\n prompt: string | null;\n promptSource: \"thread\" | \"thread-preview\" | \"not-captured\" | \"unavailable\";\n threadId: string | null;\n runId: string | null;\n taskId: string | null;\n sourcePlatform: string | null;\n sourceId: string | null;\n}\n\nexport type UsageMetricsScope = \"me\" | \"workspace\" | \"app\";\n\nexport interface UsageUserOption {\n email: string;\n role: string | null;\n}\n\nexport interface DispatchUsageMetrics {\n billing: UsageBillingMode;\n viewScope: UsageMetricsScope;\n selectedUserEmail: string | null;\n selectedAppId: string | null;\n availableUsers: UsageUserOption[];\n sinceMs: number;\n sinceDays: number;\n generatedAt: number;\n access: {\n viewerEmail: string;\n orgId: string | null;\n role: string | null;\n scope: \"organization\" | \"solo\";\n totalUsers: number;\n };\n totals: {\n costCents: number;\n calls: number;\n chatCalls: number;\n inputTokens: number;\n outputTokens: number;\n cacheReadTokens: number;\n cacheWriteTokens: number;\n activeUsers: number;\n chatThreads: number;\n chatMessages: number;\n workspaceApps: number;\n };\n byApp: UsageMetricBucket[];\n byUser: UserUsageMetric[];\n byLabel: UsageMetricBucket[];\n byModel: UsageMetricBucket[];\n daily: DailyUsageMetric[];\n dailyAvailable: boolean;\n monthlyByUser: MonthlyUserUsageMetric[];\n workspaceAppCreationsByUserMonth: WorkspaceAppCreationMetric[];\n appAccess: AppAccessMetric[];\n recent: RecentUsageMetric[];\n}\n\ninterface MemberRecord {\n email: string;\n role: string | null;\n joinedAt: number | null;\n}\n\ninterface ChatStats {\n threads: number;\n messages: number;\n lastChatAt: number | null;\n}\n\nfunction numberField(row: Record<string, unknown>, key: string): number {\n return Number(row[key] ?? 0) || 0;\n}\n\nfunction stringField(row: Record<string, unknown>, key: string): string {\n const value = row[key];\n return typeof value === \"string\" || typeof value === \"number\"\n ? String(value)\n : value == null\n ? \"\"\n : JSON.stringify(value);\n}\n\nfunction nullableNumberField(\n row: Record<string, unknown>,\n key: string,\n): number | null {\n const value = row[key];\n if (value == null) return null;\n const numberValue = Number(value);\n return Number.isFinite(numberValue) ? numberValue : null;\n}\n\nfunction nullableStringField(\n row: Record<string, unknown>,\n key: string,\n): string | null {\n const value = row[key];\n if (typeof value !== \"string\") return null;\n const trimmed = value.trim();\n return trimmed || null;\n}\n\ntype ParsedThreadData =\n | { status: \"absent\"; value: null }\n | { status: \"invalid\"; value: null }\n | { status: \"parsed\"; value: Record<string, unknown> };\n\nfunction parseJson(value: unknown): ParsedThreadData {\n if (typeof value !== \"string\" || !value.trim()) {\n return { status: \"absent\", value: null };\n }\n try {\n const parsed = JSON.parse(value);\n return parsed && typeof parsed === \"object\"\n ? { status: \"parsed\", value: parsed as Record<string, unknown> }\n : { status: \"invalid\", value: null };\n } catch {\n return { status: \"invalid\", value: null };\n }\n}\n\nfunction textFromPromptContent(value: unknown): string {\n if (typeof value === \"string\") return value.trim();\n if (!Array.isArray(value)) return \"\";\n return value\n .map((part) => {\n if (!part || typeof part !== \"object\") return \"\";\n const item = part as Record<string, unknown>;\n return item.type === \"text\" && typeof item.text === \"string\"\n ? item.text.trim()\n : \"\";\n })\n .filter(Boolean)\n .join(\"\\n\")\n .trim();\n}\n\nfunction truncatePrompt(value: string, maxLength = 360): string {\n if (value.length <= maxLength) return value;\n return `${value.slice(0, maxLength - 1).trimEnd()}…`;\n}\n\nfunction firstUserPrompt(threadData: unknown): string | null {\n const parsed = parseJson(threadData);\n if (parsed.status !== \"parsed\") return null;\n const messages = parsed.value.messages;\n if (!Array.isArray(messages)) return null;\n\n for (const entry of messages) {\n if (!entry || typeof entry !== \"object\") continue;\n const record = entry as Record<string, unknown>;\n const message =\n record.message && typeof record.message === \"object\"\n ? (record.message as Record<string, unknown>)\n : record;\n const role = typeof message.role === \"string\" ? message.role : \"\";\n if (role !== \"user\" && role !== \"human\") continue;\n const text = textFromPromptContent(message.content);\n if (text) return truncatePrompt(text);\n }\n return null;\n}\n\ninterface ThreadPromptRow {\n id?: unknown;\n preview?: unknown;\n thread_data?: unknown;\n}\n\nasync function hydrateRecentPrompts(\n rows: Array<Record<string, unknown>>,\n): Promise<RecentUsageMetric[]> {\n const threadIds = [\n ...new Set(\n rows\n .map((row) => nullableStringField(row, \"thread_id\"))\n .filter((value): value is string => Boolean(value)),\n ),\n ];\n const threads = new Map<string, ThreadPromptRow>();\n let threadQueryUnavailable = false;\n\n if (threadIds.length > 0) {\n try {\n const result = await getDbExec().execute({\n sql: `SELECT id, preview, thread_data FROM chat_threads WHERE id IN (${threadIds.map(() => \"?\").join(\", \")})`,\n args: threadIds,\n });\n for (const row of result.rows as ThreadPromptRow[]) {\n const id = typeof row.id === \"string\" ? row.id : \"\";\n if (id) threads.set(id, row);\n }\n } catch {\n threadQueryUnavailable = true;\n }\n }\n\n return rows.map((row) => {\n const threadId = nullableStringField(row, \"thread_id\");\n const thread = threadId ? threads.get(threadId) : undefined;\n const prompt = thread ? firstUserPrompt(thread.thread_data) : null;\n const preview =\n typeof thread?.preview === \"string\" ? thread.preview.trim() : \"\";\n const promptSource = prompt\n ? \"thread\"\n : preview\n ? \"thread-preview\"\n : threadQueryUnavailable && threadId\n ? \"unavailable\"\n : \"not-captured\";\n\n return {\n id: numberField(row, \"id\"),\n createdAt: numberField(row, \"created_at\"),\n ownerEmail: stringField(row, \"owner_email\"),\n app: stringField(row, \"app\") || \"unattributed\",\n label: stringField(row, \"label\") || \"chat\",\n model: stringField(row, \"model\") || \"unknown\",\n inputTokens: numberField(row, \"input_tokens\"),\n outputTokens: numberField(row, \"output_tokens\"),\n cacheReadTokens: numberField(row, \"cache_read_tokens\"),\n cacheWriteTokens: numberField(row, \"cache_write_tokens\"),\n costCents: numberField(row, \"cost_cents_x100\") / 100,\n prompt: prompt ?? (preview ? truncatePrompt(preview) : null),\n promptSource,\n threadId,\n runId: nullableStringField(row, \"run_id\"),\n taskId: nullableStringField(row, \"task_id\"),\n sourcePlatform: nullableStringField(row, \"source_platform\"),\n sourceId: nullableStringField(row, \"source_id\"),\n } satisfies RecentUsageMetric;\n });\n}\n\nfunction labelForKey(value: string): string {\n const trimmed = value.trim();\n return trimmed || \"Unattributed\";\n}\n\nfunction appUsageKey(value: string | null | undefined): string {\n const raw = (value ?? \"\").trim().toLowerCase();\n return raw || \"unattributed\";\n}\n\nfunction appOwner(app: WorkspaceAppSummary): string | null {\n const owner = app.owner?.trim();\n return owner || null;\n}\n\nasync function detectUsageEngineName(): Promise<string | null> {\n try {\n const stored = (await readDefaultAgentEngineSetting()) as {\n engine?: string;\n } | null;\n if (isAgentEngineSettingConfigured(stored)) {\n return (stored as { engine: string }).engine;\n }\n if (stored && typeof stored.engine === \"string\") {\n const entry = getAgentEngineEntry(stored.engine);\n if (entry && isStoredEngineUsable(stored, entry)) {\n return stored.engine;\n }\n }\n\n const detectedFromUser = await detectEngineFromUserSecrets();\n if (detectedFromUser) return detectedFromUser.name;\n\n return detectEngineFromEnv()?.name ?? null;\n } catch {\n return null;\n }\n}\n\nasync function queryRows<T extends Record<string, unknown>>(\n sql: string,\n args: unknown[] = [],\n): Promise<T[]> {\n try {\n const result = await getDbExec().execute({ sql, args });\n return result.rows as T[];\n } catch {\n return [];\n }\n}\n\nasync function initializeUsageMetricsTable(sinceMs: number): Promise<void> {\n try {\n await getUsageSummary({ ownerEmail: \"__dispatch_metrics_init__\", sinceMs });\n } catch {\n // Metrics should still render an empty state if usage storage is locked,\n // stale, or unavailable; each aggregate read below is already best-effort.\n }\n}\n\nasync function listOrgMembers(orgId: string | null): Promise<MemberRecord[]> {\n if (!orgId) return [];\n const result = await getDbExec().execute({\n sql: `SELECT email, role, joined_at AS joined_at FROM org_members\n WHERE org_id = ? AND federation_removal_pending_at IS NULL\n ORDER BY joined_at ASC`,\n args: [orgId],\n });\n const rows = result.rows as Record<string, unknown>[];\n return rows\n .map((row) => ({\n email: stringField(row, \"email\").trim(),\n role: stringField(row, \"role\") || null,\n joinedAt: nullableNumberField(row, \"joined_at\"),\n }))\n .filter((member) => member.email);\n}\n\nfunction usageScope(\n sinceMs: number,\n memberEmails: string[],\n): { where: string; args: unknown[] } {\n if (memberEmails.length === 0) {\n return { where: \"created_at >= ?\", args: [sinceMs] };\n }\n const placeholders = memberEmails.map(() => \"?\").join(\", \");\n return {\n where: `created_at >= ? AND LOWER(owner_email) IN (${placeholders})`,\n args: [sinceMs, ...memberEmails.map((email) => email.toLowerCase())],\n };\n}\n\nfunction withOrgUsageScope(\n scope: { where: string; args: unknown[] },\n orgId: string | null,\n selfScoped: boolean,\n): { where: string; args: unknown[] } {\n const org = usageOrgScope({ orgId, selfScoped });\n return {\n where: `${scope.where} AND ${org.where || \"org_id IS NULL\"}`,\n args: [...scope.args, ...org.args],\n };\n}\n\nfunction threadScope(\n sinceMs: number,\n memberEmails: string[],\n): { where: string; args: unknown[] } {\n if (memberEmails.length === 0) {\n return { where: \"updated_at >= ?\", args: [sinceMs] };\n }\n const placeholders = memberEmails.map(() => \"?\").join(\", \");\n return {\n where: `updated_at >= ? AND LOWER(owner_email) IN (${placeholders})`,\n args: [sinceMs, ...memberEmails.map((email) => email.toLowerCase())],\n };\n}\n\nfunction ownerScope(\n sinceMs: number,\n ownerEmail: string,\n): {\n where: string;\n args: unknown[];\n} {\n return {\n where: \"created_at >= ? AND LOWER(owner_email) = ?\",\n args: [sinceMs, ownerEmail.toLowerCase()],\n };\n}\n\nfunction ownerThreadScope(\n sinceMs: number,\n ownerEmail: string,\n): {\n where: string;\n args: unknown[];\n} {\n return {\n where: \"updated_at >= ? AND LOWER(owner_email) = ?\",\n args: [sinceMs, ownerEmail.toLowerCase()],\n };\n}\n\nfunction appUsageScope(\n sinceMs: number,\n memberEmails: string[],\n appId: string,\n orgId: string | null,\n viewerEmail: string,\n): { where: string; args: unknown[] } {\n const scope = withOrgUsageScope(\n usageScope(sinceMs, memberEmails),\n orgId,\n isSelfScopedUsageRead(memberEmails, viewerEmail),\n );\n return {\n where: `${scope.where} AND LOWER(app) = ?`,\n args: [...scope.args, appUsageKey(appId)],\n };\n}\n\nfunction workspaceAppCreationScope(\n sinceMs: number,\n orgId: string | null,\n memberEmails: string[],\n): { where: string; args: unknown[] } {\n const filters = [\"created_at >= ?\", \"action = ?\"];\n const args: unknown[] = [sinceMs, \"workspace-app.pending\"];\n\n if (orgId) {\n filters.push(\"org_id = ?\");\n args.push(orgId);\n }\n if (memberEmails.length > 0) {\n filters.push(\n `LOWER(owner_email) IN (${memberEmails.map(() => \"?\").join(\", \")})`,\n );\n args.push(...memberEmails.map((email) => email.toLowerCase()));\n }\n\n return { where: filters.join(\" AND \"), args };\n}\n\nfunction bucketFromRow(row: Record<string, unknown>): UsageMetricBucket {\n const key = stringField(row, \"k\");\n return {\n key,\n label: labelForKey(key),\n costCents: numberField(row, \"cost_x100\") / 100,\n calls: numberField(row, \"calls\"),\n chatCalls: numberField(row, \"chat_calls\"),\n inputTokens: numberField(row, \"input_tokens\"),\n outputTokens: numberField(row, \"output_tokens\"),\n cacheReadTokens: numberField(row, \"cache_read_tokens\"),\n cacheWriteTokens: numberField(row, \"cache_write_tokens\"),\n activeUsers: numberField(row, \"active_users\"),\n lastActiveAt: nullableNumberField(row, \"last_active_at\"),\n };\n}\n\nasync function usageBuckets(\n columnExpression: string,\n where: string,\n args: unknown[],\n limit: number,\n): Promise<UsageMetricBucket[]> {\n const rows = await queryRows<Record<string, unknown>>(\n `SELECT ${columnExpression} AS k,\n COALESCE(SUM(cost_cents_x100), 0) AS cost_x100,\n COUNT(*) AS calls,\n SUM(CASE WHEN label = 'chat' THEN 1 ELSE 0 END) AS chat_calls,\n COALESCE(SUM(input_tokens), 0) AS input_tokens,\n COALESCE(SUM(output_tokens), 0) AS output_tokens,\n COALESCE(SUM(cache_read_tokens), 0) AS cache_read_tokens,\n COALESCE(SUM(cache_write_tokens), 0) AS cache_write_tokens,\n COUNT(DISTINCT owner_email) AS active_users,\n MAX(created_at) AS last_active_at\n FROM token_usage\n WHERE ${where}\n GROUP BY ${columnExpression}\n ORDER BY cost_x100 DESC\n LIMIT ?`,\n [...args, limit],\n );\n return rows.map(bucketFromRow);\n}\n\nconst adoptionActionKeySql = `CASE\n WHEN LOWER(TRIM(label)) = 'chat' THEN 'chat'\n WHEN LOWER(TRIM(label)) IN ('automation', 'manual-automation')\n OR LOWER(TRIM(label)) LIKE 'automation:%'\n OR LOWER(TRIM(label)) LIKE 'manual-automation:%'\n OR LOWER(TRIM(label)) LIKE 'recurring-job:%' THEN 'automation'\n WHEN LOWER(TRIM(label)) = 'custom-agent'\n OR LOWER(TRIM(label)) LIKE 'custom-agent:%' THEN 'custom-agent'\n ELSE 'other'\nEND`;\n\ninterface AppAdoptionAggregate {\n calls: number;\n costCents: number;\n chatCalls: number;\n activeUsers: number;\n dailyActiveUsers: number;\n weeklyActiveUsers: number;\n lastActiveAt: number | null;\n actions: Map<\n string,\n { calls: number; activeUsers: number; lastActiveAt: number | null }\n >;\n}\n\nfunction emptyAppAdoptionAggregate(): AppAdoptionAggregate {\n return {\n calls: 0,\n costCents: 0,\n chatCalls: 0,\n activeUsers: 0,\n dailyActiveUsers: 0,\n weeklyActiveUsers: 0,\n lastActiveAt: null,\n actions: new Map(),\n };\n}\n\nasync function loadAppAdoption(\n usage: { where: string; args: unknown[] },\n adoptionUsage: { where: string; args: unknown[] },\n generatedAt: number,\n): Promise<Map<string, AppAdoptionAggregate>> {\n const appExpression = \"COALESCE(NULLIF(app, ''), 'unattributed')\";\n const [selectedRows, adoptionRows, actionRows] = await Promise.all([\n queryRows<Record<string, unknown>>(\n `SELECT ${appExpression} AS app,\n COALESCE(SUM(cost_cents_x100), 0) AS cost_x100,\n COUNT(*) AS calls,\n SUM(CASE WHEN label = 'chat' THEN 1 ELSE 0 END) AS chat_calls,\n COUNT(DISTINCT owner_email) AS active_users,\n MAX(created_at) AS last_active_at\n FROM token_usage\n WHERE ${usage.where}\n GROUP BY ${appExpression}`,\n usage.args,\n ),\n queryRows<Record<string, unknown>>(\n `SELECT ${appExpression} AS app,\n COUNT(DISTINCT CASE WHEN created_at >= ? THEN owner_email END) AS daily_active_users,\n COUNT(DISTINCT CASE WHEN created_at >= ? THEN owner_email END) AS weekly_active_users\n FROM token_usage\n WHERE ${adoptionUsage.where}\n GROUP BY ${appExpression}`,\n [generatedAt - DAY_MS, generatedAt - 7 * DAY_MS, ...adoptionUsage.args],\n ),\n queryRows<Record<string, unknown>>(\n `SELECT ${appExpression} AS app,\n ${adoptionActionKeySql} AS action_key,\n COUNT(*) AS calls,\n COUNT(DISTINCT owner_email) AS active_users,\n MAX(created_at) AS last_active_at\n FROM token_usage\n WHERE ${usage.where}\n GROUP BY ${appExpression}, ${adoptionActionKeySql}`,\n usage.args,\n ),\n ]);\n\n const adoptionByApp = new Map<string, AppAdoptionAggregate>();\n const getAdoption = (app: string): AppAdoptionAggregate => {\n const key = appUsageKey(app);\n const existing = adoptionByApp.get(key);\n if (existing) return existing;\n const created = emptyAppAdoptionAggregate();\n adoptionByApp.set(key, created);\n return created;\n };\n\n for (const row of selectedRows) {\n const adoption = getAdoption(stringField(row, \"app\"));\n adoption.calls = numberField(row, \"calls\");\n adoption.costCents = numberField(row, \"cost_x100\") / 100;\n adoption.chatCalls = numberField(row, \"chat_calls\");\n adoption.activeUsers = numberField(row, \"active_users\");\n adoption.lastActiveAt = nullableNumberField(row, \"last_active_at\");\n }\n for (const row of adoptionRows) {\n const adoption = getAdoption(stringField(row, \"app\"));\n adoption.dailyActiveUsers = numberField(row, \"daily_active_users\");\n adoption.weeklyActiveUsers = numberField(row, \"weekly_active_users\");\n }\n for (const row of actionRows) {\n const adoption = getAdoption(stringField(row, \"app\"));\n adoption.actions.set(stringField(row, \"action_key\"), {\n calls: numberField(row, \"calls\"),\n activeUsers: numberField(row, \"active_users\"),\n lastActiveAt: nullableNumberField(row, \"last_active_at\"),\n });\n }\n\n return adoptionByApp;\n}\n\nasync function loadDailyAndMonthlyUsage(usage: {\n where: string;\n args: unknown[];\n}): Promise<{\n daily: DailyUsageMetric[];\n dailyAvailable: boolean;\n monthlyByUser: MonthlyUsageAggregate[];\n usersByDay: Map<string, Set<string>>;\n}> {\n const dayBucketExpression = `CAST(created_at / ${DAY_MS} AS INTEGER)`;\n let result;\n try {\n result = await getDbExec().execute({\n sql: `SELECT ${dayBucketExpression} AS day_bucket,\n owner_email,\n COALESCE(SUM(cost_cents_x100), 0) AS cost_x100,\n COALESCE(SUM(builder_credits_used), 0) AS builder_credits,\n COALESCE(SUM(CASE\n WHEN engine_name = 'builder' AND builder_credits_used IS NULL\n THEN cost_cents_x100 ELSE 0\n END), 0) AS builder_estimated_cost_x100,\n COUNT(*) FILTER (\n WHERE NULLIF(engine_name, '') IS NULL AND builder_credits_used IS NULL\n ) AS unclassified_calls,\n COUNT(*) FILTER (\n WHERE engine_name = 'builder' AND builder_credits_used IS NULL\n AND cost_source = 'unavailable' AND cost_cents_x100 <= 0\n ) AS unpriced_builder_calls,\n COUNT(*) AS calls,\n SUM(CASE WHEN label = 'chat' THEN 1 ELSE 0 END) AS chat_calls,\n COALESCE(SUM(input_tokens), 0) AS input_tokens,\n COALESCE(SUM(output_tokens), 0) AS output_tokens,\n COALESCE(SUM(cache_read_tokens), 0) AS cache_read_tokens,\n COALESCE(SUM(cache_write_tokens), 0) AS cache_write_tokens\n FROM token_usage\n WHERE ${usage.where}\n GROUP BY ${dayBucketExpression}, owner_email\n ORDER BY ${dayBucketExpression} ASC`,\n args: usage.args,\n });\n } catch {\n return {\n daily: [],\n dailyAvailable: false,\n monthlyByUser: [],\n usersByDay: new Map(),\n };\n }\n const rows = result.rows as Record<string, unknown>[];\n const dailyMap = new Map<\n string,\n { costX100: number; calls: number; chatCalls: number; users: Set<string> }\n >();\n const monthlyByUserMap = new Map<string, MonthlyUsageAggregate>();\n const usersByDay = new Map<string, Set<string>>();\n\n for (const row of rows) {\n const date = new Date(\n numberField(row, \"day_bucket\") * DAY_MS,\n ).toISOString();\n const day = date.slice(0, 10);\n const ownerEmail = stringField(row, \"owner_email\");\n const daily = dailyMap.get(day) ?? {\n costX100: 0,\n calls: 0,\n chatCalls: 0,\n users: new Set<string>(),\n };\n daily.costX100 += numberField(row, \"cost_x100\");\n daily.calls += numberField(row, \"calls\");\n daily.chatCalls += numberField(row, \"chat_calls\");\n daily.users.add(ownerEmail.toLowerCase());\n dailyMap.set(day, daily);\n const users = usersByDay.get(day) ?? new Set<string>();\n users.add(ownerEmail.toLowerCase());\n usersByDay.set(day, users);\n\n const month = day.slice(0, 7);\n const monthlyKey = `${ownerEmail}\\u0000${month}`;\n const monthly = monthlyByUserMap.get(monthlyKey) ?? {\n month,\n ownerEmail,\n costCents: 0,\n builderCredits: 0,\n builderEstimatedCostX100: 0,\n unclassifiedCalls: 0,\n unpricedBuilderCalls: 0,\n calls: 0,\n chatCalls: 0,\n inputTokens: 0,\n outputTokens: 0,\n cacheReadTokens: 0,\n cacheWriteTokens: 0,\n };\n monthly.costCents += numberField(row, \"cost_x100\") / 100;\n monthly.builderCredits += numberField(row, \"builder_credits\");\n monthly.builderEstimatedCostX100 += numberField(\n row,\n \"builder_estimated_cost_x100\",\n );\n monthly.unclassifiedCalls += numberField(row, \"unclassified_calls\");\n monthly.unpricedBuilderCalls += numberField(row, \"unpriced_builder_calls\");\n monthly.calls += numberField(row, \"calls\");\n monthly.chatCalls += numberField(row, \"chat_calls\");\n monthly.inputTokens += numberField(row, \"input_tokens\");\n monthly.outputTokens += numberField(row, \"output_tokens\");\n monthly.cacheReadTokens += numberField(row, \"cache_read_tokens\");\n monthly.cacheWriteTokens += numberField(row, \"cache_write_tokens\");\n monthlyByUserMap.set(monthlyKey, monthly);\n }\n\n return {\n daily: [...dailyMap.entries()]\n .map(([date, value]) => ({\n date,\n costCents: value.costX100 / 100,\n calls: value.calls,\n chatCalls: value.chatCalls,\n activeUsers: value.users.size,\n dailyActiveUsers: value.users.size,\n weeklyActiveUsers: null,\n }))\n .sort((a, b) => a.date.localeCompare(b.date)),\n dailyAvailable: true,\n monthlyByUser: [...monthlyByUserMap.values()].sort(\n (a, b) =>\n a.month.localeCompare(b.month) ||\n a.ownerEmail.localeCompare(b.ownerEmail),\n ),\n usersByDay,\n };\n}\n\nasync function loadWeeklyActiveUsers(\n usage: { where: string; args: unknown[] },\n visibleUsersByDay: Map<string, Set<string>>,\n startDate: string,\n endDate: string,\n): Promise<Map<string, number> | null> {\n const dayBucketExpression = `CAST(created_at / ${DAY_MS} AS INTEGER)`;\n let result;\n try {\n result = await getDbExec().execute({\n sql: `SELECT ${dayBucketExpression} AS day_bucket, owner_email\n FROM token_usage\n WHERE ${usage.where}\n GROUP BY ${dayBucketExpression}, owner_email\n ORDER BY ${dayBucketExpression} ASC`,\n args: usage.args,\n });\n // coercion-ok: null distinguishes an unavailable optional trend from empty activity.\n } catch {\n return null;\n }\n const rows = result.rows as Record<string, unknown>[];\n const usersByDay = new Map(\n [...visibleUsersByDay.entries()].map(([day, users]) => [\n day,\n new Set(users),\n ]),\n );\n for (const row of rows) {\n const day = new Date(numberField(row, \"day_bucket\") * DAY_MS)\n .toISOString()\n .slice(0, 10);\n const users = usersByDay.get(day) ?? new Set<string>();\n users.add(stringField(row, \"owner_email\").toLowerCase());\n usersByDay.set(day, users);\n }\n\n const activityByDay = new Map<string, number>();\n const firstDay = Date.parse(`${startDate}T00:00:00Z`);\n const lastDay = Date.parse(`${endDate}T00:00:00Z`);\n for (let dayStart = firstDay; dayStart <= lastDay; dayStart += DAY_MS) {\n const day = new Date(dayStart).toISOString().slice(0, 10);\n const weeklyUsers = new Set<string>();\n for (\n let previousDayStart = dayStart;\n previousDayStart >= dayStart - 6 * DAY_MS;\n previousDayStart -= DAY_MS\n ) {\n const previousDay = new Date(previousDayStart).toISOString().slice(0, 10);\n for (const user of usersByDay.get(previousDay) ?? []) {\n weeklyUsers.add(user);\n }\n }\n activityByDay.set(day, weeklyUsers.size);\n }\n return activityByDay;\n}\n\nasync function loadChatStats(\n where: string,\n args: unknown[],\n): Promise<Map<string, ChatStats>> {\n const rows = await queryRows<Record<string, unknown>>(\n `SELECT owner_email AS owner_email,\n COUNT(*) AS threads,\n COALESCE(SUM(message_count), 0) AS messages,\n MAX(updated_at) AS last_chat_at\n FROM chat_threads\n WHERE ${where}\n GROUP BY owner_email`,\n args,\n );\n return new Map(\n rows.map((row) => [\n stringField(row, \"owner_email\"),\n {\n threads: numberField(row, \"threads\"),\n messages: numberField(row, \"messages\"),\n lastChatAt: nullableNumberField(row, \"last_chat_at\"),\n },\n ]),\n );\n}\n\nasync function assertCanViewMetrics(viewScope: UsageMetricsScope): Promise<{\n viewerEmail: string;\n orgId: string | null;\n role: string | null;\n}> {\n const viewerEmail = currentOwnerEmail();\n const orgId = currentOrgId();\n const role = orgId ? await readOrgMemberRole(orgId, viewerEmail) : null;\n if (\n viewScope === \"me\" ||\n isDispatchEnvironmentAdmin(viewerEmail) ||\n role === \"owner\" ||\n role === \"admin\"\n ) {\n return { viewerEmail, orgId, role };\n }\n if (!orgId) {\n return { viewerEmail, orgId, role };\n }\n throw new ForbiddenError(\n \"Only organization owners and admins can view workspace usage metrics.\",\n );\n}\n\nexport async function listDispatchUsageMetrics(input: {\n sinceDays?: number;\n scope?: UsageMetricsScope;\n userEmail?: string | null;\n appId?: string | null;\n}): Promise<DispatchUsageMetrics> {\n const viewScope: UsageMetricsScope =\n input.scope === \"me\" ? \"me\" : input.scope === \"app\" ? \"app\" : \"workspace\";\n const { viewerEmail, orgId, role } = await assertCanViewMetrics(\n viewScope === \"app\" ? \"me\" : viewScope,\n );\n const sinceDays = Math.max(1, Math.min(365, input.sinceDays ?? 30));\n const generatedAt = Date.now();\n const sinceMs = generatedAt - sinceDays * DAY_MS;\n const apps = await listWorkspaceApps({ includeAgentCards: false });\n const requestedAppId = input.appId?.trim() || null;\n const selectedApp =\n viewScope === \"app\" && requestedAppId\n ? apps.find((app) => app.id === requestedAppId)\n : null;\n if (viewScope === \"app\" && !requestedAppId) {\n throw new Error(\"App metrics require an appId.\");\n }\n if (viewScope === \"app\" && !selectedApp) {\n throw new ForbiddenError(\n \"You do not have access to metrics for this workspace app.\",\n );\n }\n const selectedAppOwner = selectedApp ? appOwner(selectedApp) : null;\n const isMetricsAdmin = Boolean(\n isDispatchEnvironmentAdmin(viewerEmail) ||\n role === \"owner\" ||\n role === \"admin\",\n );\n if (\n viewScope === \"app\" &&\n !isMetricsAdmin &&\n selectedAppOwner?.toLowerCase() !== viewerEmail.toLowerCase()\n ) {\n throw new ForbiddenError(\n \"Only the app owner or an organization owner or admin can view app metrics.\",\n );\n }\n\n await initializeUsageMetricsTable(sinceMs);\n\n const rawMembers =\n viewScope === \"me\"\n ? [{ email: viewerEmail, role, joinedAt: null }]\n : orgId\n ? await listOrgMembers(orgId)\n : [{ email: viewerEmail, role: null, joinedAt: null }];\n const members =\n viewScope !== \"me\" && orgId && rawMembers.length === 0\n ? [{ email: viewerEmail, role, joinedAt: null }]\n : rawMembers;\n const requestedUserEmail =\n viewScope === \"app\" ? null : input.userEmail?.trim() || null;\n const selectedUserEmail =\n viewScope === \"me\"\n ? viewerEmail\n : requestedUserEmail\n ? (members.find(\n (member) =>\n member.email.toLowerCase() === requestedUserEmail.toLowerCase(),\n )?.email ?? null)\n : null;\n if (viewScope === \"workspace\" && requestedUserEmail && !selectedUserEmail) {\n throw new ForbiddenError(\n \"The selected user is not available in this workspace.\",\n );\n }\n const memberEmails = selectedUserEmail\n ? [selectedUserEmail]\n : members.map((member) => member.email);\n const selfScopedUsage = isSelfScopedUsageRead(memberEmails, viewerEmail);\n const memberByEmail = new Map(\n members.map((member) => [member.email.toLowerCase(), member]),\n );\n const usage =\n viewScope === \"app\" && selectedApp\n ? appUsageScope(sinceMs, memberEmails, selectedApp.id, orgId, viewerEmail)\n : withOrgUsageScope(\n selectedUserEmail\n ? ownerScope(sinceMs, selectedUserEmail)\n : usageScope(sinceMs, memberEmails),\n orgId,\n selfScopedUsage,\n );\n const visibleSinceMs = Math.floor(sinceMs / DAY_MS) * DAY_MS;\n const adoptionSinceMs = Math.min(\n visibleSinceMs - 6 * DAY_MS,\n generatedAt - 7 * DAY_MS,\n );\n const adoptionUsage =\n viewScope === \"app\" && selectedApp\n ? appUsageScope(\n adoptionSinceMs,\n memberEmails,\n selectedApp.id,\n orgId,\n viewerEmail,\n )\n : withOrgUsageScope(\n selectedUserEmail\n ? ownerScope(adoptionSinceMs, selectedUserEmail)\n : usageScope(adoptionSinceMs, memberEmails),\n orgId,\n selfScopedUsage,\n );\n const weeklyLookbackUsage = {\n where: `${adoptionUsage.where} AND created_at < ?`,\n args: [...adoptionUsage.args, sinceMs],\n };\n const threads = selectedUserEmail\n ? ownerThreadScope(sinceMs, selectedUserEmail)\n : threadScope(sinceMs, memberEmails);\n\n const workspaceAppCreation = workspaceAppCreationScope(\n sinceMs,\n orgId,\n memberEmails,\n );\n\n const [\n totalsRows,\n byApp,\n byUserBase,\n byLabel,\n byModel,\n chatStats,\n workspaceAppCreationRows,\n ] = await Promise.all([\n queryRows<Record<string, unknown>>(\n `SELECT\n COALESCE(SUM(cost_cents_x100), 0) AS cost_x100,\n COUNT(*) AS calls,\n SUM(CASE WHEN label = 'chat' THEN 1 ELSE 0 END) AS chat_calls,\n COALESCE(SUM(input_tokens), 0) AS input_tokens,\n COALESCE(SUM(output_tokens), 0) AS output_tokens,\n COALESCE(SUM(cache_read_tokens), 0) AS cache_read_tokens,\n COALESCE(SUM(cache_write_tokens), 0) AS cache_write_tokens,\n COUNT(*) FILTER (WHERE engine_name = 'builder' OR builder_credits_used IS NOT NULL) AS builder_calls,\n COUNT(*) FILTER (WHERE NULLIF(engine_name, '') IS NOT NULL AND NULLIF(engine_name, '') <> 'builder' AND builder_credits_used IS NULL) AS provider_calls,\n COUNT(*) FILTER (WHERE NULLIF(engine_name, '') IS NULL AND builder_credits_used IS NULL) AS unknown_calls,\n COUNT(DISTINCT owner_email) AS active_users\n FROM token_usage\n WHERE ${usage.where}`,\n usage.args,\n ),\n usageBuckets(\n `COALESCE(NULLIF(app, ''), 'unattributed')`,\n usage.where,\n usage.args,\n 20,\n ),\n viewScope === \"app\"\n ? Promise.resolve([] as UsageMetricBucket[])\n : usageBuckets(\"owner_email\", usage.where, usage.args, 50),\n viewScope === \"app\"\n ? Promise.resolve([] as UsageMetricBucket[])\n : usageBuckets(\n `COALESCE(NULLIF(label, ''), 'chat')`,\n usage.where,\n usage.args,\n 20,\n ),\n usageBuckets(\n `COALESCE(NULLIF(model, ''), 'unknown')`,\n usage.where,\n usage.args,\n 20,\n ),\n viewScope === \"app\"\n ? Promise.resolve(new Map<string, ChatStats>())\n : loadChatStats(threads.where, threads.args),\n viewScope === \"app\"\n ? Promise.resolve([])\n : queryRows<Record<string, unknown>>(\n `SELECT owner_email, actor, target_id, created_at\n FROM dispatch_audit_events\n WHERE ${workspaceAppCreation.where}\n ORDER BY created_at ASC`,\n workspaceAppCreation.args,\n ),\n ]);\n\n const totals = totalsRows[0] ?? {};\n const builderCalls = numberField(totals, \"builder_calls\");\n const providerCalls = numberField(totals, \"provider_calls\");\n const unknownCalls = numberField(totals, \"unknown_calls\");\n const billing = unknownCalls\n ? UNKNOWN_USAGE_BILLING\n : builderCalls > 0 && providerCalls > 0\n ? MIXED_USAGE_BILLING\n : builderCalls > 0\n ? usageBillingForEngine(\"builder\")\n : providerCalls > 0\n ? usageBillingForEngine(\"external\")\n : usageBillingForEngine(await detectUsageEngineName());\n\n const topAppRows =\n viewScope === \"app\"\n ? []\n : await queryRows<Record<string, unknown>>(\n `SELECT owner_email AS owner_email,\n COALESCE(NULLIF(app, ''), 'unattributed') AS app,\n COALESCE(SUM(cost_cents_x100), 0) AS cost_x100\n FROM token_usage\n WHERE ${usage.where}\n GROUP BY owner_email, COALESCE(NULLIF(app, ''), 'unattributed')\n ORDER BY owner_email ASC, cost_x100 DESC`,\n usage.args,\n );\n const topAppByUser = new Map<string, string>();\n for (const row of topAppRows) {\n const email = stringField(row, \"owner_email\");\n if (!topAppByUser.has(email)) {\n topAppByUser.set(email, stringField(row, \"app\"));\n }\n }\n\n const byUserMap = new Map<string, UserUsageMetric>();\n for (const bucket of byUserBase) {\n const ownerEmail = bucket.key;\n const stats = chatStats.get(ownerEmail) ?? {\n threads: 0,\n messages: 0,\n lastChatAt: null,\n };\n const member = memberByEmail.get(ownerEmail.toLowerCase());\n byUserMap.set(ownerEmail, {\n ...bucket,\n ownerEmail,\n chatThreads: stats.threads,\n chatMessages: stats.messages,\n lastChatAt: stats.lastChatAt,\n topApp: topAppByUser.get(ownerEmail) ?? null,\n role: member?.role ?? null,\n });\n }\n for (const [ownerEmail, stats] of chatStats) {\n if (byUserMap.has(ownerEmail)) continue;\n const member = memberByEmail.get(ownerEmail.toLowerCase());\n byUserMap.set(ownerEmail, {\n key: ownerEmail,\n label: ownerEmail,\n ownerEmail,\n costCents: 0,\n calls: 0,\n chatCalls: 0,\n inputTokens: 0,\n outputTokens: 0,\n cacheReadTokens: 0,\n cacheWriteTokens: 0,\n activeUsers: 1,\n lastActiveAt: stats.lastChatAt,\n chatThreads: stats.threads,\n chatMessages: stats.messages,\n lastChatAt: stats.lastChatAt,\n topApp: null,\n role: member?.role ?? null,\n });\n }\n\n const [\n {\n daily: usageDaily,\n dailyAvailable,\n monthlyByUser: monthlyUsage,\n usersByDay,\n },\n appAdoptionMap,\n ] = await Promise.all([\n loadDailyAndMonthlyUsage(usage),\n loadAppAdoption(usage, adoptionUsage, generatedAt),\n ]);\n const usageByDate = new Map(usageDaily.map((row) => [row.date, row]));\n const weeklyActiveUsers = dailyAvailable\n ? await loadWeeklyActiveUsers(\n weeklyLookbackUsage,\n usersByDay,\n new Date(visibleSinceMs).toISOString().slice(0, 10),\n new Date(generatedAt).toISOString().slice(0, 10),\n )\n : null;\n const daily = !dailyAvailable\n ? []\n : weeklyActiveUsers\n ? [...weeklyActiveUsers.entries()].map(([date, weeklyUsers]) => ({\n ...(usageByDate.get(date) ?? {\n date,\n costCents: 0,\n calls: 0,\n chatCalls: 0,\n activeUsers: 0,\n dailyActiveUsers: 0,\n weeklyActiveUsers: 0,\n }),\n weeklyActiveUsers: weeklyUsers,\n }))\n : usageDaily.map((row) => ({ ...row, weeklyActiveUsers: null }));\n\n const monthlyByUser =\n viewScope === \"app\"\n ? []\n : monthlyUsage.map(\n ({\n builderCredits,\n builderEstimatedCostX100,\n unclassifiedCalls,\n unpricedBuilderCalls,\n ...row\n }) => ({\n ...row,\n credits:\n billing.unit === \"usd\" ||\n billing.unit === \"unknown\" ||\n unclassifiedCalls > 0 ||\n unpricedBuilderCalls > 0\n ? null\n : builderCredits +\n builderCreditsFromCostCents(builderEstimatedCostX100 / 100),\n }),\n );\n\n const workspaceAppCreationMap = new Map<\n string,\n { month: string; ownerEmail: string; count: number; appIds: Set<string> }\n >();\n for (const row of workspaceAppCreationRows) {\n const month = new Date(numberField(row, \"created_at\"))\n .toISOString()\n .slice(0, 7);\n const ownerEmail =\n stringField(row, \"owner_email\") || stringField(row, \"actor\");\n if (!ownerEmail) continue;\n const key = `${ownerEmail}\\u0000${month}`;\n const current = workspaceAppCreationMap.get(key) ?? {\n month,\n ownerEmail,\n count: 0,\n appIds: new Set<string>(),\n };\n current.count += 1;\n const appId = stringField(row, \"target_id\");\n if (appId) current.appIds.add(appId);\n workspaceAppCreationMap.set(key, current);\n }\n const workspaceAppCreationsByUserMonth = [...workspaceAppCreationMap.values()]\n .map(({ appIds, ...row }) => ({\n ...row,\n appIds: [...appIds].sort(),\n }))\n .sort(\n (a, b) =>\n a.month.localeCompare(b.month) ||\n a.ownerEmail.localeCompare(b.ownerEmail),\n );\n\n const recentRows =\n viewScope === \"app\"\n ? []\n : await queryRows<Record<string, unknown>>(\n `SELECT id, created_at, owner_email, app, label, model,\n input_tokens, output_tokens, cache_read_tokens, cache_write_tokens,\n cost_cents_x100, thread_id, run_id, task_id, source_platform, source_id\n FROM token_usage\n WHERE ${usage.where}\n ORDER BY created_at DESC\n LIMIT 50`,\n usage.args,\n );\n const recent =\n viewScope === \"app\" ? [] : await hydrateRecentPrompts(recentRows);\n\n const appUsageByKey = new Map(\n byApp.map((bucket) => [appUsageKey(bucket.key), bucket]),\n );\n const accessUsers = members.length || byUserMap.size;\n const accessModel =\n viewScope === \"me\" ? \"solo\" : orgId ? \"workspace\" : \"solo\";\n const accessLabel =\n viewScope === \"me\"\n ? \"Your account\"\n : orgId\n ? \"Workspace members\"\n : \"Signed-in users\";\n const appRows = selectedApp ? [selectedApp] : apps;\n const appAccess = appRows.map((app) => {\n const usageBucket = appUsageByKey.get(appUsageKey(app.id));\n const adoption = appAdoptionMap.get(appUsageKey(app.id));\n const ownerEmail = appOwner(app);\n const isOwnedByViewer =\n ownerEmail?.toLowerCase() === viewerEmail.toLowerCase();\n const canViewUsage = isMetricsAdmin || isOwnedByViewer;\n const visibleUsageBucket = canViewUsage ? usageBucket : undefined;\n const visibleAdoption = canViewUsage ? adoption : undefined;\n return {\n id: app.id,\n name: app.name,\n path: app.path,\n status: app.status,\n statusLabel: app.statusLabel,\n isDispatch: app.isDispatch,\n accessModel,\n accessLabel,\n accessUsers,\n ownerEmail: canViewUsage ? ownerEmail : null,\n isOwnedByViewer,\n canViewUsage,\n usersWithUsage:\n visibleAdoption?.activeUsers ?? visibleUsageBucket?.activeUsers ?? 0,\n dailyActiveUsers: visibleAdoption?.dailyActiveUsers ?? 0,\n weeklyActiveUsers: visibleAdoption?.weeklyActiveUsers ?? 0,\n usageCalls: visibleAdoption?.calls ?? visibleUsageBucket?.calls ?? 0,\n chatCalls:\n visibleAdoption?.chatCalls ?? visibleUsageBucket?.chatCalls ?? 0,\n costCents:\n visibleAdoption?.costCents ?? visibleUsageBucket?.costCents ?? 0,\n lastActiveAt:\n visibleAdoption?.lastActiveAt ??\n visibleUsageBucket?.lastActiveAt ??\n null,\n actionMetrics: visibleAdoption\n ? [...visibleAdoption.actions.entries()]\n .map(([key, action]) => ({\n key,\n label: key,\n calls: action.calls,\n activeUsers: action.activeUsers,\n lastActiveAt: action.lastActiveAt,\n }))\n .sort((a, b) => b.calls - a.calls)\n : [],\n } satisfies AppAccessMetric;\n });\n\n const chatThreadTotals = [...chatStats.values()].reduce(\n (acc, value) => ({\n threads: acc.threads + value.threads,\n messages: acc.messages + value.messages,\n }),\n { threads: 0, messages: 0 },\n );\n\n return {\n billing,\n viewScope,\n selectedUserEmail,\n selectedAppId: selectedApp?.id ?? null,\n availableUsers:\n viewScope === \"app\"\n ? []\n : members\n .map(({ email, role }) => ({ email, role }))\n .sort((a, b) => a.email.localeCompare(b.email)),\n sinceMs,\n sinceDays,\n generatedAt,\n access: {\n viewerEmail,\n orgId,\n role,\n scope: orgId ? \"organization\" : \"solo\",\n totalUsers: accessUsers,\n },\n totals: {\n costCents: numberField(totals, \"cost_x100\") / 100,\n calls: numberField(totals, \"calls\"),\n chatCalls: numberField(totals, \"chat_calls\"),\n inputTokens: numberField(totals, \"input_tokens\"),\n outputTokens: numberField(totals, \"output_tokens\"),\n cacheReadTokens: numberField(totals, \"cache_read_tokens\"),\n cacheWriteTokens: numberField(totals, \"cache_write_tokens\"),\n activeUsers: numberField(totals, \"active_users\"),\n chatThreads: chatThreadTotals.threads,\n chatMessages: chatThreadTotals.messages,\n workspaceApps: apps.filter((app) => !app.isDispatch).length,\n },\n byApp,\n byUser:\n viewScope === \"app\"\n ? []\n : [...byUserMap.values()].sort((a, b) => {\n if (b.costCents !== a.costCents) return b.costCents - a.costCents;\n return (b.lastActiveAt ?? 0) - (a.lastActiveAt ?? 0);\n }),\n byLabel,\n byModel,\n daily,\n dailyAvailable,\n monthlyByUser,\n workspaceAppCreationsByUserMonth,\n appAccess,\n recent,\n };\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"vault-store.d.ts","sourceRoot":"","sources":["../../../src/server/lib/vault-store.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"vault-store.d.ts","sourceRoot":"","sources":["../../../src/server/lib/vault-store.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import crypto from "node:crypto";
|
|
2
|
-
import { getDbExec } from "@agent-native/core/db";
|
|
3
2
|
import { and, desc, eq, isNull, or, sql } from "@agent-native/core/db/schema";
|
|
4
3
|
import { ssrfSafeFetch } from "@agent-native/core/extensions/url-safety";
|
|
5
4
|
import { deleteAppSecret, last4, listAppSecretsForScope, VAULT_SYNC_DESCRIPTION_PREFIX, writeAppSecret, } from "@agent-native/core/secrets";
|
|
5
|
+
import { readOrgMemberRole } from "@agent-native/core/server";
|
|
6
6
|
import { discoverAgents } from "@agent-native/core/server/agent-discovery";
|
|
7
7
|
import { getOrgSetting, getUserSetting, putOrgSetting, putUserSetting, } from "@agent-native/core/settings";
|
|
8
8
|
import { asc, gt } from "drizzle-orm";
|
|
@@ -90,14 +90,7 @@ export async function assertCanManageVault() {
|
|
|
90
90
|
const email = currentOwnerEmail().trim().toLowerCase();
|
|
91
91
|
let role = null;
|
|
92
92
|
try {
|
|
93
|
-
|
|
94
|
-
sql: `SELECT role FROM org_members
|
|
95
|
-
WHERE org_id = ? AND LOWER(email) = ?
|
|
96
|
-
AND federation_removal_pending_at IS NULL
|
|
97
|
-
LIMIT 1`,
|
|
98
|
-
args: [orgId, email],
|
|
99
|
-
});
|
|
100
|
-
role = result.rows[0]?.role;
|
|
93
|
+
role = await readOrgMemberRole(orgId, email);
|
|
101
94
|
}
|
|
102
95
|
catch {
|
|
103
96
|
// coercion-ok: unknown membership is treated as unauthorized below.
|