/** * Whether a run may load one more skill. * * Two bounds, and they are not redundant. The **count** is cheap and is checked * before anything is resolved. The **token total** is the one that actually * protects the context window: twelve short skills fit and three long ones do * not, so a count cap alone bounds the wrong quantity. Without the second, a * model in a loop loads its way to a context-limit error mid-run, which reads * to a user as the agent breaking rather than as it over-reaching. * * Shaped like `admitChildRun` in `run/children.ts`, and for the same reason: * **the host measures, the harness judges.** Estimating the token cost of the * would-be active set means resolving bodies, which is I/O; comparing a number * to a limit is not. So each bound arrives with the measurement it judges, and * a bound whose number the host could not produce is simply omitted — a rule * that silently never fires is worse than one that is visibly absent. */ export type SkillLoadRefusal = { kind: "active_count"; active: number; max: number; } | { kind: "active_body_tokens"; tokens: number; max: number; }; export type SkillLoadDecision = { admitted: true; } | { admitted: false; refusal: SkillLoadRefusal; /** * A noun phrase, carrying no identifiers. Hosts surface a refusal to the * model as a tool error and sometimes to a person, so it must be safe to * render in both places and must read after a host's own prefix. */ reason: string; }; export interface SkillLoadBounds { /** * Refs already active. Omit the pair to skip the count bound; a non-finite or * negative count **refuses**, because a broken measurement is not evidence * that there is room. */ activeCount?: number; maxActive?: number; /** * Estimated tokens of the instruction set the load would produce — the whole * would-be active set, not the increment. Omit the pair to skip the bound. */ projectedBodyTokens?: number; maxBodyTokens?: number; } /** * Judge a `load_skill` against the active-set bounds. A skill that is already * active is never subject to either bound — reloading it adds nothing — so * callers should short-circuit before calling. */ export declare function admitSkillLoad(bounds: SkillLoadBounds): SkillLoadDecision; /** Estimated token cost of a resolved instruction set — the input to the body bound. */ export declare function estimateSkillBodyTokens(instructions: readonly string[]): number;