@sema-agent/core 7.15.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 +29 -0
- package/dist/core/governance-codes.js +2 -0
- 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 +222 -224
- 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 +19 -19
- 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 +2 -2
- 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 +5 -5
- package/dist/core/runner/prepare-hands-readface.d.ts +33 -33
- package/dist/core/runner/prepare-inherited-gate.d.ts +4 -4
- 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 +6 -6
- package/dist/core/runner/prepare-policy-chain.d.ts +4 -4
- 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-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 +1 -1
- package/dist/core/runner/tool-disclosure.d.ts +33 -33
- 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/engine/llm/types.d.ts +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.js +2 -2
- 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 +35 -35
- 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 +5 -1
|
@@ -4,7 +4,7 @@ import type { ExecutionEnv } from "../../internal/harness-types.js";
|
|
|
4
4
|
import { type PdfModelCapabilities } from "./pdf.js";
|
|
5
5
|
import { type ReadImageDownsamplerOption } from "./fs-shared.js";
|
|
6
6
|
import { type ReminderDisclosureCounts } from "../../core/reminder-disclosure.js";
|
|
7
|
-
/**
|
|
7
|
+
/** The Read tool's disclosure state, threaded into the PDF TEXT legs (the
|
|
8
8
|
* two `pdftotext` extraction arms — the only PDF returns with a model-facing text projection of
|
|
9
9
|
* the document; the native document block and rendered page images have no text to scan). Shares
|
|
10
10
|
* the Read closure's throttle windows so a PDF and its text read dedup on the same file key. */
|
|
@@ -21,7 +21,7 @@ type ReadPdfReturn = string | {
|
|
|
21
21
|
details: unknown;
|
|
22
22
|
};
|
|
23
23
|
/**
|
|
24
|
-
* PDF read pipeline (CC FileReadTool parity — mechanism
|
|
24
|
+
* PDF read pipeline (CC FileReadTool parity — mechanism + limits in fs/pdf.ts):
|
|
25
25
|
* - no `pages` → whole file as a native `document` block, gated at ≤{@link PDF_TARGET_RAW_SIZE} raw and
|
|
26
26
|
* ≤{@link PDF_INLINE_PAGE_THRESHOLD} pages (page count via `pdfinfo`, byte-scan fallback; unknown = fail-open,
|
|
27
27
|
* CC-identical — the size gate still bounds the request);
|
|
@@ -30,11 +30,11 @@ type ReadPdfReturn = string | {
|
|
|
30
30
|
* degradation with the working alternative, never a fake success.
|
|
31
31
|
* Wire discipline: the base64 payload rides `details.file` only while ≤48K chars (same OMIT rule as the
|
|
32
32
|
* image variant — a bigger card would be dropped whole by the card projector's 4×cap and blind the shell).
|
|
33
|
-
*
|
|
34
|
-
*
|
|
35
|
-
* code and the pages/fallback-level disclosure invisible to a host.
|
|
33
|
+
* The budget rule only means anything while `"document"` is registered on `CC_DETAIL_TYPES`: without
|
|
34
|
+
* that word every `document` card, sized or not, is dropped at the gate, which makes the 48K rule dead
|
|
35
|
+
* code and the pages/fallback-level disclosure invisible to a host.
|
|
36
36
|
*
|
|
37
|
-
* Degradation chain
|
|
37
|
+
* Degradation chain (the brain-level placeholder is NOT the end state): when the SERVING model
|
|
38
38
|
* cannot take a native document block (`caps.document === false` — e.g. any openai-compatible API), the
|
|
39
39
|
* whole-PDF path degrades IN THE TOOL (the only layer holding env.exec), best first:
|
|
40
40
|
* 1. `pdftotext -layout` text extraction → the content arrives as TEXT (Read byte-cap discipline applies);
|
|
@@ -42,10 +42,10 @@ type ReadPdfReturn = string | {
|
|
|
42
42
|
* pages via the existing `pdftoppm` pipeline (note directs `pages` for more);
|
|
43
43
|
* 3. honest placeholder explaining WHY levels 1–2 did not run + the Bash self-help.
|
|
44
44
|
* Every degraded return carries `details.fallback = { level, reason }` (telemetry on the structured frame).
|
|
45
|
-
* `caps` absent ⇒ fully capable (
|
|
45
|
+
* `caps` absent ⇒ fully capable (native document block; the brain placeholder still guards).
|
|
46
46
|
*/
|
|
47
47
|
export declare function readPdfFile(env: ExecutionEnv, path: string, key: string, pages: string | undefined, signal: AbortSignal | undefined, downsamplerOpt: ReadImageDownsamplerOption, cwd: string, preRead?: Uint8Array, caps?: PdfModelCapabilities, readDeny?: import("./read-deny.js").ReadDenyMatcher, disclosure?: PdfReminderDisclosure): Promise<ReadPdfReturn>;
|
|
48
|
-
/**
|
|
48
|
+
/** readPdfFile's own return type stays `ReadPdfReturn` (its INTERNAL string-means-error dispatch
|
|
49
49
|
* contract, shared with pdfPagesToImageBlocks) — the isError flag is applied once, here, at the tool's
|
|
50
50
|
* actual execute() boundary, not inside the helper. */
|
|
51
51
|
export declare function pdfResultToToolReturn(r: ReadPdfReturn): ReturnType<typeof errorResult> | Exclude<ReadPdfReturn, string>;
|
|
@@ -5,10 +5,10 @@ import type { CwdRef } from "./fs-shared.js";
|
|
|
5
5
|
/**
|
|
6
6
|
* The Grep card's details assembly, PURE over the engine text ({mode, offset} from the request) —
|
|
7
7
|
* exported so the text→structured mapping is pinnable with synthetic texts (the byte-truncation and
|
|
8
|
-
* fenced-partial shapes are impractical to construct through a live tool call).
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
8
|
+
* fenced-partial shapes are impractical to construct through a live tool call). PATH IDENTITY comes
|
|
9
|
+
* off the engines' served rows, not the text (both legs supply them); the counts and totals below
|
|
10
|
+
* still read the engine's own honesty markers out of the text, which is what keeps this seam the
|
|
11
|
+
* honesty boundary.
|
|
12
12
|
*/
|
|
13
13
|
export declare function grepDetailFields(text: string, mode: "files_with_matches" | "content" | "count", offset?: number, structuredRows?: readonly import("./search.js").GrepRow[]): Record<string, unknown>;
|
|
14
14
|
export declare function createGrepTool(env: ExecutionEnv, rootCanonical: string, additionalRoots?: readonly string[], readDeny?: ReadDenyMatcher, readFace?: ReadFace, cwdRef?: CwdRef): AgentTool;
|
|
@@ -5,18 +5,18 @@ import { type DecodedTextFile } from "./encoding.js";
|
|
|
5
5
|
import { type ImageDownsampler } from "../../core/mcp.js";
|
|
6
6
|
import { type EngineNotice } from "../../core/types.js";
|
|
7
7
|
/**
|
|
8
|
-
* The "hand" tool band
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
* edit
|
|
12
|
-
*
|
|
13
|
-
*
|
|
8
|
+
* The "hand" tool band — built per task over an injected {@link ExecutionEnv} and a per-task
|
|
9
|
+
* {@link ReadFileState}, closure-captured (the codebase tool idiom; no `ToolExecuteContext` growth).
|
|
10
|
+
* Every edit/write enforces the CC-ported safety invariants (read-before-edit, content-hash staleness,
|
|
11
|
+
* edit uniqueness, write-back) plus rootPath containment. The band is the file tools
|
|
12
|
+
* read/edit/write/grep/glob plus a shell: `bash` (effect:write, full shell) for normal tasks, or
|
|
13
|
+
* `bash_readonly` (effect:read, allowlisted) under the verifier read-only boundary.
|
|
14
14
|
*/
|
|
15
|
-
/** Byte cap on a single read (
|
|
16
|
-
*
|
|
17
|
-
*
|
|
15
|
+
/** Byte cap on a single read (CC `MAX_OUTPUT_SIZE = 0.25*1024*1024`). A DEFAULT whole-file read over
|
|
16
|
+
* this is refused with guidance; an explicit offset/limit slice is served, which keeps
|
|
17
|
+
* read-before-edit satisfiable on large files. */
|
|
18
18
|
export declare const MAX_READ_BYTES: number;
|
|
19
|
-
/** Hard MEMORY upper bound on a sliced (explicit offset/limit) read
|
|
19
|
+
/** Hard MEMORY upper bound on a sliced (explicit offset/limit) read. The offset/limit
|
|
20
20
|
* escape hatch bypasses the whole-file byte cap above, but the reader still loads the ENTIRE file into
|
|
21
21
|
* memory (`readBinaryFile`) before slicing by line — so without this cap, an explicit `offset:1,limit:1`
|
|
22
22
|
* on a multi-GB file is an OOM lever the model can pull. This bounds the bytes loaded into MEMORY, not
|
|
@@ -24,30 +24,27 @@ export declare const MAX_READ_BYTES: number;
|
|
|
24
24
|
* explicit slice, with guidance to stream a portion via bash (`sed -n` / `head -c`) instead, which
|
|
25
25
|
* never loads the whole file. */
|
|
26
26
|
export declare const SLICED_READ_MAX_BYTES: number;
|
|
27
|
-
/**
|
|
28
|
-
*
|
|
29
|
-
*
|
|
30
|
-
*
|
|
31
|
-
*
|
|
32
|
-
*
|
|
33
|
-
* ({@link SLICED_READ_MAX_BYTES} above) — same pattern, reused here rather than invented fresh. */
|
|
27
|
+
/** The byte cap Edit refuses ABOVE (CC's own constant, verbatim). CC stats the target before touching
|
|
28
|
+
* it and refuses with a formatted-size message when it exceeds this. Without the gate, Edit goes
|
|
29
|
+
* straight to a whole-file `readBinaryFile` (twice: the `old_string:""` full-overwrite branch and the
|
|
30
|
+
* normal find/replace branch), so a multi-GB target is an unguarded OOM lever an ordinary Edit call
|
|
31
|
+
* can pull. The shape is Read's: a pre-read `env.fileInfo` stat plus a post-read TOCTOU recheck
|
|
32
|
+
* ({@link SLICED_READ_MAX_BYTES} above). */
|
|
34
33
|
export declare const MAX_EDIT_BYTES: number;
|
|
35
|
-
/**
|
|
34
|
+
/** `Edit`'s human-readable byte-count formatter (CC `pl()` verbatim: bytes below 1KB, else
|
|
36
35
|
* KB/MB/GB with one decimal, trailing ".0" stripped). */
|
|
37
36
|
export declare function formatByteSize(n: number): string;
|
|
38
|
-
/**
|
|
39
|
-
*
|
|
40
|
-
*
|
|
41
|
-
*
|
|
42
|
-
*
|
|
43
|
-
*
|
|
44
|
-
* a
|
|
45
|
-
*
|
|
46
|
-
*
|
|
47
|
-
*
|
|
48
|
-
*
|
|
49
|
-
* future engine ever lowers the ceiling further) — this instead catches ANY decode failure, at
|
|
50
|
-
* whatever byte count actually broke, and reports it exactly like the byte-count gate would have. */
|
|
37
|
+
/** Node's own string-length ceiling (`buffer.constants.MAX_STRING_LENGTH` — ~512MiB on V8/Node 24)
|
|
38
|
+
* sits BELOW `MAX_EDIT_BYTES` (1GiB, CC's constant, which was never cross-checked against a host
|
|
39
|
+
* engine's actual limit). A file whose size lands between the two thresholds passes Edit's byte-count
|
|
40
|
+
* gate (both the pre-read `fileInfo` stat and the post-read TOCTOU recheck) and still crashes
|
|
41
|
+
* `decodeTextBytes`'s `Buffer#toString` with an uncaught `RangeError` — no race needed, reachable
|
|
42
|
+
* through the `old_string:""` branch's documented "no read-before-edit gate" path. The model would
|
|
43
|
+
* then see a bare, unactionable "Cannot create a string longer than…" instead of the "too large to
|
|
44
|
+
* edit" guidance the byte gate exists to provide. A numeric threshold pinned to today's engine
|
|
45
|
+
* constant would be fragile across Node/V8 versions (and would do nothing for Read's own decode call
|
|
46
|
+
* if a future engine lowered the ceiling further), so this catches ANY decode failure, at whatever
|
|
47
|
+
* byte count actually broke, and reports it exactly like the byte-count gate would have. */
|
|
51
48
|
export declare function decodeEditBytes(bytes: Uint8Array, path: string): {
|
|
52
49
|
ok: true;
|
|
53
50
|
value: DecodedTextFile;
|
|
@@ -65,7 +62,7 @@ export declare function truncatedUtf16BodyMessage(tool: string, path: string): s
|
|
|
65
62
|
/** Why a bash_readonly refusal is terminal rather than escalated. Appended by every arm of that refusal
|
|
66
63
|
* family; the arms differ in what they found, never in what the model can do about it. */
|
|
67
64
|
export declare const BASH_READONLY_CONFINEMENT_NOTE = "bash_readonly is confined to the workspace roots; it has no approval path, so the call is refused rather than escalated.";
|
|
68
|
-
/**
|
|
65
|
+
/** The readFileState hash coordinate for a file that was JUST WRITTEN via
|
|
69
66
|
* `encodeTextForFile`: decode the EXACT payload handed to `env.writeFile`, i.e. what the next
|
|
70
67
|
* re-read's `decodeTextBytes` will produce. A blanket `normalizeFileText` is WRONG on the
|
|
71
68
|
* encode-preserving Edit lanes: a leading U+FEFF in the new text is stripped by the next read only
|
|
@@ -75,7 +72,7 @@ export declare const BASH_READONLY_CONFINEMENT_NOTE = "bash_readonly is confined
|
|
|
75
72
|
* and stays correct if the encoding rules ever change. */
|
|
76
73
|
export declare function persistedTextOf(encoded: string | Uint8Array): string;
|
|
77
74
|
/**
|
|
78
|
-
*
|
|
75
|
+
* One APPLIED edit as the Edit tool's `details` card records it: the RESOLVED old/new strings
|
|
79
76
|
* (post quote/escape resolution, post deletion-newline widening) in the normalized originalFile
|
|
80
77
|
* coordinate. This is the card shape a transcript replay must re-apply, so the application step is a
|
|
81
78
|
* single source shared by the Edit tool's own apply loop and the replay — two spellings of "apply"
|
|
@@ -88,14 +85,14 @@ export interface RecordedEdit {
|
|
|
88
85
|
replaceAll: boolean;
|
|
89
86
|
}
|
|
90
87
|
/**
|
|
91
|
-
*
|
|
88
|
+
* Apply ONE recorded edit mechanically (no matching layers, no validation: the recording site
|
|
92
89
|
* already resolved and validated the strings; a replay consumer that cannot prove `oldString` is
|
|
93
90
|
* present must fall back to retracting its record, never guess here).
|
|
94
91
|
*
|
|
95
92
|
* Two load-bearing details, both shared with the Edit tool's historical inline apply:
|
|
96
93
|
* - Function-form replacement: the callback's return value is NOT interpreted as a replacement
|
|
97
|
-
* pattern, so `$&`/`$$`/`` $` ``/`$'` in `newString` are written literally (
|
|
98
|
-
* split/join path
|
|
94
|
+
* pattern, so `$&`/`$$`/`` $` ``/`$'` in `newString` are written literally (the replaceAll
|
|
95
|
+
* split/join path is literal by construction).
|
|
99
96
|
* - `oldString === ""` is the whole-content OVERWRITE shape: the Edit tool's whitespace-only-file
|
|
100
97
|
* overwrite lane records `{oldString: "", newString: <full new text>}` after REPLACING the file's
|
|
101
98
|
* content wholesale (fs-write.ts, the `old_string:""` existing-file branch). The tool's own apply
|
|
@@ -103,32 +100,30 @@ export interface RecordedEdit {
|
|
|
103
100
|
* it exists for the replay consumer alone — a plain `replace("", ...)` would PREPEND instead.
|
|
104
101
|
*/
|
|
105
102
|
export declare function applyRecordedEdit(text: string, edit: RecordedEdit): string;
|
|
106
|
-
/**
|
|
107
|
-
*
|
|
108
|
-
*
|
|
109
|
-
* bare CC-verbatim refusal.
|
|
103
|
+
/** Render the read-before-edit refusal, appending the slice/bash escape hatch when the target is over
|
|
104
|
+
* the Read byte cap — a bare "read it first" is un-followable there (a default whole-file Read
|
|
105
|
+
* refuses such files). Best-effort: an un-stattable file keeps the bare CC-verbatim refusal.
|
|
110
106
|
*
|
|
111
|
-
*
|
|
112
|
-
*
|
|
113
|
-
*
|
|
114
|
-
*
|
|
115
|
-
*
|
|
116
|
-
* buries the one that applies. */
|
|
107
|
+
* `fallbackHint` is a caller-supplied parenthetical for the case NO branch below diagnosed anything
|
|
108
|
+
* (all three writing tools pass {@link READ_REFUSED_ESCAPE_HINT} — the Read-refuses-this-file
|
|
109
|
+
* deadlock, which by construction leaves nothing to stat). It is NOT appended beside a sharper hint:
|
|
110
|
+
* both sharper shapes describe files Read handled successfully, so the encoding-deadlock sentence
|
|
111
|
+
* would be false there — and stacking two escape routes on one refusal buries the one that applies. */
|
|
117
112
|
export declare function notReadRefusalText(env: ExecutionEnv, toolName: string, key: string, v: Pick<FsViolation, "code" | "message" | "partialView">, signal?: AbortSignal, fallbackHint?: string): Promise<string>;
|
|
118
|
-
/** Byte cap on a Read-image WITHOUT a downsampler
|
|
119
|
-
*
|
|
120
|
-
*
|
|
121
|
-
*
|
|
113
|
+
/** Byte cap on a Read-image WITHOUT a downsampler: an image file is returned AS a visual
|
|
114
|
+
* `ImageContent` block (base64) rather than refused. Bounded so a huge image cannot blow the request.
|
|
115
|
+
* This stat-time cap only bounds the READ; the accept/refuse decision is the base64 gate below (the
|
|
116
|
+
* provider limit is on base64 LENGTH, so the effective no-sharp accept bound is raw ≤ 3.75MB). */
|
|
122
117
|
export declare const MAX_IMAGE_READ_BYTES: number;
|
|
123
|
-
/** Byte cap on a Read-image WITH a downsampler
|
|
124
|
-
*
|
|
125
|
-
*
|
|
118
|
+
/** Byte cap on a Read-image WITH a downsampler: sharp can shrink a big photo to CC's 2000×2000/3.75MB
|
|
119
|
+
* target, so the smaller hard refusal does not apply (CC readImageWithTokenBudget reads the file
|
|
120
|
+
* unbounded; we keep an OOM sanity bound — deliberate delta, camera photos fit comfortably). */
|
|
126
121
|
export declare const MAX_IMAGE_DOWNSAMPLE_INPUT_BYTES: number;
|
|
127
|
-
/**
|
|
128
|
-
*
|
|
129
|
-
*
|
|
130
|
-
*
|
|
131
|
-
*
|
|
122
|
+
/** The no-downsampler cap above is a DELIBERATE bound and does not move — but its refusal must not
|
|
123
|
+
* read like a hard ceiling. Whether the higher cap is reachable depends on an OPTIONAL dependency the
|
|
124
|
+
* caller can install, and only this package knows that, so the refusal names the move instead of
|
|
125
|
+
* leaving the caller to guess that the limit is negotiable. Appended ONLY on the no-downsampler
|
|
126
|
+
* branch: with sharp already resolved the hint would be false advice. */
|
|
132
127
|
export declare const NO_DOWNSAMPLER_IMAGE_CAP_HINT = "Install the optional \"sharp\" dependency (declared in this package's optionalDependencies) to read images up to 67108864 bytes \u2014 it downsamples them to fit the API image limit.";
|
|
133
128
|
/** Read-image downsampler seam: `undefined` → auto-detect sharp; `false` → force-disabled (deterministic
|
|
134
129
|
* no-sharp path, used by tests + envs that must not touch native deps); a function → injected. */
|
|
@@ -136,28 +131,25 @@ export type ReadImageDownsamplerOption = ImageDownsampler | false | undefined;
|
|
|
136
131
|
/** Resolve (and memoize) the auto-detected sharp downsampler, process-wide. Shared accessor for the two
|
|
137
132
|
* consumers of the module-private {@link autoDownsampler} cache. */
|
|
138
133
|
export declare function resolveAutoDownsampler(): Promise<ImageDownsampler | undefined>;
|
|
139
|
-
/** Output-token cap as a char proxy (
|
|
140
|
-
*
|
|
134
|
+
/** Output-token cap as a char proxy (CC's 25000, at ~4 chars/token). Caps the shown body so 2000 very
|
|
135
|
+
* long lines cannot blow the context budget.
|
|
141
136
|
*
|
|
142
|
-
*
|
|
143
|
-
*
|
|
144
|
-
*
|
|
145
|
-
*
|
|
146
|
-
* (
|
|
147
|
-
* token-
|
|
148
|
-
*
|
|
149
|
-
*
|
|
150
|
-
*
|
|
151
|
-
* states the served window truthfully). */
|
|
137
|
+
* Only the 25000 NUMBER is CC's. CC does NOT use a flat chars/4 proxy — it pre-filters with a
|
|
138
|
+
* PER-EXTENSION chars-per-token coefficient (json/jsonl = 2, half the 4 assumed here) and then
|
|
139
|
+
* confirms with a REAL tokenizer; its budget is also overridable per call and by a feature gate,
|
|
140
|
+
* neither of which has a sema lane. Consequence, stated rather than hidden: on token-dense text
|
|
141
|
+
* (JSON/CJK/base64) this proxy UNDER-counts, so sema serves a page CC would have cut further; on
|
|
142
|
+
* token-sparse text it over-counts and paginates earlier than CC. A real tokenizer here would need a
|
|
143
|
+
* provider-neutral counting seam (BYOM — no single vocabulary), which is why the proxy stands; the
|
|
144
|
+
* divergence is a fidelity delta, not a correctness one (the partial-view marker always states the
|
|
145
|
+
* served window truthfully). */
|
|
152
146
|
export declare const MAX_READ_OUTPUT_CHARS = 100000;
|
|
153
|
-
/** Per-read content-safety reminder appended after a text read
|
|
147
|
+
/** Per-read content-safety reminder appended after a text read.
|
|
154
148
|
*
|
|
155
|
-
* Attribution, stated precisely because
|
|
156
|
-
*
|
|
157
|
-
*
|
|
158
|
-
*
|
|
159
|
-
* mitigation moved inside the serving model. So "not an upstream port" is false against 88 and true
|
|
160
|
-
* against 220, and neither reading alone describes the situation.
|
|
149
|
+
* Attribution, stated precisely because either half alone is wrong. The upstream 88 source DOES carry
|
|
150
|
+
* the same mechanism — `FileReadTool`'s `CYBER_RISK_MITIGATION_REMINDER`, appended after every text
|
|
151
|
+
* read, behind a PER-MODEL exemption gate. The 220 baseline does NOT: the text is gone, retired once
|
|
152
|
+
* the mitigation moved inside the serving model.
|
|
161
153
|
*
|
|
162
154
|
* This engine keeps it because a BYOM deployment cannot assume its serving model carries the
|
|
163
155
|
* mitigation, and adjacency is the whole mechanism (a reminder in a system prompt hundreds of turns
|
|
@@ -169,16 +161,15 @@ export declare const MAX_READ_OUTPUT_CHARS = 100000;
|
|
|
169
161
|
* COVERAGE, stated because the switch is easy to over-read: the reminder rides the plain-text read and
|
|
170
162
|
* the notebook projection. PDF text extraction returns through its own result builder and has never
|
|
171
163
|
* carried it, so extracted PDF text reaches the model without this mitigation whatever the switch says.
|
|
172
|
-
* That gap predates the switch; its IMPERSONATION half is
|
|
173
|
-
*
|
|
174
|
-
*
|
|
175
|
-
*
|
|
176
|
-
*
|
|
177
|
-
* not a wiring fix.
|
|
164
|
+
* That gap predates the switch; its IMPERSONATION half is closed — the PDF text legs carry the same
|
|
165
|
+
* detect-and-disclose trailer as this lane (reminder-shaped bytes in extracted PDF text are disclosed
|
|
166
|
+
* at the outlet, fs-pdf.ts), and their bodies are fenced. The CYBER half (this malware-alertness
|
|
167
|
+
* sentence) still does not ride PDF text and stays an open item rather than closed silently —
|
|
168
|
+
* widening it to a third surface is a change to what every PDF read costs, not a wiring fix.
|
|
178
169
|
*
|
|
179
|
-
*
|
|
180
|
-
*
|
|
181
|
-
* the
|
|
170
|
+
* A FUNCTION over the session mark, not a constant: the open tag is rendered by the mint home so it
|
|
171
|
+
* carries the run's provenance mark; the sentence bytes are unchanged, and a markless call renders
|
|
172
|
+
* the bare form verbatim. */
|
|
182
173
|
export declare function readCyberReminderText(mark: string | undefined): string;
|
|
183
174
|
export declare const BASH_DEFAULT_TIMEOUT_SEC = 120;
|
|
184
175
|
export declare const BASH_MAX_TIMEOUT_SEC = 600;
|
|
@@ -238,10 +229,9 @@ export declare function bashTimeoutArgRefusal(timeoutMs: number | undefined, cap
|
|
|
238
229
|
maxMs: number;
|
|
239
230
|
}): string | undefined;
|
|
240
231
|
/**
|
|
241
|
-
*
|
|
242
|
-
*
|
|
243
|
-
*
|
|
244
|
-
* resolver adds — is configurability.
|
|
232
|
+
* The SINGLE authority for the Bash `timeout` parameter's two numbers: the default budget applied
|
|
233
|
+
* when the model omits `timeout`, and the engine ceiling requests are clamped to. The 120s/600s
|
|
234
|
+
* constants themselves are CC-same; what this resolver adds on top is configurability.
|
|
245
235
|
*
|
|
246
236
|
* Resolution, per leg (options over env over constant — the standing sema discipline: "deployments
|
|
247
237
|
* configure the tool, not the process"; env stays as the CC-shaped fallback for process-level tuning):
|
|
@@ -252,7 +242,7 @@ export declare function bashTimeoutArgRefusal(timeoutMs: number | undefined, cap
|
|
|
252
242
|
* default floors the cap. Invalid values (non-finite / <= 0) are discarded at every leg, options
|
|
253
243
|
* included, exactly like CC's env read.
|
|
254
244
|
*
|
|
255
|
-
*
|
|
245
|
+
* Readable seam: a shell/host rendering its OWN copy of the Bash tool description MUST
|
|
256
246
|
* read the true values from here instead of holding a sibling constant — the engine's description/param
|
|
257
247
|
* text and its runtime clamp both interpolate this function's output (resolved once per tool instance),
|
|
258
248
|
* so a self-held "600s" only matches by coincidence and forks silently the moment a deployment
|
|
@@ -273,8 +263,8 @@ export declare function resolveBashTimeoutCaps(opts?: {
|
|
|
273
263
|
* the line must be able to re-arm the ledger. Re-arms BOTH arms (a WeakMap has no clear — it is
|
|
274
264
|
* re-minted). Never called by production code. */
|
|
275
265
|
export declare function __resetBashTimeoutAnnouncements(): void;
|
|
276
|
-
/**
|
|
277
|
-
*
|
|
266
|
+
/** The seconds view of a resolved {@link resolveBashTimeoutCaps} pair — the shell's INTERNAL unit
|
|
267
|
+
* stays seconds while every model-facing surface stays ms. One rounding
|
|
278
268
|
* point, same Math.round form as the model-supplied timeout's own ms→s conversion, floored at 1s. */
|
|
279
269
|
export declare function bashTimeoutCapsSec(caps: {
|
|
280
270
|
defaultMs: number;
|
|
@@ -287,22 +277,21 @@ export declare function bashMaxOutputChars(): number;
|
|
|
287
277
|
export declare const FILE_PATH_PARAMS: {
|
|
288
278
|
file_path: Type.TString;
|
|
289
279
|
};
|
|
290
|
-
/** Honest head+tail truncation to {@link bashMaxOutputChars}
|
|
291
|
-
* the head AND tail both matter for a shell
|
|
292
|
-
* file-backed recovery below
|
|
293
|
-
* command's head can carry status a bare tail-keep would drop
|
|
294
|
-
*
|
|
295
|
-
* {@link clipWithFilePointer}
|
|
296
|
-
* here passes a path. */
|
|
280
|
+
/** Honest head+tail truncation to {@link bashMaxOutputChars}: the middle is dropped with a real-total
|
|
281
|
+
* marker, because the head AND tail both matter for a shell. Kept as the inline shape even beside the
|
|
282
|
+
* file-backed recovery below — unlike a background task's poll-for-the-latest-tail interaction, a
|
|
283
|
+
* foreground command's head can carry status a bare tail-keep would drop. Shared by runShell
|
|
284
|
+
* (foreground) and TaskOutput (background poll). Delegates its arithmetic to the shared
|
|
285
|
+
* {@link clipWithFilePointer} but never exercises its pointer arm — no caller here passes a path. */
|
|
297
286
|
export declare function clipShellOutput(s: string): string;
|
|
298
287
|
/**
|
|
299
|
-
*
|
|
300
|
-
*
|
|
301
|
-
*
|
|
302
|
-
*
|
|
303
|
-
*
|
|
304
|
-
*
|
|
305
|
-
*
|
|
288
|
+
* A foreground command's captured stdout/stderr are ALREADY fully in memory here (the env delivered
|
|
289
|
+
* them whole — only `clipShellOutput` above decides how much of that the model's turn actually sees).
|
|
290
|
+
* What this closes is that the omitted middle would otherwise be discarded, forcing a blind full
|
|
291
|
+
* re-run to recover output that was, in fact, captured. "Whole" means whatever THIS layer received,
|
|
292
|
+
* not a guarantee about what the process originally wrote: the env's own rolling-tail cap
|
|
293
|
+
* (`MAX_EXEC_OUTPUT_BYTES`, exec-output-tail.ts) can already have dropped the head before delivery on
|
|
294
|
+
* a truly enormous single command — this file is a faithful copy
|
|
306
295
|
* of the received bytes either way, and still carries that cap's own `markTruncated()` marker when it
|
|
307
296
|
* fired, so nothing here overclaims completeness beyond what the text itself already discloses. Purely
|
|
308
297
|
* ADDITIVE: the inline head+tail framing above is untouched; this only gives the model a second, explicit
|
|
@@ -320,20 +309,20 @@ export declare function clipShellOutput(s: string): string;
|
|
|
320
309
|
* containment on their explicit path arguments), so the model already has a direct route to the file: a
|
|
321
310
|
* later `bash` call — the message text says so explicitly rather than implying Read will work, and picks
|
|
322
311
|
* an example command the CALLING tool variant can actually run (see {@link shellRecoveryHint}: `sed -n`
|
|
323
|
-
* for full `bash`, an allowlisted `tail -c` for `bash_readonly
|
|
324
|
-
*
|
|
325
|
-
*
|
|
312
|
+
* for full `bash`, an allowlisted `tail -c` for `bash_readonly`). Creation/write failure degrades
|
|
313
|
+
* silently to no file (the inline clip is unaffected either way), matching the background lane's own
|
|
314
|
+
* degrade posture.
|
|
326
315
|
*/
|
|
327
316
|
export declare function writeShellOverflowFile(env: ExecutionEnv, stdout: string, stderr: string): Promise<string | undefined>;
|
|
328
317
|
/**
|
|
329
|
-
*
|
|
330
|
-
*
|
|
318
|
+
* Recognise the engine's OWN shell overflow recovery files, so `bash_readonly` can keep honouring the
|
|
319
|
+
* `tail -c … <file>` command its result trailer advertises.
|
|
331
320
|
*
|
|
332
|
-
*
|
|
333
|
-
*
|
|
334
|
-
*
|
|
335
|
-
*
|
|
336
|
-
*
|
|
321
|
+
* NOT a `Set` of the exact paths one tool instance minted: the trailer lives in the transcript, not in
|
|
322
|
+
* the instance, and the hands toolkit is rebuilt on every task preparation — a later run replaying the
|
|
323
|
+
* advertised command would meet a tool with no memory of it and be refused, i.e. the engine refusing
|
|
324
|
+
* its own advice, and (in the read-only band, whose Read tool is fenced by the same roots) the only
|
|
325
|
+
* route to the truncated output.
|
|
337
326
|
*
|
|
338
327
|
* Judged by SHAPE instead, which survives any rebuild, with the grant kept pinned to the engine's own
|
|
339
328
|
* temp area on three counts that must ALL hold:
|
|
@@ -358,7 +347,7 @@ export declare function writeShellOverflowFile(env: ExecutionEnv, stdout: string
|
|
|
358
347
|
*/
|
|
359
348
|
export declare function createShellOverflowSpoolFence(env: ExecutionEnv): (path: string) => Promise<boolean>;
|
|
360
349
|
/**
|
|
361
|
-
*
|
|
350
|
+
* The recovery-file trailer's example command must be one the
|
|
362
351
|
* CALLING tool can actually run. `sed` is not in {@link import("./bash-readonly-classifier.js").BASH_READONLY_DEFAULT_ALLOW} and `bash_readonly`
|
|
363
352
|
* forbids the operators a pipe/redirect would need, so a `bash_readonly` command that overflows gets a
|
|
364
353
|
* single-command, allowlisted alternative instead (`tail -c`, byte-bounded so it doesn't depend on line
|
|
@@ -366,17 +355,17 @@ export declare function createShellOverflowSpoolFence(env: ExecutionEnv): (path:
|
|
|
366
355
|
* executable. Full `bash` keeps the precise form.
|
|
367
356
|
*/
|
|
368
357
|
export declare function shellRecoveryHint(path: string, readOnly: boolean | undefined): string;
|
|
369
|
-
/** CC 2.1.198 live-verbatim Edit/Write success trailer
|
|
370
|
-
*
|
|
358
|
+
/** CC 2.1.198 live-verbatim Edit/Write success trailer — appended to every Edit/Write success message
|
|
359
|
+
* (NOT NotebookEdit — CC ships it without the trailer). */
|
|
371
360
|
export declare const FILE_STATE_TRAILER = " (file state is current in your context \u2014 no need to Read it back)";
|
|
372
361
|
export declare const CWD_SENTINEL = "__cc_cwd_9f2c1b__";
|
|
373
|
-
/** Convert a model-supplied millisecond timeout to our internal seconds, clamped
|
|
374
|
-
*
|
|
375
|
-
* ⚠️
|
|
376
|
-
* caller's number before it can be disclosed. The Bash legs deliberately do NOT use
|
|
377
|
-
*
|
|
378
|
-
*
|
|
379
|
-
*
|
|
362
|
+
/** Convert a model-supplied millisecond timeout to our internal seconds, clamped. Exported for the
|
|
363
|
+
* cc-parity unit (model sees ms, internal stays seconds — no ×1000 error).
|
|
364
|
+
* ⚠️ This returns the EFFECTIVE budget, not the request — capping at a call site destroys the
|
|
365
|
+
* caller's number before it can be disclosed. The Bash legs deliberately do NOT use it (they pass the
|
|
366
|
+
* uncapped conversion into runShell, which caps once and reports the true request); use this only
|
|
367
|
+
* where the post-ceiling value is what you mean.
|
|
368
|
+
* The clamp bounds are not the bare constants — pass the caller's resolved caps
|
|
380
369
|
* ({@link resolveBashTimeoutCaps}) to clamp against a configured deployment; omitted ⇒ resolve fresh
|
|
381
370
|
* (zero-config = the historical 120s/600s, byte-compat).
|
|
382
371
|
* ⚠️ This is the RAW converter and NOT the authority on what the tool accepts: it still folds the whole
|
|
@@ -388,7 +377,7 @@ export declare function msTimeoutToSec(timeoutMs: number | undefined, caps?: {
|
|
|
388
377
|
defaultMs: number;
|
|
389
378
|
maxMs: number;
|
|
390
379
|
}): number;
|
|
391
|
-
/** `.ipynb` redirect (
|
|
380
|
+
/** `.ipynb` redirect (CC FileEditTool parity): a raw text edit/overwrite corrupts the
|
|
392
381
|
* notebook JSON, so the text-edit face refuses and redirects to the NotebookEdit tool (built in
|
|
393
382
|
* src/tools/fs/fs-write.ts, mounted with the rest of the hands band). */
|
|
394
383
|
export declare function ipynbRedirect(toolName: string, path: string): string | undefined;
|
|
@@ -397,32 +386,29 @@ export declare function ipynbRedirect(toolName: string, path: string): string |
|
|
|
397
386
|
* ends in "\n". Behavior is identical for content WITHOUT a trailing newline. Shared by read_file's
|
|
398
387
|
* `total`, edit_file/write_file's "N lines" report, and the persisted ReadFileState.totalLines. */
|
|
399
388
|
export declare function countLines(s: string): number;
|
|
400
|
-
/**
|
|
401
|
-
*
|
|
402
|
-
* CC: ``Wfc(e) = `${qfc} (see "Contents of ${e}" above) and has not changed on disk. Use that content
|
|
403
|
-
* instead of re-reading.</system-reminder>``` with `qfc = '<system-reminder>This file is already in
|
|
404
|
-
* your context'`. `filePath` is the CANONICAL key (CC passes the resolved full path `f`, matching the
|
|
389
|
+
/** CC 2.1.204 VERBATIM: the reminder served when a DEFAULT whole-file Read hits a startup-seeded,
|
|
390
|
+
* unchanged file. `filePath` is the CANONICAL key (CC passes the resolved full path, matching the
|
|
405
391
|
* `Contents of <path>` header its context seeding emits — deployments seeding files should title the
|
|
406
|
-
* injected block the same way so the back-reference lands). Locked verbatim by test
|
|
407
|
-
*
|
|
408
|
-
*
|
|
392
|
+
* injected block the same way so the back-reference lands). Locked verbatim by test: the BODY and
|
|
393
|
+
* close tag stay CC-verbatim; the open tag alone is rendered by the mint home and carries the session
|
|
394
|
+
* mark when one is threaded (the recorded wire-form divergence). */
|
|
409
395
|
export declare function seededFileUnchangedReminder(filePath: string, mark?: string): string;
|
|
410
396
|
/**
|
|
411
|
-
*
|
|
412
|
-
*
|
|
413
|
-
*
|
|
414
|
-
*
|
|
415
|
-
*
|
|
397
|
+
* True when `resultText` is one of the Read tool's TWO dedup markers (the ordinary
|
|
398
|
+
* unchanged-since-last-read stub below, or {@link seededFileUnchangedReminder}) rather than a genuine
|
|
399
|
+
* content transmission. A consumer deciding "is this file's real content present in THIS message"
|
|
400
|
+
* (e.g. auto-compaction's kept-tail visibility scan) must treat a stub hit as absence — the marker
|
|
401
|
+
* POINTS AT an earlier read that may itself no longer be in context.
|
|
416
402
|
*
|
|
417
|
-
*
|
|
403
|
+
* Both emitters ALSO carry a structured marker (`details.type === "file_unchanged"`,
|
|
418
404
|
* fs-read.ts `fileUnchangedResult`) — consumers with access to the tool result's `details` should
|
|
419
405
|
* branch on that instead of this prose match (which can false-positive on file CONTENT that quotes
|
|
420
406
|
* either sentence). This predicate stays for text-only surfaces (compaction sees rendered text).
|
|
421
407
|
*/
|
|
422
408
|
export declare function isReadDedupStubResult(resultText: string): boolean;
|
|
423
|
-
/**
|
|
424
|
-
*
|
|
425
|
-
*
|
|
409
|
+
/** Pre-seed the hands' read state for a file whose FULL, disk-verbatim text was injected into the
|
|
410
|
+
* model's context at startup (CC 2.1.204 `seededFromContext` seeding of the memory preload; sema:
|
|
411
|
+
* ProjectMemoryLoad.seededFiles → prepare-task).
|
|
426
412
|
* `content` MUST be the file's exact disk text at load time — the Read tool's seeded dedup treats a
|
|
427
413
|
* hash match as "unchanged"; a truncated/annotated variant must NOT be seeded (CC exempts those via
|
|
428
414
|
* `isPartialView`; sema's contract is simply "don't seed partials"). `key` is the CANONICAL path
|
|
@@ -431,7 +417,7 @@ export declare function isReadDedupStubResult(resultText: string): boolean;
|
|
|
431
417
|
export declare function seedReadFileStateFromContext(state: ReadFileState, key: string, content: string): void;
|
|
432
418
|
/**
|
|
433
419
|
* Seed the hands' read state from a WHOLE-file content the session transcript recorded on an earlier
|
|
434
|
-
* turn (
|
|
420
|
+
* turn (the selection rules live in core/runner/session-file-state-replay.ts).
|
|
435
421
|
*
|
|
436
422
|
* Same minting as {@link seedReadFileStateFromContext} and the same normalization reason, with three
|
|
437
423
|
* deliberate differences, each of which is a claim this seed cannot honestly make:
|
|
@@ -446,7 +432,7 @@ export declare function seedReadFileStateFromContext(state: ReadFileState, key:
|
|
|
446
432
|
*/
|
|
447
433
|
export declare function seedReadFileStateFromTranscript(state: ReadFileState, key: string, content: string, lastReadAt: number): void;
|
|
448
434
|
/**
|
|
449
|
-
*
|
|
435
|
+
* Copy a SESSION-inherited read-file state into a new task's map, under the new task's
|
|
450
436
|
* own containment judgment (CC parity: readFileState is session-scoped — minted once per REPL session,
|
|
451
437
|
* mutated across turns, with no turn-boundary or abort clear site; sema's per-task map inherits the
|
|
452
438
|
* previous turn's live state instead).
|
|
@@ -458,7 +444,7 @@ export declare function seedReadFileStateFromTranscript(state: ReadFileState, ke
|
|
|
458
444
|
* replay leg already judges — an unjudged copy would smuggle out-of-face entries into the task
|
|
459
445
|
* (and into its checkpoints).
|
|
460
446
|
* - **`seededFromContext` entries do not inherit.** That flag claims the file's text lives in the
|
|
461
|
-
* system-prompt lane OF THIS TASK — a claim only this task's own startup seeding
|
|
447
|
+
* system-prompt lane OF THIS TASK — a claim only this task's own startup seeding can make.
|
|
462
448
|
* A still-declared file is re-seeded the same turn (no loss); a no-longer-declared one must not
|
|
463
449
|
* keep answering reads with an "already in your context" reminder that is no longer true.
|
|
464
450
|
*
|
|
@@ -468,8 +454,8 @@ export declare function seedReadFileStateFromTranscript(state: ReadFileState, ke
|
|
|
468
454
|
*/
|
|
469
455
|
export declare function inheritSessionReadFileState(target: ReadFileState, inherited: ReadFileState, judgeKey: (recordedKey: string) => Promise<string | undefined>): Promise<void>;
|
|
470
456
|
/**
|
|
471
|
-
*
|
|
472
|
-
*
|
|
457
|
+
* CC parity: a landed compaction summarizes old Read results OUT of the context, so every non-seeded
|
|
458
|
+
* read-state entry must be dropped — CC snapshots then
|
|
473
459
|
* `readFileState.clear()`s at the same spot. Without this, the Read dedup stub above answers a re-read of
|
|
474
460
|
* an unchanged file with "content omitted to save context" pointing at content that no longer exists
|
|
475
461
|
* anywhere in the context (the model works from hallucinated memory or has to vary offset/limit to escape).
|
|
@@ -482,14 +468,14 @@ export declare function inheritSessionReadFileState(target: ReadFileState, inher
|
|
|
482
468
|
* The read-before-edit gate tightens as a consequence, matching CC: after a compaction the model must
|
|
483
469
|
* re-Read a summarized-away file before editing it, instead of blind-editing from a stale recollection.
|
|
484
470
|
*
|
|
485
|
-
*
|
|
486
|
-
*
|
|
471
|
+
* A THIRD category besides seeded/re-attached: a file whose most recent Read is still visible
|
|
472
|
+
* verbatim in the compaction's KEPT tail is deliberately left OUT of
|
|
487
473
|
* `attachedComplete` (re-attaching it would just duplicate content already in context), but its
|
|
488
474
|
* existing read-state entry must survive unmodified for the SAME reason a seeded entry does: the
|
|
489
|
-
* model's view of it did not change. Wiping it
|
|
490
|
-
*
|
|
491
|
-
*
|
|
492
|
-
*
|
|
475
|
+
* model's view of it did not change. Wiping it breaks two things for exactly these files — the
|
|
476
|
+
* read-before-edit gate would reject an Edit the model could visibly justify from its own kept-tail
|
|
477
|
+
* Read, and a next Read would miss the dedup stub and retransmit the whole file, recreating the exact
|
|
478
|
+
* waste this dedup exists to remove. `preserveKeys` is the caller's kept-tail set
|
|
493
479
|
* (see `maybeCompact`'s `candidateFiles` computation) — passed as keys already in `state`'s own
|
|
494
480
|
* coordinate (canonicalized the same way the Read/Edit/Write tools populate it), so a plain lookup
|
|
495
481
|
* suffices; no re-hash/re-register needed since the entry's content genuinely has not changed.
|
|
@@ -498,7 +484,7 @@ export declare function applyCompactionToReadFileState(state: ReadFileState, att
|
|
|
498
484
|
path: string;
|
|
499
485
|
content: string;
|
|
500
486
|
}>, preserveKeys?: ReadonlyArray<string>): void;
|
|
501
|
-
/**
|
|
487
|
+
/** CC 2.1.198 verbatim skeleton: the ENOENT error body for a
|
|
502
488
|
* missing Read/Edit target — `File does not exist. Note: your current working directory is <cwd>.`
|
|
503
489
|
* plus a `Did you mean <sibling>?` correction when the parent directory holds a near-name (case
|
|
504
490
|
* variant / same stem different extension — the high-frequency self-heal path). Best-effort: a
|
|
@@ -508,7 +494,7 @@ export declare function enoentMessage(env: ExecutionEnv, key: string, cwd: strin
|
|
|
508
494
|
pattern: string;
|
|
509
495
|
} | null;
|
|
510
496
|
}): Promise<string>;
|
|
511
|
-
/** Per-task mutable working directory shared by the shell and the path-taking fs tools
|
|
497
|
+
/** Per-task mutable working directory shared by the shell and the path-taking fs tools.
|
|
512
498
|
* Holds the RAW path (never canonicalized): bash `cd` updates `current`, and the fs tools resolve relative
|
|
513
499
|
* paths against it. Containment is still enforced per-op by resolveKey (canonicalize + within), so a `cd`
|
|
514
500
|
* through a symlink out of root cannot carry across a relative fs path outside. */
|