Agent.define(config) takes the Loop core minus everything
that serves convergence — no verify, no rounds, no Lock, no Record, no Persist —
and agent.run() runs Execute once and returns.
run accepts the other’s config.
AgentConfig
Onlygoal is required.
| Field | Type | Default | Meaning |
|---|---|---|---|
goal | Prompt | required | The objective — same Prompt shape as a Loop’s. |
execute | Prompt | { prompt?: Prompt; model?: string; permissions?: Permissions } | — | The Execute binding — a bare Prompt is shorthand for { prompt }. Prompt omitted → the Goal stands in. |
limits | AgentLimits | usd: 1, timeout: "5m" | usd and timeout only — no convergence, so no rounds. |
permissions | Permissions | "auto" | Same Permissions values as a Loop’s Execute phase. |
workspace | string | "./workspace" | Points the work tree elsewhere. |
agent.run
run(options?) returns an AgentRun — the same handle shape as a Loop’s Run, over the
Agent’s leaner event and exit types:
fresh, force, rounds, or deadline — there is nothing to resume, take over, or
slice. Startup failures never include LoopBusy (there is no Lock); if two Agent runs
share a Workspace, serializing them is the caller’s job.
AgentExit
finished: true means the agent reached a terminal stop — ungraded, not a “done”
claim. Nothing judged the work; if “done” must be proven, that is what a
Loop is for.
AgentEvent
The stream is content + cost + a terminalexit — its own clean type, not a subset of
LoopEvent. There are no phases, so the envelope is a bare { seq }; there is no
phase-start and no verdict. The event kinds it shares with the Loop stream
(text, text-delta, reasoning, tool-call, tool-result, cost) carry the same
payloads — see Events.
No status()
An Agent run keeps no Record, so there is nothing to read back —AgentDefinition has no
status(). For a Loop’s disk snapshot, see definition.status.