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

85 lines (84 loc) • 4.39 kB
/** * Per-Account Quota Tracking * * Captures Anthropic rate-limit / utilisation headers from proxy responses * and persists them to ~/.neurolink/account-quotas.json so the CLI can * display remaining session & weekly capacity per account. * * Hot-path design: parseQuotaHeaders is pure CPU (no I/O). saveAccountQuota * updates an in-memory cache and debounces disk writes so the request/response * path is never blocked by file I/O. */ import type { AccountQuota, AccountQuotaWindow } from "../types/index.js"; /** * Collapse a wire model id to its family by dropping the snapshot date, so * `claude-fable-5-20260115` and `claude-fable-5-20260320` both tag the same * scoped window. Without this a window would stop matching the day Anthropic * ships a new snapshot. */ export declare function modelFamilyToken(model: string): string; /** Read and normalize Anthropic's authoritative top-level unified status. */ export declare function getUnifiedRateLimitStatus(headers: Headers | Record<string, string>): string | undefined; /** * Whether Anthropic explicitly permits a request to use overage after a * subscription window is exhausted. An active overage signal is authoritative; * otherwise fresh responses require explicit fallback and upgrade-path signals. * Older persisted snapshots predate those raw fields, but retain a positive * fallback percentage together with an allowed overage status, which is the * equivalent provider state. */ export declare function isQuotaOverageAvailable(quota: Pick<AccountQuota, "fallbackPercentage" | "fallbackStatus" | "overageStatus" | "overageInUse" | "overageEnabled" | "overageDisabledReason" | "upgradePaths"> | null | undefined): boolean; /** * Parse Anthropic rate-limit / quota headers into an `AccountQuota`. * Returns `null` when key headers are absent. * Pure computation — no I/O, no blocking. */ export declare function parseQuotaHeaders(headers: Headers | Record<string, string>, opts?: { model?: string; now?: number; }): AccountQuota | null; /** * Merge dynamic limit windows across snapshots from different sources. * * The two sources see different things and neither is a superset: the usage API * reports every plan bucket but only when explicitly refreshed, while response * headers report only the window(s) touched by the request just served — but do * so continuously. A plain overwrite in either direction loses real data, which * is why a header capture used to erase the model-scoped windows a `/limits` * refresh had just fetched. */ export declare function mergeQuotaWindows(existing: AccountQuotaWindow[] | undefined, incoming: AccountQuotaWindow[] | undefined): AccountQuotaWindow[] | undefined; /** * Fold a freshly observed snapshot onto the previous one for the same account, * preserving dynamic windows the new snapshot does not carry. */ export declare function mergeQuotaSnapshot(previous: AccountQuota | undefined, incoming: AccountQuota): AccountQuota; /** * Initialise the quota module with a custom file path. * When set, all reads/writes go to this path instead of the default * ~/.neurolink/account-quotas.json. Call before the first load/save. */ export declare function initAccountQuota(quotaFilePath: string): void; export declare function loadAccountQuotas(): Promise<Record<string, AccountQuota>>; /** * Load quota for a single account. */ export declare function loadAccountQuota(accountKey: string): Promise<AccountQuota | null>; /** * Update quota for a single account. * Updates in-memory cache immediately (non-blocking), * then debounces the disk write to every 5 seconds. * * Loads the persisted file into the cache before the first write so a save * after a process restart merges with existing entries instead of rewriting * the file with only the accounts used since boot (which silently erased * other accounts' snapshots and blinded quota-aware routing to them). */ export declare function saveAccountQuota(accountKey: string, quota: AccountQuota): Promise<void>; /** * Cancel any pending debounced write and flush the cache to disk now. * Short-lived processes (CLI refresh path) must call this before exit — * the debounce timer is unref()'d and will not keep the process alive. */ export declare function flushAccountQuotas(): Promise<void>; export declare function flushAccountQuotaStateForTests(): Promise<void>;