Harness spec 1.2.0: the library's tools fit both projects; the CLI implements it
The CLI's facts in memory, notes_search, note_manage, skills_list, skill_view and skill_manage are `variables` now, filled with the CLI's own values (src/tool/spec-vars.ts): every description and parameter list the CLI sends is word for word what 1.1.0 said, except note and document ids, which are strings on both sides (a number is still taken). Descriptions are filled by the prompt texts' rules, parameter descriptions too. `narrow` says what a project offers of a shared tool's parameters. Memory's changes are one pure function (applyOps). Conformance: fill, narrow, memory. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
23 files changed
+1398
-88
No files matched your search
@@ -16,6 +16,9 @@ import { apply, fromTodos, normalise, type Plan } from "../src/plan/plan.ts"
|
||||
import { ToolCallAccumulator } from "../src/provider/openai-chat.ts"
|
||||
import { parseInfo, titleFor } from "../src/prototype/fence.ts"
|
||||
import { resolveBase } from "../src/library/store.ts"
|
||||
import { NarrowError, narrowParameters, type Narrow } from "../src/harness.ts"
|
||||
import { fillPrompt } from "../src/prompt/fill.ts"
|
||||
import { applyOps, type Op, type Target } from "../src/memory/store.ts"
|
||||
|
||||
type Case = Record<string, unknown>
|
||||
|
||||
@@ -71,6 +74,26 @@ export const AREAS: Record<string, (c: Case) => unknown> = {
|
||||
const info = parseInfo(c.info as string)
|
||||
return info ? { kind: info.kind, title: titleFor(c.code as string, info.title) } : null
|
||||
},
|
||||
fill: (c) => {
|
||||
try {
|
||||
return { text: fillPrompt(c.text as string, c.vars as Record<string, string>) }
|
||||
} catch (e) {
|
||||
// "prompt: no value for {{a}}, {{c}}": the names, sorted.
|
||||
return { missing: [...(e as Error).message.matchAll(/\{\{(\w+)\}\}/g)].map((m) => m[1]!).sort() }
|
||||
}
|
||||
},
|
||||
narrow: (c) => {
|
||||
try {
|
||||
return { parameters: narrowParameters(c.parameters as Record<string, unknown>, c.narrow as Narrow) }
|
||||
} catch (e) {
|
||||
if (e instanceof NarrowError) return { error: e.code }
|
||||
throw e
|
||||
}
|
||||
},
|
||||
memory: (c) => {
|
||||
const r = applyOps(c.target as Target, c.entries as string[], c.ops as Op[], c.limit as number)
|
||||
return { ok: r.ok, entries: r.ok ? r.after : c.entries, message: r.message, usage: r.usage, shown: Boolean(r.entries) }
|
||||
},
|
||||
library_scope: (c) => resolveBase(c.bases as { id: string; name: string }[], c.base as string | null),
|
||||
toolcall_index: (c) => {
|
||||
// The deltas as the OpenAI stream carries them: `function.name` and `function.arguments`.
|
||||
|
||||
Reference in new issue
Block a user