UNPKG

@sema-agent/core

Version:

Stateless, task-oriented AI agent core

57 lines (56 loc) • 3.12 kB
import type { Model } from "../../internal/llm.js"; import { type ModelPricing } from "../pricing.js"; /** How a provider counts cached tokens in its reported `input`. */ export type CacheFamily = "input-includes-cached" | "input-excludes-cached"; /** * Resolve the prompt-cache accounting family for a model. **Auto-inferred from `model.api`** by * default (Anthropic/Bedrock report `input` EXCLUDING cached tokens; OpenAI/vLLM/Google INCLUDE them), * but a deployment can **override** it via `model.params.promptCacheFamily` when `model.api` doesn't * match the brain that actually serves the model — e.g. a routing brain that dispatches by `provider` * while `api` is left at a default. Accepts the explicit values or the aliases `"anthropic"`/`"openai"`. * (a route-by-provider setup with `api` hardcoded misjudged the family → 1090% hit rate.) */ export declare function cacheFamilyOf(model: Model): CacheFamily; /** Total prompt tokens presented this turn, normalized so `cachedTokens` is always ⊆ the total. */ export declare function promptTokensOf(family: CacheFamily, u: { input: number; cacheRead: number; cacheWrite: number; }): number; /** * The prompt tokens that were NOT served from (or written to) the cache this turn — i.e. the quantity * the Anthropic protocol calls `usage.input_tokens`, normalized across families. Derived from the * normalized total so the identity `total = uncached + cacheRead + cacheWrite` holds by construction. * * The wire faces named `inputTokens`/`promptTokens` carry THIS, not the total — a consumer * computing `cacheRead / (input + cacheRead)` on a same-named protocol field otherwise double-counts * the cache subset and reports `h/(1+h)` (a real 98% hit rate surfaces as 49.5%). The BILLING path * still consumes the total (`promptTokensOf`) — `computeCostMicroUsd` subtracts the priced subsets * itself, so handing it the uncached figure would drop the cache legs from the bill entirely. * * Clamped at 0: when a provider reports subsets LARGER than its own total the cache family is * misdeclared, which the run loop already reports on its own face; here the identity * degrades to `total ≤ uncached + cacheRead + cacheWrite` rather than going negative. */ export declare function uncachedInputTokensOf(family: CacheFamily, u: { input: number; cacheRead: number; cacheWrite: number; }): number; /** * Normalize one turn's reported usage into its `{ totalInputTokens, uncachedInputTokens, costMicroUsd }` * — the authoritative cost re-priced in core from injected pricing (so cached tokens aren't charged at * full price). Shared by the run loop's per-turn accounting and post-task memory consolidation * so a pricing change lives in ONE place. We emit only 5-min-TTL cache writes, so * `cacheWriteTokensLong` is 0. */ export declare function usageCostMicroUsd(family: CacheFamily, u: { input?: number; output?: number; cacheRead?: number; cacheWrite?: number; }, pricing: ModelPricing): { totalInputTokens: number; uncachedInputTokens: number; costMicroUsd: number; };