durable

package
v0.2.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 30, 2026 License: Apache-2.0 Imports: 15 Imported by: 0

Documentation

Index

Constants

View Source
const (
	TopicEvents = "events"
	TopicRetry  = "retry"
)

EventLog topics. Temporal Workflow Streams uses the same names.

View Source
const SessionKindSpecialist = "specialist"

SessionKindSpecialist is Status.Kind for spawn_specialist children.

Variables

View Source
var (
	// ErrSessionNotFound is unknown, closed, or already torn down.
	ErrSessionNotFound = errors.New("session not found")
	// ErrSessionExists is CreateSession with an id that is already live.
	ErrSessionExists = errors.New("session already exists")
	// ErrAgentNotFound is Catalog miss.
	ErrAgentNotFound = errors.New("agent not found")
	// ErrStaleCheckpoint is SnapshotStore.Save when expected Revision does not
	// match the row (another writer already saved). Reload and retry.
	ErrStaleCheckpoint = errors.New("stale checkpoint")
)

Functions

func BindingsForTurn

func BindingsForTurn(recipes []MountRecipe, auth AuthContext) []vfs.Binding

BindingsForTurn builds the secret-bearing mounts for one activity/turn. Each cached recipe is included when a token for its provider is on auth.

func ChildState

func ChildState(st SessionState) string

ChildState is the tool-facing running/completed/failed for a session.

func ChildrenNudge

func ChildrenNudge(rows []SessionStatus) string

ChildrenNudge is injected when inference would complete while children remain.

func ClearSessionVFS

func ClearSessionVFS(Catalog, SessionID)

ClearSessionVFS is a no-op: user tokens live on the work item, not the catalog.

func CloseTurnTrees

func CloseTurnTrees(workspace, skills *vfs.MountSession, sessionID, reason string)

CloseTurnTrees closes the agent workspace tree and the host-only skills tree.

func CloseTurnVFS

func CloseTurnVFS(ms *vfs.MountSession, sessionID, reason string)

CloseTurnVFS unmounts a turn-scoped MountSession (FUSE telemetry, Close, host dir).

func EncodeUserState

func EncodeUserState(state map[string]any) (map[string]any, error)

EncodeUserState JSON-roundtrips host session state so checkpoint types are stable (numbers become float64) and non-serializable values fail now.

func MergeUserState

func MergeUserState(base, overlay map[string]any) map[string]any

MergeUserState copies overlay onto a clone of base. Overlay wins on conflict.

func NormalizeSpawn

func NormalizeSpawn(specialist, task string) (string, string, error)

NormalizeSpawn trims spawn_specialist arguments. Specialist is required; an empty task is allowed so a retry of the same callID can be idempotent.

func OpenSkillsVFS

func OpenSkillsVFS(ctx context.Context, threadID string, spec AgentSpec) (*vfs.MountSession, error)

OpenSkillsVFS builds the host-only skills MountSession from AgentSpec.OpenSkills. It does not attach a FUSE projection. The agent never receives this session.

func OpenTurnSessions

func OpenTurnSessions(ctx context.Context, threadID string, spec AgentSpec, bindings []vfs.Binding, proj vfs.Projection) (workspace, skills *vfs.MountSession, err error)

OpenTurnSessions opens the agent workspace and the host-only skills tree. On OpenSkills failure the workspace session is closed.

func OpenTurnVFS

func OpenTurnVFS(ctx context.Context, threadID string, spec AgentSpec, bindings []vfs.Binding, proj vfs.Projection) (*vfs.MountSession, error)

OpenTurnVFS builds the turn-scoped MountSession from AgentSpec.OpenVFS. Nil when OpenVFS is nil or the projection is unavailable.

func UnknownChild

func UnknownChild(id string) error

UnknownChild is get_child/cancel_child with an id that is not this session's child.

Types

type AgentSpec

type AgentSpec struct {
	Name string
	// Options is the canonical agent definition. SessionID and MountSession
	// must be empty; the runtime injects those per turn.
	Options tacklr.AgentOptions
	// OpenVFS builds the agent /workspace tree (typically vfs.Tree). Nil means no VFS.
	OpenVFS vfs.OpenVFS
	// OpenSkills builds a host-only skills tree (typically vfs.Tree with
	// Union of packs). The agent MountSession never includes this tree.
	// Nil means no skills unless Options.SkillsLoader is set.
	OpenSkills vfs.OpenVFS
	// SkillsRoot is the virtual directory the loader walks on the skills
	// session. Empty means /workspace/skills.
	SkillsRoot string
}

AgentSpec is the immutable agent definition. Runtime injects SessionID and MountSession per turn. Protocol-neutral: no server.Protocol types.

func OverlaySpecialist

func OverlaySpecialist(parent AgentSpec, specialist string) (AgentSpec, error)

