Harness spec 3.2.0 in the CLI: effort levels, reasoning round-trip, no absolute paths
ci / check (push) Waiting to run
ci / check (push) Waiting to run
Levels (models/schema.json levels): provider/effort.ts levelsOf/levelFields/ readLevel — `off` only with thinking_switch and sends enable_thinking false and no effort, `default` for a model that takes no efforts and sends nothing, a level not offered is read as the start level. The engine's effort is a level; /effort shows nothing for one level, a Thinking switch for [off, X], a list otherwise; the status bar follows. /v1/models' thinking_switch, efforts [] and capacity.parallel are read (lembas/webui.ts); session/capacity.ts counts parallel slots. Reasoning (context.md §8): an assistant message of the current turn carries reasoning_content (provider/common.ts turnReasoning, openai-chat.ts); step-boundary deliveries, nudges and the wrap-up are marked turn: false and do not start a turn. Paths (context.md §11): the <env> block names the project and, started below the root, that directory relative to it (assemble.ts envLines); instruction files and @ attachments are named from the root or as ~/…; file tools and bash resolve relative paths against the project root. The team rules (team/team.ts) and conformance runners for levels, reasoning, paths and team; the team runtime follows. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
36 files changed
+1168
-153
No files matched your search
+10
-8
@@ -33,7 +33,8 @@ import { addPendingDeleted, clearPendingDeleted, pendingDeleted } from "./pendin
|
||||
import { shellLaunch } from "./shellrc.ts"
|
||||
import { sessionTurnFile, sessionTurns, TurnLog } from "./turns.ts"
|
||||
import { expandHome } from "../config/paths.ts"
|
||||
import { asMode, EFFORTS, MODES, type Effort, type Mode } from "../config/schema.ts"
|
||||
import { asMode, MODES, type Mode } from "../config/schema.ts"
|
||||
import { isLevel, readLevel, type Level } from "../provider/effort.ts"
|
||||
import { HARNESS_VERSION } from "../harness.ts"
|
||||
import { findProject, trustedRoots, trustedWithin, trustOf } from "../project/root.ts"
|
||||
import { VERSION } from "../version.ts"
|
||||
@@ -131,10 +132,10 @@ interface Terminal {
|
||||
/** Most terminals one link may hold at once. */
|
||||
const MAX_TERMINALS = 4
|
||||
|
||||
/** An effort as the instance sends it: a level, or "off"; anything else is not one. */
|
||||
export function effortOf(v: unknown): Effort | "off" | undefined {
|
||||
if (v === "off" || v === "" || v === null) return "off"
|
||||
return typeof v === "string" && (EFFORTS as readonly string[]).includes(v) ? (v as Effort) : undefined
|
||||
/** An effort level as the instance sends it (an effort, "off" or "default"); anything else is not
|
||||
* one. Whether the model offers it is the session's to decide (readLevel). */
|
||||
export function effortOf(v: unknown): Level | undefined {
|
||||
return isLevel(v) ? v : undefined
|
||||
}
|
||||
|
||||
const MODE_RANK: Record<Mode, number> = { auto: 0, edit: 1, manual: 2, plan: 3 }
|
||||
@@ -619,7 +620,7 @@ export class AcpAgent {
|
||||
sessionId: id,
|
||||
modes: { currentModeId: session.app.engine.mode, availableModes: this.modes().map((m) => ({ id: m, name: m })) },
|
||||
// `instance` (spec 3.0.0): the model is one this link's instance serves, as the model event says.
|
||||
_meta: { lembas: { model: session.app.engine.model.ref, mode: session.app.engine.mode, effort: session.app.engine.effort ?? "off", instance: this.isInstance(session.app.engine.model.connectionName) } },
|
||||
_meta: { lembas: { model: session.app.engine.model.ref, mode: session.app.engine.mode, effort: session.app.engine.effort, instance: this.isInstance(session.app.engine.model.connectionName) } },
|
||||
}
|
||||
}
|
||||
|
||||
@@ -672,8 +673,9 @@ export class AcpAgent {
|
||||
s.app.switchModel(ref)
|
||||
}
|
||||
const effort = effortOf(p?.effort)
|
||||
if (effort !== undefined) s.app.engine.effort = effort === "off" ? null : effort
|
||||
return { model: s.app.engine.model.ref, effort: s.app.engine.effort ?? "off" }
|
||||
// A level the model does not offer is read as its start level; the answer says the one used.
|
||||
if (effort !== undefined) s.app.engine.effort = readLevel(s.app.engine.model, effort)
|
||||
return { model: s.app.engine.model.ref, effort: s.app.engine.effort }
|
||||
}
|
||||
|
||||
private modes(): Mode[] {
|
||||
|
||||
Reference in new issue
Block a user