@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
54 lines (53 loc) • 3.1 kB
TypeScript
/**
* Reads token usage out of Hermes Agent's SQLite state store.
*
* Hermes Agent is Nous Research's official CLI agent (github.com/NousResearch/
* hermes-agent), a Python program installed from its own install script — not
* an npm package. An earlier note in this folder said the opposite ("no
* official CLI, only an unofficial npm bridge"); it had searched npm for a
* product that is not distributed there, and is retracted here.
*
* Store: `$HERMES_HOME/state.db`, defaulting to `~/.hermes/state.db`, plus one
* `state.db` per profile under `profiles/<name>/`. SQLite, `schema_version`
* table (26 when this was written; `PRAGMA user_version` stays 0, so it is
* not the version to read). Confirmed on a real store produced by running the
* CLI itself, not inferred from documentation.
*
* Two tables carry usage, and they are NOT additive:
*
* sessions one row per session, with cumulative token columns
* for the PRIMARY task only.
* session_model_usage one row per (session, model, billing, task), each
* with its own `api_call_count`, token columns and cost.
*
* Measured on the real store: a one-prompt session held a `sessions` row of
* 10,568 input / 1 output / 1 call, and TWO usage rows — the primary task
* (`task = ''`, identical numbers) and a `title_generation` task of 248 / 8 /
* 1 call that the `sessions` aggregate does not include. The usage rows are
* therefore the complete record of what Hermes actually sent to a provider,
* and this reader sums them. The `sessions` aggregate is read only for a
* session that has no usage rows at all (a store older than the migration
* that introduced the table), and never in addition to them. A usage table
* that exists but lacks a required column is a changed schema, and is reported
* rather than read around.
*
* Cost: Hermes records `estimated_cost_usd` with a `cost_status` of
* `estimated`, from its own pricing snapshot. That is a modeled figure and is
* reported as such. `actual_cost_usd` is `NOT NULL DEFAULT 0` on usage rows,
* so a zero there is a schema default, not evidence of a free call — it is
* used only when `cost_status` explicitly says the figure is actual. A row
* with no trustworthy cost is counted as unpriced and its model named.
*
* Cache and reasoning columns are reported as stored. Every real sample so far
* has them at zero, so whether `cache_read_tokens` is a subset of
* `input_tokens` (OpenAI convention) or disjoint from it (Anthropic
* convention) has not been measured, and no subtraction or folding is applied
* until it has. Reasoning tokens are not added to output for the same reason.
*
* The time window is a snapshot filter, not an attribution: every row is a
* cumulative counter, so a session that spans the cutoff is either included
* whole or excluded whole, keyed on its last activity. Timestamps are epoch
* SECONDS stored as REAL.
*/
import type { LocalUsageReader } from "../types/index.js";
export declare function createHermesReader(): Promise<LocalUsageReader>;