Documentation
¶
Overview ¶
Package checkpoint defines the Checkpoint entity for human-in-the-loop control.
Index ¶
Constants ¶
const KindDeferredModelCall = "deferred_model_call"
KindDeferredModelCall is the MetadataKind of a checkpoint opened because the model client deferred a call (cortex.DeferredModelCallError). Such a checkpoint has no pending tool calls. An approval continues the run with the same model call; a rejection stops the run with the decision's reason. A decision that carries Calls or AmendedArguments is refused with cortex.ErrInvalidDecision.
const MetadataDeferralKind = "deferral_kind"
MetadataDeferralKind is the metadata key that carries cortex.DeferredModelCallError.Kind on a deferred model call's checkpoint.
const MetadataKind = "kind"
MetadataKind is the metadata key that names what a checkpoint the engine opened is waiting on. It is set to KindDeferredModelCall on a checkpoint opened for a deferred model call, and absent on a tool approval.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type CallDecision ¶ added in v1.10.6
type CallDecision struct {
// Approved runs the call. A call that is not approved is rejected
// and answered with Reason.
Approved bool `json:"approved"`
// AmendedArguments, on an approved call, replace the whole argument
// object the call runs with. They must be a JSON object. A rejected
// call ignores them.
AmendedArguments json.RawMessage `json:"amended_arguments,omitempty"`
// Reason is what the model reads when the call is rejected.
Reason string `json:"reason,omitempty"`
}
CallDecision is the outcome of one pending tool call within a Decision.
type Checkpoint ¶
type Checkpoint struct {
cortex.Entity
ID id.CheckpointID `json:"id"`
RunID id.AgentRunID `json:"run_id"`
AgentID id.AgentID `json:"agent_id"`
Scope cortex.Scope `json:"scope"`
Reason string `json:"reason"`
StepIndex int `json:"step_index"`
State string `json:"state"`
Decision *Decision `json:"decision,omitempty"`
Metadata map[string]any `json:"metadata,omitempty"`
}
Checkpoint represents a point where a run pauses for approval.
func PublicList ¶ added in v1.10.0
func PublicList(cps []*Checkpoint) []*Checkpoint
PublicList applies Public to every checkpoint in cps.
func (*Checkpoint) Public ¶ added in v1.10.0
func (c *Checkpoint) Public() *Checkpoint
Public is a copy of c for a reader outside the engine, such as an API response or a dashboard. It drops Decision.DecidedByPrincipal: the store keeps the decider's codec bytes as the record of who decided, and they are the host's own, so no reader of the checkpoint gets them.
type Decision ¶
type Decision struct {
Approved bool `json:"approved"`
DecidedBy string `json:"decided_by,omitempty"`
Reason string `json:"reason,omitempty"`
DecidedAt time.Time `json:"decided_at"`
// DecidedByPrincipal is the decider's principal, as the engine's
// cortex.PrincipalCodec encoded it. ResolveCheckpoint fills it from
// the context and overwrites whatever the caller supplied. It records
// who decided; the run itself continues under its own principal.
//
// It is serialized because the SQL stores persist a decision as JSON.
// Anything that serves a checkpoint to a reader goes through
// Checkpoint.Public, which drops it.
DecidedByPrincipal []byte `json:"decided_by_principal,omitempty"`
// AmendedArguments, on an approval, are the arguments the suspended
// call runs with instead of the model's. They replace the whole
// argument object, nothing is merged. They must be a JSON object, and
// the suspension must hold exactly one pending call, or the decision
// is refused with cortex.ErrInvalidDecision. The engine does not
// validate them against the tool's schema; that is the caller's job.
// A rejection ignores them and does not record them.
AmendedArguments json.RawMessage `json:"amended_arguments,omitempty"`
// Calls decides each pending tool call on its own, keyed by the
// pending call's id. When it is set, Approved is derived (true when
// any call is approved), AmendedArguments must be empty, and every
// pending call must have an entry and every entry must name a
// pending call, or the decision is refused with
// cortex.ErrInvalidDecision. A rejected call's Reason is what the
// model reads for that call. When it is empty, Approved and
// AmendedArguments decide every pending call together.
Calls map[string]CallDecision `json:"calls,omitempty"`
}
Decision represents the resolution of a checkpoint.
type ListFilter ¶
ListFilter controls pagination for checkpoint listing.
type Store ¶
type Store interface {
CreateCheckpoint(ctx context.Context, cp *Checkpoint) error
GetCheckpoint(ctx context.Context, cpID id.CheckpointID) (*Checkpoint, error)
// Resolve records decision on a pending checkpoint at the caller's
// exact scope. A checkpoint that is no longer pending keeps its first
// decision and Resolve returns an error wrapping cortex.ErrInvalidState;
// one that does not exist there is cortex.ErrCheckpointNotFound.
Resolve(ctx context.Context, cpID id.CheckpointID, decision Decision) error
ListPending(ctx context.Context, filter *ListFilter) ([]*Checkpoint, error)
CountPending(ctx context.Context, filter *ListFilter) (int64, error)
}
Store defines persistence for checkpoints.
type SweepStore ¶ added in v1.10.0
type SweepStore interface {
// ListPendingAcrossScopes lists pending checkpoints whose id sorts
// after the given one, in id order, at most limit. A nil id starts
// from the first. It deliberately bypasses scope, for the sweeper
// only, which acts on each checkpoint under that checkpoint's own
// scope.
ListPendingAcrossScopes(ctx context.Context, after id.CheckpointID, limit int) ([]*Checkpoint, error)
}
SweepStore is an optional capability of checkpoint stores, for the engine sweeper. It finds pending checkpoints that no decision will ever reach, such as one whose run has ended or moved on to another pause.