Harness spec: stubs per request, the compaction table from the reads it covers
context.md and loop.json `context`, spec 3.0.0-draft: - A stub names only a result in the request being built. A chat on the server sends no earlier reply's tool results, so a read in the next reply is answered in full there; the CLI, which resends every result, keeps stubbing across steps. Said for reads and for repeated listings alike. - The compaction table is drawn from the reads the summary covers: the full reads since the previous compaction in turns still in the history, whether or not the request still carries them. A turn taken back takes its reads with it. The CLI's dedupe table is exactly that set; a chat finds it in what it stored. - Ids are the result's number in the session, in hex, at least 4 digits (#0001); the examples and the prompt block now use such ids. - A bracket names the path as the call gave it; what identifies a file is its absolute path. Conformance `context`: a `reply` step (a request carrying none of the results so far) and a case for both rules. The CLI's runner keeps the history apart from the request; compactionTable takes the reads. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
6 files changed
+150
-40
No files matched your search
+12
-8
@@ -7,8 +7,8 @@
|
||||
//
|
||||
// The one rule: every measure acts when a result is inserted, and nothing already sent is ever
|
||||
// rewritten — changing earlier context throws the prompt cache away from that point. A stub only
|
||||
// ever points at a result that is still in the conversation (`present`): after a compaction, an
|
||||
// /undo or a rewind, the result it would point at is gone, so the read is answered in full.
|
||||
// ever points at a result in the request being built (`present`): after a compaction, an /undo or
|
||||
// a rewind, the result it would point at is gone, so the read is answered in full.
|
||||
import { createHash } from "node:crypto"
|
||||
import { structuredPatch } from "diff"
|
||||
import { LOOP } from "../harness.ts"
|
||||
@@ -224,18 +224,22 @@ export class ResultContext {
|
||||
return `${fill(CONTEXT.recall_header, { id, target, from, to, of: lines.length })}\n${shown}`
|
||||
}
|
||||
|
||||
/** The dedupe table: full results still in the conversation, oldest first. */
|
||||
/** The dedupe table: the full results in the request being built, oldest first. A stub names
|
||||
* only one of them (context.md §2). */
|
||||
private table(): StoredResult[] {
|
||||
const here = this.present()
|
||||
return this.store.all().filter((r) => r.full && here.has(r.id))
|
||||
}
|
||||
|
||||
/** The table compaction adds after its summary: the newest full read of each path still in the
|
||||
* conversation, newest last, at most compaction.rows; "" with none. After it the conversation is
|
||||
* the summary alone, so nothing is present and the dedupe table is empty by construction. */
|
||||
compactionTable(): string {
|
||||
/** The table compaction adds after its summary (context.md §7): of the full reads the summary
|
||||
* covers — made since the previous compaction, in turns still in the history — the newest of
|
||||
* each file, newest last, at most compaction.rows; "" with none. `reads` defaults to the dedupe
|
||||
* table: the CLI resends every result, so the results in the conversation are exactly those
|
||||
* (an /undo or a rewind took its reads with it). After it the conversation is the summary alone,
|
||||
* so nothing is present and the dedupe table is empty by construction. */
|
||||
compactionTable(reads: StoredResult[] = this.table()): string {
|
||||
const newest = new Map<string, StoredResult>()
|
||||
for (const r of this.table()) if (r.kind === "read" && r.of! > 0) newest.delete(r.key!), newest.set(r.key!, r)
|
||||
for (const r of reads) if (r.kind === "read" && r.full && r.of! > 0) newest.delete(r.key!), newest.set(r.key!, r)
|
||||
const rows = [...newest.values()].slice(-CONTEXT.compaction.rows)
|
||||
if (!rows.length) return ""
|
||||
return [
|
||||
|
||||
Reference in new issue
Block a user