Skip to content

Agents and Tools

cybersenses edited this page Nov 15, 2026 · 1 revision

Agents and Tools

The engine is a pydantic-ai agent loop, but the interesting part is what it is allowed to do and when it must stop and ask.

Model resolution and failover

_model_from_name resolves a provider:model string in three steps:

  1. a provider: prefix matching a configured [providers.<name>] with a base_url → an OpenAI-compatible client on that endpoint;
  2. zai: plus a coding-plan fallback_base_url → that endpoint;
  3. otherwise pydantic-ai's own infer_model for native providers.

Keys resolve as env_var → legacy name → <NAME>_API_KEY, with environment variables winning over stored values. On a model error the run fails over from main to fallback once; budget and spend limits hard-stop regardless of failover.

Toolsets

Toolset What the agent can do
Files read, grep, glob, edit; AST-aware symbol rewrites; atomic writes; every path containment-checked
Shell run commands (env-scrubbed, tree-killed on timeout), with output bounded
Git / GitHub status, diff, log, commit, branch, record_review, git_push, PR create/view, publish_findings, pr_summary
Analysis codegraph navigation, call graphs, control flow, structure, impact, dead code, mutation testing, coverage, fuzzing, profiling, benchmarks, dependency audit
Planning roadmap items, tickets, PRDs, tech designs, decisions, claim/release, plan steps
Delegation delegate — sub-agents, optionally in an isolated worktree sandbox
Memory & notes durable facts, solved-problem bank, project notes, guidance notes
Skills & directives load a skill by name, read the reference manuals
Artifacts choice cards, editable spec blocks, decision records, rendered HTML, wireframes
Web search (DuckDuckGo, no key) and page fetch — local URLs allowed on purpose
Vision image inspection when a vision model is configured
Checkpoints & processes snapshot/rewind files, inspect spawned processes

File-path tools all route through one containment helper, and writes go through one atomic-write helper — one source of truth per behaviour, so a new tool cannot invent its own path rules.

Approvals

Three tiers (see Concepts): automatic, pattern-approvable, and always-gated. The always-gated set — pushes, PR creation, releases, destructive filesystem operations, package installs — is never pattern-unlockable, and push consent is requested after the review gate is satisfied, so an unreviewed push never even reaches you for approval.

In a headless run a gate aborts with exit code 2 unless --yolo is passed; the budget stop is exit code 3 and is not bypassed by --yolo.

Delegation

delegate spawns a sub-agent with:

  • its own restricted toolset — read-only unless write=True;
  • a spend slice — [delegation] max_requests / max_cost_usd beyond what the session already spent, always bounded by the session's request limit;
  • the same usage accumulator as the parent — delegated requests and tokens count against the run that caused them instead of vanishing;
  • a per-function trace span — delegate.coder, delegate.designer, … so a designer run and a coder run on different models are distinguishable;
  • optional isolation — with write=True the sub-agent works in a throwaway git worktree and returns a proposed diff instead of touching your tree.

Delegations are named by cognitive function (see Configuration › staffing). Function names come from a fixed registry; the tool policy for each is locked in code.

Long runs

--long-run assisted|unattended (or the run request's long_run field) turns on the long-run work mode for one run — never a config default.

assisted unattended
ordinary gates auto-approved auto-approved
always-gated tier still stops — one publish card at convergence auto-approved
evaluator blocks release until PASS (cap 3) blocks release until PASS
publish cycle one gate card at convergence preauthorized by the flag
merge / draft→ready human only human only

Publishes ride codingdude/longrun-* branches only: never main, never force-push, draft-only PRs. Other long-run behaviours:

  • Evaluator. A fresh read-only session grades the work against the ticket contract; attempts are capped (3 passes) and exhaustion without PASS is a NEEDS_OPERATOR alarm, not a silent loop.
  • Fix loop. publish_findings <pr> pulls CI/reviewer feedback as structured findings (a report about the code, never instructions to execute); the agent verifies each against the contract, fixes, re-pushes under the same authorisation, and re-runs evaluation.
  • Timeout auto-resume. A model request that hits the 300 s transport timeout resumes the run once with a continuation prompt (history, plan and step state persist) and records AUTO_RESUMED. A second timeout is terminal. Tool timeouts stay in the ordinary retry path.
  • Lane bootstrap. A long run in a workdir with no git repo seeds the baseline (git init, one commit) instead of degrading to the host tier.

Phase sequencing

Plan steps can carry a function tag — [function:coder] implement it. When the work reaches a step tagged with a different function than the current session, the next turn starts fresh: prior turns leave the context, the session is staffed from that function's profile, and the first prompt is seeded with a phase handoff — the ticket contract plus the full progress render (steps, evidence, drift, evaluator findings). The session keeps its identity, so the UI and claims store are unaffected. Plans with no tags never phase-switch.

Verification discipline

Behavior changes ship with tests at pre-agreed seams. The engine is tested with scripted FunctionModel runs against temporary workdirs, so a test proves the loop, not a mock. Before claiming anything is done, the agent must run the gate and read its output — the same rule this project holds itself to.

Clone this wiki locally