Documentation
¶
Overview ¶
Package agent runs the "propose" step: it gives the role's question to a coding agent and collects its proposals in out/intentions.yaml.
Index ¶
Constants ¶
const BlockScalars = "" /* 293-byte string literal not displayed */
BlockScalars is how a text holding code is written so that it reads: a plain text starting with a backtick, or holding `: ` or ` #`, does not (#138), and a block scalar takes code as it is, with no escaping. Said in the prompt, and again when an answer did not read.
const TokensRatio = "711 + 0.82 a character"
TokensRatio says the estimate, in the refusal.
Variables ¶
var ErrInvalidOutput = errors.New("agent answered without valid proposals")
ErrInvalidOutput means the agent answered, but not with proposals the engine can read. Its answer is dropped, as if it had proposed nothing.
var ErrOverBudget = errors.New("prompt too large")
ErrOverBudget means the prompt is over the role's context budget: the agent was not asked. What the task held is judged by no one this run, a finding for a person, never an error that stops the line.
ErrUnavailable means the agent could not be reached for a reason outside the role: quota, authentication, network, not installed. The run ends as blocked-external if the role cannot pass without it.
Functions ¶
func Mend ¶ added in v0.13.0
Mend fixes the slips that leave agents' answers unreadable or cut, before any YAML reader takes them, and says what it mended: code quoted with its tabs under a block scalar, when the answer fails on a tab (#157); a value opening on a quoted phrase and going on after it, when the answer fails there (#128); and a plain free text cut by ` #`, read whole (#156). The block's text and the line's are kept exactly as written; an answer that still does not read comes back as it came. Why and the rules: docs/spec/role-contract.md, "One run", step 3.
func Notice ¶
Notice records the model that answered call in file, and says so when it is not the one that answered the same question last time on this machine. A call that did not say what it asked or what answered is not recorded. It never fails a run: a file it cannot read or write only means no notice.
func Prompt ¶
Prompt assembles what the agent reads, in the contract's order: persona (returned apart, as the system prompt), knowledge, instruction, the task, the output contract, and the policy last.
func Seen ¶
func Seen() string
Seen is where a machine keeps the last exact model that answered for each model asked: an alias floats to a new generation on its own, and the evaluation's scores are worth something only for the model that earned them (docs/adr/0004-follow-model-aliases-and-measure.md). WORKLINE_MODELS_SEEN names another file.
func Tokens ¶ added in v0.19.0
Tokens estimates what a prompt of so many characters (bytes) costs, before the call, with no tokenizer: 711 + 0.82 a character. Fitted on ten real calls of the reviewer, Go code and diffs, Claude Sonnet and Opus, 87k to 117k characters (#147, roles/reviewer/docs/tried.md, 2026-10-06), within 2% of what Claude reported. On the documentalist's evaluation calls (Sonnet and Opus, 6k to 43k characters) it reads Markdown 5 to 15% high and C++ sources 10% low (#235): one ratio, code and prose alike, since prose here is far from four characters a token.
Types ¶
type Agent ¶
Agent answers the question in in/task.md by writing out/intentions.yaml, and says what answered, even when it fails.
func Parse ¶
Parse turns an agent spec into an agent. "none" (or "") returns nil: no agent.
none no AI; the role's without-ai rule applies
claude Claude Code, headless (claude -p), on the model the role's tier asks
claude:<model> on that model, whatever the tier: an alias (sonnet) or an exact id
claude:<model>@<effort>, claude:@<effort>
and at that effort (none, low, medium, high, max), whatever the role's
cmd:<script> runs <script> with sh -c: the prompt in, the proposals out (command.go)
fake:<file> replays the proposals in <file> (conformance tests)
unavailable:<reason> fails like an agent whose quota or login is gone
type Call ¶
type Call struct {
Agent string `json:"agent"`
Task string `json:"task,omitempty"` // the kind of task, when pre named one
For string `json:"for,omitempty"` // what it answered: a part (1-correctness), a judge's question (judge/03)
Tier string `json:"tier,omitempty"`
Effort string `json:"effort,omitempty"` // the role's level, before the agent maps it
Asked string `json:"asked,omitempty"` // the model named to the agent: an alias or an exact id
Model string `json:"model,omitempty"` // the one that wrote the answer, as the agent reports it
// What the call used, side calls included, as the agent reports it. On a
// subscription the tokens are what counts; the cost is the list price.
TokensIn int `json:"tokens-in,omitempty"` // the whole input, cache included
TokensCached int `json:"tokens-cached,omitempty"` // the part of it read from cache
TokensOut int `json:"tokens-out,omitempty"`
CostUSD float64 `json:"cost-usd,omitempty"`
Seconds float64 `json:"seconds"`
// Mended: what the engine fixed of the answer before reading it (Mend).
Mended []string `json:"mended,omitempty"`
}
Call records one question put to an agent: what was asked, and what answered. The same tier names a newer model when the agent's aliases move, so a score is only worth something next to the exact model.