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>
This commit is contained in:
@@ -0,0 +1,50 @@
|
||||
# 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.
|
||||
@@ -17,3 +17,4 @@ One decision per file, append-only; supersede rather than rewrite.
|
||||
| [0011](0011-google-provider.md) | Google provider on the official Gen AI SDK | Accepted |
|
||||
| [0012](0012-agent-loop.md) | Agent run loop | Accepted |
|
||||
| [0013](0013-skill-model.md) | Skill model — additive instruction+tool bundles | Accepted |
|
||||
| [0014](0014-conversion-driven-extensions.md) | Conversion-driven extensions (resolvers, typed tools, hooks, ops controls) | Accepted |
|
||||
|
||||
Reference in New Issue
Block a user