From 0cb95cdae2ee7ebb2f7bb18c1b4847422462c669 Mon Sep 17 00:00:00 2001 From: redshift <213178690+1ftredsh@users.noreply.github.com> Date: Sat, 21 Mar 2026 16:42:59 +0000 Subject: [PATCH] feat(daemon): include client ID in usage tracking entries - Add getClientIdFromRequest helper to extract API key from Authorization header - Look up clientId from store's clientIds array - Include client field in both streaming and non-streaming usage entries - Enables per-client usage tracking for integrations --- src/daemon/http/index.ts | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/src/daemon/http/index.ts b/src/daemon/http/index.ts index a5d8d6d..424d8e6 100644 --- a/src/daemon/http/index.ts +++ b/src/daemon/http/index.ts @@ -12,6 +12,33 @@ import { import type { UsageData } from "../types"; import { logger } from "../../utils/logger"; +/** + * Extracts the client ID from an incoming request by looking up the API key + * in the store's clientIds list. + */ +function getClientIdFromRequest( + req: IncomingMessage, + store: { getState(): any }, +): string | undefined { + const authHeader = req.headers.authorization; + if (!authHeader || !authHeader.startsWith("Bearer ")) { + return undefined; + } + + const apiKey = authHeader.slice(7); // Remove "Bearer " prefix + if (!apiKey.startsWith("sk-")) { + return undefined; + } + + const state = store.getState(); + const clientIds = state.clientIds || []; + const matchingClient = (clientIds as { clientId: string; apiKey: string }[]).find( + (c) => c.apiKey === apiKey, + ); + + return matchingClient?.clientId; +} + async function readBody(req: IncomingMessage): Promise { return new Promise((resolve, reject) => { let data = ""; @@ -419,6 +446,7 @@ export function createDaemonRequestHandler(deps: { modelId, baseUrl: usageBaseUrl, requestId: usageRequestId, + client: getClientIdFromRequest(req, deps.store), ...capturedUsage, }); logger.log( @@ -447,6 +475,7 @@ export function createDaemonRequestHandler(deps: { modelId, baseUrl: usageBaseUrl, requestId: responseRequestId, + client: getClientIdFromRequest(req, deps.store), ...nonStreamUsage, }); }