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

111 lines (110 loc) • 5.66 kB
/** * Peer-sharing admission policy. * * Pure evaluation, no I/O — every input is passed in, so this module is cheap on * the hot path and directly exercisable from a test. * * The gate set is deliberately **orthogonal and AND-ed**: a grant may carry a * headroom floor *and* a window-slice ceiling *and* a model allowlist, and each * is checked independently. The effective allowance is therefore the minimum * across whatever is configured, which is what lets "share only what I am not * using, and never more than a fifth of it" be one grant rather than two * competing modes. * * Evaluation splits in two, because the two halves answer different questions: * * - `evaluateShareAdmission` — request-level. Is this borrower allowed to ask at * all, right now, for this model? * - `filterAccountsForGrant` — account-level. Of the lender's accounts, which * may serve this borrower? Headroom and slice ceilings live here because they * are properties of an individual account's windows, not of the request. * * @module proxy/sharePolicy */ import type { ProxyShareAccountExclusion, ProxyShareAccountFilterResult, ProxyShareAccountView, ProxyShareAdmission, ProxyShareAdmissionInput, ProxyShareGates, ProxyShareGrant, ProxyShareRefusalReason, ProxyShareRefusedAdmission, ProxySharePoolUsage } from "../types/index.js"; /** * Narrow an admission to its refusing half. * * A plain `!admission.admitted` check would do this under `strict`, but one of * the package's build steps compiles without `strictNullChecks`, where TypeScript * declines to narrow a boolean discriminant at all. An explicit predicate holds * in both modes. */ export declare function isShareRefusal(admission: ProxyShareAdmission): admission is ProxyShareRefusedAdmission; export declare function shareRefusalMessage(reason: ProxyShareRefusalReason): string; /** HTTP status for a refusal. 401 is "who are you", 403 is "not you, not ever * under this grant", 429 is "not now" — the borrower retries only the last. */ export declare function shareRefusalStatus(reason: ProxyShareRefusalReason): number; /** * Is `now` inside the grant's allowed hours? * * A window whose start hour is greater than its end hour wraps midnight * (`21 → 9` means the night shift), which is the common case for lending * capacity you are asleep through. */ export declare function isWithinSchedule(schedule: { fromHour: number; toHour: number; }, now: number): boolean; /** * Does the requested model fall inside the allowlist? * * Entries are matched as case-insensitive substrings so a grant can name a tier * (`sonnet`) rather than having to track every dated model id. */ export declare function isModelAllowed(models: string[] | undefined, model: string | undefined): boolean; /** * Request-level admission. * * Order matters: identity and lifecycle first (they are permanent refusals), * then scope, then the transient limits that carry a `Retry-After`. A borrower * that is told "paused" must not also be told "slow down". */ export declare function evaluateShareAdmission(input: ProxyShareAdmissionInput): ProxyShareAdmission; /** * Is the account inside its spillover window — close enough to a reset, with * little enough consumed, that the remaining capacity would otherwise expire? * * Unknown reset times fail closed. A spillover grant is a promise about capacity * that is *about to be lost*; without a reset time there is no such promise to * keep, and guessing would hand out capacity the lender still intends to use. */ export declare function isSpilloverActive(gates: ProxyShareGates, account: ProxyShareAccountView, now: number): boolean; /** * Split the pool into the accounts this grant may draw on and the rest. * * An entry in `gates.accounts` matches either the full store key * (`anthropic:alice`) or the bare label (`alice`), because operators think in * labels and the routing path thinks in keys. * * Exported because the scope decides more than admission: it is also the * denominator of the pool-wide slice, and computing that over accounts the grant * can never touch would loosen the ceiling in proportion to how many there are. */ export declare function accountsInGrantScope(gates: ProxyShareGates, accounts: readonly ProxyShareAccountView[]): { inScope: ProxyShareAccountView[]; outOfScope: ProxyShareAccountView[]; }; /** * Decide which of the lender's accounts this grant may draw on. * * Returning exclusions alongside the survivors is deliberate: when nothing * survives, the caller needs to say *why* — "your slice is spent" and "I am * holding back my reserve" are different answers, and only one of them will * change on its own. */ export declare function filterAccountsForGrant(grant: ProxyShareGrant, accounts: readonly ProxyShareAccountView[], now: number, /** * Required, not optional. `gates.maxSlice` is a ceiling on what this grant * has already drawn from the pool, and with nothing to compare against the * only available answer is "not yet" — so an omitted argument would not relax * the ceiling, it would remove it. `readSharePoolWindowUsage` returns zeroed * fractions for a grant with no history, which is the honest empty value. */ poolUsage: ProxySharePoolUsage): ProxyShareAccountFilterResult; /** * Collapse per-account exclusions into the single reason the borrower is told * when nothing survived. A transient cause outranks a structural one so the * borrower learns whether waiting is worth anything. */ export declare function summarizeAccountExclusions(excluded: readonly ProxyShareAccountExclusion[]): ProxyShareRefusalReason;