OverlaySpecialist copies the parent catalog spec and applies the named Specialist. Nested specialists stay on the child spec so grandchild spawn is the same path.

type AuthContext

type AuthContext struct {
	// Bindings are this slice's mounts and/or provider tokens. A binding with
	// an alias upserts the recipe. A binding with only provider+token refreshes
	// every cached recipe for that provider.
	Bindings []vfs.Binding `json:"bindings,omitempty"`
	// Drop removes cached recipes by alias or provider. Applied before Bindings.
	Drop []string `json:"drop,omitempty"`
}

AuthContext is credentials and mount intent for one work item (Prompt, Resume, or a one-shot child workflow). Protocols map their wire auth into this type. Autonomous hosts set it on the payload that queues the work. Tokens are not stored in SnapshotStore.

type Catalog

type Catalog interface {
	Lookup(agentID string) (AgentSpec, bool)
	DefaultID() string
	IDs() []string
}

Catalog is the agent lookup table. Hosts construct it and pass it to inprocess.New or temporal.New. There is no backend plugin registry.

type CreateSession

type CreateSession struct {
	AgentID    string
	SessionID  SessionID
	MCPServers []mcp.MCPConfig
	// Mounts seeds the session recipe cache (no secrets). Tokens arrive on Prompt.
	Mounts []MountRecipe
	// Parent, when set, makes this a child session of that parent. The child
	// reuses the same wait loop. Empty MCPServers/Mounts inherit from parent.
	Parent SessionID
	// Specialist selects a Specialist from the parent's catalog spec. Required
	// with Parent for spawn_specialist children. The host does not register the
	// worker as a top-level catalog agent.
	Specialist string
	// State seeds host-owned session userState (JSON-serializable values).
	// Tools read it via HarnessRuntime.StateGet. It is checkpointed — do not
	// store tokens or clients. Child sessions do not inherit this map.
	State map[string]any
}

CreateSession is the typed input for Runtime.CreateSession.

type EventLog

type EventLog interface {
	Append(ctx context.Context, sessionID SessionID, topic string, ev tacklr.StreamEvent) error
	Subscribe(ctx context.Context, sessionID SessionID, after Seq) (<-chan tacklr.StreamEvent, error)
	Head(ctx context.Context, sessionID SessionID) (Seq, error)
	CloseSession(ctx context.Context, sessionID SessionID) error
}

EventLog is the portable progress stream. Temporal implements it with Workflow Streams. In-process uses a memory channel. Topics are TopicEvents and TopicRetry (activity attempt > 1).

type MemoryCatalog

type MemoryCatalog struct {
	// contains filtered or unexported fields
}

MemoryCatalog is an in-process Catalog.

func NewCatalog

func NewCatalog(defaultID string) *MemoryCatalog

NewCatalog returns an empty catalog. defaultID may be empty.

func (*MemoryCatalog) DefaultID

func (c *MemoryCatalog) DefaultID() string

DefaultID implements Catalog.

func (*MemoryCatalog) IDs

func (c *MemoryCatalog) IDs() []string

IDs implements Catalog.

func (*MemoryCatalog) Lookup

func (c *MemoryCatalog) Lookup(agentID string) (AgentSpec, bool)

Lookup implements Catalog.

func (*MemoryCatalog) Register

func (c *MemoryCatalog) Register(agentID string, spec AgentSpec)

Register adds or replaces an agent. Panics on invalid spec (host misconfig).

type MountRecipe

type MountRecipe struct {
	Provider  string            `json:"provider"`
	Alias     string            `json:"alias"`
	Params    map[string]string `json:"params,omitempty"`
	SourceIDs []string          `json:"sourceIds,omitempty"`
	Writable  bool              `json:"writable,omitempty"`
}

MountRecipe is secret-free VFS context remembered across turns. It records where a mount came from (provider, alias, backend ids). File contents are never stored; providers lazy-load on open/read.

func ApplyAuth

func ApplyAuth(recipes []MountRecipe, auth AuthContext) []MountRecipe

ApplyAuth updates cached recipes from a work-item AuthContext. Drop is applied first. Bindings with an alias upsert that recipe. Tokens are not stored on the returned recipes.

type Prompt

type Prompt struct {
	Text        string
	UserMessage *tacklr.Message
	// AgentID, when set, selects the catalog agent for this turn slice.
	AgentID string
	// MCPServers, when non-nil, replaces session-scoped MCP configs for this turn.
	MCPServers []mcp.MCPConfig
	Auth       AuthContext
	// State merges into session userState for this turn (after checkpoint restore).
	// JSON-serializable values only. Checkpointed — no tokens or clients.
	State map[string]any
}

Prompt is the typed input for Runtime.Prompt.

type Resume

