agentstate

package
v0.20.0 Latest Latest
Warning

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

Go to latest
Published: Sep 15, 2026 License: AGPL-3.0 Imports: 3 Imported by: 0

Documentation

Overview

Package agentstate defines the External Agent persistence contract for native session checkpoints: JSONL trees owned by an out-of-process runtime (an ACP agent, codex, claude-code) that Memoh snapshots to and restores from the database without making their opaque records part of the canonical chat timeline.

Index

Constants

This section is empty.

Variables

View Source
var (
	// ErrRuntimeConfigStale means the runtime process was created from an older
	// bot configuration generation. Retrying the write from that process would
	// let stale credentials or configuration replace the current generation.
	ErrRuntimeConfigStale = errors.New("runtime configuration generation is stale")
	// ErrRuntimeConfigResetInProgress is transient: a bot-scoped reset owns the
	// workspace configuration publication lock. Session-scoped history resets
	// deliberately do not block bot-global configuration synchronization.
	ErrRuntimeConfigResetInProgress = errors.New("bot runtime reset is in progress")
)
View Source
var ErrSessionStateDivergent = errors.New("agent session state diverged from the canonical checkpoint")

ErrSessionStateDivergent means the captured native state can no longer be proven to extend the canonical checkpoint: a canonical file was rewritten, shortened, or removed by the runtime. Staging must decline without touching any row the canonical version references (staging and publication commit in different transactions, so a destructive rewrite would corrupt the still- canonical version if this round never commits). The caller publishes an explicit reset instead; once that reset is canonical the shared rows are unreferenced and the next turn may stage a full rewrite safely.

View Source
var ErrSessionStateOutOfSync = errors.New("agent session checkpoint is out of sync with canonical history")

ErrSessionStateOutOfSync means canonical history has advanced to a successful run whose staged native snapshot is missing. Falling back to a fresh native session would silently fork the two histories, so callers must surface or explicitly repair this condition.

Functions

This section is empty.

Types

type PersistedSessionState

type PersistedSessionState struct {
	// AgentID names the runtime flavor that owns the snapshot (an ACP agent
	// id, or a direct runtime type such as "codex" or "claude-code").
	AgentID string
	// AgentSessionID is the runtime's own session identifier (the ACP
	// session id, codex thread id, or claude session id).
	AgentSessionID      string
	ThroughRunID        string
	Cwd                 string
	TranscriptPath      string
	RuntimeFencingToken int64
	FileCount           int32
	RecordCount         int64
	// Files describes every captured file in path order. Replace uses the
	// prefix proofs to append only each file's tail; Load uses the committed
	// shapes as its authoritative read bound.
	Files []PersistedSessionStateFile
}

PersistedSessionState is the database-backed checkpoint needed to resume a runtime-native session inside a new process-owned runtime directory. JSONL files stay out of the durable workspace profile; the store reconstructs them from ordered JSONB rows only for the lifetime of the resumed runtime.

type PersistedSessionStateFile

type PersistedSessionStateFile struct {
	SessionStateFileShape
	PrefixRecords int64
	PrefixDigest  string
}

PersistedSessionStateFile is one captured file plus its optional prefix proof. PrefixRecords/PrefixDigest describe the capture's running digest at the previous canonical boundary; a zero PrefixRecords means no proof was taken and the file must be fully rewritten.

type RuntimeConfigEpoch

type RuntimeConfigEpoch struct {
	Bot     int64
	Session int64
}

RuntimeConfigEpoch is the durable generation of process-affecting bot and session configuration. It is deliberately independent of publication head: credentials and workspace config may change while canonical chat history does not.

type SessionPublicationHead

type SessionPublicationHead struct {
	RunID string
	Kind  SessionPublicationKind
}

SessionPublicationHead is the lightweight canonical-history watermark used to fence process-local warm handles across server instances. Absence is represented by the bool returned from SessionStateStore.Head, not by a sentinel RunID or Kind.

type SessionPublicationKind

type SessionPublicationKind string

SessionPublicationKind identifies what the newest successful canonical runtime turn published. A checkpoint can be restored after a cold start; a reset is an explicit, successful turn with no resumable native state.

const (
	SessionPublicationCheckpoint SessionPublicationKind = "checkpoint"
	SessionPublicationReset      SessionPublicationKind = "reset"
)

type SessionStateFileShape

type SessionStateFileShape struct {
	Path    string `json:"path"`
	Records int64  `json:"records"`
	Digest  string `json:"digest"`
}

SessionStateFileShape names one JSONL file of a persisted version: its record count and the digest over its compacted records. The digest doubles as the append-only proof between versions: when a newer capture's running digest at PrefixRecords equals the canonical version's full-file Digest, the canonical prefix is byte-identical and only the tail needs to be written.

type SessionStateRecord

type SessionStateRecord struct {
	FilePath   string          `json:"file_path"`
	LineNumber int64           `json:"line_number"`
	Content    json.RawMessage `json:"content"`
}

SessionStateRecord is one ordered JSONL value in a persisted snapshot.

type SessionStateRecordConsumer

type SessionStateRecordConsumer func(
	context.Context,
	PersistedSessionState,
	SessionStateRecordReader,
) error

SessionStateRecordConsumer consumes one published snapshot. The reader is valid only while the callback is running and must be consumed through io.EOF before the callback returns nil. Load keeps its consistency transaction open for that lifetime, so consumers should do only the bounded restore work needed to durably accept each record.

type SessionStateRecordReader

type SessionStateRecordReader func(context.Context) (SessionStateRecord, error)

SessionStateRecordReader yields records ordered by FilePath and LineNumber. io.EOF ends the snapshot. Implementations and consumers must not retain or mutate Content after the next call unless they first copy it.

type SessionStateStore

type SessionStateStore interface {
	RuntimeConfigEpoch(ctx context.Context, botID, sessionID string) (RuntimeConfigEpoch, error)
	GuardRuntimeSync(ctx context.Context, botID string, expectedBotEpoch int64, fn func(context.Context) error) error
	Head(ctx context.Context, botID, sessionID string) (SessionPublicationHead, bool, error)
	// CanonicalShape returns the committed head version's per-file shapes. It
	// is an advisory pre-capture read: capture snapshots prefix digests at
	// these boundaries, and Replace re-reads the canonical shape inside its
	// transaction before trusting any proof.
	CanonicalShape(ctx context.Context, botID, sessionID string) (map[string]SessionStateFileShape, bool, error)
	Load(ctx context.Context, botID, sessionID string, consume SessionStateRecordConsumer) (bool, error)
	Replace(
		ctx context.Context,
		botID, sessionID string,
		state PersistedSessionState,
		records SessionStateRecordReader,
	) error
}

SessionStateStore is the narrow persistence port shared by runtime session managers (the ACP pool, direct runtime drivers). A Replace implementation stages the complete snapshot under ThroughRunID in one runtime-fenced transaction. Load may expose that version only after the same run is the newest successful canonical watermark; this prevents a crash between native completion and chat-history persistence from publishing a ghost transcript.

Jump to

Keyboard shortcuts

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