Documentation
¶
Index ¶
- Constants
- Variables
- type AgentSpec
- type AuthContext
- type Catalog
- type CreateSession
- type EventLog
- type MemoryCatalog
- type MemorySecretStorage
- type MountRecipe
- type Prompt
- type Resume
- type Revision
- type Runtime
- type SecretStorage
- type Secrets
- type Seq
- type SessionID
- type SessionState
- type SessionStatus
- type Snapshot
- type SnapshotStore
- type Subscription
Constants ¶
const ( TopicEvents = "events" TopicRetry = "retry" )
EventLog topics. Temporal Workflow Streams uses the same names.
const SessionKindSpecialist = "specialist"
SessionKindSpecialist is Status.Kind for spawn_specialist children.
Variables ¶
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 ¶
This section is empty.
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.
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 or Temporal event history. The Temporal adapter writes them to SecretStorage before signaling.
func (AuthContext) WithoutSecrets ¶ added in v0.3.0
func (a AuthContext) WithoutSecrets() AuthContext
WithoutSecrets returns a copy with Credential Token and ExpiresAt cleared. Binding metadata (provider, alias, params, writable) is kept. The input is not modified.
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 checkpoint userState (JSON-serializable values).
// Tools read it via HarnessRuntime.StateGet. Canonical copy is
// Snapshot.Checkpoint, not Temporal workflow variables. No 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) 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 MemorySecretStorage ¶ added in v0.3.0
type MemorySecretStorage struct {
// contains filtered or unexported fields
}
MemorySecretStorage is an in-memory SecretStorage for tests and single-process workers. Client and worker must share the same instance.
func NewMemorySecretStorage ¶ added in v0.3.0
func NewMemorySecretStorage() *MemorySecretStorage
func (*MemorySecretStorage) Delete ¶ added in v0.3.0
func (s *MemorySecretStorage) Delete(_ context.Context, sessionID SessionID) error
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.
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 checkpoint userState for this turn after restore.
// JSON-serializable values only. 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 checkpoint 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 SecretStorage ¶ added in v0.3.0
type SecretStorage interface {
// Put replaces Auth when secrets.Auth.Bindings is non-empty.
// Empty Bindings (including drop-only) is a no-op on the bag.
Put(ctx context.Context, sessionID SessionID, secrets Secrets) error
// Get returns the last Put bag. Missing session: zero Secrets, nil error.
Get(ctx context.Context, sessionID SessionID) (Secrets, error)
Delete(ctx context.Context, sessionID SessionID) error
}
SecretStorage holds Secrets for Temporal activities. Runtime client and worker must share one instance. It is not SnapshotStore.
type Secrets ¶ added in v0.3.0
type Secrets struct {
Auth AuthContext
}
Secrets is the session-scoped secret bag that must not enter Temporal history or SnapshotStore. Auth holds VFS credentials. Add fields here when more work-item secrets need the same path.
type SessionID ¶
type SessionID string
SessionID is the durable agent session identifier.
func ChildSessionID ¶
ChildSessionID is the stable id for a spawn_specialist child session.
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 the session record in SnapshotStore. Both runtimes write the same shape. Wait-loop fields (leftover Temporal tool calls, MCP overlay, child futures) stay on the loop, not here.
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 is the session record: what the harness needs to think again after HITL or a worker recycle. It is not the wait loop and not credentials.
Frozen contents: SessionCheckpoint (window, plan, parked interrupt, userState), MountRecipe topology, and session identity (agent, parent, specialist, child ids). Tokens, file bytes, leftover unstarted Temporal tool calls, MCP env and headers, and child workflow futures never go 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.