Agent feature roadmap¶
The five v1.0 agent primitives — agents, mailboxes, supervisors, protocols, budgets — are sufficient for the kinds of programs the canonical examples and demos exercise. The features below are the next layer: instruments and integrations that make a Mighty agent system production-grade.
This document is a forward-looking plan, not a spec. Each item is sized roughly so the v0.16+ integrator can pull from it without re-doing the design work.
Tier 1 — production observability + reload (v0.16 candidates)¶
agent.introspect() + mty inspect <pid> CLI¶
Runtime exposes a snapshot view of any live agent:
- agent name, type, supervisor parent
- mailbox depth (current + high-water)
- in-flight handler (if any) + elapsed wall time
- budget state (memory used, ticks used, deadline)
- last N messages handled (ring buffer; opt-in to capture bodies)
Wire shape: a __inspect system message every agent answers
without going through the handler dispatch. CLI: mty inspect
<sock-or-pid> connects to the runtime's local control socket (new
opt-in RUNTIME_CONTROL_SOCK env var) and pretty-prints the
snapshot.
Stretch: a mty top mode that polls every 1s and shows the
worker-by-worker schedule.
OpenTelemetry agent spans¶
opentelemetry-otlp is already a workspace dep. Auto-instrument:
spawn— span nameagent.spawn, attributeagent.typesend— link-only span (one-way); attributeprotocol.msgask— full span; child of caller; closed when reply arrivessupervise.restart— event on the supervisor's spanbudget.exhausted— event with reason
Off by default. Enable via MTY_OTLP_ENDPOINT=... env or
[telemetry] block in mighty.toml. The handler-span context is
threaded through the runtime's task-local store so user code can
add child spans.
Live diagnostic logs¶
Every agent already has access to log(). Add structured
counterpart: agent.event(name: &str, fields: &[(&str, &str)])
that emits a typed event into the OTEL pipeline (or stdout when no
OTLP). Tested against wasi:logging@0.2.x shape so it round-trips
through the Component Model unchanged.
Tier 2 — debugger-grade recording (v0.17 candidates)¶
Deterministic replay¶
Mighty already supports a deterministic-execution mode. Extend it to record:
- every external IO event (file reads, network reads, clock reads,
random reads — anything from the
wasi:*import surface) - every message exchanged on every mailbox
Output: a mty-trace-<timestamp>.bin file (compact wire format,
likely cbor or postcard). Re-run with mty replay
trace-<timestamp>.bin produces byte-identical output. Backed
agent-by-agent so a sub-graph can be re-played in isolation for
debugging.
Step debugger over the trace¶
mty debug trace.bin enters a REPL:
stepadvances one message dispatchpeek <agent>shows current stateprint msgshows the in-flight messagebtshows the call chain (supervisor → spawn → handler)
This piggybacks on the existing DWARF source maps so the user sees Mighty-source-level positions, not MtyIR.
Tier 3 — hot reload (v0.17 / v0.18 candidates)¶
State-preserving code swap¶
mty reload <agent-type> --from new.wasm:
- Drain the agent's current handler to completion (deadline enforced)
- Serialise the agent state via a derived
Resumabletrait (new in stdlib) - Stop the agent
- Load the new wasm module, spawn an agent of the same type
- Deserialise the state into the new agent
- Reattach the mailbox; resume
Constraint: the Resumable trait derive checks that the state
shape is forward-compatible — fields can be added or removed but
not renamed in conflicting ways. The runtime refuses the swap if
the new version's Resumable::SCHEMA_HASH is incompatible with
the recorded snapshot's hash.
This unblocks long-running services (a backend server can update its handlers without dropping connections, because connection sockets live in the supervisor's external state, not the agent's).
Tier 4 — distributed agents (v0.19+)¶
Single-cluster mesh¶
- Agent addresses become
node:type:pidinstead oftype:pid send/askcross node boundaries transparently- Wire protocol: framed cbor over TLS (rustls already in tree)
- Initial topology: static peer list in
mighty.toml[cluster.peers]
Cluster supervisor¶
A supervisor can have children on remote nodes. The supervisor
strategy (one-for-one, etc.) applies across the cluster. Node
failure marks all of that node's children as :noproc, triggering
the supervisor's restart policy.
Lossless live migration¶
(Already on the README's Post-v1.0 roadmap.) Building on Tier 3
(state-preserving reload) + Tier 4 (cluster), an agent can move
between nodes while preserving its mailbox and continuation. A
migrate(node) call drains, snapshots, ships the snapshot over
the cluster wire, restores on the target.
Tier 5 — agent composition primitives (any v0.16+)¶
pipe! macro for handler chains¶
pipe!(A, B, C) wires A → B → C so each agent's response is
fed to the next. Backpressure built in: if B's mailbox is full,
A blocks (or drops, configurable). Simpler than hand-wiring
supervisors for ETL-style workloads.
broadcast! macro for fan-out¶
broadcast!(msg, [a1, a2, a3]) sends msg to all listed
mailboxes in parallel. Returns a JoinHandle[Vec[Reply]] for
gather.
circuit_breaker agent¶
Supervisor variant that opens a breaker after N failures in a
sliding window. While open, all send to its children fail-fast
with :circuit_open. After a cooldown, half-open probes one
message; on success closes the breaker.
What ships when¶
| Tier | Items | Status |
|---|---|---|
| 1 | introspect, OTel spans, agent events | SHIPPED v0.16 |
| 2 | record + replay + step debugger | SHIPPED v0.17 → v0.19 (byte-identical replay end-to-end) |
| 3 | hot reload + Resumable trait | SHIPPED v0.17 → v0.21 (wasm-bytes swap + schema migrations + condvar drain + control-socket op=reload all live) |
| 4 | single-cluster mesh | SHIPPED v0.18 → v0.19 (cross-node send/ask, framed CBOR-over-TLS) |
| 4 | cluster supervisor | SHIPPED v0.20 (OneForOne/RestForOne/OneForAll + per-child circuit breaker) |
| 4 | lossless live migration | SHIPPED v0.21 (RFC-006: MigrationOrchestrator + 3 placement policies + OTel cluster metrics) |
| 5 | per-message work-stealing | SHIPPED v0.22 (crossbeam-deque per-worker queues + NUMA-locality steal ordering + worker.steals_total{src,dst} OTel counter) |
| 5 | pipe/broadcast/circuit-breaker | drop-in helpers — not roadmap blockers |
| post-v1.0 | std.eval replay-driven LLM eval harness |
SHIPPED v0.28 Track G (Suite/Case/Member/Compare builder on top of the v0.21 replay machinery; three comparators — Equal, SemanticSimilarity, ToolCallSetEqual — with per-cell verdicts + divergence reporting. See docs/internals/std-eval.md.) |
Every Tier in the roadmap has now landed pre-v1.0. What
remains for v1.0 GA is RFC comment-window disposition collection
(blocker #2 in the README Roadmap section), the polish items
tracked in the repo-level CHANGELOG.md's [Unreleased] block
(BOLT post-link optimisation, multi-socket NUMA benchmark,
mty conform CLI shim, v1.0-RC validation sweep, MT3012 closure
pending HIR CONST_DECL lowering), and Tier-5 pipe/broadcast/
circuit-breaker helpers which are drop-in additions rather than
roadmap blockers.
Open questions¶
-
Wire stability. Once the introspection wire format ships, the
mty inspectclient / server contract becomes a compatibility surface. Version it from day one (aversion: u32field on every introspection reply). -
Privacy. The introspection snapshot can carry mailbox bodies (per opt-in). When OTel is also enabled, the spans can include message attributes. Document the capability boundary: a process with the
introspectcapability sees everything; without it, only public counters. -
Wasm Component Model implications. Components run in isolation by default. Cross-component agent communication through
askshould lower to a typed interface in the component world. This is a follow-up to the v0.13/v0.14 WASI Preview 2 work — likely needs an RFC of its own.