@sema-agent/core 7.14.0 → 7.16.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 +59 -0
- package/dist/core/ask-origin.d.ts +2 -2
- package/dist/core/checkpoint-store.d.ts +14 -15
- package/dist/core/governance-codes.js +2 -0
- package/dist/core/hooks.d.ts +4 -3
- package/dist/core/memory-engine/delegation-settlement.d.ts +37 -12
- package/dist/core/memory-engine/delegation-settlement.js +128 -39
- package/dist/core/memory-engine/engine.d.ts +9 -8
- package/dist/core/memory-engine/engine.js +115 -120
- package/dist/core/memory-engine/file-backend.d.ts +17 -5
- package/dist/core/memory-engine/file-backend.js +78 -34
- package/dist/core/memory-engine/index.d.ts +2 -2
- package/dist/core/memory-engine/index.js +2 -2
- package/dist/core/memory-engine/layout.d.ts +152 -54
- package/dist/core/memory-engine/layout.js +441 -104
- package/dist/core/memory-engine/types.d.ts +8 -3
- package/dist/core/memory-engine/types.js +5 -0
- package/dist/core/runner/abort-race.d.ts +3 -3
- package/dist/core/runner/active-skill-scope.d.ts +2 -2
- package/dist/core/runner/assemble-result.d.ts +29 -29
- package/dist/core/runner/checkpoint-scope.d.ts +4 -4
- package/dist/core/runner/clock-and-limits.d.ts +3 -3
- package/dist/core/runner/compaction-call-options.d.ts +11 -11
- package/dist/core/runner/compaction-knobs.d.ts +4 -4
- package/dist/core/runner/compaction-seams.d.ts +5 -5
- package/dist/core/runner/contracts.d.ts +224 -226
- package/dist/core/runner/decide-continuation.d.ts +6 -6
- package/dist/core/runner/denial-limit-arms.d.ts +8 -8
- package/dist/core/runner/derived-route-fallback.d.ts +2 -2
- package/dist/core/runner/gate-exit.d.ts +6 -6
- package/dist/core/runner/git-status-frame.d.ts +7 -7
- package/dist/core/runner/inherited-ask-grants.d.ts +6 -6
- package/dist/core/runner/memory-capture-optout.d.ts +1 -1
- package/dist/core/runner/memory-consolidation-driver.d.ts +4 -4
- package/dist/core/runner/memory-consolidation.d.ts +6 -6
- package/dist/core/runner/park-commit.d.ts +6 -6
- package/dist/core/runner/permission-rule-lanes.d.ts +22 -20
- package/dist/core/runner/permission-rule-lanes.js +1 -1
- package/dist/core/runner/prepare-acquire-reconcile.d.ts +4 -4
- package/dist/core/runner/prepare-ask-lane.d.ts +3 -3
- package/dist/core/runner/prepare-boundary-parks.d.ts +3 -3
- package/dist/core/runner/prepare-caps-and-workflow.d.ts +5 -5
- package/dist/core/runner/prepare-config-doors.d.ts +21 -21
- package/dist/core/runner/prepare-context-lane.d.ts +6 -6
- package/dist/core/runner/prepare-defer-classify.d.ts +3 -3
- package/dist/core/runner/prepare-defer-classify.js +12 -10
- package/dist/core/runner/prepare-delegation-surface.d.ts +1 -1
- package/dist/core/runner/prepare-file-history.d.ts +2 -2
- package/dist/core/runner/prepare-gate-stations.d.ts +8 -9
- package/dist/core/runner/prepare-gate-stations.js +2 -2
- package/dist/core/runner/prepare-hands-readface.d.ts +41 -41
- package/dist/core/runner/prepare-hands-readface.js +27 -29
- package/dist/core/runner/prepare-inherited-gate.d.ts +6 -6
- package/dist/core/runner/prepare-listings.d.ts +3 -3
- package/dist/core/runner/prepare-lsp.d.ts +3 -3
- package/dist/core/runner/prepare-memory-engine-session.d.ts +5 -5
- package/dist/core/runner/prepare-memory.js +6 -7
- package/dist/core/runner/prepare-offload-wrappers.d.ts +2 -2
- package/dist/core/runner/prepare-park-ask.d.ts +11 -12
- package/dist/core/runner/prepare-park-ask.js +3 -3
- package/dist/core/runner/prepare-policy-chain.d.ts +6 -6
- package/dist/core/runner/prepare-policy-chain.js +2 -2
- package/dist/core/runner/prepare-prompt-inputs.d.ts +5 -5
- package/dist/core/runner/prepare-protocol-tools.d.ts +1 -1
- package/dist/core/runner/prepare-question-face.d.ts +4 -4
- package/dist/core/runner/prepare-run-refs.d.ts +11 -11
- package/dist/core/runner/prepare-safety-scan.d.ts +1 -1
- package/dist/core/runner/prepare-suspend-saga.d.ts +4 -4
- package/dist/core/runner/prepare-task.d.ts +12 -12
- package/dist/core/runner/prepare-task.js +5 -7
- package/dist/core/runner/prepare-tool-disclosure-mount.d.ts +2 -3
- package/dist/core/runner/prepare-wiring-manifest.d.ts +4 -4
- package/dist/core/runner/prepare-workspace-restore.d.ts +1 -1
- package/dist/core/runner/remote-env-retry.d.ts +3 -3
- package/dist/core/runner/resume-admission.d.ts +1 -1
- package/dist/core/runner/resume-claim.d.ts +1 -1
- package/dist/core/runner/resume-internals-and-config.d.ts +1 -1
- package/dist/core/runner/resume-policy-outcome.d.ts +1 -1
- package/dist/core/runner/resume-preflight.d.ts +1 -1
- package/dist/core/runner/resume-review-outcome.d.ts +1 -1
- package/dist/core/runner/run-brain-sinks.d.ts +1 -1
- package/dist/core/runner/run-clock-and-content.d.ts +4 -4
- package/dist/core/runner/run-compaction-machinery.d.ts +3 -3
- package/dist/core/runner/run-git-lane.d.ts +1 -1
- package/dist/core/runner/run-harness-handlers.d.ts +2 -2
- package/dist/core/runner/run-identity-wiring.d.ts +4 -4
- package/dist/core/runner/run-leg.d.ts +3 -3
- package/dist/core/runner/run-notification-lane.d.ts +2 -2
- package/dist/core/runner/run-reasoning-seat.d.ts +2 -2
- package/dist/core/runner/run-settle-and-teardown.d.ts +4 -4
- package/dist/core/runner/run-telemetry-and-budget-seats.d.ts +2 -2
- package/dist/core/runner/run-terminal-adoption.d.ts +5 -5
- package/dist/core/runner/runtask.d.ts +14 -14
- package/dist/core/runner/session-file-state-replay.d.ts +3 -3
- package/dist/core/runner/session-rule-policy.d.ts +2 -2
- package/dist/core/runner/steer-admission.d.ts +2 -2
- package/dist/core/runner/stream-halt-verbs.d.ts +1 -1
- package/dist/core/runner/stream-reap.d.ts +1 -1
- package/dist/core/runner/synthetic-tools.d.ts +8 -8
- package/dist/core/runner/teardown-bounded.d.ts +2 -2
- package/dist/core/runner/tool-defer-gate.d.ts +86 -0
- package/dist/core/runner/tool-defer-gate.js +57 -0
- package/dist/core/runner/tool-disclosure.d.ts +33 -69
- package/dist/core/runner/tool-disclosure.js +0 -43
- package/dist/core/runner/tool-end-body.d.ts +3 -3
- package/dist/core/runner/tool-face-overlay.d.ts +2 -2
- package/dist/core/runner/tool-output-projection.d.ts +2 -2
- package/dist/core/runner/turn-attachments.d.ts +53 -53
- package/dist/core/runner/usage-accounting.d.ts +4 -4
- package/dist/core/runner/workspace-path.d.ts +1 -1
- package/dist/core/runner-deps.d.ts +16 -9
- package/dist/core/task-spec.d.ts +8 -2
- package/dist/core/tool-spec.d.ts +7 -4
- package/dist/core/types.d.ts +1 -1
- package/dist/engine/llm/types.d.ts +1 -1
- package/dist/index.d.ts +4 -4
- package/dist/index.js +3 -3
- package/dist/tools/fs/bash-readonly-classifier.d.ts +40 -40
- package/dist/tools/fs/encoding.d.ts +31 -40
- package/dist/tools/fs/fs-bash.d.ts +76 -35
- package/dist/tools/fs/fs-bash.js +86 -29
- package/dist/tools/fs/fs-pdf.d.ts +8 -8
- package/dist/tools/fs/fs-search-tools.d.ts +4 -4
- package/dist/tools/fs/fs-shared.d.ts +144 -158
- package/dist/tools/fs/fs-write.d.ts +8 -8
- package/dist/tools/fs/gh-rate-limit.d.ts +13 -14
- package/dist/tools/fs/index.d.ts +74 -78
- package/dist/tools/fs/notebook.d.ts +24 -25
- package/dist/tools/fs/pdf.d.ts +3 -3
- package/dist/tools/fs/read-deny.d.ts +22 -22
- package/dist/tools/fs/read-face.d.ts +21 -24
- package/dist/tools/fs/repo-map.d.ts +8 -8
- package/dist/tools/fs/safety.d.ts +116 -129
- package/dist/tools/fs/search.d.ts +63 -71
- package/package.json +5 -2
- package/test/export-surface.snapshot.json +9 -1
|
@@ -2,7 +2,7 @@ import type { McpDroppedTool } from "../mcp.js";
|
|
|
2
2
|
import type { TaskSpec } from "../types.js";
|
|
3
3
|
import { type SkillListingEntry } from "./synthetic-tools.js";
|
|
4
4
|
/**
|
|
5
|
-
*
|
|
5
|
+
* Turn-boundary attachment seam: the PURE producer layer (CC `getContextAttachments`
|
|
6
6
|
* parity). This module is the single home of the CC-parity cadence judgment + reminder copy (提示词主权批:
|
|
7
7
|
* harness 语料归 core); it holds NO harness handle, does NO I/O, and never injects anything itself — the
|
|
8
8
|
* run loop (runtask onTurnBoundary) is the ONLY steerer. That split exists so every trigger window is
|
|
@@ -21,7 +21,7 @@ export declare const PLAN_MODE_ATTACHMENT_CONFIG: {
|
|
|
21
21
|
readonly TURNS_BETWEEN_ATTACHMENTS: 5;
|
|
22
22
|
readonly FULL_REMINDER_EVERY_N_ATTACHMENTS: 5;
|
|
23
23
|
};
|
|
24
|
-
/**
|
|
24
|
+
/** CC 2.1.220 tool-search reminder cadence, the shipped defaults of its `juniper_shoal`
|
|
25
25
|
* config block (`sru = 15` / `aru = 10` @185913-185914, read as `{everyNTurns, maxNames}` @185836-185849).
|
|
26
26
|
* `EVERY_N_TURNS` gates BOTH windows (since-last-ToolSearch and since-last-reminder, @608920);
|
|
27
27
|
* `MAX_NAMES` bounds how many undiscovered names the body enumerates before the `(+N more)` tail. */
|
|
@@ -30,7 +30,7 @@ export declare const TOOL_SEARCH_REMINDER_CONFIG: {
|
|
|
30
30
|
readonly MAX_NAMES: 10;
|
|
31
31
|
};
|
|
32
32
|
/**
|
|
33
|
-
*
|
|
33
|
+
* The `total_tokens_reminder` mode set, CC 2.1.245-VERBATIM and in CC's declaration order
|
|
34
34
|
* (bundle `R9o`; the settings schema declares the same five for its `totalTokensReminder` key).
|
|
35
35
|
* Each arm names what the rendered number IS, per CC's own schema prose:
|
|
36
36
|
* - `off` — the lane is silent. Kept as a member rather than folded into the opt-in flag because it
|
|
@@ -47,7 +47,7 @@ export declare const TOOL_SEARCH_REMINDER_CONFIG: {
|
|
|
47
47
|
*/
|
|
48
48
|
export declare const TOTAL_TOKENS_REMINDER_MODES: readonly ["off", "infinite", "fixed", "countdown", "padded-countdown"];
|
|
49
49
|
/**
|
|
50
|
-
*
|
|
50
|
+
* The closed set is spelled TWICE (the public `TaskSpec.attachments.
|
|
51
51
|
* totalTokensReminderMode` literal union and this array), and only the TaskSpec→array direction had
|
|
52
52
|
* a compile chain (runtask's AttachmentInputs assignment). The config door widens this array to
|
|
53
53
|
* `readonly string[]` before `includes`, so a member added HERE and never to the public union used
|
|
@@ -59,11 +59,11 @@ export declare const TOTAL_TOKENS_REMINDER_MODES: readonly ["off", "infinite", "
|
|
|
59
59
|
*/
|
|
60
60
|
type TaskSpecTotalTokensReminderMode = NonNullable<NonNullable<TaskSpec["attachments"]>["totalTokensReminderMode"]>;
|
|
61
61
|
export type TotalTokensReminderMode = [TaskSpecTotalTokensReminderMode] extends [(typeof TOTAL_TOKENS_REMINDER_MODES)[number]] ? (typeof TOTAL_TOKENS_REMINDER_MODES)[number] : never;
|
|
62
|
-
/**
|
|
62
|
+
/** CC 2.1.245's own default ("Defaults to padded-countdown"). The 2026-07-30 registration of
|
|
63
63
|
* this lane rested on the 2.1.220 premise "OFF by default even in 220"; 245 flipped it, which is the
|
|
64
64
|
* fact that reopened the ruling. Applies only ONCE the deployment has opted the lane in. */
|
|
65
65
|
export declare const TOTAL_TOKENS_REMINDER_DEFAULT_MODE: TotalTokensReminderMode;
|
|
66
|
-
/**
|
|
66
|
+
/** CC's `fixed` arm constant (bundle `A9o`). A fixed anchor is the POINT of that arm (the
|
|
67
67
|
* number is meant not to move), so it is copied as the constant it is rather than re-pointed at a
|
|
68
68
|
* declared ceiling — a deployment that wants its own number picks a countdown arm instead. */
|
|
69
69
|
export declare const TOTAL_TOKENS_FIXED_ARM_VALUE = 5000000;
|
|
@@ -88,7 +88,7 @@ export interface AgentListingEntry {
|
|
|
88
88
|
* "All tools" / "All tools except X, Y" / an explicit list / "None"). Computed by the producer
|
|
89
89
|
* (createSubagentTool → {@link import("../../agents/subagent.js").agentToolsNote}).
|
|
90
90
|
*
|
|
91
|
-
*
|
|
91
|
+
* Omitting it no longer drops the tail. 220's `fvd` (@465664-465668) interpolates
|
|
92
92
|
* `WW_(def)` UNCONDITIONALLY and `WW_` is total — its no-allow/no-deny arm returns the literal
|
|
93
93
|
* "All tools" — so every roster line in 220 carries the boundary. sema's optional field only ever
|
|
94
94
|
* meant "a hand-built entry did not precompute one"; that entry's real boundary IS the full offered
|
|
@@ -147,13 +147,13 @@ export interface AttachmentState {
|
|
|
147
147
|
todoLastWriteTurn?: number;
|
|
148
148
|
lastTodoReminderTurn: number;
|
|
149
149
|
lastTaskReminderTurn: number;
|
|
150
|
-
/**
|
|
150
|
+
/** Cadence-clock value at the last `ToolSearch` tool_use block (CC 220 `cFy` @608887-608914
|
|
151
151
|
* finds it by BACKWARD transcript scan: `turnsSinceLastToolSearch`). Same INITIATION-anchor semantics
|
|
152
152
|
* as {@link taskLastWriteTurn} — the block existing in the transcript is the anchor, no outcome check.
|
|
153
153
|
* `undefined` = never used this leg, which is the state the reminder exists for (220's scan returns the
|
|
154
154
|
* full transcript length there). */
|
|
155
155
|
toolSearchLastUseTurn?: number;
|
|
156
|
-
/**
|
|
156
|
+
/** Cadence-clock value at the last tool_search_usage_reminder emitted (CC 220 `cFy`'s
|
|
157
157
|
* `turnsSinceLastReminder`, found by scanning back for the attachment entry itself). */
|
|
158
158
|
lastToolSearchReminderTurn: number;
|
|
159
159
|
/** plan_mode attachments emitted so far — drives CC's full/sparse rotation (1st, 6th, 11th… = full).
|
|
@@ -204,7 +204,7 @@ export interface AttachmentState {
|
|
|
204
204
|
* construction — agent roster ≤ cap by deployment size, skills block ≤ SKILLS_BLOCK_MAX_BYTES). */
|
|
205
205
|
skillsListingStarved?: boolean;
|
|
206
206
|
/**
|
|
207
|
-
*
|
|
207
|
+
* The `padded-countdown` arm's SMOOTHING FLOOR: the highest usage figure this run has
|
|
208
208
|
* already published against. CC's `cumulativeUsed` (bundle: `Math.max(storedFloor, rolledOver +
|
|
209
209
|
* used − anchor)`, stored back) exists so the countdown never RUNS BACKWARDS when the live usage
|
|
210
210
|
* coordinate drops under it — a model that watched its budget shrink and then saw it grow again
|
|
@@ -280,7 +280,7 @@ export declare function createAttachmentState(): AttachmentState;
|
|
|
280
280
|
* bash, fs, mcp, …) is structurally ignored, which is also the child-isolation contract: a subagent's
|
|
281
281
|
* own todo state never reaches the parent's onToolEnd, and its delegation-card types don't parse here.
|
|
282
282
|
*
|
|
283
|
-
* task #51 F3 (
|
|
283
|
+
* task #51 F3 (窗口复位/投影摄入拆分): this reducer is PROJECTION INGEST ONLY — it
|
|
284
284
|
* never touches the write windows. CC's window anchor is the tool_use block's PRESENCE in the
|
|
285
285
|
* transcript (qFm/BFm match the block by name, :480217-480219/:480253-480254, with no execution-
|
|
286
286
|
* outcome check), so the run loop stamps the windows on INITIATION via {@link stampWriteAnchor}
|
|
@@ -294,9 +294,9 @@ export declare function createAttachmentState(): AttachmentState;
|
|
|
294
294
|
*/
|
|
295
295
|
export declare function reduceToolEnd(state: AttachmentState, details: unknown): void;
|
|
296
296
|
/** task #51 F2/F3 — which reminder window a tool_use block resets. Resolved by the run loop (alias-aware:
|
|
297
|
-
* ToolSpec.aliases over the mounted roster;
|
|
297
|
+
* ToolSpec.aliases over the mounted roster; retired-name normalization is gone); the producers
|
|
298
298
|
* here never inspect tool names themselves.
|
|
299
|
-
*
|
|
299
|
+
* Adds `tool_search`: not a write, but the same INITIATION-anchor mechanism (a `ToolSearch`
|
|
300
300
|
* tool_use block resets that lane's "haven't used it recently" window), so it rides the same walk
|
|
301
301
|
* instead of duplicating the message scan. */
|
|
302
302
|
export type WriteFamily = "todo" | "task" | "tool_search";
|
|
@@ -309,7 +309,7 @@ export type WriteFamily = "todo" | "task" | "tool_search";
|
|
|
309
309
|
*/
|
|
310
310
|
export declare function stampWriteAnchor(state: AttachmentState, family: WriteFamily, clock: number): void;
|
|
311
311
|
/**
|
|
312
|
-
* 口径④ cadence clock, task #51 F1 (
|
|
312
|
+
* 口径④ cadence clock, task #51 F1 (verified against observed CC behavior) — CC's cadence unit is the
|
|
313
313
|
* per-content-block assistant TRANSCRIPT ENTRY, not the physical turn. CC 198 mints ONE
|
|
314
314
|
* `{type:"assistant"}` entry PER content block: the streaming layer at `content_block_stop`
|
|
315
315
|
* (pretty.js:593011-593038 — `content: pnn([Pr],…)` single-block array, `rn.push` per block) and the
|
|
@@ -336,7 +336,7 @@ export declare function stampWriteAnchor(state: AttachmentState, family: WriteFa
|
|
|
336
336
|
*/
|
|
337
337
|
export declare function advanceCadenceClock(state: AttachmentState, clock: number, content: unknown, writeFamilyOf: (toolName: string) => WriteFamily | undefined): number;
|
|
338
338
|
/**
|
|
339
|
-
* task #51 F4 (
|
|
339
|
+
* task #51 F4 (压缩交互) — rebase every reminder window to the CURRENT cadence clock
|
|
340
340
|
* when a compaction LANDS. CC's windows are recomputed per request by BACKWARD TRANSCRIPT SCAN
|
|
341
341
|
* (BFm/qFm): compaction removes the write tool_use anchors and the reminder attachment entries, so
|
|
342
342
|
* both counters find nothing (t=-1/n=-1) and only count post-compaction entries — the windows
|
|
@@ -380,7 +380,7 @@ export interface AttachmentInputs {
|
|
|
380
380
|
used: number;
|
|
381
381
|
total: number;
|
|
382
382
|
};
|
|
383
|
-
/**
|
|
383
|
+
/** The TOKEN twin of {@link budgetUsd}, fed
|
|
384
384
|
* from the same place for the same reason: `used` is the run's cumulative token spend
|
|
385
385
|
* (`stats.tokens`) and `total` is the ceiling the budget gate enforces against it
|
|
386
386
|
* (`rs.budget.maxTokensWindow` = min(`limits.maxTokens`, the cross-slice allocation's remainder)),
|
|
@@ -408,7 +408,7 @@ export interface AttachmentInputs {
|
|
|
408
408
|
* value (or absence) = CC `"baseline"` (on). sema keeps env resolution at the deployment shell
|
|
409
409
|
* and carries only the resolved mode here — core reads no env. */
|
|
410
410
|
todoReminderMode?: "baseline" | "off";
|
|
411
|
-
/**
|
|
411
|
+
/** Tool_search_usage_reminder lane (opt-in, default OFF; CC 220 mounts it only when the
|
|
412
412
|
* `toolSearchReminder` config resolves non-null, @607450-607456 / `cXi` @185859). */
|
|
413
413
|
toolSearchReminder?: boolean;
|
|
414
414
|
changedFiles: boolean;
|
|
@@ -420,12 +420,12 @@ export interface AttachmentInputs {
|
|
|
420
420
|
* loop adds a continuation gate (tool-calling turns only — a boundary steer must never EXTEND a
|
|
421
421
|
* finished run, see runtask's `lastTurnHadToolCalls`).
|
|
422
422
|
*
|
|
423
|
-
*
|
|
423
|
+
* Attribution CORRECTED (the previous note claimed "gated `d = !t.agentId` :479177 —
|
|
424
424
|
* subagents never see it", which reads 220 wrong). In 220 the `!agentId` flag gates only the
|
|
425
425
|
* MAIN-AGENT-EXCLUSIVE producer group (`_` @607478-607522: ide_selection / output_style /
|
|
426
426
|
* diagnostics / memory_update / token_usage / output_token_usage). `budget_usd` sits in the SHARED
|
|
427
427
|
* group `g` (@607474) and its ONLY door is `maxBudgetUsd === undefined → []` — so a 220 SUBAGENT
|
|
428
|
-
* whose own options carry a ceiling DOES see the readout. Core
|
|
428
|
+
* whose own options carry a ceiling DOES see the readout. Core follows 220. There is no
|
|
429
429
|
* agent-identity door in this collector to remove — the lane's reachability is entirely
|
|
430
430
|
* "does this task's spec carry a ceiling and opt in", which is true for a child exactly when the
|
|
431
431
|
* deployment gave it both. Capability位 (what the delegation lane does NOT do): `buildChildSpec`
|
|
@@ -435,16 +435,16 @@ export interface AttachmentInputs {
|
|
|
435
435
|
* snapshots `maxCostUsd` and every other governance field) reaches the lane. */
|
|
436
436
|
budgetUsd?: boolean;
|
|
437
437
|
/**
|
|
438
|
-
*
|
|
438
|
+
* `total_tokens_reminder` (CC 2.1.245 producer `MPs`, renderer `Oje`,
|
|
439
439
|
* registered in the SHARED producer group beside `budget_usd`, so a subagent carrying its own
|
|
440
|
-
* ceiling sees it too — the
|
|
441
|
-
*
|
|
440
|
+
* ceiling sees it too — the attribution verbatim). DEFAULT ON, matching 2.1.245+'s own default;
|
|
441
|
+
* explicit `false` opts out. Before the
|
|
442
442
|
* flip an un-opted deployment rendered no reminder frame at all. The countdown arms still need a
|
|
443
443
|
* declared ceiling, so a task without one is silent either way. (Scoped deliberately to this lane:
|
|
444
444
|
* registering
|
|
445
445
|
* `<total_tokens>` in ENGINE_ENVELOPES changed the SANITIZE/DISCLOSURE faces for every
|
|
446
446
|
* deployment, opted or not — untrusted text carrying that spelling is now defused on the fenced
|
|
447
|
-
* lanes and envelope-shaped external data trips the
|
|
447
|
+
* lanes and envelope-shaped external data trips the disclosure tail. That is the
|
|
448
448
|
* defensive direction and unconditional by design: the envelope family must be un-forgeable
|
|
449
449
|
* whether or not anyone renders the real frame.)
|
|
450
450
|
*
|
|
@@ -456,7 +456,7 @@ export interface AttachmentInputs {
|
|
|
456
456
|
* ({@link AttachmentInputs.totalTokens}), the ceiling is the deployment's own declared
|
|
457
457
|
* `limits.maxTokens`, and with no ceiling declared the countdown arms simply never fire.
|
|
458
458
|
*
|
|
459
|
-
* AND WHY IT IS NOW ON BY DEFAULT
|
|
459
|
+
* AND WHY IT IS NOW ON BY DEFAULT: the same 245 fact that
|
|
460
460
|
* justified BUILDING it is a statement about its DEFAULT, so shipping it opt-in left the engine
|
|
461
461
|
* one ruling short of the anchor. Both halves of "is this safe on by default" hold here — the
|
|
462
462
|
* readout cannot be wrong (it reads the enforced coordinate, never an estimate), and it cannot
|
|
@@ -468,7 +468,7 @@ export interface AttachmentInputs {
|
|
|
468
468
|
* TOTAL_TOKENS_REMINDER_DEFAULT_MODE}); `off` there silences the lane without un-wiring it.
|
|
469
469
|
*/
|
|
470
470
|
totalTokensReminder?: boolean;
|
|
471
|
-
/**
|
|
471
|
+
/** The RESOLVED mode (see {@link TOTAL_TOKENS_REMINDER_MODES}). CC resolves it from env /
|
|
472
472
|
* settings / a server gate; sema keeps env resolution at the deployment shell and carries only the
|
|
473
473
|
* resolved value, exactly like {@link todoReminderMode}. Absent ⇒ {@link
|
|
474
474
|
* TOTAL_TOKENS_REMINDER_DEFAULT_MODE}. A value outside the closed set is refused at the config
|
|
@@ -476,7 +476,7 @@ export interface AttachmentInputs {
|
|
|
476
476
|
totalTokensReminderMode?: TotalTokensReminderMode;
|
|
477
477
|
/** G1: post-compact background-task announce (opt-in, default OFF like the 133 members). */
|
|
478
478
|
backgroundTasks?: boolean;
|
|
479
|
-
/** G1: deferred-tool materialization announce (
|
|
479
|
+
/** G1: deferred-tool materialization announce (setTools delta → boundary notice). */
|
|
480
480
|
toolsDelta?: boolean;
|
|
481
481
|
/** G1 续批: agent-type roster announce (CC `agent_listing_delta`). [c209-C]: listing-family
|
|
482
482
|
* member — default ON at the TaskSpec layer (the frame is the ONLY roster source since the
|
|
@@ -488,13 +488,13 @@ export interface AttachmentInputs {
|
|
|
488
488
|
/** G1 续批: MCP server-instruction delta announce (CC `mcp_instructions_delta`). */
|
|
489
489
|
mcpInstructions?: boolean;
|
|
490
490
|
};
|
|
491
|
-
/**
|
|
491
|
+
/** Deferred tools whose schemas the model has NOT loaded yet (declared but not
|
|
492
492
|
* activated), sorted, snapshotted by the run loop. CC 220's equivalent is
|
|
493
493
|
* `tools.filter(iY(u) && !discovered.has(u.name)).map(name).sort()` (@608934-608938). Only passed
|
|
494
494
|
* when `config.toolSearchReminder` is opted in AND the task actually has deferred tools — an empty
|
|
495
495
|
* or absent list silences the lane permanently (CC `no_undiscovered_tools`, @608939 (cli250.js:44368)). */
|
|
496
496
|
undiscoveredTools?: readonly string[];
|
|
497
|
-
/**
|
|
497
|
+
/** Is the direct-call lane mounted on this run's placeholders (`Prepared.deferDirectCall`,
|
|
498
498
|
* i.e. `TaskSpec.deferSelfResolve` not disabled)? Selects which closing sentence the
|
|
499
499
|
* tool_search_usage_reminder body carries; absent ⇒ the default direct-lane posture, matching the
|
|
500
500
|
* spec field's own default. Meaningless unless `config.toolSearchReminder` is on. */
|
|
@@ -513,16 +513,16 @@ export interface AttachmentInputs {
|
|
|
513
513
|
* CALLER owns consumption: drain its pending list only when the returned capped bundle actually
|
|
514
514
|
* retained the `tools_delta` block (cap starvation must not lose the announcement forever). */
|
|
515
515
|
newTools?: readonly string[];
|
|
516
|
-
/**
|
|
516
|
+
/** `true` when the run materializes statically (activation never swaps the tools
|
|
517
517
|
* block): the tools_delta wording must then not claim "full schemas are loaded". Rides beside
|
|
518
518
|
* `newTools` because it qualifies the same frame. */
|
|
519
519
|
newToolsStaticFace?: boolean;
|
|
520
|
-
/**
|
|
520
|
+
/** The subset of `newTools` that the static face could not carry in result text and
|
|
521
521
|
* that materialized into the tools block instead. See {@link renderToolsDelta}. */
|
|
522
522
|
newToolsSwappedUnderStatic?: readonly string[];
|
|
523
|
-
/**
|
|
523
|
+
/** The same fact for the READDED arm. See {@link renderToolsDelta}. */
|
|
524
524
|
readdedToolsSwappedUnderStatic?: readonly string[];
|
|
525
|
-
/**
|
|
525
|
+
/** The MCP-driven arms of the SAME tools_delta frame (removed / readded / failed servers).
|
|
526
526
|
* Same pre-diffed input + CALLER-owned intact-survival consumption discipline as `newTools`; only
|
|
527
527
|
* passed when `config.toolsDelta` is opted in. See {@link McpToolsDeltaFacts} for reachability. */
|
|
528
528
|
mcpToolsDelta?: McpToolsDeltaFacts;
|
|
@@ -576,14 +576,14 @@ export interface AttachmentInputs {
|
|
|
576
576
|
*/
|
|
577
577
|
export declare function collectDueAttachments(state: AttachmentState, inp: AttachmentInputs): readonly TurnAttachment[];
|
|
578
578
|
/**
|
|
579
|
-
*
|
|
579
|
+
* CC 2.1.220 (@626269-626280, the `tool_search_usage_reminder` renderer), with the two
|
|
580
580
|
* interpolations resolved: the name list (+ `(+N more)` tail when the census exceeds
|
|
581
581
|
* {@link TOOL_SEARCH_REMINDER_CONFIG}.MAX_NAMES) and the ToolSearch tool's mounted name — sema mounts
|
|
582
582
|
* the same name. The quoted `select:<name>[,<name>...]` form is also sema's real ToolSearch contract
|
|
583
583
|
* (tool-disclosure.ts's `select:` prefix parser), so the copy stays true rather than merely quoted.
|
|
584
584
|
*
|
|
585
585
|
* ONE sema amendment, the same one DD-5 already applied to the sibling ToolSearch description: the
|
|
586
|
-
* closing sentence is POSTURE-AWARE rather than an absolute failure promise. With the
|
|
586
|
+
* closing sentence is POSTURE-AWARE rather than an absolute failure promise. With the
|
|
587
587
|
* direct-call lane mounted — the default (`TaskSpec.deferSelfResolve` not disabled) — a call on a
|
|
588
588
|
* still-deferred tool whose arguments match the real schema EXECUTES and activates it, so "calling a
|
|
589
589
|
* tool before its schema is loaded will fail" is false for that posture. This face must not assert an
|
|
@@ -655,7 +655,7 @@ export declare function commitInstructionsChange(state: InstructionsChangeState,
|
|
|
655
655
|
}>): void;
|
|
656
656
|
export declare function renderBudgetUsd(used: number, total: number): string;
|
|
657
657
|
/**
|
|
658
|
-
*
|
|
658
|
+
* CC 2.1.245 `Oje` VERBATIM: the whole body is the one-line envelope
|
|
659
659
|
* `<total_tokens>N tokens left</total_tokens>`, where N is the arm's own substitution — the literal
|
|
660
660
|
* `Infinite`, the {@link TOTAL_TOKENS_FIXED_ARM_VALUE} constant, or the remaining count clamped at
|
|
661
661
|
* zero (CC's `Math.max(0, …)`: an over-spent run reads `0 tokens left`, never a negative number).
|
|
@@ -683,11 +683,11 @@ export declare function renderOrphanedBackgroundTasks(tasks: ReadonlyArray<{
|
|
|
683
683
|
description?: string;
|
|
684
684
|
}>): string;
|
|
685
685
|
/**
|
|
686
|
-
*
|
|
686
|
+
* CC's per-frame list cap for the `deferred_tools_delta` arms (`lP`, (pretty220.js:518269, historical; not relocated in 250 — see cc-250 anchors)).
|
|
687
687
|
* Lists longer than this collapse to a grouped one-liner + "…and N more".
|
|
688
688
|
*/
|
|
689
689
|
export declare const TOOLS_DELTA_LIST_MAX = 30;
|
|
690
|
-
/**
|
|
690
|
+
/** The MCP-driven arms of the deferred-tools announce. All fields are pre-diffed by the
|
|
691
691
|
* producer (prepare-task's `rematerialize` seam / the materialize-time failed-server projection) and
|
|
692
692
|
* are CALLER-drained on intact cap survival, exactly like {@link AttachmentInputs.newTools}. */
|
|
693
693
|
export interface McpToolsDeltaFacts {
|
|
@@ -705,7 +705,7 @@ export interface McpToolsDeltaFacts {
|
|
|
705
705
|
}>;
|
|
706
706
|
}
|
|
707
707
|
/**
|
|
708
|
-
* G1 — deferred-tool materialization announce (
|
|
708
|
+
* G1 — deferred-tool materialization announce (boundary notice). CC 2.1.198 template
|
|
709
709
|
* (bundle pretty.js:599148, `deferred_tools_delta` case) verbatim reads: "The following deferred
|
|
710
710
|
* tools are now available via ${ToolSearch}. Their schemas are NOT loaded — calling them directly
|
|
711
711
|
* will fail with InputValidationError. Use ${ToolSearch} with query \"select:<name>[,...]\" to load
|
|
@@ -714,9 +714,9 @@ export interface McpToolsDeltaFacts {
|
|
|
714
714
|
* the middle clause is inverted to match sema's actual contract. Same CC shape: lead sentence +
|
|
715
715
|
* name list.
|
|
716
716
|
*
|
|
717
|
-
*
|
|
717
|
+
* CC 2.1.220 (`deferred_tools_delta`, cli250.js:45890-45918) carries SIX arms; sema
|
|
718
718
|
* shipped only the `added` one. The arms below are the ones whose STATE IS REACHABLE in this engine
|
|
719
|
-
* (data-side audit
|
|
719
|
+
* (data-side audit):
|
|
720
720
|
* - `readded` (@626525) / `removed` (@626530 (cli250.js:45892)): reachable via RefreshMcpTools — the refresh splices a
|
|
721
721
|
* server's whole `mcp__<server>__` prefix domain out of the live tool array and pushes the fresh
|
|
722
722
|
* listing back, so a withdrawn tool genuinely leaves (and a re-advertised one genuinely returns)
|
|
@@ -739,7 +739,7 @@ export interface McpToolsDeltaFacts {
|
|
|
739
739
|
export declare function renderToolsDelta(input: {
|
|
740
740
|
added?: readonly string[];
|
|
741
741
|
staticFace?: boolean;
|
|
742
|
-
/**
|
|
742
|
+
/** The subset of `added` that the STATIC face could not carry and that therefore
|
|
743
743
|
* materialized into the tools block instead (a declaration too large to inline in result text,
|
|
744
744
|
* or one that does not serialize; see the per-tool exemption in prepare-task). Empty/absent on
|
|
745
745
|
* every ordinary static run, which keeps the common frame byte-identical; when it is non-empty
|
|
@@ -752,7 +752,7 @@ export declare function renderToolsDelta(input: {
|
|
|
752
752
|
* assert compact placeholders the model can see are not there. */
|
|
753
753
|
readdedSwappedUnderStatic?: readonly string[];
|
|
754
754
|
} & McpToolsDeltaFacts): string | undefined;
|
|
755
|
-
/**
|
|
755
|
+
/** The `(Tools: …)` value for an entry that precomputed none (CC 220 `WW_`'s terminal arm
|
|
756
756
|
* @465662: no allowlist and no denylist ⇒ the literal "All tools"). */
|
|
757
757
|
export declare const AGENT_TOOLS_NOTE_DEFAULT = "All tools";
|
|
758
758
|
/** CC 2.1.198 verbatim (bundle pretty.js:599221, `agent_listing_delta` isInitial+showConcurrencyNote arm). */
|
|
@@ -792,11 +792,11 @@ export declare function agentListingDeltaHeader(toolName: string): string;
|
|
|
792
792
|
* calls announce only drift: adds under "New agent types are now available…", removals under "The
|
|
793
793
|
* following agent types are no longer available:" + `- <name>` lines, followed by the CC-verbatim
|
|
794
794
|
* {@link AMBIENT_CONTEXT_NOTE} (CC `Emr`, pretty.js:599211/599992). Name-keyed like CC: a description
|
|
795
|
-
* change on an existing name is not re-announced. Every line carries a `(Tools: …)` tail (
|
|
795
|
+
* change on an existing name is not re-announced. Every line carries a `(Tools: …)` tail (
|
|
796
796
|
* 220 `fvd`/`WW_` @465651-465668 — the model needs each type's tool boundary to pick a type;
|
|
797
797
|
* PARITY-SPOT-AGENT-TYPES F3), defaulted to {@link AGENT_TOOLS_NOTE_DEFAULT} when the entry precomputed none.
|
|
798
798
|
*
|
|
799
|
-
*
|
|
799
|
+
* ShowConcurrencyNote, honest attribution: `entries.length > 1` is a sema APPROXIMATION, not
|
|
800
800
|
* CC semantics. 220's real predicate (@607882) is `Aa() !== "pro" && Cq() === "default"` — subscription
|
|
801
801
|
* tier is not "pro" AND the output style is the default one. Neither axis exists in core (BYOM has no
|
|
802
802
|
* subscription plane; there is no output-style plane at all), so the predicate is untranslatable, and
|
|
@@ -806,7 +806,7 @@ export declare function agentListingDeltaHeader(toolName: string): string;
|
|
|
806
806
|
* noise. RESIDUAL (divergences candidate): under a >1 roster sema shows the note where 220 would hide it
|
|
807
807
|
* for a pro/non-default-style user.
|
|
808
808
|
*
|
|
809
|
-
*
|
|
809
|
+
* Added/removed ordering: adds are sorted by `localeCompare` and removals by the default
|
|
810
810
|
* `sort()`, exactly as 220 does at @607873 (`c.sort((p,f) => p.agentType.localeCompare(f.agentType)), u.sort()`).
|
|
811
811
|
* This is not cosmetic here: the announced-set advance ({@link commitAgentListing}) is gated on the
|
|
812
812
|
* rendered block surviving the capped bundle BYTE-IDENTICAL against a re-render, so a deployment that
|
|
@@ -818,7 +818,7 @@ export declare function agentListingDeltaHeader(toolName: string): string;
|
|
|
818
818
|
* information an alphabetical sort would destroy. The initial frame renders one array once, so it has
|
|
819
819
|
* no re-render byte-identity exposure of its own.
|
|
820
820
|
*
|
|
821
|
-
*
|
|
821
|
+
* PURE — never mutates `state`. The announced-set advance is CALLER-owned via
|
|
822
822
|
* {@link commitAgentListing}, committed ONLY when the rendered block survived the byte cap INTACT
|
|
823
823
|
* (tools_delta/mcp_instructions discipline — a cap-clipped/dropped block previously advanced the
|
|
824
824
|
* announced map anyway, losing the roster announcement forever).
|
|
@@ -870,7 +870,7 @@ export declare function renderSkillsListingDelta(state: AttachmentState, entries
|
|
|
870
870
|
* announced map untouched so the next quiet boundary re-announces. */
|
|
871
871
|
export declare function commitSkillsListing(state: AttachmentState, entries: ReadonlyArray<SkillListingEntry>): void;
|
|
872
872
|
/**
|
|
873
|
-
*
|
|
873
|
+
* Per-server bound (in CODE POINTS, matching every other clipper in `untrusted-text.ts`) on
|
|
874
874
|
* ONE MCP server's `instructions` text. The text is SERVER-controlled and UNBOUNDED on the wire: the
|
|
875
875
|
* bundle byte cap ({@link ATTACHMENT_BYTE_CAP}) is a per-frame structural backstop on the delta lane
|
|
876
876
|
* and does not exist AT ALL on the stable system-prompt lane, so without this a single server could
|
|
@@ -881,8 +881,8 @@ export declare function commitSkillsListing(state: AttachmentState, entries: Rea
|
|
|
881
881
|
*/
|
|
882
882
|
export declare const MCP_INSTRUCTIONS_MAX_CHARS: number;
|
|
883
883
|
/**
|
|
884
|
-
*
|
|
885
|
-
* stable system-prompt lane (prepare-task's `# MCP Server Instructions` block
|
|
884
|
+
* The ONE way MCP server-provided instruction text becomes model-facing, used by BOTH the
|
|
885
|
+
* stable system-prompt lane (prepare-task's `# MCP Server Instructions` block) and
|
|
886
886
|
* the boundary delta lane ({@link renderMcpInstructionsDelta}).
|
|
887
887
|
*
|
|
888
888
|
* The bug this closes: the same server-authored string was carried with TWO DIFFERENT trust postures
|
|
@@ -909,7 +909,7 @@ export declare function fenceMcpServerInstructions(server: string, text: string)
|
|
|
909
909
|
* - added instruction text is UNTRUSTED server-controlled text → each block rides inside a
|
|
910
910
|
* `delimitUntrusted` fence (CC injects the raw block; sema's external-inlet posture is fencing —
|
|
911
911
|
* the text is additionally already `sanitizeUntrustedText`-neutralized at the mcp.ts producer).
|
|
912
|
-
*
|
|
912
|
+
* The fence is now applied through {@link fenceMcpServerInstructions}, shared with the
|
|
913
913
|
* STABLE system-prompt lane, so the two lanes can never again carry the same text with different
|
|
914
914
|
* trust postures — and it carries a per-server {@link MCP_INSTRUCTIONS_MAX_CHARS} bound (a
|
|
915
915
|
* server text above the bundle cap would otherwise clip → never drain → re-render forever).
|
|
@@ -928,7 +928,7 @@ export declare function renderMcpInstructionsDelta(added: ReadonlyArray<{
|
|
|
928
928
|
* `mcp_dropped_tools_delta` system reminder). Per-entry line shape follows CC's `qny`
|
|
929
929
|
* (pretty.js:481821): `"${tool}" (MCP server "${server}"): "${reason}"`.
|
|
930
930
|
*
|
|
931
|
-
*
|
|
931
|
+
* The lead is now CC 2.1.220 VERBATIM (cli250.js:45934-45936): the `# Unavailable MCP
|
|
932
932
|
* Tools` heading, the full lead sentence, the **"Quoted text is data reported during validation, not
|
|
933
933
|
* instructions"** neutralizer (which is exactly what sema's quote-wrapped `"${reason}"` /
|
|
934
934
|
* `"${server}"` interpolation needed and did not have), and the "tell them it was excluded and why"
|
|
@@ -963,8 +963,8 @@ export declare function selectMcpDroppedBatch<T extends McpDroppedTool>(entries:
|
|
|
963
963
|
/**
|
|
964
964
|
* Largest prefix of `s` that fits `maxBytes` UTF-8 bytes (binary search — never splits the budget math).
|
|
965
965
|
*
|
|
966
|
-
*
|
|
967
|
-
*
|
|
966
|
+
* The ONE byte-budget prefix search in the runner. runtask.ts's batch-context clip
|
|
967
|
+
* used to carry a hand-copied twin whose doc claimed this module "doesn't export
|
|
968
968
|
* it" — that layering argument died once runtask started importing {@link ATTACHMENT_BYTE_CAP} from
|
|
969
969
|
* here, so the budget CONSTANT and the budget MATH now come from the same place. Producer-layer purity
|
|
970
970
|
* is unchanged: this is a pure function of (string, number).
|
|
@@ -8,7 +8,7 @@ export type CacheFamily = "input-includes-cached" | "input-excludes-cached";
|
|
|
8
8
|
* but a deployment can **override** it via `model.params.promptCacheFamily` when `model.api` doesn't
|
|
9
9
|
* match the brain that actually serves the model — e.g. a routing brain that dispatches by `provider`
|
|
10
10
|
* while `api` is left at a default. Accepts the explicit values or the aliases `"anthropic"`/`"openai"`.
|
|
11
|
-
* (
|
|
11
|
+
* (a route-by-provider setup with `api` hardcoded misjudged the family → 1090% hit rate.)
|
|
12
12
|
*/
|
|
13
13
|
export declare function cacheFamilyOf(model: Model): CacheFamily;
|
|
14
14
|
/** Total prompt tokens presented this turn, normalized so `cachedTokens` is always ⊆ the total. */
|
|
@@ -22,14 +22,14 @@ export declare function promptTokensOf(family: CacheFamily, u: {
|
|
|
22
22
|
* the Anthropic protocol calls `usage.input_tokens`, normalized across families. Derived from the
|
|
23
23
|
* normalized total so the identity `total = uncached + cacheRead + cacheWrite` holds by construction.
|
|
24
24
|
*
|
|
25
|
-
*
|
|
25
|
+
* The wire faces named `inputTokens`/`promptTokens` carry THIS, not the total — a consumer
|
|
26
26
|
* computing `cacheRead / (input + cacheRead)` on a same-named protocol field otherwise double-counts
|
|
27
27
|
* the cache subset and reports `h/(1+h)` (a real 98% hit rate surfaces as 49.5%). The BILLING path
|
|
28
28
|
* still consumes the total (`promptTokensOf`) — `computeCostMicroUsd` subtracts the priced subsets
|
|
29
29
|
* itself, so handing it the uncached figure would drop the cache legs from the bill entirely.
|
|
30
30
|
*
|
|
31
31
|
* Clamped at 0: when a provider reports subsets LARGER than its own total the cache family is
|
|
32
|
-
* misdeclared
|
|
32
|
+
* misdeclared, which the run loop already reports on its own face; here the identity
|
|
33
33
|
* degrades to `total ≤ uncached + cacheRead + cacheWrite` rather than going negative.
|
|
34
34
|
*/
|
|
35
35
|
export declare function uncachedInputTokensOf(family: CacheFamily, u: {
|
|
@@ -41,7 +41,7 @@ export declare function uncachedInputTokensOf(family: CacheFamily, u: {
|
|
|
41
41
|
* Normalize one turn's reported usage into its `{ totalInputTokens, uncachedInputTokens, costMicroUsd }`
|
|
42
42
|
* — the authoritative cost re-priced in core from injected pricing (so cached tokens aren't charged at
|
|
43
43
|
* full price). Shared by the run loop's per-turn accounting and post-task memory consolidation
|
|
44
|
-
*
|
|
44
|
+
* so a pricing change lives in ONE place. We emit only 5-min-TTL cache writes, so
|
|
45
45
|
* `cacheWriteTokensLong` is 0.
|
|
46
46
|
*/
|
|
47
47
|
export declare function usageCostMicroUsd(family: CacheFamily, u: {
|
|
@@ -18,7 +18,7 @@
|
|
|
18
18
|
*/
|
|
19
19
|
export declare function rebaseWorkspacePath(p: string, fromRaw: string, toRaw: string): string;
|
|
20
20
|
/**
|
|
21
|
-
*
|
|
21
|
+
* {@link rebaseWorkspacePath} over a SET of accepted spellings of the old root: the first
|
|
22
22
|
* prefix that actually matches wins, and a path under none of them is returned unchanged.
|
|
23
23
|
*
|
|
24
24
|
* The set exists because "the old root" has no single spelling. `WorkspaceHandle.mountPath` is whatever the
|
|
@@ -1370,15 +1370,22 @@ export interface RunnerDeps {
|
|
|
1370
1370
|
removedBytes: number;
|
|
1371
1371
|
}) => void;
|
|
1372
1372
|
/**
|
|
1373
|
-
* Deferred-tool disclosure policy (design/36).
|
|
1374
|
-
*
|
|
1375
|
-
*
|
|
1376
|
-
*
|
|
1377
|
-
*
|
|
1378
|
-
*
|
|
1379
|
-
*
|
|
1380
|
-
*
|
|
1381
|
-
*
|
|
1373
|
+
* Deferred-tool disclosure policy (design/36). Two rules govern deferral. ① The caller's list is
|
|
1374
|
+
* literal: {@link TaskSpec.deferTools} names defer on every request, `ToolSpec.alwaysLoad` /
|
|
1375
|
+
* {@link TaskSpec.alwaysLoadTools} pins inline on every request (judged first) — neither reads this
|
|
1376
|
+
* knob. ② The engine's own candidates — `ToolSpec.defer === true`, every REMOTE-PROTOCOL tool name
|
|
1377
|
+
* (MCP **and** A2A peer tools), and built-in tools that declare their own `defer` — sit behind ONE
|
|
1378
|
+
* threshold gate, all or nothing: deferred iff their inlined size (name + description + schema; the
|
|
1379
|
+
* candidate set only — the caller's list, pins and non-candidates are not measured) reaches 10% of the
|
|
1380
|
+
* model's context window; below that they ship inline in full and no ToolSearch is mounted.
|
|
1381
|
+
*
|
|
1382
|
+
* `"auto"` is a CANDIDATE-WIDENING knob, not a second gate: it adds every caller spec — undeclared
|
|
1383
|
+
* caller tools included — to the candidate set, measured and decided by the same threshold. Engine
|
|
1384
|
+
* built-ins the deployment did not name are candidates under no setting. An explicit opt-in (council
|
|
1385
|
+
* minor #6) because it makes `tools[]` depend on the caller roster's total weight, which a deployment
|
|
1386
|
+
* with many thin tools may not want. Any other value refuses at prepare (`config.defer_mode_invalid`).
|
|
1387
|
+
* `classifyDeferred` / `deferralGate` in `src/core/runner/tool-disclosure.ts` are the single authority
|
|
1388
|
+
* if this text drifts.
|
|
1382
1389
|
*/
|
|
1383
1390
|
deferMode?: "auto";
|
|
1384
1391
|
/**
|
package/dist/core/task-spec.d.ts
CHANGED
|
@@ -31,6 +31,10 @@ export type ImageInput = {
|
|
|
31
31
|
url: string;
|
|
32
32
|
};
|
|
33
33
|
/** A single self-contained task with its full configuration. */
|
|
34
|
+
/** The shell-gate doctrine vocabulary — {@link TaskSpec.shellGate}'s value set, and the word the engine persists on a
|
|
35
|
+
* shell-gated ask (`RiskDescriptor.shellGateDoctrine`) and folds across a delegation chain (max-rank: `off` <
|
|
36
|
+
* `classify` < `always`). One closed set; every seat that names a doctrine spells it through this alias. */
|
|
37
|
+
export type ShellGateDoctrine = "off" | "classify" | "always";
|
|
34
38
|
export interface TaskSpec {
|
|
35
39
|
taskId?: string;
|
|
36
40
|
/** The instruction / latest user message for this turn. */
|
|
@@ -400,6 +404,8 @@ export interface TaskSpec {
|
|
|
400
404
|
* included — `ToolSpec.defer` only covers caller specs): wire names listed here ship as
|
|
401
405
|
* lightweight placeholders (name + one-line hint, schema bytes OFF the cache prefix) and are
|
|
402
406
|
* activated on demand via the injected ToolSearch (design/36 materialization — prefix untouched).
|
|
407
|
+
* This list is LITERAL — an intentional deferral, deferred on every request regardless of the
|
|
408
|
+
* deferral gate ({@link RunnerDeps.deferMode}) and not counted toward its threshold.
|
|
403
409
|
* "Default-on but not exposed" = the deployment lists the tool here on requests where no
|
|
404
410
|
* activation source fired (e.g. Workflow unless the user said "workflow"/"ultracode"); omitting
|
|
405
411
|
* the name on a later request mounts it fully (activation = not deferring). Unknown names are
|
|
@@ -445,7 +451,7 @@ export interface TaskSpec {
|
|
|
445
451
|
* direction; CC 220 `alwaysLoad` 对位): names listed here are NEVER deferred — not by
|
|
446
452
|
* `ToolSpec.defer`, not by the MCP constant-defer arm (besides the server's own
|
|
447
453
|
* `_meta["anthropic/alwaysLoad"]` declaration this list is the only channel that keeps a chosen
|
|
448
|
-
* MCP tool's full schema inlined), not by `deferTools`, not by `deferMode
|
|
454
|
+
* MCP tool's full schema inlined), not by `deferTools`, not by the deferral gate under any `deferMode`. Unknown names
|
|
449
455
|
* are ignored (the valve only subtracts). Names also in `excludeTools` stay excluded (exclusion
|
|
450
456
|
* wins — an unmounted tool has no schema to keep inline).
|
|
451
457
|
*/
|
|
@@ -862,7 +868,7 @@ export interface TaskSpec {
|
|
|
862
868
|
* task config — a resume that omits it leaves the resumed run's SUBSEQUENT `bash` calls ungated (the approved
|
|
863
869
|
* pending call itself runs once, having been adjudicated). Re-pass the same value the original task used.
|
|
864
870
|
*/
|
|
865
|
-
shellGate?:
|
|
871
|
+
shellGate?: ShellGateDoctrine;
|
|
866
872
|
/**
|
|
867
873
|
* The caller's AUTO-MODE INTENT for this task — the "user turned auto on" half of the classifier
|
|
868
874
|
* arming (CC 2.1.250 polarity: auto mode is something the USER enables at the permission-mode
|
package/dist/core/tool-spec.d.ts
CHANGED
|
@@ -363,9 +363,12 @@ export interface ToolSpec<TParams extends TSchema = TSchema> {
|
|
|
363
363
|
* for this tool — it is not a "threshold so low that everything offloads". */
|
|
364
364
|
offloadThresholdChars?: number;
|
|
365
365
|
/**
|
|
366
|
-
* Deferred disclosure (design/36): when `true`, this tool is
|
|
367
|
-
*
|
|
368
|
-
*
|
|
366
|
+
* Deferred disclosure (design/36): when `true`, this tool is a CANDIDATE of the engine's deferral gate.
|
|
367
|
+
* When the gate opens (the candidate set's inlined size reaching 10% of the model's context window; see
|
|
368
|
+
* {@link RunnerDeps.deferMode}) it is NOT inlined with its full JSON Schema: it appears as a lightweight
|
|
369
|
+
* placeholder (`{name, one-line hint, empty params}`) so the model knows it exists; when the gate stays
|
|
370
|
+
* shut it ships inline in full. (A caller that wants a tool deferred on every request names it in
|
|
371
|
+
* {@link TaskSpec.deferTools} — that list is literal.) Activation is a DISCLOSURE fact (has the model seen the schema?), not an
|
|
369
372
|
* execution precondition: the model activates the tool via the injected ToolSearch, or by making a call
|
|
370
373
|
* whose arguments already match the real parameters (see {@link TaskSpec.deferSelfResolve}, on by
|
|
371
374
|
* default). Where the schema then lands depends on {@link TaskSpec.toolMaterializeStrategy} — the next
|
|
@@ -386,7 +389,7 @@ export interface ToolSpec<TParams extends TSchema = TSchema> {
|
|
|
386
389
|
* `alwaysLoad`, declared per MCP tool via `_meta["anthropic/alwaysLoad"]`, whose `isDeferredTool`
|
|
387
390
|
* checks it before every deferral arm): `true` pins this tool's full schema inline in every
|
|
388
391
|
* request — it is never deferred, regardless of its own {@link defer}, {@link TaskSpec.deferTools},
|
|
389
|
-
* or
|
|
392
|
+
* or the deferral gate. The deferral sources only ever ADD; this is the explicit subtract valve.
|
|
390
393
|
* Exclusion still wins ({@link TaskSpec.excludeTools} unmounts — nothing left to keep inline).
|
|
391
394
|
*/
|
|
392
395
|
alwaysLoad?: boolean;
|
package/dist/core/types.d.ts
CHANGED
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
import type { AgentTool, ThinkingLevel, ToolInputValidationContext, ToolInputVerdict } from "../internal/harness.js";
|
|
13
13
|
import type { Model, StreamFn } from "../internal/llm.js";
|
|
14
14
|
export type { ModelRef, ModelRole, RoleSpec, ModelRoles, Brain } from "./model-seat.js";
|
|
15
|
-
export type { StaleToolResultOffloadOptions, ImageInput, TaskSpec } from "./task-spec.js";
|
|
15
|
+
export type { StaleToolResultOffloadOptions, ImageInput, TaskSpec, ShellGateDoctrine } from "./task-spec.js";
|
|
16
16
|
export type { ToolEffect, ToolContentOrigin, ReversibilityVerdict, ToolSpec, ToolReturn, NestedUsage, NestedUsageAccum, ToolExecuteContext } from "./tool-spec.js";
|
|
17
17
|
export type { BeforeWriteRequest, BeforeWriteResult, BeforeWriteHook, TrackEditRequest, TrackEditResult, TrackFileEditHook, FileEditedNotice, FileEditedHook, HandsBandOptions } from "./hands-band.js";
|
|
18
18
|
export type { AgentDefinition, SkillManifest, SkillSpec } from "./agent-definition.js";
|