type Resume struct {
	Responses map[string][]byte
	Auth      AuthContext
	// State merges into session userState when the parked turn continues.
	State map[string]any
}

Resume is the typed input for Runtime.Resume (HITL answer plus optional auth).

type Revision

type Revision string

Revision is the SnapshotStore compare-and-swap token for one session row. The zero value means no row exists yet; the next Save creates it.

type Runtime

type Runtime interface {
	CreateSession(ctx context.Context, req CreateSession) (SessionID, error)
	Prompt(ctx context.Context, sessionID SessionID, msg Prompt) error
	Resume(ctx context.Context, sessionID SessionID, resume Resume) error
	// Cancel aborts the in-flight turn and stops child sessions. The parent
	// session stays open for a later Prompt. Client stop (session/cancel and
	// cancelling the original Prompt/Resume context) uses this.
	Cancel(ctx context.Context, sessionID SessionID) error
	// Close destroys the session and recursively stops children.
	Close(ctx context.Context, sessionID SessionID) error
	// Head is the current EventLog offset. Protocol pumps pass it to Subscribe
	// to tail from now (skip events from prior turns).
	Head(ctx context.Context, sessionID SessionID) (Seq, error)
	Subscribe(ctx context.Context, sessionID SessionID, after Seq) (Subscription, error)
	// Children returns child session ids of parent, in start order.
	Children(ctx context.Context, parent SessionID) ([]SessionID, error)
	// Status is running, complete, failed, or unknown. A child waiting on HITL
	// stays running until that interrupt is resolved.
	Status(ctx context.Context, id SessionID) (SessionStatus, error)
}

Runtime is the only session kernel API. Protocol handlers and hosts call it. Backends: in-process (goroutine wait loop) or Temporal (one workflow per session).

A later Restate/DBOS/custom-log adapter plugs in here. It must supply:

  • start a session process (workflow / durable handler)
  • signals: prompt, resume, cancel, close, child-waiting
  • named steps with heartbeat + retry: Inference; Tool (one call; the wait loop still schedules a batch)
  • start a child session process (same machine, overlay specialist)
  • query: status, children
  • append to EventLog (the adapter wakes the loop)

Leftover-tool and HITL rules live in tacklr.Next. Do not fork them.

Prompt and Resume signal the session; they do not return a harness. Subscribe yields StreamEvent values (message, tool, yield, error, complete).

VFS credentials travel on Prompt / Resume / CreateSession.Mounts — not as separate kernel bind RPCs. Protocols map wire auth into AuthContext.

type Seq

type Seq uint64

Seq is a monotonically increasing EventLog offset for one session.

type SessionID

type SessionID string

SessionID is the durable agent session identifier.

func ChildSessionID

func ChildSessionID(parent SessionID, specialist, callID string) SessionID

ChildSessionID is the stable id for a spawn_specialist child session. Same shape as embed workerSessionID: {parent}/w/{worker}/{call}.

type SessionState

type SessionState string

SessionState is parent-facing session/job state. Child HITL does not change this from running until the interrupt is resolved and the child completes, fails, or is cancelled.

const (
	SessionRunning  SessionState = "running"
	SessionComplete SessionState = "complete"
	SessionFailed   SessionState = "failed"
	SessionUnknown  SessionState = "unknown"
)

type SessionStatus

type SessionStatus struct {
	ID         SessionID
	Parent     SessionID
	State      SessionState
	Specialist string
	Kind       string
	Result     string
	Err        error
	// Waiting is true while the session is parked for HITL. Parent-facing
	// State stays running until that interrupt is resolved.
	Waiting bool
}

SessionStatus is a value type returned by Runtime.Status. Not an interface.

type Snapshot

type Snapshot struct {
	AgentID    string
	Specialist string
	Parent     SessionID
	// Children are child session ids in start order (no handles, no tokens).
	Children   []SessionID
	Checkpoint tacklr.SessionCheckpoint
	Mounts     []MountRecipe
}

Snapshot is one session's harness checkpoint plus VFS recipes (no tokens).

type SnapshotStore

type SnapshotStore interface {
	Save(ctx context.Context, sessionID SessionID, snap Snapshot, expected Revision) (Revision, error)
	Load(ctx context.Context, sessionID SessionID) (Snapshot, Revision, error)
	Delete(ctx context.Context, sessionID SessionID) error
}

SnapshotStore holds one session's harness blob (window, plan, parked interrupts, VFS recipes). Close deletes the row. Tokens and file bytes are never stored here.

Save's expected Revision must match the last Load (zero if no row). Mismatch means another writer already saved — reload and retry.

type Subscription

type Subscription interface {
	Events() <-chan tacklr.StreamEvent
	Close() error
}

Subscription is one consumer of a session EventLog.

Directories

Path Synopsis

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL