feat: agent run loop, Generate[T], reflect-derived schemas
Phase 5: - agent/: model + system prompt + toolboxes composition; bounded tool-dispatch loop (default 10 steps); panic-proof tool execution; unknown-tool and duplicate-name handling; history continuation; step observers; partial results on ErrMaxSteps/errors (ADR-0012) - llm.SchemaFor[T]: strict-compatible JSON schemas from Go types (nullable pointers, description/enum tags, recursion rejected) - majordomo.Generate[T]: typed structured output with fence-stripping decode and model-naming errors - README agents/structured-output sections + matrix synced Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,53 @@
|
||||
# ADR-0012: Agent run loop
|
||||
|
||||
**Status:** Accepted — 2026-06-10
|
||||
|
||||
## Context
|
||||
|
||||
Agents are the consumer-facing composition: Model + system prompt +
|
||||
toolboxes (+ skills), run as a tool-dispatch loop. mort's agents need
|
||||
multi-step tool use, bounded loops, per-step observation (tracing/usage
|
||||
recording), conversation continuation, and a loop that survives every tool
|
||||
failure.
|
||||
|
||||
## Decision
|
||||
|
||||
- `agent.New(model, system, opts...)` with options WithToolbox, WithTools,
|
||||
WithSkill, WithMaxSteps (default 10), WithRequestOptions (per-step
|
||||
generation knobs), WithStepObserver. `AddSkill`/`AddToolbox` extend an
|
||||
agent after construction (configure-then-share concurrency contract).
|
||||
- `Run(ctx, input, opts...)`: history seeds via WithHistory (a previous
|
||||
`Result.Messages` round-trips), per-run request options, per-run OnStep
|
||||
callbacks. The loop: Generate with the merged toolset → no tool calls =
|
||||
final answer → otherwise execute calls sequentially, append the
|
||||
assistant turn + one RoleTool message, repeat.
|
||||
- **Never panics, never stalls on tool failure:** handlers run through
|
||||
`llm.ExecuteTool` (panic-recovering, errors → IsError results); unknown
|
||||
tool names come back as IsError results the model can react to; observer
|
||||
panics are swallowed. Only model errors (already retried/failed-over by
|
||||
the chain) and ctx cancellation abort the run — and even then the
|
||||
partial `Result` (transcript, steps, usage) is returned alongside the
|
||||
error, as it is on ErrMaxSteps.
|
||||
- **Duplicate tool names across toolboxes/skills fail loudly at Run** —
|
||||
a silently shadowed tool is a debugging trap.
|
||||
- Skills compose additively (the `agent.Skill` interface lives in this
|
||||
package so agent does not import skill): `Instructions()` append to the
|
||||
system prompt in attachment order; `Tools()` join the merged toolset.
|
||||
- **Intermediate-step streaming = step observers** (agent-level and
|
||||
per-run), invoked synchronously after every step with the response and
|
||||
tool results. Token-level streaming inside the loop was deliberately
|
||||
deferred: tool-heavy steps end on buffered tool calls anyway, and mort's
|
||||
observers (trace/usage recorders) want completed steps. `Model.Stream`
|
||||
remains available for direct streaming outside the loop.
|
||||
- `Generate[T]` + `llm.SchemaFor[T]` give typed structured output:
|
||||
reflect-derived schemas (strict-compatible: all properties required,
|
||||
additionalProperties:false, pointers → nullable anyOf), markdown-fence
|
||||
stripping as a decode fallback, errors that name the serving model.
|
||||
|
||||
## Consequences
|
||||
|
||||
- An agent over a failover chain inherits retry/backoff/media
|
||||
normalization transparently — no agent-level error handling for
|
||||
transient provider trouble.
|
||||
- Sequential tool execution is deterministic and trace-friendly; parallel
|
||||
dispatch can be added later behind an option without API change.
|
||||
@@ -15,3 +15,4 @@ One decision per file, append-only; supersede rather than rewrite.
|
||||
| [0009](0009-multimodal-strategy.md) | Multimodal strategy — normalize per target, enforce at provider | Accepted |
|
||||
| [0010](0010-tools-structured-output-mapping.md) | Tools and structured output — canonical shape, native mappings | Accepted |
|
||||
| [0011](0011-google-provider.md) | Google provider on the official Gen AI SDK | Accepted |
|
||||
| [0012](0012-agent-loop.md) | Agent run loop | Accepted |
|
||||
|
||||
Reference in New Issue
Block a user