Compare commits

...

1 Commits

Author SHA1 Message Date
Codex 66d4e6b93e Expose durable agent resume APIs
Harness (E2E) / Harnesses (mock LLM) (push) Waiting to run
Harness (E2E) / Provider harnesses (live LLM conformance) (push) Waiting to run
Lint / golangci-lint (push) Waiting to run
Run Tests / Unit Tests (push) Waiting to run
Run Tests / Etcd Integration Tests (push) Waiting to run
2026-06-29 01:35:51 +00:00
3 changed files with 61 additions and 3 deletions
+34 -1
View File
@@ -36,13 +36,46 @@ your stack — the harness *is* the stack.
| Discovery & RPC | Registry + client; agents and services find and call each other | Shipped |
| Interop | MCP (tools), A2A (agents), x402 (paid tools) | Shipped |
| Resilience | Per-call timeout with context propagation; opt-in retry/backoff (`ModelRetry`) across the loop | Shipped |
| Durable runs | Checkpoint and resume an agent run (flows already do) | In progress |
| Durable runs | Checkpoint and resume an agent run with the same checkpoint backend flows use | Shipped |
| Observability | `RunInfo` → OpenTelemetry spans for runs, model calls, tools, delegation, and failures; persisted run history | Shipped |
| Streaming | `ai.Stream` through chat, agent, and A2A | In progress |
The "in progress" rows are exactly the roadmap's [Now and Next](/docs/roadmap.html),
and the work is happening in the open.
## Durable agent runs
Agents can persist their execution history to the same `Checkpoint` backend as
flows. A checkpointed `Ask` records the run id, original prompt, model result,
and completed tool calls. If the process restarts after a tool succeeds but
before the model finishes, `AgentResume` continues the same run and returns the
recorded tool result instead of re-running the side effect. If a run already
completed, resume returns the persisted response without calling the model.
```go
agent := micro.NewAgent("conductor",
micro.AgentProvider("anthropic"),
micro.AgentWithCheckpoint(checkpoint),
)
resp, err := agent.Ask(ctx, "charge order 42 and send a receipt")
if err != nil {
// On startup, or after a transient failure, discover unfinished work:
pending, _ := micro.AgentPending(ctx, agent)
for _, run := range pending {
_, _ = micro.AgentResume(ctx, agent, run.ID)
}
}
_ = resp
```
For human-in-the-loop runs that pause through the built-in `request_input` tool,
resume with the operator's response:
```go
_, err := micro.AgentResumeInput(ctx, agent, runID, "Deploy to us-east-1")
```
## Observing agent runs
Pass an OpenTelemetry tracer provider when you construct an agent to turn the
+1 -2
View File
@@ -36,14 +36,13 @@ The priority is that what exists works everywhere, under real conditions.
## Next — agentic depth
- **Durable agent loop.** Flows resume; the agent's own loop does not yet. Reuse `Checkpoint` so a long-running agent survives a restart and continues.
- **Streaming.** Broaden provider-backed `ai.Stream` coverage and keep chat plus A2A `message/stream` working end to end for real chat and long-task UX.
- **Agent observability.** Wire the new `RunInfo` into OpenTelemetry spans so a run — steps, tool calls, delegation — is traceable. This is also what anyone running it in production will need.
## Later
- **Memory management** — summarization and retrieval (RAG) beyond a fixed buffer.
- **Human-in-the-loop** — pause and resume mid-run (`input-required`), beyond the binary `ApproveTool` gate.
- **Human-in-the-loop** — broaden pause/resume UX around `input-required` runs and approvals.
- **A2A** — richer live-stream reconnection (`tasks/resubscribe`) and `input-required` handoffs.
## Developer experience (ongoing)
+26
View File
@@ -23,12 +23,18 @@ type Service = service.Service
// Agent is the interface for an AI agent that manages services.
type Agent = agent.Agent
// AgentResponse is what an agent returns from Ask or a resumed run.
type AgentResponse = agent.Response
// AgentOption configures an Agent.
type AgentOption = agent.Option
// Flow is an event-driven LLM orchestration unit.
type Flow = flow.Flow
// FlowRun is a checkpointed flow or agent run record.
type FlowRun = flow.Run
// FlowOption configures a Flow.
type FlowOption = flow.Option
@@ -164,6 +170,26 @@ func AgentWrapTool(w ...ai.ToolWrapper) AgentOption {
// tool calls, delegation, and failures.
func AgentTraceProvider(tp trace.TracerProvider) AgentOption { return agent.TraceProvider(tp) }
// AgentWithCheckpoint sets the durability backend for agent Ask runs.
// It uses the same Checkpoint interface as flows so services, agents,
// and workflows can share one execution history backend.
func AgentWithCheckpoint(c Checkpoint) AgentOption { return agent.WithCheckpoint(c) }
// AgentPending returns checkpointed agent runs that have not completed.
// Use it at process startup to discover agent work that should be resumed.
func AgentPending(ctx context.Context, a Agent) ([]FlowRun, error) { return agent.Pending(ctx, a) }
// AgentResume resumes a checkpointed agent run by id. Completed runs return
// the persisted response without calling the model or replaying tool calls.
func AgentResume(ctx context.Context, a Agent, runID string) (*AgentResponse, error) {
return agent.Resume(ctx, a, runID)
}
// AgentResumeInput resumes a checkpointed agent run waiting for human input.
func AgentResumeInput(ctx context.Context, a Agent, runID, input string) (*AgentResponse, error) {
return agent.ResumeInput(ctx, a, runID, input)
}
// NewFlow creates an event-driven LLM orchestration unit.
//
// f := micro.NewFlow("onboard-user",