Documentation
¶
Overview ¶
Package agentruntime runs application-owned task agents with durable ordered tool execution. It has no database, authentication, scheduler, or SDK-root dependency. Controls are model tools, never JavaScript capabilities.
A host scopes Store to one run and its conversation, and serializes all run attempts and session continuations using durable leases with fencing. Every SaveCheckpoint transaction must append Checkpoint.Append and replace the checkpoint atomically, rejecting a stale revision or expired lease. An exact retry of a committed revision is idempotent. LoadCheckpoint returns nil only for a fresh run; continuations use a fresh run checkpoint in the same session. Load returns the current compacted transcript. Compact must atomically advance the session's context window, retain audit history, and enforce the same lease. The runtime does not call Store.Append separately. No in-memory or no-op store is suitable for production.
Controller owns authority, child admission, durable budgets, cancellation and completion. Spawn and Continue must deduplicate by parent run plus model tool call ID and recover the same durable handle after interruption. Wait must persist its dependency and original deadline by that key before ErrWaiting, and be idempotent on resume. Complete must atomically reject active children and accept an identical reply idempotently: it can be called again after a crash. Other interrupted calls have unknown effects and are not replayed. Complete must leave the lease and checkpoint writable until the runtime's completed checkpoint commits. Only then may the host finalize the run and admit a session continuation. Ordinary control errors are model feedback; errors implementing tool.FatalToolError terminate the attempt. Context errors and all store/model/budget errors terminate the attempt without executing tail calls. Persisted tool arguments are exact dispatch data and can be sensitive; access to checkpoints requires the same protection as execution records.
BeforeModel reserves a durable hierarchical reasoning step before each model request, including compaction. The injected model wrapper accounts for all input and output tokens, including compaction and interrupted requests. The host enforces wall-clock deadlines across waits and restarts and cancels the supplied context on expiry or lease loss. Zero Steps means unlimited steps; no Sol runner defaults are applied. Host enforcement covers descendants too. A reservation is not atomic with model dispatch. An interruption after a successful BeforeModel can consume a step without a request; recovery reserves another step and can exhaust the remaining budget. PhaseModel alone cannot prove whether BeforeModel committed, so it must not bypass the budget gate.
ExecutorFactory is the existing chatruntime factory backed by jsexec in production. Each uninterrupted attempt allocates lazily and closes its realm on every exit. JavaScript heap state is never persisted or reconstructed by replaying completed calls. Models must use transcript results for durable data. All dependencies, including Redactor, are required; a host with no secrets supplies an explicit identity redactor. Backend must redact callback results before they cross into JavaScript. Runtime redacts transcript and sink text. Executor close failures after acknowledged completion are returned in Result.CleanupError with a nil execution error. The host logs that diagnostic without failing the completed run. On unfinished or waiting exits, cleanup failures remain in the returned error chain; waiting Results also expose the diagnostic separately. Cleanup diagnostics are not checkpoint state.
Index ¶
Constants ¶
This section is empty.
Variables ¶
var ErrWaiting = errors.New("agentruntime: waiting for agent calls")
ErrWaiting parks a run without completing it. Run returns both a Waiting result and this error. The host releases its worker and resumes on wakeup.
Functions ¶
This section is empty.
Types ¶
type Call ¶
type Call struct {
ID string `json:"id"`
Name string `json:"name"`
Input json.RawMessage `json:"input"`
Result *session.Message `json:"result,omitempty"`
}
Call records model order. Result is set only after the outcome is committed.
type Checkpoint ¶
type Checkpoint struct {
Version int `json:"version"`
Revision int64 `json:"revision"`
ContractHash string `json:"contractHash"`
Phase Phase `json:"phase"`
Response []session.Message `json:"response,omitempty"`
Calls []Call `json:"calls,omitempty"`
CallIDs []string `json:"callIds,omitempty"`
Next int `json:"next"`
Reply *wire.AgentReply `json:"reply,omitempty"`
Append []session.Message `json:"append,omitempty"`
}
Checkpoint is a JSON-serializable journal scoped to one run, not its session. The host must preserve it verbatim and must not infer completion from Phase until the associated transaction commits. Version is currently 1.
type Controller ¶
type Controller interface {
BeforeModel(ctx context.Context) error
Spawn(ctx context.Context, toolCallID, definitionSlug string, input json.RawMessage) (wire.AgentRunInfo, error)
Continue(ctx context.Context, toolCallID, sessionID, prompt string) (wire.AgentRunInfo, error)
Get(ctx context.Context, ids []string) ([]wire.AgentRunInfo, error)
Wait(ctx context.Context, toolCallID string, request wire.AgentWaitRequest) (wire.AgentWaitResult, error)
Cancel(ctx context.Context, ids []string) (wire.AgentCancelResult, error)
Complete(ctx context.Context, reply wire.AgentReply) error
}
type Input ¶
type Input struct {
Definition wire.AgentDefinition
// Subagents supplies the exact contracts named by Definition.Subagents.
Subagents []wire.AgentDefinition
Message string
Model stream.Model
ModelLimits session.ModelLimits
Store Store
Capabilities []capability.Definition
Backend chatruntime.Backend
ExecutorFactory chatruntime.ExecutorFactory
Controller Controller
Sink eventstream.Sink
Redactor func(string) string
RecoveryNotice string
}
type Result ¶
type Result struct {
Reply *wire.AgentReply
Waiting bool
// CleanupError reports executor teardown failure separately from a durably
// committed reply. The host must log it without changing completed status.
// For waiting results it is also joined into Run's returned error. Unfinished
// runs without a Result report cleanup failure only in the returned error.
// This attempt-local diagnostic is not part of the durable checkpoint.
CleanupError error
}
type Store ¶
type Store interface {
session.SessionStore
LoadCheckpoint(context.Context) (*Checkpoint, error)
// SaveCheckpoint atomically appends Append and saves the checkpoint. Revision
// starts at 1 and increases by one. Reject stale writers; an identical retry
// of a committed revision must not append messages twice. Append is a commit
// payload, not a buffer to replay on LoadCheckpoint. See package documentation.
SaveCheckpoint(context.Context, *Checkpoint) error
}