/** * OpenRouter's activity report, read as a usage log. * * The eighth converter, and the third that reads a provider rather than a * tool in front of one. OpenRouter is the one provider Trazum already has a * price list for by construction: `openrouter.ts` turns its public model * catalogue into a pricing overlay, keyed by the same slugs this report * carries. So a row here is priceable the moment the overlay is loaded, for * hundreds of models the bundled table never typed. * * ## Derived from the published schema * * `GET /api/v1/activity` needs a **management key** and answers the last * thirty completed UTC days, one row per model per endpoint per day: * `date` (`YYYY-MM-DD`), `model` (slug), `model_permaslug` (slug with * version), `endpoint_id`, `provider_name`, `usage` (cost in USD), * `byok_usage_inference` (BYOK cost in USD), `requests`, `prompt_tokens`, * `completion_tokens`, `reasoning_tokens`, and `workspace_id` when the * request said `group_by=workspace`. The schema's own example is the * fixture. * * It takes the answer and never the key, for the reason `anthropic-usage.ts` * gives: a management key manages the account, and this project holds no * provider credential. * * ## Two figures that are never added * * `usage` is what OpenRouter charged, in dollars, and it is carried out of * this conversion **beside** Trazum's catalogue-priced total, never merged * into it — the rule `docs/commands.md` states for LiteLLM's `spend`. They * are two measurements of the same rows; a reader is entitled to both and to * the gap. `byok_usage_inference` is what an upstream provider charged on the * operator's own key through OpenRouter, and is carried separately for the * same reason. * * ## What the record says, and what it declines to say * * The record is `prompt_tokens` and `completion_tokens` under the model's * slug, at the day's start. `model` rather than `model_permaslug`, because * the slug is what the pricing overlay is keyed by and a versioned slug * would price nothing until somebody mapped it. * * `reasoning_tokens` are counted and **not added** to the completion count. * The schema does not say whether `completion_tokens` already includes * them, and adding them if it does would charge reasoning twice on the * models where it is the largest line. They are reported so the operator * can see the count and settle the question against their own invoice. * * `endpoint_id` and `provider_name` are read by nothing that reaches the * output: a row is priced by model, and which provider served it is what * `usage` already reflects. `workspace_id` is read only through a mapping * the operator writes, exact match, and unlike Anthropic's a `null` here has * one meaning only — the request did not group by workspace. */ /** One workspace, and the label the operator gives it. Exact match. */ export interface OpenrouterWorkspaceLabel { workspace: string; label: string; } export interface OpenrouterActivityRecord { model: string; ts: string; label?: string; usage: { prompt_tokens: number; completion_tokens: number; }; } export interface OpenrouterActivityConversion { records: OpenrouterActivityRecord[]; /** Rows that became records. */ rows: number; /** `requests`, summed. A row is a day's aggregate, not a call. */ requests: number; /** What OpenRouter charged, summed, in dollars. Never merged into Trazum's total. */ reportedUsageUsd: number; /** What upstream providers charged on the operator's own keys, summed. */ byokUsd: number; /** `reasoning_tokens`, summed, and deliberately not added to any record. */ reasoningTokens: number; /** Rows with no model slug, which nothing can price. */ unnamedModel: number; /** Rows whose date was not a `YYYY-MM-DD` day. */ undatedRows: number; /** Distinct days seen, so a reader knows how much of the thirty this is. */ days: number; labelledByWorkspace: number; unruledWorkspace: number; /** Rules were given and no row carried a workspace id. */ workspaceNotGrouped: boolean; /** The input was not the JSON this endpoint returns. */ unparseable: number; } export declare function openrouterActivityRecords(text: string, options?: { label?: string; labelByWorkspace?: readonly OpenrouterWorkspaceLabel[]; }): OpenrouterActivityConversion; /** * Whether this text is an OpenRouter activity report. `model_permaslug` * belongs to no other document, and `byok_usage_inference` likewise. */ export declare function looksLikeOpenrouterActivity(text: string, prefixBytes?: number): boolean; //# sourceMappingURL=openrouter-activity.d.ts.map