UNPKG

@juspay/neurolink

Version:

The pipe layer of an AI nervous system: one interface connecting provider neurons to your application, across three inference types — generate, stream and decide. `decide` returns typed, calibrated judgements from a non-generative model (~400ms, ~$0.00002

51 lines (50 loc) • 3.03 kB
/** * Reads token usage out of Cursor CLI's local chat store. * * Store: `~/.cursor/chats/<workspaceHash>/<agentId>/store.db`, one SQLite file * per agent session, with two tables: * * - `meta` — a single row whose `value` is **hex-encoded** JSON (not JSON, * and not a blob: a hex *string*), carrying `latestRootBlobId`, `name`, * `createdAt` and `lastUsedModel`. * - `blobs` — a content-addressed store, `id` = SHA-256 of `data`. Some * blobs are UTF-8 JSON messages; the root blob is **protobuf**. * * **What this reader reports is NOT cumulative spend, and that difference is * the whole reason to read this file before trusting the number.** Every other * reader here sums per-turn usage across a transcript. Cursor persists no * per-turn usage at all: the only counts in the store are a snapshot of the * *current context composition* on the newest root blob — how many tokens the * system prompt, tools, rules, skills, subagents and conversation each occupy * right now. A session with 200 turns and a session with 1 turn produce one * snapshot each. Summing across sessions therefore answers "how much context * was loaded, last time each session was touched", never "how much was billed". * It lands in `inputTokens` because context is what gets sent as input, and it * is the honest home for it — but a dashboard adding this to a metered CLI's * input tokens is adding two different quantities. The same hazard OpenCode's * reader documents for double-counted proxy traffic, one step further. * * **Why the parse validates itself.** Protobuf field numbers are an internal * detail of a closed-source binary that updates itself, so hard-coding "the * total is field 5.1" is a claim about a format nobody published. Instead the * parser finds the breakdown by *shape* — submessages of exactly * `{1: string, 2: string, 3?: varint, 4?: varint}` — sums their token fields, * and then requires that sum to appear verbatim as a varint elsewhere in the * same message. On the reference store that is * 480 + 11592 + 9257 + 6621 + 391 + 143 = 28484, matching the stored 28484 * exactly, against a 200000 window. If a future Cursor renumbers its fields the * shape match still works; if it changes the *structure*, the sum stops * matching and the session is reported as an error rather than counted wrong. * A reader that cannot tell "I parsed nothing" from "this session used nothing" * is the failure this check exists to prevent. * * Cost is `unavailable`, not zero-with-confidence: Cursor is a subscription and * the store records no model-priced turns to derive a figure from. */ import type { LocalUsageReader } from "../types/index.js"; /** * @returns the session's context-token total, or `null` when the blob holds no * breakdown whose entries sum to a total stated alongside them. */ export declare function extractCursorContextTokens(rootBlob: Uint8Array): number | null; export declare function createCursorReader(): Promise<LocalUsageReader>;