@sema-agent/core 7.17.7 → 7.19.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +233 -13
- package/dist/agents/send-message-tool.js +1 -0
- package/dist/agents/subagent.d.ts +1 -0
- package/dist/agents/subagent.js +5 -0
- package/dist/agents/teacher.js +1 -0
- package/dist/agents/verify.js +3 -0
- package/dist/brain/anthropic.js +6 -3
- package/dist/brain/open-responses.js +10 -4
- package/dist/brain/openai.js +5 -2
- package/dist/brain/reasoning.d.ts +13 -13
- package/dist/brain/reasoning.js +2 -2
- package/dist/brain/route-adjudicator.d.ts +18 -0
- package/dist/brain/route-adjudicator.js +16 -0
- package/dist/brain/stream-engine.js +2 -1
- package/dist/brain/stream-shared.d.ts +3 -0
- package/dist/brain/stream-shared.js +1 -0
- package/dist/core/agent-definition.d.ts +10 -0
- package/dist/core/artifact-host.d.ts +41 -4
- package/dist/core/artifact-host.js +18 -2
- package/dist/core/ask-origin.d.ts +16 -0
- package/dist/core/ask-origin.js +8 -0
- package/dist/core/auto-mode-arming.d.ts +6 -0
- package/dist/core/auto-mode-arming.js +5 -5
- package/dist/core/auto-mode-defaults.d.ts +43 -15
- package/dist/core/auto-mode-defaults.js +4 -1
- package/dist/core/auto-mode.d.ts +184 -59
- package/dist/core/auto-mode.js +188 -13
- package/dist/core/checkpoint-store.d.ts +23 -2
- package/dist/core/checkpoint-store.js +2 -2
- package/dist/core/engine-notice.d.ts +77 -1
- package/dist/core/engine-notice.js +7 -0
- package/dist/core/gate-fold.js +5 -1
- package/dist/core/gate-lanes.js +9 -8
- package/dist/core/gate-outcome.d.ts +42 -2
- package/dist/core/gate-outcome.js +23 -0
- package/dist/core/governance-codes.d.ts +1 -1
- package/dist/core/governance-codes.js +14 -0
- package/dist/core/hook-seats.d.ts +66 -0
- package/dist/core/hook-seats.js +37 -0
- package/dist/core/hooks.d.ts +1 -1
- package/dist/core/read-root-candidate.d.ts +12 -0
- package/dist/core/read-root-candidate.js +24 -0
- package/dist/core/roles.d.ts +9 -1
- package/dist/core/roles.js +4 -0
- package/dist/core/runner/advertised-writable-dirs.d.ts +8 -3
- package/dist/core/runner/assemble-result.d.ts +2 -1
- package/dist/core/runner/assemble-result.js +1 -1
- package/dist/core/runner/classifier-ladder.d.ts +227 -0
- package/dist/core/runner/classifier-ladder.js +214 -0
- package/dist/core/runner/contracts.d.ts +71 -13
- package/dist/core/runner/decide-continuation.d.ts +1 -3
- package/dist/core/runner/decide-continuation.js +1 -7
- package/dist/core/runner/deferral-census.d.ts +52 -0
- package/dist/core/runner/deferral-census.js +44 -0
- package/dist/core/runner/denial-limit-arms.js +2 -2
- package/dist/core/runner/derived-route-fallback.d.ts +8 -4
- package/dist/core/runner/derived-route-fallback.js +8 -3
- package/dist/core/runner/gate-exit.d.ts +12 -0
- package/dist/core/runner/gate-exit.js +6 -3
- package/dist/core/runner/prepare-artifact.d.ts +10 -2
- package/dist/core/runner/prepare-artifact.js +5 -4
- package/dist/core/runner/prepare-ask-lane.js +1 -0
- package/dist/core/runner/prepare-caps-and-workflow.d.ts +4 -2
- package/dist/core/runner/prepare-caps-and-workflow.js +43 -55
- package/dist/core/runner/prepare-config-doors.d.ts +7 -1
- package/dist/core/runner/prepare-config-doors.js +13 -13
- package/dist/core/runner/prepare-defer-classify.d.ts +13 -19
- package/dist/core/runner/prepare-defer-classify.js +8 -3
- package/dist/core/runner/prepare-gate-stations.d.ts +26 -0
- package/dist/core/runner/prepare-gate-stations.js +1 -1
- package/dist/core/runner/prepare-hands-readface.d.ts +24 -7
- package/dist/core/runner/prepare-hands-readface.js +60 -24
- package/dist/core/runner/prepare-inherited-gate.d.ts +17 -4
- package/dist/core/runner/prepare-inherited-gate.js +10 -2
- package/dist/core/runner/prepare-lsp.d.ts +2 -2
- package/dist/core/runner/prepare-lsp.js +1 -1
- package/dist/core/runner/prepare-policy-chain.js +2 -0
- package/dist/core/runner/prepare-project-context.d.ts +5 -1
- package/dist/core/runner/prepare-project-context.js +7 -4
- package/dist/core/runner/prepare-prompt-inputs.d.ts +4 -2
- package/dist/core/runner/prepare-prompt-inputs.js +4 -1
- package/dist/core/runner/prepare-run-refs.d.ts +9 -1
- package/dist/core/runner/prepare-run-refs.js +3 -2
- package/dist/core/runner/prepare-suspend-saga.d.ts +5 -0
- package/dist/core/runner/prepare-suspend-saga.js +5 -2
- package/dist/core/runner/prepare-task.js +19 -14
- package/dist/core/runner/prepare-tool-disclosure-mount.d.ts +5 -0
- package/dist/core/runner/prepare-tool-disclosure-mount.js +10 -2
- package/dist/core/runner/prepare-turn-wiring.d.ts +8 -4
- package/dist/core/runner/prepare-turn-wiring.js +3 -2
- package/dist/core/runner/prepare-wiring-manifest.d.ts +5 -5
- package/dist/core/runner/prepare-wiring-manifest.js +5 -2
- package/dist/core/runner/resume-apply.js +3 -3
- package/dist/core/runner/resume-checkpoint-screen.js +7 -0
- package/dist/core/runner/run-harness-handlers.js +4 -1
- package/dist/core/runner/run-identity-wiring.js +6 -2
- package/dist/core/runner/run-leg.d.ts +2 -0
- package/dist/core/runner/run-leg.js +45 -45
- package/dist/core/runner/run-notification-lane.js +55 -27
- package/dist/core/runner/run-settle-and-teardown.js +1 -0
- package/dist/core/runner/run-terminal-adoption.js +16 -13
- package/dist/core/runner/run-turn-boundary.js +15 -5
- package/dist/core/runner/runtask.d.ts +6 -5
- package/dist/core/runner/runtask.js +26 -14
- package/dist/core/runner/skill-base-dir.d.ts +54 -0
- package/dist/core/runner/skill-base-dir.js +42 -0
- package/dist/core/runner/synthetic-tools.d.ts +83 -48
- package/dist/core/runner/synthetic-tools.js +69 -32
- package/dist/core/runner/tool-defer-gate.d.ts +22 -9
- package/dist/core/runner/tool-defer-gate.js +15 -5
- package/dist/core/runner/tool-disclosure.d.ts +5 -0
- package/dist/core/runner/tool-disclosure.js +2 -0
- package/dist/core/runner/tool-progress-lane.d.ts +42 -0
- package/dist/core/runner/tool-progress-lane.js +61 -0
- package/dist/core/runner/turn-attachments.d.ts +43 -12
- package/dist/core/runner/turn-attachments.js +58 -14
- package/dist/core/runner-deps.d.ts +48 -7
- package/dist/core/sensitive-path-policy.d.ts +58 -17
- package/dist/core/sensitive-path-policy.js +33 -5
- package/dist/core/skill-listing-budget.d.ts +112 -0
- package/dist/core/skill-listing-budget.js +58 -0
- package/dist/core/swappable-deps.d.ts +9 -7
- package/dist/core/swappable-deps.js +7 -3
- package/dist/core/task-event.d.ts +96 -29
- package/dist/core/task-notification.d.ts +142 -16
- package/dist/core/task-notification.js +106 -0
- package/dist/core/task-result.d.ts +9 -1
- package/dist/core/task-spec.d.ts +46 -3
- package/dist/core/tighten-task-spec.js +7 -5
- package/dist/core/tool-model-gate.d.ts +1 -1
- package/dist/core/tool-policy.d.ts +19 -4
- package/dist/core/tool-policy.js +6 -7
- package/dist/core/tool-search-setting.d.ts +78 -0
- package/dist/core/tool-search-setting.js +90 -0
- package/dist/core/tool-spec.d.ts +45 -4
- package/dist/core/types.d.ts +2 -2
- package/dist/core/types.js +1 -1
- package/dist/core/wiring-manifest.d.ts +46 -0
- package/dist/core/wiring-manifest.js +9 -1
- package/dist/core/write-protect.d.ts +8 -3
- package/dist/core/write-protect.js +8 -5
- package/dist/engine/execution-env/node-execution-env.js +10 -4
- package/dist/engine/harness/agent-harness.d.ts +42 -0
- package/dist/engine/harness/agent-harness.js +61 -29
- package/dist/engine/loop/agent-loop.d.ts +68 -3
- package/dist/engine/loop/agent-loop.js +109 -16
- package/dist/index.d.ts +13 -8
- package/dist/index.js +11 -7
- package/dist/internal/harness.d.ts +1 -1
- package/dist/orchestration/run-workflow-tool.d.ts +3 -0
- package/dist/orchestration/run-workflow-tool.js +6 -1
- package/dist/orchestration/workflow-governance.d.ts +7 -1
- package/dist/orchestration/workflow-governance.js +9 -5
- package/dist/orchestration/workflow-primitives.d.ts +3 -0
- package/dist/orchestration/workflow-primitives.js +6 -1
- package/dist/orchestration/workflow-types.d.ts +48 -13
- package/dist/orchestration/workflow-types.js +1 -1
- package/dist/orchestration/workflow.js +45 -17
- package/dist/prompt-assembly/epoch.js +2 -0
- package/dist/prompt-assembly/packs/sema-default.js +2 -2
- package/dist/prompt-assembly/section-usage.d.ts +26 -0
- package/dist/prompt-assembly/section-usage.js +10 -0
- package/dist/prompt-assembly/types.d.ts +8 -6
- package/dist/prompts/default.d.ts +13 -0
- package/dist/prompts/default.js +16 -8
- package/dist/tools/artifact/artifact-text.d.ts +10 -1
- package/dist/tools/artifact/artifact-text.js +6 -3
- package/dist/tools/artifact/artifact-tool.d.ts +12 -2
- package/dist/tools/artifact/artifact-tool.js +203 -70
- package/dist/tools/artifact/conformance.d.ts +56 -0
- package/dist/tools/artifact/conformance.js +349 -0
- package/dist/tools/artifact/local-stub.js +1 -1
- package/dist/tools/artifact/reject-breaker.d.ts +28 -0
- package/dist/tools/artifact/reject-breaker.js +42 -0
- package/dist/tools/fs/bash-lexer.d.ts +132 -0
- package/dist/tools/fs/bash-lexer.js +563 -0
- package/dist/tools/fs/bash-program-position.d.ts +142 -0
- package/dist/tools/fs/bash-program-position.js +125 -0
- package/dist/tools/fs/bash-readonly-classifier.d.ts +81 -16
- package/dist/tools/fs/bash-readonly-classifier.js +180 -558
- package/dist/tools/fs/containment-face.d.ts +89 -0
- package/dist/tools/fs/containment-face.js +81 -0
- package/dist/tools/fs/fs-bash.d.ts +46 -1
- package/dist/tools/fs/fs-bash.js +165 -25
- package/dist/tools/fs/fs-read.d.ts +1 -1
- package/dist/tools/fs/fs-search-tools.d.ts +3 -3
- package/dist/tools/fs/fs-write.d.ts +4 -3
- package/dist/tools/fs/fs-write.js +9 -9
- package/dist/tools/fs/index.d.ts +24 -5
- package/dist/tools/fs/index.js +18 -6
- package/dist/tools/fs/read-deny.d.ts +4 -3
- package/dist/tools/fs/repo-map.d.ts +2 -2
- package/dist/tools/fs/safety.d.ts +18 -3
- package/dist/tools/fs/safety.js +11 -4
- package/package.json +1 -1
- package/test/export-surface.snapshot.json +99 -13
- package/wire-changes/core@7.17.7.json +49 -0
- package/wire-changes/core@7.18.0.json +1273 -0
- package/wire-changes/core@7.19.0.json +457 -0
- package/dist/tools/fs/read-face.d.ts +0 -68
- package/dist/tools/fs/read-face.js +0 -47
|
@@ -1,5 +1,19 @@
|
|
|
1
|
-
/**
|
|
2
|
-
|
|
1
|
+
/**
|
|
2
|
+
* Hard cap on one classification RUNG (both attempts) when `AutoModeDeciderOptions.timeoutMs` is omitted — CC
|
|
3
|
+
* 2.1.259's per-attempt classifier base (`j7e = 60000`; 2.1.250 `oue`, the same number), which upstream
|
|
4
|
+
* stretches to 120 s with prompt size and sema leaves to the deployment knob. The 15 s that stood here was
|
|
5
|
+
* never upstream's: live 2026-09-15 a thinking-by-default gateway answers in 5–165 s (Qwen 3.8 p50 11–24 s,
|
|
6
|
+
* kimi and GLM p50 ~10 s), so 15 s turned most classifications into `unavailable (timed out)`. Worst-case
|
|
7
|
+
* walk = this × rungs (2) = 120 s.
|
|
8
|
+
*/
|
|
9
|
+
export declare const AUTO_MODE_DEFAULT_TIMEOUT_MS = 60000;
|
|
10
|
+
/**
|
|
11
|
+
* What an arming RECORDING that carries no `timeoutMs` meant when it was written: the default of its day. Every
|
|
12
|
+
* recipe minted since the deadline moved to 60 s MATERIALISES its bound, so an absent recorded knob dates the
|
|
13
|
+
* recording — the fold reads it as the 15 s it ran under, never as the current default
|
|
14
|
+
* (`auto_mode.arming.absent_timeout_reads_recorded_default`, on the fold).
|
|
15
|
+
*/
|
|
16
|
+
export declare const AUTO_MODE_RECORDED_ABSENT_TIMEOUT_MS = 15000;
|
|
3
17
|
/** Newest transcript entries in the classify window when `AutoModeWindowOptions.maxEntries` is omitted. */
|
|
4
18
|
export declare const AUTO_MODE_DEFAULT_WINDOW_MAX_ENTRIES = 40;
|
|
5
19
|
/** Per-entry excerpt cap when `AutoModeWindowOptions.maxCharsPerEntry` is omitted. */
|
|
@@ -17,25 +31,39 @@ export declare const AUTO_MODE_DEFAULT_WINDOW_MAX_CHARS = 2000;
|
|
|
17
31
|
* parses as a block (the parser tolerates a missing tail), a truncated allow does not exist (it is
|
|
18
32
|
* seven tokens), and the cap's job is to make a model that ignores the "no preamble" instruction —
|
|
19
33
|
* or that reasons in-text — cost a bounded, quickly-detected contract failure instead of a slow one.
|
|
20
|
-
* Paired with `reasoning:"off"` at the call: the cap hosts the ANSWER, so it
|
|
21
|
-
* wire
|
|
34
|
+
* Paired with `reasoning:"off"` at the call: the cap hosts the ANSWER, so it stands alone only where the
|
|
35
|
+
* wire SPELLS off (`thinkingOffSpelled`); every other seat adds a thinking allowance to it.
|
|
22
36
|
*/
|
|
23
37
|
export declare const AUTO_MODE_CLASSIFIER_MAX_TOKENS = 256;
|
|
24
38
|
/**
|
|
25
|
-
* The output-budget ALLOWANCE for a classifier request
|
|
26
|
-
* seat asks for `reasoning:"low"` instead of `"off"` — a model whose wire
|
|
27
|
-
*
|
|
28
|
-
*
|
|
29
|
-
*
|
|
39
|
+
* The output-budget ALLOWANCE for a classifier request whose thinking the wire could not turn OFF: added to
|
|
40
|
+
* the verdict cap when the seat asks for `reasoning:"low"` instead of `"off"` — a model whose wire has no off
|
|
41
|
+
* spelling (`reasoning:true` on an effort-only wire with no declared off, the anthropic adaptive family) and a
|
|
42
|
+
* model that declares NO reasoning (the wire then carries nothing and the request is the gateway's default,
|
|
43
|
+
* which on a default-on gateway is a think). The seat pays for the least the wire can grade plus the verdict,
|
|
44
|
+
* never for an open-ended budget.
|
|
30
45
|
*
|
|
31
|
-
* 2048 is anchored twice: CC 2.1.
|
|
32
|
-
* its `rejects_disabled_thinking` family (`BHe`); and it is 2 × `MIN_THINKING_TOKENS` (1024), so
|
|
33
|
-
* anthropic BUDGET path a HARD cap of 256 + 2048 clears the cap-wins skip (`budgetCapSkipsThinking`)
|
|
34
|
-
* hosts a legal `low` budget (`1024 ≤ budget_tokens < max_tokens`) without the brain having to raise a
|
|
35
|
-
* it refuses to raise.
|
|
36
|
-
* is the
|
|
46
|
+
* 2048 is anchored twice: CC 2.1.259 `MU` adds exactly this many tokens to the verdict cap for a model in
|
|
47
|
+
* its `rejects_disabled_thinking` family (2.1.250 `E4`/`BHe`); and it is 2 × `MIN_THINKING_TOKENS` (1024), so
|
|
48
|
+
* on the anthropic BUDGET path a HARD cap of 256 + 2048 clears the cap-wins skip (`budgetCapSkipsThinking`)
|
|
49
|
+
* and hosts a legal `low` budget (`1024 ≤ budget_tokens < max_tokens`) without the brain having to raise a
|
|
50
|
+
* cap it refuses to raise. Live 2026-09-15: deepseek's default think fits it ~90–100% of the time; the tail
|
|
51
|
+
* is the re-ask seat's ({@link AUTO_MODE_CLASSIFIER_THINK_BUDGET_TOKENS}). What a cap can and cannot promise is
|
|
52
|
+
* the seat's contract (`classifier.budget_is_room`, on `classifierRungSeat`).
|
|
37
53
|
*/
|
|
38
54
|
export declare const AUTO_MODE_CLASSIFIER_LOW_REASONING_BUDGET_TOKENS = 2048;
|
|
55
|
+
/**
|
|
56
|
+
* The RE-ASK seat's allowance — the room a rung gets ONCE after its first attempt produced no verdict: CC
|
|
57
|
+
* 2.1.259's stage-2 classifier cap (`max_tokens: 8192 + bn`). Live 2026-09-15 the thinking tail that overruns
|
|
58
|
+
* 2048 (deepseek 1–2 of 20, some past 4096; Qwen up to 6k) sits under it. One re-ask, never a loop.
|
|
59
|
+
*/
|
|
60
|
+
export declare const AUTO_MODE_CLASSIFIER_THINK_BUDGET_TOKENS = 8192;
|
|
61
|
+
/**
|
|
62
|
+
* How many CONSECUTIVE no-verdict classifications on ONE model mint `classifier.contract_broken` (once per run
|
|
63
|
+
* per model): one is a fluke, two is a pattern, and at three the denial limit already hands the user a card —
|
|
64
|
+
* the operator line lands before that one.
|
|
65
|
+
*/
|
|
66
|
+
export declare const AUTO_MODE_CLASSIFIER_CONTRACT_BROKEN_AFTER = 2;
|
|
39
67
|
/** The sentinel a deployment puts INSIDE a paired rule list to splice the CC default rules back in at
|
|
40
68
|
* that position (CC `XYt = "$defaults"`). It lives here, beside the other defaults, because the #503
|
|
41
69
|
* recipe canonicalizer needs its VALUE and must not load the assembly face (and its SHA-locked assets)
|
|
@@ -1,8 +1,11 @@
|
|
|
1
|
-
export const AUTO_MODE_DEFAULT_TIMEOUT_MS =
|
|
1
|
+
export const AUTO_MODE_DEFAULT_TIMEOUT_MS = 60_000;
|
|
2
|
+
export const AUTO_MODE_RECORDED_ABSENT_TIMEOUT_MS = 15_000;
|
|
2
3
|
export const AUTO_MODE_DEFAULT_WINDOW_MAX_ENTRIES = 40;
|
|
3
4
|
export const AUTO_MODE_DEFAULT_WINDOW_MAX_CHARS = 2_000;
|
|
4
5
|
export const AUTO_MODE_CLASSIFIER_MAX_TOKENS = 256;
|
|
5
6
|
export const AUTO_MODE_CLASSIFIER_LOW_REASONING_BUDGET_TOKENS = 2048;
|
|
7
|
+
export const AUTO_MODE_CLASSIFIER_THINK_BUDGET_TOKENS = 8192;
|
|
8
|
+
export const AUTO_MODE_CLASSIFIER_CONTRACT_BROKEN_AFTER = 2;
|
|
6
9
|
export const AUTO_MODE_DEFAULTS_SENTINEL = "$defaults";
|
|
7
10
|
export const AUTO_MODE_DENIAL_LIMIT_DEFAULTS = Object.freeze({ maxConsecutive: 3, maxTotal: 20 });
|
|
8
11
|
export const AUTO_MODE_DENIAL_AUTO_DENY_DEFAULT_MS = 120_000;
|
package/dist/core/auto-mode.d.ts
CHANGED
|
@@ -10,72 +10,179 @@ export declare const AUTO_MODE_UNAVAILABLE_CAUSES: readonly ["error", "timeout"]
|
|
|
10
10
|
export type AutoModeUnavailableCause = (typeof AUTO_MODE_UNAVAILABLE_CAUSES)[number];
|
|
11
11
|
/** Whether a value is a member of the unavailable-cause set — the screen a row reader applies to a stored word. */
|
|
12
12
|
export declare function isAutoModeUnavailableCause(v: unknown): v is AutoModeUnavailableCause;
|
|
13
|
-
/**
|
|
14
|
-
|
|
13
|
+
/**
|
|
14
|
+
* HOW a reply failed to carry a verdict — the closed set behind `parse_error.form`. `missing` = the reader found
|
|
15
|
+
* NO answer (empty text, prose, an answer only inside a thinking block); `conflict` = it found TWO distinct
|
|
16
|
+
* `<block>` answers (raw or thinking-stripped). The split exists for the classify leg's re-ask: a missing
|
|
17
|
+
* answer is asked for again (CC 2.1.259 `Vrr` re-asks an unparseable reply), a conflict is not — it carries a
|
|
18
|
+
* `yes`, and a second attempt that answered `no` would erase it. Not on any wire face; the trace frame and the
|
|
19
|
+
* gate record keep the one word `parse_error`.
|
|
20
|
+
*/
|
|
21
|
+
export declare const AUTO_MODE_PARSE_FAILURES: readonly ["missing", "conflict"];
|
|
22
|
+
export type AutoModeParseFailure = (typeof AUTO_MODE_PARSE_FAILURES)[number];
|
|
23
|
+
/** Whether a value is a member of the parse-failure set. */
|
|
24
|
+
export declare function isAutoModeParseFailure(v: unknown): v is AutoModeParseFailure;
|
|
25
|
+
/**
|
|
26
|
+
* WHY a classification moved DOWN the candidate ladder — the closed set behind
|
|
27
|
+
* {@link AutoModeClassifierRound}'s `fallback.cause`, i.e. the ways a candidate produces NO RULING
|
|
28
|
+
* ({@link rungDidNotRule}). Two words are the unavailable causes verbatim (the leg threw / rejected; the
|
|
29
|
+
* round-trip cap elapsed); `parse_error` is the candidate that ANSWERED without a verdict. A ruling is not a
|
|
30
|
+
* member: the ladder stops at a verdict either way.
|
|
31
|
+
*/
|
|
32
|
+
export declare const AUTO_MODE_FALLBACK_CAUSES: readonly ["error", "timeout", "parse_error"];
|
|
33
|
+
export type AutoModeFallbackCause = (typeof AUTO_MODE_FALLBACK_CAUSES)[number];
|
|
34
|
+
/** Whether a value is a member of the fallback-cause set — the screen a row reader applies to a stored word. */
|
|
35
|
+
export declare function isAutoModeFallbackCause(v: unknown): v is AutoModeFallbackCause;
|
|
36
|
+
/**
|
|
37
|
+
* The deployment's answer to "what happens when the classifier seat does not rule?"
|
|
38
|
+
* (`RunnerDeps.autoMode.classifierFallback`) — the closed set behind the candidate ladder's LENGTH:
|
|
39
|
+
* `main` = [classifier seat, the run's main model]; `none` = [classifier seat].
|
|
40
|
+
*/
|
|
41
|
+
export declare const AUTO_MODE_CLASSIFIER_FALLBACKS: readonly ["main", "none"];
|
|
42
|
+
export type AutoModeClassifierFallback = (typeof AUTO_MODE_CLASSIFIER_FALLBACKS)[number];
|
|
43
|
+
/** Whether a value is a member of the classifier-fallback set. */
|
|
44
|
+
export declare function isAutoModeClassifierFallback(v: unknown): v is AutoModeClassifierFallback;
|
|
45
|
+
/** Read the knob: absent ⇒ the default `main`; a member ⇒ itself; ANYTHING ELSE ⇒ a loud refusal carrying
|
|
46
|
+
* `config.auto_mode_classifier_fallback_invalid`. A typo'd knob must not read as the default: `"non"` would
|
|
47
|
+
* keep paying for the rung it meant to turn off. */
|
|
48
|
+
export declare function autoModeClassifierFallbackOf(v: unknown): AutoModeClassifierFallback;
|
|
49
|
+
/** The classifier's verdict over one pending `ask`. Every arm may carry the classification's model
|
|
50
|
+
* attribution ({@link AutoModeClassifierRound}), present iff the decider was wired with a candidate ladder. */
|
|
51
|
+
export type AutoModeVerdict = ({
|
|
15
52
|
kind: "allow";
|
|
16
|
-
}
|
|
53
|
+
} & AutoModeRoundAttributed)
|
|
17
54
|
/** `category` is the matched BLOCK rule name (207 output contract); `reason` starts with `[Rule Name]`. */
|
|
18
|
-
| {
|
|
55
|
+
| ({
|
|
19
56
|
kind: "block";
|
|
20
57
|
category: string;
|
|
21
58
|
reason: string;
|
|
22
|
-
}
|
|
59
|
+
} & AutoModeRoundAttributed)
|
|
23
60
|
/** The classifier could not run: the model leg threw / rejected, or ran past the cap. NOT a decision — the
|
|
24
61
|
* gate denies and says so ({@link classifierUnavailableDenyMessage}). */
|
|
25
|
-
| {
|
|
62
|
+
| ({
|
|
26
63
|
kind: "unavailable";
|
|
27
64
|
cause: AutoModeUnavailableCause;
|
|
28
|
-
}
|
|
65
|
+
} & AutoModeRoundAttributed)
|
|
29
66
|
/** The model responded but not in the `<block>…` contract shape. Handled as a BLOCK with the CC
|
|
30
|
-
* parse-failure sentence ({@link
|
|
31
|
-
|
|
67
|
+
* parse-failure sentence ({@link classifierParseFailureDenyMessage}), counted by the denial limit. `form`
|
|
68
|
+
* says WHICH way the reply failed ({@link AutoModeParseFailure}): the classify leg re-asks a `missing`
|
|
69
|
+
* reply once and never a `conflict`. */
|
|
70
|
+
| ({
|
|
32
71
|
kind: "parse_error";
|
|
33
72
|
raw: string;
|
|
73
|
+
form: AutoModeParseFailure;
|
|
74
|
+
} & AutoModeRoundAttributed);
|
|
75
|
+
/** The member every verdict arm shares: WHICH MODEL this classification asked and which one answered. */
|
|
76
|
+
export interface AutoModeRoundAttributed {
|
|
77
|
+
/** Absent when the decider was given no candidate ladder (a hand-built decider, the cross-process rebuild's
|
|
78
|
+
* single fresh leg): it ran on whatever model the leg is bound to and can vouch for no name. Never faked. */
|
|
79
|
+
readonly classifier?: AutoModeClassifierRound;
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* WHICH MODEL answered one classification — the record a walk of the CANDIDATE LADDER
|
|
83
|
+
* ({@link AutoModeDeciderOptions.candidates}) hands its consumers: `modelRequested` = the ladder's FIRST rung
|
|
84
|
+
* (the seat the classification was for); `modelUsed` = the rung whose answer the gate acted on, and where NO
|
|
85
|
+
* candidate ruled, the last rung ATTEMPTED (stated, not implied by absence); `fallback` = present exactly
|
|
86
|
+
* when the ladder MOVED to reach `modelUsed` — which rung it left, which it arrived at, and why
|
|
87
|
+
* ({@link AutoModeFallbackCause}); absent = the first rung answered.
|
|
88
|
+
*/
|
|
89
|
+
export interface AutoModeClassifierRound {
|
|
90
|
+
readonly modelRequested: string;
|
|
91
|
+
readonly modelUsed: string;
|
|
92
|
+
readonly fallback?: {
|
|
93
|
+
readonly from: string;
|
|
94
|
+
readonly to: string;
|
|
95
|
+
readonly cause: AutoModeFallbackCause;
|
|
96
|
+
};
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* The classify hook's word for "this classification was NEVER PUT TO A MODEL" — the failure is in assembling
|
|
100
|
+
* the QUESTION (the transcript window every rung shares), not in a rung's answer.
|
|
101
|
+
*
|
|
102
|
+
* WHY IT EXISTS. The ladder advances on "the rung produced no ruling", and a hook that rejects looks exactly
|
|
103
|
+
* like that. But a classification whose prompt could not be built fails IDENTICALLY on every rung (the build is one
|
|
104
|
+
* shared promise, by contract — "the same prompt, re-asked" is literal), so the walk recorded a fallback
|
|
105
|
+
* `{from: seat, to: main, cause: "error"}` and a deny sentence naming two models, for a classification in which NO
|
|
106
|
+
* MODEL WAS EVER DISPATCHED: a transcript-store outage read, on every face a person can see, as a broken
|
|
107
|
+
* classifier seat. The verdict is unchanged (fail-closed `unavailable`); what changes is that the record
|
|
108
|
+
* stops attributing it to models that were never asked.
|
|
109
|
+
*
|
|
110
|
+
* Carried as a `code` on the thrown error rather than a class so any classify hook — including one this
|
|
111
|
+
* package never constructed — can raise it without importing a constructor.
|
|
112
|
+
*
|
|
113
|
+
* WHAT IT DOES NOT COVER, stated: a build that OUTRUNS a rung's cap is still recorded as that rung's
|
|
114
|
+
* `timeout`. The cap bounds the whole classify call, assembly included, so at that point nothing distinguishes
|
|
115
|
+
* a slow transcript store from a slow model. Moving the per-classification build outside the rung cap is a
|
|
116
|
+
* seam change, filed for a later version.
|
|
117
|
+
*/
|
|
118
|
+
export declare const AUTO_MODE_ROUND_NOT_ASKED_CODE = "auto_mode.round_not_asked";
|
|
119
|
+
/** Mint the marker above around whatever failed, keeping the original as `cause` for the host's own logs.
|
|
120
|
+
* TOTAL by construction: the failure it wraps is an arbitrary value, and an `instanceof` or a `.message` read
|
|
121
|
+
* on a revoked proxy (or a throwing getter) THROWS — which would replace the marker with an ordinary error and
|
|
122
|
+
* hand the walk back the attribution this whole seat exists to remove. So the detail is a guarded read that
|
|
123
|
+
* must already be a string, and the total describer otherwise. */
|
|
124
|
+
export declare function autoModeRoundNotAsked(reason: unknown): Error & {
|
|
125
|
+
code: string;
|
|
34
126
|
};
|
|
127
|
+
/** Why a rung did not settle the classification, or `undefined` when it RULED and the ladder stops — the ONE
|
|
128
|
+
* predicate behind the advance (there is no `if (fallback)` arm anywhere). */
|
|
129
|
+
export declare function rungDidNotRule(v: AutoModeVerdict): AutoModeFallbackCause | undefined;
|
|
35
130
|
/**
|
|
36
131
|
* The model-facing deny text for an `unavailable` verdict — CC 2.1.250 `x1t`, with the parenthetical `EIt`
|
|
37
132
|
* spells for the causes this engine distinguishes (a wall-clock / connection timeout reads " (timed out)";
|
|
38
|
-
* an
|
|
39
|
-
*
|
|
40
|
-
*
|
|
41
|
-
*
|
|
133
|
+
* an unknown kind reads nothing). The subject is the classifier itself rather than a model id: without a
|
|
134
|
+
* candidate ladder the decider cannot vouch for a name. One writer for every deny site. ROOT CAUSE, when
|
|
135
|
+
* `attribution.fallback` is present: the sentence names BOTH rungs that failed to answer; a ladder that did
|
|
136
|
+
* NOT move keeps the CC text byte for byte.
|
|
42
137
|
*/
|
|
43
|
-
export declare function classifierUnavailableDenyMessage(toolName: string, cause: AutoModeUnavailableCause): string;
|
|
44
|
-
/** The model-facing deny text for a `parse_error` verdict — CC 2.1.250 `Ure` over the R3t stem: the classifier
|
|
45
|
-
* answered, but not with a verdict, and auto mode blocks what it could not evaluate. */
|
|
46
|
-
export declare const CLASSIFIER_PARSE_FAILURE_DENY_MESSAGE = "Auto mode could not evaluate this action and is blocking it for safety \u2014 the classifier's reply carried no verdict.";
|
|
138
|
+
export declare function classifierUnavailableDenyMessage(toolName: string, cause: AutoModeUnavailableCause, attribution?: AutoModeClassifierRound): string;
|
|
47
139
|
/**
|
|
48
|
-
*
|
|
49
|
-
*
|
|
140
|
+
* The model-facing deny text for a `parse_error` verdict — CC 2.1.259 `i7t` stem ("Auto mode could not evaluate
|
|
141
|
+
* this action and is blocking it for safety"; 2.1.250 `Ure`): the classifier answered, but not with a verdict,
|
|
142
|
+
* and auto mode blocks what it could not evaluate. With a candidate ladder wired the tail NAMES the model whose
|
|
143
|
+
* reply carried no verdict (`attribution.modelUsed`) — a declared departure from upstream, whose card names no
|
|
144
|
+
* model: the person reading this card is the one who can change the catalog, and on a single-model deployment
|
|
145
|
+
* the name is the whole diagnosis. Without attribution the sentence is unchanged. The stem is a stable prefix
|
|
146
|
+
* either way; one writer for both deny sites.
|
|
147
|
+
*/
|
|
148
|
+
export declare function classifierParseFailureDenyMessage(attribution?: AutoModeClassifierRound): string;
|
|
149
|
+
/**
|
|
150
|
+
* Parse the classifier's output contract — the CC 2.1.259 verdict reader (`MTt`, its thinking strip `QTt`, its
|
|
151
|
+
* reason reader `TTt`; unchanged from 2.1.250 `wCe`/`xCe`/`yCe`), plus ONE arm of sema's own:
|
|
50
152
|
* blocked: `<block>yes</block><category>Rule Name</category><reason>[Rule Name] …</reason>`
|
|
51
153
|
* allowed: `<block>no</block>`
|
|
52
154
|
*
|
|
53
155
|
* The verdict is the set of `<block>yes|no` hits, NOT a prefix match:
|
|
54
156
|
* 1. CONFLICT, read on the RAW text (thinking included): `<block>(yes|no)\b` collected over the whole
|
|
55
|
-
* response — more than one distinct answer ⇒ no verdict (`parse_error`). A scratch-space
|
|
56
|
-
* contradicting a final "no" is a contradiction, not an allow.
|
|
57
|
-
* 2. HITS, read on the text with
|
|
58
|
-
*
|
|
59
|
-
*
|
|
60
|
-
*
|
|
157
|
+
* response — more than one distinct answer ⇒ no verdict (`parse_error`, form `conflict`). A scratch-space
|
|
158
|
+
* "yes" contradicting a final "no" is a contradiction, not an allow.
|
|
159
|
+
* 2. HITS, read on the text with thinking blocks removed ({@link stripThinking}): `<block>(yes|no)\b` with
|
|
160
|
+
* the closing tag OPTIONAL, at ANY position. Two distinct answers ⇒ `conflict`; the one distinct answer ⇒
|
|
161
|
+
* `no` = allow, `yes` = block.
|
|
162
|
+
* 3. BARE ANSWER (sema, ruled 2026-09-15 — small open models drop the tag; recorded as a divergence; a caller
|
|
163
|
+
* that knows the reply is not a complete answer passes `bareAnswer: false` and this arm is closed): zero
|
|
164
|
+
* hits AND the whole thinking-stripped text is an answer by {@link bareAnswerOf} ⇒ that word is the
|
|
165
|
+
* verdict (a bare `yes` blocks with empty category/reason) — unless a `<block>` answer inside the
|
|
166
|
+
* thinking disagrees with it (`conflict`). Zero hits and anything else — prose, a question with its
|
|
167
|
+
* answer, a reply that only answered inside its thinking — ⇒ `parse_error`, form `missing`.
|
|
61
168
|
* So a preamble before the tag, prose after `<block>no`, a missing `</block>` and a reply that repeats
|
|
62
169
|
* its answer all read as the answer they carry; the tag must be spelled `<block>yes` / `<block>no` with
|
|
63
170
|
* no whitespace inside (the word-boundary form — `<block>yesterday` is not a hit) and case does not matter.
|
|
64
171
|
*
|
|
65
172
|
* A stated BLOCK stands with or without its tail: `<category>` (the BLOCK rule NAME the prompt asked
|
|
66
|
-
* for, read case-insensitively as free text — the deployment authors those names, so there is no
|
|
67
|
-
*
|
|
68
|
-
*
|
|
69
|
-
*
|
|
70
|
-
*
|
|
71
|
-
* downgrading a stated block to `parse_error` (a block with the generic parse-failure sentence instead
|
|
72
|
-
* of the classifier's own reason) would lose the classifier's explicit verdict on the exact calls it flagged.
|
|
173
|
+
* for, read case-insensitively as free text — the deployment authors those names, so there is no fixed
|
|
174
|
+
* vocabulary to screen them against) and `<reason>` (first `<reason>…</reason>` pair on the stripped
|
|
175
|
+
* text, trimmed) are carried when present and `""` when absent; the consumers render their own fallback
|
|
176
|
+
* line from the tool name in that case. Downgrading a stated block to `parse_error` would lose the
|
|
177
|
+
* classifier's explicit verdict on the exact calls it flagged.
|
|
73
178
|
*
|
|
74
|
-
* `parse_error` is fail-closed: the gate handles it as a BLOCK (CC 2.1.
|
|
179
|
+
* `parse_error` is fail-closed: the gate handles it as a BLOCK (CC 2.1.259's own outcome for a reply with no
|
|
75
180
|
* verdict) that the denial limit counts like any other — never a silent allow, and never a question handed
|
|
76
181
|
* to a person on the classifier's behalf.
|
|
77
182
|
*/
|
|
78
|
-
export declare function parseAutoModeResponse(text: string
|
|
183
|
+
export declare function parseAutoModeResponse(text: string, options?: {
|
|
184
|
+
bareAnswer?: boolean;
|
|
185
|
+
}): AutoModeVerdict;
|
|
79
186
|
/** What the decider hands the deployment's `classify` hook (the assembled prompt is the hook's job
|
|
80
187
|
* when it owns assembly; when using {@link buildAutoModePrompt} the decider passes its output). */
|
|
81
188
|
export interface AutoModeClassifyInput {
|
|
@@ -84,19 +191,42 @@ export interface AutoModeClassifyInput {
|
|
|
84
191
|
/** The human-readable text of the ask being decided (policy/safety message), when present. */
|
|
85
192
|
askMessage?: string;
|
|
86
193
|
}
|
|
87
|
-
/**
|
|
88
|
-
*
|
|
89
|
-
export
|
|
194
|
+
/** One rung of the ladder, as the leg is told about it. `index` is the ADDRESS (a ladder may carry two rungs
|
|
195
|
+
* whose model id is the same string), while `model` is the NAME the record will carry. */
|
|
196
|
+
export interface AutoModeLadderRung {
|
|
197
|
+
readonly index: number;
|
|
198
|
+
readonly model: string;
|
|
199
|
+
}
|
|
200
|
+
/** The pluggable model leg: given the classify input and the RUNG the ladder is on, return that model's raw
|
|
201
|
+
* text response. Deployment-injected; MAY throw / reject — the decider fail-closes. A rejection carrying
|
|
202
|
+
* {@link AUTO_MODE_ROUND_NOT_ASKED_CODE} says the failure was in assembling the QUESTION rather than in this
|
|
203
|
+
* rung's answer, and stops the walk instead of blaming the next rung. `rung` is `undefined`
|
|
204
|
+
* for a decider wired with no ladder. Both trailing parameters are OPTIONAL, not `| undefined`: a caller
|
|
205
|
+
* INVOKING it with one or two arguments must keep compiling. */
|
|
206
|
+
export type AutoModeClassifyFn = (input: AutoModeClassifyInput, signal?: AbortSignal, rung?: AutoModeLadderRung) => Promise<string>;
|
|
90
207
|
export interface AutoModeDeciderOptions {
|
|
91
208
|
classify: AutoModeClassifyFn;
|
|
92
|
-
/**
|
|
93
|
-
*
|
|
209
|
+
/**
|
|
210
|
+
* The CANDIDATE LADDER this decider walks, in order — the models a classification may be asked on, NOT a
|
|
211
|
+
* second way to say what `classify` says (that hook is the DISPATCH; this is the sequence it dispatches
|
|
212
|
+
* to). Rung 0 is the seat the classification is for; every later rung is consulted only when the one
|
|
213
|
+
* before it produced NO RULING ({@link rungDidNotRule}). The FIRST ruling ends the walk and is the
|
|
214
|
+
* verdict; when no rung rules, the LAST rung's own non-ruling verdict stands.
|
|
215
|
+
*
|
|
216
|
+
* Omitted = a one-rung anonymous ladder: the leg as wired, no attribution on the verdict. An EMPTY array,
|
|
217
|
+
* or a rung that is not a non-empty string, is REFUSED loudly at construction (a deployment that computed
|
|
218
|
+
* its ladder and got nothing has a bug, not a default). COST: {@link timeoutMs} bounds ONE rung, so the
|
|
219
|
+
* worst case is the cap times the rungs actually walked.
|
|
220
|
+
*/
|
|
221
|
+
candidates?: readonly string[];
|
|
222
|
+
/** Hard cap on one classification round-trip — one LADDER RUNG, not the whole classification (see
|
|
223
|
+
* {@link candidates}). Default 15_000 ms: a permission gate must not stall the whole run on a slow classifier. */
|
|
94
224
|
timeoutMs?: number;
|
|
95
225
|
/**
|
|
96
|
-
* Fired once per `decide` call with the verdict the gate is about to act on and the wall time it
|
|
97
|
-
*
|
|
98
|
-
*
|
|
99
|
-
*
|
|
226
|
+
* Fired once per `decide` call with the verdict the gate is about to act on and the wall time it waited
|
|
227
|
+
* (`ms`, integer ≥ 0; a timed-out classification reads the deadline, one that walked two rungs the whole
|
|
228
|
+
* walk). `cause` is present iff the verdict is `unavailable`; `classifier` iff a ladder was wired. A
|
|
229
|
+
* throwing hook never breaks the gate.
|
|
100
230
|
*/
|
|
101
231
|
onClassified?: (info: AutoModeClassified) => void;
|
|
102
232
|
}
|
|
@@ -110,16 +240,17 @@ export interface AutoModeClassified {
|
|
|
110
240
|
cause?: Extract<AutoModeVerdict, {
|
|
111
241
|
kind: "unavailable";
|
|
112
242
|
}>["cause"];
|
|
243
|
+
/** The classification's model attribution, present exactly when the decider was wired with a candidate ladder
|
|
244
|
+
* ({@link AutoModeClassifierRound}) — the same object the verdict carries. */
|
|
245
|
+
classifier?: AutoModeClassifierRound;
|
|
113
246
|
}
|
|
114
247
|
export interface AutoModeDecider {
|
|
115
248
|
/** Never rejects. Any internal failure surfaces as `unavailable`/`parse_error` (fail-closed). */
|
|
116
249
|
decide(input: AutoModeClassifyInput, signal?: AbortSignal): Promise<AutoModeVerdict>;
|
|
117
250
|
}
|
|
118
|
-
/**
|
|
119
|
-
*
|
|
120
|
-
*
|
|
121
|
-
* next one, which asks the model again.
|
|
122
|
-
*/
|
|
251
|
+
/** The per-run decider: timeout + fail-closed error mapping, nothing carried between rounds. One instance per
|
|
252
|
+
* run (it binds the run's model leg and assembled prompt); a round that failed says nothing about the next,
|
|
253
|
+
* which asks the model again. */
|
|
123
254
|
export declare function createAutoModeDecider(opts: AutoModeDeciderOptions): AutoModeDecider;
|
|
124
255
|
/** The deployment's bounds for the denial limit (`RunnerDeps.autoMode.denialLimit`). Every member
|
|
125
256
|
* optional; an omitted member takes its CC default. A present member with a bad value is REFUSED
|
|
@@ -152,24 +283,18 @@ export interface DenialLimitCounts {
|
|
|
152
283
|
* The DECISION-layer member of a denial-limit fallback ask (`PermissionResult` ask arm): the counts
|
|
153
284
|
* that tripped the bound, and NOTHING about a window. A window is a fact of the ask's ROUTE — a live
|
|
154
285
|
* function approver can count down, a durable park row and a headless deny cannot — and the route is
|
|
155
|
-
* chosen downstream of the count
|
|
156
|
-
* a position to state one. The type says so: there is no window member to write here, and the only
|
|
286
|
+
* chosen downstream of the count. The type says so: there is no window member to write here, and the only
|
|
157
287
|
* ways to reach a {@link DenialLimitFallback} (the member an {@link
|
|
158
288
|
* import("./tool-policy.js").AskRequest} carries) are the two route stations,
|
|
159
|
-
* {@link AutoModeDenialTracker.armTimedWindow} and {@link unarmedWindow}.
|
|
160
|
-
* gate adapter therefore cannot forward a decision's member straight into an approval request: the
|
|
161
|
-
* compiler stops it and names the station it skipped.
|
|
289
|
+
* {@link AutoModeDenialTracker.armTimedWindow} and {@link unarmedWindow}.
|
|
162
290
|
*/
|
|
163
291
|
export interface UnarmedDenialLimitFallback extends DenialLimitCounts {
|
|
164
292
|
/** FORBIDDEN on a decision, and stated rather than merely omitted. Leaving the member out would only
|
|
165
293
|
* stop a FRESH object literal (TypeScript's excess-property check); a policy that writes its window
|
|
166
294
|
* through a `const`, an `as const`, or an annotated return type would still compile — and would then
|
|
167
|
-
* have its number silently replaced at whichever route station the ask reached
|
|
168
|
-
*
|
|
169
|
-
*
|
|
170
|
-
* TOLD about rather than one it discovers when nobody is auto-denied. (A host that casts past the
|
|
171
|
-
* type still meets the route stations' runtime belt: they write the route's number, never the
|
|
172
|
-
* decision's.) */
|
|
295
|
+
* have its number silently replaced at whichever route station the ask reached. `never` makes the old
|
|
296
|
+
* shape a compile error at the policy boundary instead. (A host that casts past the type still meets
|
|
297
|
+
* the route stations' runtime belt: they write the route's number, never the decision's.) */
|
|
173
298
|
readonly autoDenyAfterMs?: never;
|
|
174
299
|
}
|
|
175
300
|
/** The REQUEST-layer member (`AskRequest`, a durable park row, a checkpoint summary's echo): the same
|