Files
majordomo/docs/adr/0014-conversion-driven-extensions.md
T
steve 0147a79d18
CI / Tidy (push) Successful in 9m31s
CI / Build & Test (push) Successful in 10m13s
feat: conversion-driven extensions — resolvers, DefineTool, hooks, ops controls
Phase 9a (ADR-0014): Registry.RegisterResolver for dynamic tiers;
DefineTool[Args] typed tools; Usage cache/reasoning detail fields wired
through anthropic/openai/google; WithPromptCaching (Anthropic
cache_control); agent supervision hooks (WithMaxStepsFunc, WithSteer,
WithCompactor, WithToolErrorLimits + ErrToolLoop); health
Bench/Unbench/Snapshot; ChainConfig.Observer failover events.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-06-10 13:30:06 +02:00

51 lines
2.6 KiB
Markdown

# ADR-0014: Conversion-driven extensions (resolvers, typed tools, hooks, ops controls)
**Status:** Accepted — 2026-06-10
## Context
Executing the mort conversion (docs/mort-migration.md) surfaced seven
capabilities mort's orchestration layer needs from its model substrate.
Each is general-purpose — none encodes anything mort-specific — and each
was promised in the migration blueprint.
## Decision
1. **`Registry.RegisterResolver`** — dynamic alias resolution for DB/
config-backed tiers. Checked after static aliases (static wins), in
registration order, without holding the registry lock (resolvers do
I/O); output expands recursively under the existing cycle guard.
2. **`DefineTool[Args]`** — typed tools: parameters from `SchemaFor[Args]`,
arguments unmarshaled before the handler. Schema failure panics
(startup-time programming error, mirroring NewToolbox).
3. **`Usage` detail fields** — CacheReadTokens / CacheWriteTokens /
ReasoningTokens, populated where providers report them (Anthropic cache
fields; OpenAI prompt/completion detail objects; Google cached-content
+ thoughts). Input/Output remain totals; details are portions.
4. **`WithPromptCaching`** — Anthropic top-level `cache_control`
auto-placement; a no-op for providers that cache implicitly or not at
all.
5. **Agent loop hooks**`WithMaxStepsFunc` (dynamic ceiling, consulted
every step, for supervisor budget adjustment), `WithSteer` (per-run
message injection drained before each step), `WithCompactor`
(pre-Generate transcript transformation; errors fall back to the
original — losing a request to a broken summarizer is worse than a long
prompt), `WithToolErrorLimits` (consecutive all-error steps and
identical-call repeats end the run with `ErrToolLoop` + partial result).
The canonical transcript in `Result.Messages` is always the
uncompacted truth; compaction affects only what is sent.
6. **Manual health controls**`Tracker.Bench/Unbench/Snapshot` for
ops surfaces (".failover bench" commands, dashboards).
7. **`ChainConfig.Observer`** — one synchronous callback per failover
decision (failed attempt with classification, bench, benched-skip).
This is a hook, not an observability stack; persistence/metrics remain
the consumer's business (anti-creep guardrail intact).
## Consequences
- mort's tier resolver, `.failover` admin surface, failover-event log,
run-critic budget control, steering, and compaction all rebase onto
public API.
- The agent loop gains supervision points without changing its
never-panic, partial-result-on-error contract.