UNPKG

@sema-agent/core

Version:

Stateless, task-oriented AI agent core

92 lines (91 loc) • 7.01 kB
/** * Hard cap on one classification RUNG (both attempts) when `AutoModeDeciderOptions.timeoutMs` / * `RunnerDeps.autoMode.timeoutMs` is omitted. Sized for a self-hosted gateway, not a cloud API: a * thinking-by-default gateway answers a classification in 5–165 s (Qwen 3.8 p50 11–24 s, kimi and GLM p50 * ~10 s), and queueing plus prefill of 2–5 min is a normal wait on such a gateway (`docs/TIMEOUTS.md`). 180 s * clears the slowest classification observed with margin; CC 2.1.259's per-attempt base is 60 s (`j7e`, * stretched to 120 s with prompt size). Worst-case walk = this × rungs (2) = 360 s. Where the leg has an * approval seat a rung that runs out of time costs a question to a person, not a refusal (see the gate's * classifier station). */ export declare const AUTO_MODE_DEFAULT_TIMEOUT_MS = 180000; /** * The classifier call's transient retry budget — the reference implementation's short ladder (2.1.280 `J9e = 4`): a * provider error (an HTTP 5xx, a dropped connection) is retried this many times inside the rung's budget, then the rung * reports `unavailable` / `error`. Where the leg has an approval seat that question goes to a person, so a long ladder * would only make the person wait out the rung's budget and hear "timed out" for a failure that was not one. */ export declare const AUTO_MODE_CLASSIFIER_MAX_RETRIES = 4; /** * What an arming RECORDING that carries no `timeoutMs` meant when it was written: the default of its day. Every * recipe minted since the deadline moved to 60 s MATERIALISES its bound, so an absent recorded knob dates the * recording — the fold reads it as the 15 s it ran under, never as the current default * (`auto_mode.arming.absent_timeout_reads_recorded_default`, on the fold). */ export declare const AUTO_MODE_RECORDED_ABSENT_TIMEOUT_MS = 15000; /** Newest transcript entries in the classify window when `AutoModeWindowOptions.maxEntries` is omitted. */ export declare const AUTO_MODE_DEFAULT_WINDOW_MAX_ENTRIES = 40; /** Per-entry excerpt cap when `AutoModeWindowOptions.maxCharsPerEntry` is omitted. */ export declare const AUTO_MODE_DEFAULT_WINDOW_MAX_CHARS = 2000; /** * The classifier call's output cap (`maxTokens`), sized from the engine's OWN output contract rather * than copied from upstream: the prompt asks for exactly two shapes, `<block>no</block>` and * `<block>yes</block><category>NAME</category><reason>[NAME] one short sentence</reason>` (the parser, * `parseAutoModeResponse`, reads the verdict wherever it sits, so a short preamble costs tokens, not * the verdict). The longest rule name in the shipped rule sets is 46 characters and the reason * is one short sentence naming that rule (≈200 characters at the outside, more when several rules * match and the others are named in the reason), so the longest LEGAL reply is ≈350 characters — * ≈120 tokens at the conservative 3 chars/token that tag-heavy text tokenizes at, ≈150 with a * second and third rule name in the reason. Doubled for margin: a truncated block verdict still * parses as a block (the parser tolerates a missing tail), a truncated allow does not exist (it is * seven tokens), and the cap's job is to make a model that ignores the "no preamble" instruction — * or that reasons in-text — cost a bounded, quickly-detected contract failure instead of a slow one. * Paired with `reasoning:"off"` at the call: the cap hosts the ANSWER, so it stands alone only where the * wire SPELLS off (`thinkingOffSpelled`); every other seat adds a thinking allowance to it. */ export declare const AUTO_MODE_CLASSIFIER_MAX_TOKENS = 256; /** * The output-budget ALLOWANCE for a classifier request whose thinking the wire could not turn OFF: added to * the verdict cap when the seat asks for `reasoning:"low"` instead of `"off"` — a model whose wire has no off * spelling (`reasoning:true` on an effort-only wire with no declared off, the anthropic adaptive family) and a * model that declares NO reasoning (the wire then carries nothing and the request is the gateway's default, * which on a default-on gateway is a think). The seat pays for the least the wire can grade plus the verdict, * never for an open-ended budget. * * 2048 is anchored twice: CC 2.1.259 `MU` adds exactly this many tokens to the verdict cap for a model in * its `rejects_disabled_thinking` family (2.1.250 `E4`/`BHe`); and it is 2 × `MIN_THINKING_TOKENS` (1024), so * on the anthropic BUDGET path a HARD cap of 256 + 2048 clears the cap-wins skip (`budgetCapSkipsThinking`) * and hosts a legal `low` budget (`1024 ≤ budget_tokens < max_tokens`) without the brain having to raise a * cap it refuses to raise. Live 2026-09-15: deepseek's default think fits it ~90–100% of the time; the tail * is the re-ask seat's ({@link AUTO_MODE_CLASSIFIER_THINK_BUDGET_TOKENS}). What a cap can and cannot promise is * the seat's contract (`classifier.budget_is_room`, on `classifierRungSeat`). */ export declare const AUTO_MODE_CLASSIFIER_LOW_REASONING_BUDGET_TOKENS = 2048; /** * The RE-ASK seat's allowance — the room a rung gets ONCE after its first attempt produced no verdict: CC * 2.1.259's stage-2 classifier cap (`max_tokens: 8192 + bn`). Live 2026-09-15 the thinking tail that overruns * 2048 (deepseek 1–2 of 20, some past 4096; Qwen up to 6k) sits under it. One re-ask, never a loop. */ export declare const AUTO_MODE_CLASSIFIER_THINK_BUDGET_TOKENS = 8192; /** * How many CONSECUTIVE no-verdict classifications on ONE model mint `classifier.contract_broken` (once per run * per model): one is a fluke, two is a pattern, and at three the denial limit already hands the user a card — * the operator line lands before that one. */ export declare const AUTO_MODE_CLASSIFIER_CONTRACT_BROKEN_AFTER = 2; /** The sentinel a deployment puts INSIDE a paired rule list to splice the CC default rules back in at * that position (CC `XYt = "$defaults"`). It lives here, beside the other defaults, because the #503 * recipe canonicalizer needs its VALUE and must not load the assembly face (and its SHA-locked assets) * to get it; `auto-mode-prompt.js` re-exports it, so the public name and its module face are unchanged. */ export declare const AUTO_MODE_DEFAULTS_SENTINEL = "$defaults"; /** CC 2.1.250 `FO = {maxConsecutive: 3, maxTotal: 20}` — the classifier DENIAL LIMITS applied when * `RunnerDeps.autoMode.denialLimit` omits a bound. Count-then-judge: the block that reaches a bound is * itself the one that falls back to a person (the 3rd consecutive block asks; the 20th total asks). */ export declare const AUTO_MODE_DENIAL_LIMIT_DEFAULTS: Readonly<{ maxConsecutive: number; maxTotal: number; }>; /** CC 2.1.250 `AKe = 120000` — the fallback ask's auto-deny window (ms) when `autoDenyAfterMs` is omitted. * `0` disarms the window (the ask waits on the approver alone — the upstream original "fall back to * prompting" shape). */ export declare const AUTO_MODE_DENIAL_AUTO_DENY_DEFAULT_MS = 120000;