session

package
v1.3.102 Latest Latest
Warning

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

Go to latest
Published: Sep 22, 2026 License: MIT Imports: 26 Imported by: 0

Documentation

Index

Constants

View Source
const CurrentVersion = 3
View Source
const KnowledgeGraphSchemaVersion = 1

Variables

View Source
var (
	ErrDeliveryLeaseLost       = errors.New("delivery operation lease was lost")
	ErrDeliveryOperationBusy   = errors.New("delivery operation is leased or not ready")
	ErrDeliveryOperationAbsent = errors.New("delivery operation was not found")
)
View Source
var (
	ErrForkSessionNotFound     = errors.New("source session not found")
	ErrForkSessionActive       = errors.New("source session is active")
	ErrForkNoCompletedTurn     = errors.New("source session has no completed conversation turn")
	ErrForkUnavailable         = errors.New("fork boundary is unavailable")
	ErrForkInvalidBoundary     = errors.New("fork boundary is invalid")
	ErrForkUnsupportedEntry    = errors.New("fork contains unsupported entry")
	ErrForkIdempotencyRequired = errors.New("fork request ID is required")
	ErrForkIdempotencyTooLong  = errors.New("fork request ID is too long")
	ErrForkIdempotencyConflict = errors.New("fork idempotency request conflicts")
)
View Source
var (
	ErrKnowledgeBaseNotFound             = errors.New("knowledge base not found")
	ErrKnowledgeBaseUnindexed            = errors.New("knowledge base has no completed index")
	ErrKnowledgeBaseConfigurationChanged = errors.New("knowledge base configuration changed during indexing")
)
View Source
var (
	ErrRuntimeLeaseBusy         = errors.New("session runtime lease is held by another process")
	ErrRuntimeLeaseLost         = errors.New("session runtime lease was lost")
	ErrRuntimeSessionNotFound   = errors.New("session runtime lease requires an existing session")
	ErrSessionRunActive         = errors.New("session has an active durable run")
	ErrSessionRecoveryRequired  = errors.New("session has an active durable run that requires reconciliation")
	ErrSessionRecoveryNotNeeded = errors.New("session has no active durable run to recover")
	ErrRuntimeLeaseRunMismatch  = errors.New("session runtime lease run does not match the active durable run")
	ErrRuntimeLeasePurpose      = errors.New("session runtime lease purpose does not allow this operation")
)
View Source
var ErrConversationTurnNotOpen = errors.New("conversation turn is not open")
View Source
var ErrRuntimeSubmissionConflict = errors.New("runtime submission key conflicts with another request")
View Source
var ErrRuntimeSubmissionExists = errors.New("runtime submission already exists")
View Source
var ErrSessionIDExists = errors.New("session ID already exists")

ErrSessionIDExists means a new session attempted to reuse an existing ID. A duplicate must be rejected: updating the sessions row would merge the new header with the old entries and create a forked conversation.

View Source
var ErrSessionModified = errors.New("session was modified by another process")

Functions

func AbandonInterruptedToolExecutionRecords

func AbandonInterruptedToolExecutionRecords(sessionDir, sessionID, localTurnID string) (int64, error)

AbandonInterruptedToolExecutionRecords marks uncertain executions as explicitly abandoned. It never retries a tool or invents a tool output; callers use it only after they have established that no runtime owns the session lock. This makes a subsequent user-submitted run a new operation instead of silently replaying a potentially side-effecting call.

func AnnotateSessionRunError

func AnnotateSessionRunError(sessionDir, runID, message string) (bool, error)

AnnotateSessionRunError records a terminal error reason on a run row that reached a terminal status without one (for example a background run abandoned after interrupted tool execution). It never changes the run status and is a no-op when the run already carries an error, so an earlier finalizer stays authoritative. It reports whether the annotation was applied.

func AppendInputResourceEventTx

func AppendInputResourceEventTx(tx *dao.Tx, event InputResourceEvent) error

AppendInputResourceEventTx records a resource lifecycle event in the caller's transaction. Deterministic event IDs make retries safe after an unknown commit result.

func AppendKnowledgeFileGraph

func AppendKnowledgeFileGraph(graph *KnowledgeGraphSnapshot, source KnowledgeFileGraph)

AppendKnowledgeFileGraph clones a file subgraph into graph. New IDs prevent a successor snapshot from sharing mutable identity with its source.

func BindSession

func BindSession(sessionDir, sessionID, channelType, channelID string) error

func CloseDatabases

func CloseDatabases() error

CloseDatabases checkpoints and closes all process-owned session connections.

func CompareAndSwapResponseSessionState

func CompareAndSwapResponseSessionState(sessionDir string, state ResponseSessionState, expectedVersion int64) (bool, error)

CompareAndSwapResponseSessionState advances a session lineage only when the caller observed expectedVersion. It prevents two concurrent turns from silently branching a previous_response_id chain.

func ConsumeESMGuidance

func ConsumeESMGuidance(sessionDir, sessionID string, ids []string) error

func ConvergeSessionRunRecovery

func ConvergeSessionRunRecovery(sessionDir string, run SessionRun, terminalEvent SessionRunEvent, decisionEvents []SessionRunEvent, turnStatus, stopReason string) error

ConvergeSessionRunRecovery atomically records pending Decision resolutions, closes every open ConversationTurn owned by the Run, writes the terminal Run event and state, and completes the recovery record. The exact local purpose=recovery lease is revalidated inside the transaction so a stale recovery worker cannot commit after another owner takes over.

func ConvergeSessionRunRecoveryContext

func ConvergeSessionRunRecoveryContext(ctx context.Context, sessionDir string, run SessionRun, terminalEvent SessionRunEvent, decisionEvents []SessionRunEvent, turnStatus, stopReason string) error

ConvergeSessionRunRecoveryContext is the cancellable form used by the bounded Runtime recovery coordinator.

func CountAll

func CountAll(sessionDir string) (int, error)

func CountWithMessages

func CountWithMessages(sessionDir string, opts ...ListOption) (int, error)

CountWithMessages returns the number of sessions that contain at least one persisted conversation message. Empty sessions can be created transiently during startup or request setup and are not user-visible history.

func CreateDeliveryPlan

func CreateDeliveryPlan(ctx context.Context, sessionDir string, plan DeliveryPlan) error

CreateDeliveryPlan persists a plan outside terminalization only for recovery reconciliation and focused tools. Normal execution must attach the plan to FinishSessionRunAndConversationTurn instead.

func CreateExecutionIntentAndSessionRun

func CreateExecutionIntentAndSessionRun(sessionDir string, intent ExecutionIntent, run SessionRun) error

CreateExecutionIntentAndSessionRun atomically admits an immutable execution intent with its first or linked Run. Runtime-owned callers use this instead of writing the two records independently, so a reconnect can always resolve a durable Run back to the request that created it.

func CreateExecutionIntentAndSessionRunEvent

func CreateExecutionIntentAndSessionRunEvent(sessionDir string, intent ExecutionIntent, run SessionRun, event SessionRunEvent) (string, error)

CreateExecutionIntentAndSessionRunEvent atomically admits an immutable intent, its Run row, and (when supplied) the canonical started event. This prevents a process loss between the intent/run write and event publication from creating an accepted execution with no replay anchor.

func CreateExecutionIntentAndSessionRunEventWithTurn

func CreateExecutionIntentAndSessionRunEventWithTurn(sessionDir string, intent ExecutionIntent, run SessionRun, event SessionRunEvent, turn ConversationTurn) (string, error)

CreateExecutionIntentAndSessionRunEventWithTurn atomically admits an immutable intent, its Run/event, and the conversation turn boundary.

func CreateSessionRun

func CreateSessionRun(sessionDir string, run SessionRun) error

CreateSessionRun inserts one canonical run row. Unlike SaveSessionRun, this method never overwrites an existing identity; Runtime-owned lifecycle code must treat duplicate run IDs as an admission error.

func CreateSessionRunAndEvent

func CreateSessionRunAndEvent(sessionDir string, run SessionRun, event SessionRunEvent) (string, error)

CreateSessionRunAndEvent atomically inserts a new canonical Run and its first event. Retry attempts use this path so a process loss cannot leave a durable attempt without a replay anchor.

func CreateSessionRunAndEventWithTurn

func CreateSessionRunAndEventWithTurn(sessionDir string, run SessionRun, event SessionRunEvent, turn ConversationTurn) (string, error)

CreateSessionRunAndEventWithTurn atomically admits a Run, its first event, and a conversation turn boundary when the Run produces transcript output.

func DecisionEventType

func DecisionEventType(status string) string

DecisionEventType returns the durable run-event type for a decision status.

func DeleteKnowledgeBase

func DeleteKnowledgeBase(ctx context.Context, sessionDir, id string) error

func DeleteProject

func DeleteProject(sessionDir, id string) error

func DeleteSession

func DeleteSession(path string, sessionDir string) error

DeleteSession deletes a session only after acquiring its shared mutation lease. This keeps a direct caller from deleting a session that another process still owns for execution. Callers which already hold a mutation lease for a multi-session operation use DeleteSessionWithMutation instead.

func DeleteSessionWithMutation

func DeleteSessionWithMutation(path string, sessionDir string, guard *RuntimeLeaseGuard) error

DeleteSessionWithMutation deletes a session while the caller holds its Runtime-owned mutation lease. It is for coordinated multi-session operations that cannot reacquire the process-local lock per child. The lease identity is checked again inside the deletion transaction before any session row is removed.

func EndConversationTurn

func EndConversationTurn(sessionDir, sessionID, turnID, status, stopReason string, endedAt time.Time) error

EndConversationTurn atomically writes turn/end and closes its boundary row.

func EnsureCurrentSchema

func EnsureCurrentSchema(db *sql.DB) error

EnsureCurrentSchema creates the current schema only for an empty database. Existing databases are validated but never migrated or otherwise modified.

Failures that mean the schema cannot be brought to the current version (an unappliable migration, or a table missing required columns) are marked with database.SchemaIncompatible. internal/db reacts by backing the database up and starting a new empty one; every other failure is reported unchanged.

func EnsureKnowledgeBaseSchema

func EnsureKnowledgeBaseSchema(db *sql.DB) error

EnsureKnowledgeBaseSchema migrates one dedicated knowledge-base SQLite database. It intentionally does not invoke EnsureCurrentSchema, which owns the unrelated session/run database schema.

func FinishSessionRunAndConversationTurn

func FinishSessionRunAndConversationTurn(sessionDir string, run SessionRun, event SessionRunEvent, turnID, turnStatus, stopReason string) (string, error)

FinishSessionRunAndConversationTurn atomically closes a conversation turn, its Run row, and the terminal Run event. A missing or already-closed turn is tolerated for recovery/idempotent retries because an Agent may already have emitted the boundary before Runtime terminalization.

func GenerateID

func GenerateID() string

GenerateID generates a random 16-character hex ID. IDs such as entries.id are UNIQUE across the whole shared sessions.db, so the previous 32-bit space made collisions plausible at tens of millions of entries; 64 bits keeps the birthday probability negligible.

func GetChannelToolGeneration

func GetChannelToolGeneration(sessionDir, sessionID string) (int64, error)

func IsDecisionEventType

func IsDecisionEventType(eventType string) bool

IsDecisionEventType reports whether eventType belongs to the durable decision ledger, including the legacy serve names.

func IsNonTerminalSessionRunStatus

func IsNonTerminalSessionRunStatus(status string) bool

IsNonTerminalSessionRunStatus reports whether a durable Run still requires execution, cancellation, or terminal persistence work.

func IsTerminalSessionRunStatus

func IsTerminalSessionRunStatus(status string) bool

IsTerminalSessionRunStatus reports whether a durable Run status is terminal.

func KnowledgeBaseDatabasePath

func KnowledgeBaseDatabasePath(sessionDir, knowledgeBaseID string) (string, error)

KnowledgeBaseDatabasePath derives the private SQLite file for exactly one knowledge base. The file lives beside sessions.db but is never attached to or queried through the session database.

func LatestAdditionalDirectoriesByID

func LatestAdditionalDirectoriesByID(sessionDir, sessionID string) ([]string, error)

LatestAdditionalDirectoriesByID reads the replayed directory binding for a session without exposing SQLite details to protocol adapters.

func LatestSessionRunEventSeq

func LatestSessionRunEventSeq(sessionDir, runID string) (int64, error)

LatestSessionRunEventSeq returns the durable replay cursor for one Run. Callers use it to reconcile a disconnected adapter before requesting only the missing portion of the session event stream.

func LatestSessionTitle

func LatestSessionTitle(sessionDir, sessionID string) (string, string, error)

func ListFailedTransientDeliveryOperations

func ListFailedTransientDeliveryOperations(ctx context.Context, sessionDir, platform string) ([]string, error)

ListFailedTransientDeliveryOperations returns one platform's operations that exhausted their retry budget on a transport-level failure, in delivery order. Reconnect recovery uses it to grant another retry window.

func ListLatestSessionRuns

func ListLatestSessionRuns(ctx context.Context, sessionDir string, sessionIDs []string) (map[string]SessionRun, error)

ListLatestSessionRuns returns the most recent durable Run of each given session as a read-only projection keyed by session ID. Sessions without any Run are absent from the result. Adapters use it to project sidebar run status (for example ACP session/list lastRun); Run lifecycle writes remain owned by the Runtime and all SQL stays in the DAO.

func ListResponseReplayItems

func ListResponseReplayItems(sessionDir, sessionID string, limit int) ([]json.RawMessage, error)

ListResponseReplayItems returns the ordered, sanitized native items from completed Responses turns. Callers can pass this sequence to a provider's native replay path instead of reconstructing prior assistant output from plain transcript text.

func ListSessionMetadata

func ListSessionMetadata(sessionDir string, sessionIDs []string) (map[string]SessionMetadata, error)

ListSessionMetadata returns the persisted project/pin metadata of the given sessions in one read-only query, keyed by session ID. Sessions without a metadata row are absent from the result. All SQL stays in the DAO.

func LockRuntime

func LockRuntime(sessionDir, sessionID string) func()

LockRuntime waits for the single-session lease. It is intentionally implemented as retrying TryLockRuntime so no database transaction remains open while an execution is running.

func LockSessionData

func LockSessionData(sessionDir, sessionID string) func()

LockSessionData serializes short persistence mutations inside one process. Cross-process data consistency still comes from SQLite transactions.

func MarkSessionRunRecoveryComplete

func MarkSessionRunRecoveryComplete(sessionDir, sessionID, runID string) error

MarkSessionRunRecoveryComplete records successful fenced convergence.

func MarkSessionRunRecoveryCompleteContext

func MarkSessionRunRecoveryCompleteContext(ctx context.Context, sessionDir, sessionID, runID string) error

func MarkSessionRunRecoveryDetached

func MarkSessionRunRecoveryDetached(sessionDir, sessionID, runID string) error

MarkSessionRunRecoveryDetached records that a canonical remote record was retained. The response record, not this marker, remains the evidence used to decide whether the provider execution is still recoverable.

func MarkSessionRunRecoveryDetachedContext

func MarkSessionRunRecoveryDetachedContext(ctx context.Context, sessionDir, sessionID, runID string) error

func MarkSessionRunRecoveryFailed

func MarkSessionRunRecoveryFailed(sessionDir, sessionID, runID, message string, nextRetryAt time.Time) error

MarkSessionRunRecoveryFailed persists a retryable failure under the same fenced recovery owner. A zero nextRetryAt means retry as soon as a Runtime coordinator observes the row again.

func MarkSessionRunRecoveryFailedContext

func MarkSessionRunRecoveryFailedContext(ctx context.Context, sessionDir, sessionID, runID, message string, nextRetryAt time.Time) error

func NextSessionRunAttempt

func NextSessionRunAttempt(sessionDir, sessionID, intentID string) (int, error)

NextSessionRunAttempt returns the next ordered user-visible attempt for an ExecutionIntent. Callers must hold their Runtime admission lock while using the returned value and creating the Run, so two retry commands cannot select the same attempt number.

func NonTerminalSessionRunStatuses

func NonTerminalSessionRunStatuses() []string

NonTerminalSessionRunStatuses returns the canonical durable statuses that keep a Session busy. Callers receive a copy so the shared definition cannot be mutated outside this package.

func NotifyRuntimeStateChanged

func NotifyRuntimeStateChanged(sessionID, origin string)

NotifyRuntimeStateChanged wakes local observers after a durable Run state transition. It never carries Run content and never changes ownership.

func OpenBunDatabase

func OpenBunDatabase(path string) (*dao.Database, error)

OpenBunDatabase returns the process-wide Bun connection for path. New data access code should use this entry point and put queries in a DAO.

func OpenRootDB

func OpenRootDB(sessionDir string) (*dao.Database, error)

OpenRootDB opens the shared sessions.db through the DAO-owned database handle. Callers must not close it; use CloseDatabases for lifecycle control.

func OpenStandaloneDB

func OpenStandaloneDB(path string) (*dao.Database, error)

OpenStandaloneDB opens a configured standalone Bun connection. It is only intended for offline integrity checks; normal runtime code uses OpenRootDB.

func ProjectSessionCounts

func ProjectSessionCounts(sessionDir string) (map[string]int, error)

ProjectSessionCounts returns how many sessions are currently assigned to each project. It is a read-only projection for project listings.

func QueryRootDatabase

func QueryRootDatabase(sessionDir string, fn func(*dao.Database) error) error

QueryRootDatabase runs a read operation against a session root's DAO-owned database. The callback must not retain the handle after it returns.

func ReclaimInterruptedToolExecution

func ReclaimInterruptedToolExecution(sessionDir, executionKey string) (bool, error)

ReclaimInterruptedToolExecution atomically reopens a tool record after a process interruption. Read-only running/interrupted records are eligible automatically; side-effecting records require the explicit retry_requested state set by the confirmation API.

func RefreshDeliveryIntentStatus

func RefreshDeliveryIntentStatus(ctx context.Context, sessionDir, intentID string) error

RefreshDeliveryIntentStatus recomputes the intent aggregate after an operation result. An intent is delivered only when all operations are delivered/unsupported; failed and uncertain operations remain visible.

func ReopenFailedDeliveryOperation

func ReopenFailedDeliveryOperation(ctx context.Context, sessionDir, operationID string, now time.Time) (bool, error)

ReopenFailedDeliveryOperation returns an operation that exhausted its retry budget to retry_wait and restarts its retry window. Reconnect recovery and an explicit operator retry both use it; only a failed operation can be reopened so an in-flight or delivered operation is never clobbered.

func RequestToolExecutionRecovery

func RequestToolExecutionRecovery(sessionDir, sessionID, localTurnID string, providerCallIDs []string) (int64, error)

RequestToolExecutionRecovery marks selected interrupted tool calls for an explicit user-confirmed retry. It never changes completed records and does not itself execute any tool.

func RequeueDeliveryOperation

func RequeueDeliveryOperation(ctx context.Context, sessionDir, operationID, owner string, epoch int64, nextAttemptAt time.Time, failureCode string) error

RequeueDeliveryOperation releases a fenced lease for an explicit retry. It is used by recovery when a provider call did not yield a trustworthy result.

func RootDatabasePath

func RootDatabasePath(sessionDir string) string

RootDatabasePath returns the shared sessions.db path for a session root. Keeping path derivation here prevents adapters and DAOs from duplicating session directory rules.

func RunAssistantEntryID

func RunAssistantEntryID(runID string) string

RunAssistantEntryID is the deterministic transcript identity for the final assistant entry committed by a Runtime-owned conversation Run. Keeping the identity tied to the Run makes terminal retries and recovery idempotent.

func RunAssistantMessageFingerprint

func RunAssistantMessageFingerprint(runID string, message provider.Message) string

RunAssistantMessageFingerprint returns a stable digest for an assistant message. It is useful to validate a recovery payload without persisting the message in a separate adapter-owned table.

func RunTerminalEventID

func RunTerminalEventID(runID, eventType string) string

RunTerminalEventID is the deterministic lifecycle event identity for a terminal Run. Event type is included so a cancelled recovery cannot collide with a previously selected terminal outcome.

func RunUserEntryID

func RunUserEntryID(runID string) string

RunUserEntryID is the deterministic transcript identity for a Run's admitted user message. Retries do not create another user entry.

func RuntimeDatabaseIdentity

func RuntimeDatabaseIdentity(sessionDir string) string

RuntimeDatabaseIdentity returns the normalized SQLite identity used to scope process-local execution and recovery registries.

func RuntimeLeaseLost

func RuntimeLeaseLost(sessionDir, sessionID string) <-chan struct{}

RuntimeLeaseLost returns the loss signal for the current process lease. It is intentionally read-only; callers use it to cancel work while every durable write still performs its own epoch/token fence check.

func SaveESMGuidance

func SaveESMGuidance(sessionDir string, g ESMGuidance) error

func SaveExecutionIntent

func SaveExecutionIntent(sessionDir string, intent ExecutionIntent) error

func SaveInputResourceEvent

func SaveInputResourceEvent(ctx context.Context, sessionDir string, event InputResourceEvent) error

SaveInputResourceEvent appends a resource lifecycle event outside a larger transaction. Runtime admission paths should use AppendInputResourceEventTx.

func SaveResponseItem

func SaveResponseItem(sessionDir string, item ResponseItemArchive) error

func SaveResponseRun

func SaveResponseRun(sessionDir string, run ResponseRun) error

func SaveResponseTurn

func SaveResponseTurn(sessionDir string, turn ResponseTurn) error

func SaveSessionCapabilities

func SaveSessionCapabilities(sessionDir string, caps SessionCapabilities) error

SaveSessionCapabilities persists per-session runtime capability state.

func SaveSessionCapabilityEvent

func SaveSessionCapabilityEvent(sessionDir string, ev SessionCapabilityEvent) (string, error)

SaveSessionCapabilityEvent appends a capability transition event to the independent event table.

func SaveSessionRun

func SaveSessionRun(sessionDir string, run SessionRun) error

func SaveSessionRunEvent

func SaveSessionRunEvent(sessionDir string, ev SessionRunEvent) (string, error)

SaveSessionRunEvent appends a run lifecycle event to the independent run event table.

func SetChannelTools

func SetChannelTools(sessionDir, sessionID string, tools []ChannelToolConfig) error

func SetSessionMetadata

func SetSessionMetadata(sessionDir, sessionID string, metadata SessionMetadata) error

func StartConversationTurn

func StartConversationTurn(sessionDir string, turn ConversationTurn) error

StartConversationTurn atomically writes turn/start and its boundary row.

func SubscribeRuntimeLeaseLogs

func SubscribeRuntimeLeaseLogs(sink func(string)) func()

SubscribeRuntimeLeaseLogs receives UDP diagnostics without writing them to the process-wide logger. Serve uses this to expose the messages in WebUI; TUI, CLI, and channel transports must not receive protocol diagnostics.

func SubscribeRuntimeLeaseNotifications

func SubscribeRuntimeLeaseNotifications(handler func(RuntimeLeaseNotification)) func()

SubscribeRuntimeLeaseNotifications receives best-effort notifications from other local processes. It is deliberately optional: a bind failure simply leaves durable SQLite replay as the synchronization path.

func TerminalSessionRunStatuses

func TerminalSessionRunStatuses() []string

TerminalSessionRunStatuses returns the canonical terminal Run statuses. Callers receive a copy so the shared definition cannot be mutated.

func TransferBinding

func TransferBinding(sessionDir, channelType, channelID, fromSessionID, toSessionID string) error

TransferBinding atomically moves a channel identity from one session to another.

func TryLockRuntime

func TryLockRuntime(sessionDir, sessionID string) (func(), bool)

TryLockRuntime serializes one session across all processes. The process-local mutex remains a fast path, while the SQLite lease is the authority and is automatically renewed until release or lease loss.

func TryLockRuntimes

func TryLockRuntimes(sessionDir string, sessionIDs []string) (func(), bool)

TryLockRuntimes acquires multiple session leases in sorted order. Different sessions remain independently concurrent; ordering only applies to an operation that explicitly spans more than one session.

func UnbindSession

func UnbindSession(sessionDir, sessionID string) error

UnbindSession makes a channel-bound session local while retaining its history.

func UpdateDeliveryOperation

func UpdateDeliveryOperation(ctx context.Context, sessionDir, operationID, owner string, epoch int64, status, providerAssetID, providerMessageID string, providerState json.RawMessage, failureCode string, nextAttemptAt *time.Time) error

UpdateDeliveryOperation applies a fenced provider result. Terminal updates are idempotent when a retry repeats the same result after an unknown commit.

func UpdateDeliveryOperationProgress

func UpdateDeliveryOperationProgress(ctx context.Context, sessionDir, operationID, owner string, epoch int64, status, providerAssetID, providerMessageID string, providerState json.RawMessage, failureCode string) error

UpdateDeliveryOperationProgress persists an in-flight provider phase while retaining the current lease. A subsequent terminal update must use the same owner and epoch, so a stale worker remains fenced throughout upload/send.

func UpdateSessionRunErrorInfo

func UpdateSessionRunErrorInfo(sessionDir, runID string, info json.RawMessage) error

UpdateSessionRunErrorInfo stores the structured terminal/recovery error independently of the compatibility Error summary column.

func UpdateSessionRunProgress

func UpdateSessionRunProgress(sessionDir, runID string, progress json.RawMessage) error

UpdateSessionRunProgress persists the latest non-terminal retry/recovery projection. Terminal callers should clear it with an empty object.

func UpdateSessionRunStatus

func UpdateSessionRunStatus(sessionDir, runID, status, message string, finishedAt *time.Time) error

func UpdateSessionRunUsage

func UpdateSessionRunUsage(sessionDir, runID string, usage, contextUsage json.RawMessage) error

UpdateSessionRunUsage persists token and context-window usage independently from terminalization so reconnects can inspect partial or recovered runs.

func UpdateToolExecutionRecord

func UpdateToolExecutionRecord(sessionDir string, record ToolExecutionRecord) error

func ValidateRuntimeLease

func ValidateRuntimeLease(sessionDir, sessionID, runID string, purpose RuntimeLeasePurpose) error

ValidateRuntimeLease is the context-free compatibility wrapper.

func ValidateRuntimeLeaseContext

func ValidateRuntimeLeaseContext(ctx context.Context, sessionDir, sessionID, runID string, purpose RuntimeLeasePurpose) error

ValidateRuntimeLeaseContext rechecks the process-owned lease binding in a fresh SQLite transaction. It is the final Runtime fence before a side effect; callers must not treat client-provided identity as authority.

func WatchDatabaseRebuilds

func WatchDatabaseRebuilds(onNotice func(DatabaseRecovery)) func()

WatchDatabaseRebuilds retires this process's cached connection when another process on this host rebuilds a database after a failed migration. Without it, a long-running process keeps reading and writing the replaced file through its open handle (a deleted inode on Unix) until it restarts.

onNotice, when non-nil, receives each peer notice for UI rendering and is the only user-facing channel used (the notice is always recorded for TakeDatabaseRecoveries); without it the notice is logged. The returned function unsubscribes. The watcher is advisory: a missed datagram only means the stale handle is retired later, after a restart.

func WriteRootDatabase

func WriteRootDatabase(ctx context.Context, sessionDir string, fn func(*dao.Tx) error) error

WriteRootDatabase runs a write transaction against a session root's DAO-owned database. The callback receives the Bun transaction wrapper.

Types

type ActiveRuntimeLease

type ActiveRuntimeLease struct {
	SessionID string
	OwnerID   string
	OwnerPID  int
	OwnerKind string
	RunID     string
	Purpose   string
	ExpiresAt time.Time
}

ActiveRuntimeLease is one session lease still recorded as active in a session database. It names the process that holds it, so destructive maintenance can refuse while another mothx process may still be executing a run there.

func ActiveRuntimeLeases

func ActiveRuntimeLeases(sessionDir string) ([]ActiveRuntimeLease, error)

ActiveRuntimeLeases reports leases still marked active in a session directory's database. A directory with no database holds nothing and is not an error, so this is safe to call before the first run or after a reset.

The check is deliberately narrow: a lease exists only while a process is admitted or executing a run, so an idle TUI, serve, or ACP process holding the same directory open is not reported here. It opens the file read-only and never migrates, repairs, or initializes it: a safety preflight cannot modify the database it is deciding whether to archive.

func (ActiveRuntimeLease) Describe

func (lease ActiveRuntimeLease) Describe() string

Describe renders the holder in one line for an operator-facing refusal.

type AdditionalDirectoriesEntry

type AdditionalDirectoriesEntry struct {
	EntryBase
	Directories []string `json:"directories"`
}

AdditionalDirectoriesEntry records the complete ordered directory set granted to a session. Replacements are replayable session entries.

type ArchivedFile

type ArchivedFile struct {
	// From is the path the file had in the session directory.
	From string
	// To is the archive path it was renamed to, beside From.
	To string
}

ArchivedFile is one sessions.db file a reset renamed.

type Binding

type Binding struct {
	SessionID   string `json:"sessionId"`
	ChannelType string `json:"channelType"`
	ChannelID   string `json:"channelId"`
}

Binding describes a current external channel binding.

func FindBinding

func FindBinding(sessionDir, channelType, channelID string) (*Binding, error)

func FindBindingBySessionID

func FindBindingBySessionID(sessionDir, sessionID string) (*Binding, error)

FindBindingBySessionID returns the current external binding for a session.

func ListBindings

func ListBindings(sessionDir string) ([]Binding, error)

type BranchSummaryEntry

type BranchSummaryEntry struct {
	EntryBase
	Summary string `json:"summary"`
	FromID  string `json:"fromId"`
}

BranchSummaryEntry records a branch switch summary.

type ChannelToolConfig

type ChannelToolConfig struct {
	ToolName string `json:"toolName"`
	Enabled  bool   `json:"enabled"`
}

ChannelToolConfig describes one persisted tool selection for a channel session.

func ListChannelTools

func ListChannelTools(sessionDir, sessionID string) ([]ChannelToolConfig, error)

type CompactionEntry

type CompactionEntry struct {
	EntryBase
	Summary              string `json:"summary"`
	FirstKeptEntry       string `json:"firstKeptEntryId"`
	TokensBefore         int    `json:"tokensBefore"`
	SummaryVersion       int    `json:"summaryVersion,omitempty"`
	PreviousCompactionID string `json:"previousCompactionId,omitempty"`
	LastSummarizedEntry  string `json:"lastSummarizedEntryId,omitempty"`
}

CompactionEntry records a context compaction.

type ContentOverrideEntry

type ContentOverrideEntry struct {
	EntryBase
	TargetEntryID string           `json:"targetEntryId"`
	Message       provider.Message `json:"message"`
	Reason        string           `json:"reason,omitempty"`
	Code          string           `json:"code,omitempty"`
}

ContentOverrideEntry records an append-only, replayable replacement of a previously persisted message entry's content. Replay substitutes Message for the target entry; the original entry stays in the log for audit. It is used when a provider permanently refuses content (for example an image flagged by content inspection) and the conversation must continue without it.

Replacements are replayable session entries, exactly like directory grants: the log is never mutated or truncated, only overlaid on replay.

type ConversationTurn

type ConversationTurn struct {
	ID        string
	SessionID string
	IntentID  string
	RunID     string
	Attempt   int
	Kind      string
	Status    string
	StartSeq  int64
	EndSeq    *int64
	StartedAt time.Time
	EndedAt   *time.Time
}

ConversationTurn is the durable boundary index used by Session fork resolution. It is intentionally separate from SessionRun because a Run may execute tools or maintenance work without producing a conversation turn.

func ListConversationTurns

func ListConversationTurns(sessionDir, sessionID string) ([]ConversationTurn, error)

ListConversationTurns returns boundary rows in transcript order.

type DatabaseIndexRepair

type DatabaseIndexRepair = database.IndexRepair

DatabaseIndexRepair reports a stale secondary index internal/db rebuilt while opening a database. Nothing is lost - index contents are derived from the table rows - but the file has already survived a failed write, which a front-end should surface once.

func TakeDatabaseIndexRepairs

func TakeDatabaseIndexRepairs() []DatabaseIndexRepair

TakeDatabaseIndexRepairs returns and clears the index repairs recorded since the last call. Only this process's own repairs are reported: a repair replaces no file, so peers never announce them (unlike a migration rebuild, which must retire every other process's cached connection).

type DatabaseRecovery

type DatabaseRecovery = database.MigrationRecovery

DatabaseRecovery reports a sessions database that failed schema migration and was therefore backed up and rebuilt by internal/db. The previous data stays in BackupPath.

func TakeDatabaseRecoveries

func TakeDatabaseRecoveries() []DatabaseRecovery

TakeDatabaseRecoveries returns the database recoveries recorded since the last call and clears them, so a front-end can tell the user exactly once what was backed up and why. internal/db also logs each recovery.

The list covers both databases this process rebuilt itself and rebuilds other mothx processes announced over the advisory bus (those entries have Peer set).

type DeliveryFailure

type DeliveryFailure struct {
	OperationID   string
	IntentID      string
	SessionID     string
	RunID         string
	Platform      string
	TargetID      string
	OperationKind string
	Status        string
	FailureCode   string
	AttemptCount  int
	UpdatedAt     time.Time
}

DeliveryFailure is the operator-facing view of one delivery operation that needs attention. It never carries payload, provider state, or transport context.

func ListDeliveryFailures

func ListDeliveryFailures(ctx context.Context, sessionDir, sessionID string, limit int) ([]DeliveryFailure, error)

ListDeliveryFailures lists operations that need operator attention (failed or uncertain), optionally narrowed to one session.

type DeliveryIntent

type DeliveryIntent struct {
	ID               string
	SessionID        string
	RunID            string
	Platform         string
	TargetID         string
	ReplyMessageID   string
	TransportContext json.RawMessage
	Status           string
	CreatedAt        time.Time
	UpdatedAt        time.Time
}

DeliveryIntent is the run-level durable outbox identity. TransportContext is opaque Runtime-owned state and must never be projected into prompts or ordinary logs.

type DeliveryOperation

type DeliveryOperation struct {
	ID                string
	IntentID          string
	OperationKey      string
	ArtifactID        string
	OperationKind     string
	Sequence          int
	DependsOn         string
	IdempotencyKey    string
	PayloadDigest     string
	Status            string
	ProviderAssetID   string
	ProviderMessageID string
	ProviderState     json.RawMessage
	AttemptCount      int
	NextAttemptAt     *time.Time
	FailureCode       string
	// RetryWindowStartedAt restarts the transient retry budget after an explicit
	// retry; nil means the budget started at CreatedAt.
	RetryWindowStartedAt *time.Time
	LeaseOwner           string
	LeaseEpoch           int64
	LeaseExpiresAt       *time.Time
	CreatedAt            time.Time
	UpdatedAt            time.Time
}

DeliveryOperation is one ordered, independently recoverable outbox step.

func ClaimDeliveryOperation

func ClaimDeliveryOperation(ctx context.Context, sessionDir, operationID, owner string, now time.Time, lease time.Duration) (*DeliveryOperation, error)

ClaimDeliveryOperation atomically claims the next due operation. The lease epoch is incremented on every claim, so a delayed worker cannot overwrite a later retry after its lease expires.

func GetDeliveryOperation

func GetDeliveryOperation(ctx context.Context, sessionDir, operationID string) (*DeliveryOperation, error)

GetDeliveryOperation loads one operation without exposing transport credentials or requiring callers to know its parent intent ID.

func ListDueDeliveryOperations

func ListDueDeliveryOperations(ctx context.Context, sessionDir string, now time.Time) ([]DeliveryOperation, error)

ListDueDeliveryOperations returns recoverable operations whose retry time is due or whose previous worker lease has expired. It is intentionally a read; callers must claim each row through ClaimDeliveryOperation before executing.

type DeliveryPlan

type DeliveryPlan struct {
	Intent     DeliveryIntent
	Operations []DeliveryOperation
}

DeliveryPlan is created in the same transaction that terminalizes its Run.

func GetDeliveryPlan

func GetDeliveryPlan(ctx context.Context, sessionDir, intentID string) (*DeliveryPlan, error)

GetDeliveryPlan loads one intent and its operations in execution order.

type ESMGuidance

type ESMGuidance struct {
	ID               string     `json:"id"`
	SessionID        string     `json:"sessionId"`
	ObjectiveVersion string     `json:"objectiveVersion,omitempty"`
	Guidance         string     `json:"guidance"`
	Status           string     `json:"status"`
	CreatedAt        time.Time  `json:"createdAt"`
	ConsumedAt       *time.Time `json:"consumedAt,omitempty"`
}

func ListESMGuidance

func ListESMGuidance(sessionDir, sessionID, status string, limit int) ([]ESMGuidance, error)

type EntryBase

type EntryBase struct {
	Type      EntryType `json:"type"`
	ID        string    `json:"id"`
	ParentID  *string   `json:"parentId"`
	Timestamp time.Time `json:"timestamp"`
}

EntryBase contains common fields for all session entries.

type EntryType

type EntryType string

EntryType identifies the type of a session entry.

const (
	EntrySession               EntryType = "session"
	EntryMessage               EntryType = "message"
	EntryModelChange           EntryType = "model_change"
	EntryModeChange            EntryType = "mode_change"
	EntryThinkingChange        EntryType = "thinking_level_change"
	EntryAdditionalDirectories EntryType = "additional_directories"
	EntryCompaction            EntryType = "compaction"
	EntryContentOverride       EntryType = "content_override"
	EntryBranchSummary         EntryType = "branch_summary"
	EntryCustom                EntryType = "custom"
	EntryCustomMessage         EntryType = "custom_message"
	EntryLabel                 EntryType = "label"
	EntrySessionInfo           EntryType = "session_info"
	EntryTurnStart             EntryType = "turn_start"
	EntryTurnEnd               EntryType = "turn_end"
)

type ExecutionIntent

type ExecutionIntent struct {
	ID                 string
	SessionID          string
	Source             string
	Model              string
	Mode               string
	WorkDir            string
	RequestFingerprint string
	Request            json.RawMessage
	Policy             json.RawMessage
	CreatedAt          time.Time
}

ExecutionIntent is the durable, adapter-neutral record of an accepted user request. Request and policy snapshots are opaque to session storage; the shared Runtime owns their interpretation.

func GetExecutionIntent

func GetExecutionIntent(sessionDir, intentID string) (*ExecutionIntent, error)

type ForkKind

type ForkKind string
const (
	ForkKindSession ForkKind = "session"
	ForkKindMessage ForkKind = "message"
	ForkKindUnknown ForkKind = ""
)

type ForkOptions

type ForkOptions struct {
	SourceSessionID string
	AtSeq           *int64
	RequestID       string
	TitleMode       string
	// ExpertID overrides the forked session's expert binding when non-nil
	// (empty string unbinds); nil preserves the source session's binding.
	ExpertID *string
}

type ForkResult

type ForkResult struct {
	SessionID       string   `json:"sessionId"`
	ParentSessionID string   `json:"parentSessionId"`
	ForkKind        ForkKind `json:"forkKind"`
	BoundarySeq     int64    `json:"boundarySeq"`
	SeedLength      int64    `json:"seedLength"`
}

func ForkSession

func ForkSession(ctx context.Context, sessionDir string, options ForkOptions) (ForkResult, error)

type GeneratedArtifact

type GeneratedArtifact struct {
	ID        string
	SessionID string
	RunID     string
	Origin    string
	Kind      string
	Filename  string
	MediaType string
	Bytes     int64
	Status    string
	CreatedAt time.Time
}

GeneratedArtifact is the canonical read-only projection of one persisted session attachment row. Despite the artifact-oriented name it projects any attachment origin/status; the bytes themselves stay in the Runtime-owned private store referenced by the attachment row and are never embedded here.

func ListGeneratedArtifacts

func ListGeneratedArtifacts(ctx context.Context, sessionDir, sessionID string) ([]GeneratedArtifact, error)

ListGeneratedArtifacts returns every attachment persisted for sessionID whose lifecycle status is "generated", in durable creation order. Adapters use it for replay projections (for example ACP session/load); content access stays with the Runtime-owned attachment service and all SQL stays in the DAO.

func ListSessionAttachments

func ListSessionAttachments(ctx context.Context, sessionDir, sessionID, status string) ([]GeneratedArtifact, error)

ListSessionAttachments returns metadata-only projections of the persisted attachment rows of one session, optionally filtered by lifecycle status (an empty status returns every row), in durable creation order. Adapters use it for listing surfaces (for example ACP mothx/attachment/list); content access stays with the Runtime-owned attachment service and all SQL stays in the DAO.

type Header struct {
	Type            EntryType `json:"type"`
	Version         int       `json:"version"`
	ID              string    `json:"id"`
	Timestamp       time.Time `json:"timestamp"`
	Cwd             string    `json:"cwd"`
	ParentSession   string    `json:"parentSession,omitempty"`
	ChannelType     string    `json:"channelType,omitempty"`
	ChannelID       string    `json:"channelId,omitempty"`
	ForkBoundarySeq int64     `json:"forkBoundarySeq,omitempty"`
	SeedLength      int64     `json:"seedLength,omitempty"`
	ForkKind        string    `json:"forkKind,omitempty"`
	// ExpertID is the bound expert bundle name (empty = no expert identity).
	// Persisted like the channel binding fields so reloads restore identity.
	ExpertID string `json:"expertId,omitempty"`
}

Header is the first line of a session file.

type IdentityLocks

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

IdentityLocks serializes operations for one external channel identity. It is shared by inbound dispatch and session lifecycle management. Entries are evicted once the last holder releases them so the map does not grow without bound in long-running processes.

func NewIdentityLocks

func NewIdentityLocks() *IdentityLocks

func (*IdentityLocks) Lock

func (s *IdentityLocks) Lock(channelType, channelID string) func()

type InputResourceEvent

type InputResourceEvent struct {
	ID         string
	SessionID  string
	ResourceID string
	RunID      string
	EventType  string
	Status     string
	Timestamp  time.Time
	Data       json.RawMessage
}

InputResourceEvent is the canonical lifecycle projection for one Runtime materialized resource. Transport references are intentionally absent.

func ListInputResourceEvents

func ListInputResourceEvents(ctx context.Context, sessionDir, sessionID string) ([]InputResourceEvent, error)

ListInputResourceEvents returns resource lifecycle events in durable order.

type KnowledgeBase

type KnowledgeBase struct {
	ID string `json:"id"`
	KnowledgeBaseSpec
	ActiveSnapshotID string    `json:"activeSnapshotId,omitempty"`
	CreatedAt        time.Time `json:"createdAt"`
	UpdatedAt        time.Time `json:"updatedAt"`
	ConfigRevision   int64     `json:"-"`
}

func CreateKnowledgeBase

func CreateKnowledgeBase(ctx context.Context, sessionDir string, spec KnowledgeBaseSpec) (KnowledgeBase, error)

func GetKnowledgeBase

func GetKnowledgeBase(ctx context.Context, sessionDir, id string) (KnowledgeBase, error)

func ListKnowledgeBases

func ListKnowledgeBases(ctx context.Context, sessionDir string) ([]KnowledgeBase, error)

func UpdateKnowledgeBase

func UpdateKnowledgeBase(ctx context.Context, sessionDir, id string, spec KnowledgeBaseSpec) (KnowledgeBase, error)

type KnowledgeBaseSpec

type KnowledgeBaseSpec struct {
	Name              string `json:"name"`
	RootDir           string `json:"rootDir"`
	PreprocessProfile string `json:"preprocessProfile"`
	Provider          string `json:"provider"`
	Model             string `json:"model"`
	Mode              string `json:"mode"`
	ThinkingLevel     string `json:"thinkingLevel,omitempty"`
	Schedule          string `json:"schedule"`
	Enabled           bool   `json:"enabled"`
}

KnowledgeBaseSpec is the editable Desktop configuration. It deliberately stores provider/model/mode as references, not copied provider credentials.

type KnowledgeChunk

type KnowledgeChunk struct {
	ID            string `json:"id"`
	SnapshotID    string `json:"snapshotId"`
	FileID        string `json:"fileId"`
	RelativePath  string `json:"relativePath,omitempty"`
	Ordinal       int    `json:"ordinal"`
	Text          string `json:"text"`
	StartLine     int    `json:"startLine"`
	EndLine       int    `json:"endLine"`
	ContentSHA256 string `json:"contentSha256"`
}

type KnowledgeEdge

type KnowledgeEdge struct {
	ID           string  `json:"id"`
	SnapshotID   string  `json:"snapshotId"`
	FromNodeID   string  `json:"fromNodeId"`
	ToNodeID     string  `json:"toNodeId"`
	RelationType string  `json:"relationType"`
	Confidence   float64 `json:"confidence"`
}

type KnowledgeEvidence

type KnowledgeEvidence struct {
	ID         string  `json:"id"`
	SnapshotID string  `json:"snapshotId"`
	NodeID     string  `json:"nodeId,omitempty"`
	EdgeID     string  `json:"edgeId,omitempty"`
	ChunkID    string  `json:"chunkId"`
	StartLine  int     `json:"startLine"`
	EndLine    int     `json:"endLine"`
	Confidence float64 `json:"confidence"`
}

type KnowledgeFile

type KnowledgeFile struct {
	ID            string `json:"id"`
	SnapshotID    string `json:"snapshotId"`
	RelativePath  string `json:"relativePath"`
	ContentSHA256 string `json:"contentSha256"`
	ByteSize      int64  `json:"byteSize"`
	MediaType     string `json:"mediaType"`
	Title         string `json:"title,omitempty"`
	Status        string `json:"status"`
}

type KnowledgeFileGraph

type KnowledgeFileGraph struct {
	File     KnowledgeFile
	Chunks   []KnowledgeChunk
	Nodes    []KnowledgeNode
	Edges    []KnowledgeEdge
	Evidence []KnowledgeEvidence
}

KnowledgeFileGraph is the self-contained, evidence-backed subgraph owned by one source file. It is used to carry unchanged file work from an immutable snapshot into its successor without re-running extractors or an Indexer.

type KnowledgeGraphQuery

type KnowledgeGraphQuery struct {
	KnowledgeBase KnowledgeBase     `json:"knowledgeBase"`
	Snapshot      KnowledgeSnapshot `json:"snapshot"`
	Chunks        []KnowledgeChunk  `json:"chunks"`
	Nodes         []KnowledgeNode   `json:"nodes"`
	Edges         []KnowledgeEdge   `json:"edges"`
}

func QueryKnowledgeGraph

func QueryKnowledgeGraph(ctx context.Context, sessionDir, baseID, query string, limit int) (KnowledgeGraphQuery, error)

QueryKnowledgeGraph executes the local FTS seed lookup followed by a bounded graph projection. It never reads the source directory itself; the active completed snapshot is the sole query authority.

type KnowledgeGraphReusePlan

type KnowledgeGraphReusePlan struct {
	BaseConfigRevision int64
	SourceSnapshotID   string
	Files              map[string]KnowledgeFileGraph // key: normalized relative path
}

KnowledgeGraphReusePlan contains source-file subgraphs that still match the current directory manifest. The caller must clone them into a new snapshot; no row, node, chunk or edge identity is shared between snapshots.

func PrepareKnowledgeGraphReusePlan

func PrepareKnowledgeGraphReusePlan(ctx context.Context, sessionDir, baseID string, manifest []KnowledgeFile) (KnowledgeGraphReusePlan, error)

PrepareKnowledgeGraphReusePlan loads unchanged per-file graph work from the active snapshot. It is deliberately all-or-nothing per file: an edge whose endpoint or evidence escapes the file is omitted rather than claiming an unverified cross-file relationship in the successor snapshot.

type KnowledgeGraphSnapshot

type KnowledgeGraphSnapshot struct {
	BaseConfigRevision int64
	Snapshot           KnowledgeSnapshot
	Files              []KnowledgeFile
	Chunks             []KnowledgeChunk
	Nodes              []KnowledgeNode
	Edges              []KnowledgeEdge
	Evidence           []KnowledgeEvidence
}

KnowledgeGraphSnapshot is the immutable payload committed by a successful indexer. The session package atomically stores it and switches the active snapshot only after all graph rows are durable.

type KnowledgeNode

type KnowledgeNode struct {
	ID              string `json:"id"`
	SnapshotID      string `json:"snapshotId"`
	Kind            string `json:"kind"`
	Label           string `json:"label"`
	NormalizedLabel string `json:"normalizedLabel"`
	Summary         string `json:"summary,omitempty"`
}

type KnowledgeSnapshot

type KnowledgeSnapshot struct {
	ID              string    `json:"id"`
	KnowledgeBaseID string    `json:"knowledgeBaseId"`
	RunID           string    `json:"runId,omitempty"`
	Status          string    `json:"status"`
	SchemaVersion   int       `json:"schemaVersion"`
	FileCount       int       `json:"fileCount"`
	ChunkCount      int       `json:"chunkCount"`
	NodeCount       int       `json:"nodeCount"`
	EdgeCount       int       `json:"edgeCount"`
	StartedAt       time.Time `json:"startedAt"`
	FinishedAt      time.Time `json:"finishedAt,omitempty"`
	ErrorSummary    string    `json:"errorSummary,omitempty"`
}

func GetKnowledgeSnapshot

func GetKnowledgeSnapshot(ctx context.Context, sessionDir, id string) (KnowledgeSnapshot, error)

func ReuseKnowledgeSnapshotIfFilesMatch

func ReuseKnowledgeSnapshotIfFilesMatch(ctx context.Context, sessionDir, baseID string, expectedRevision int64, files []KnowledgeFile) (KnowledgeSnapshot, bool, error)

ReuseKnowledgeSnapshotIfFilesMatch returns the active immutable snapshot when the deterministic scan produced the exact same indexable file set. It deliberately compares content hashes rather than timestamps so a caller cannot serve stale knowledge merely because a tool preserved mtimes.

func StoreKnowledgeGraphSnapshot

func StoreKnowledgeGraphSnapshot(ctx context.Context, sessionDir string, graph KnowledgeGraphSnapshot) (KnowledgeSnapshot, error)

type LabelEntry

type LabelEntry struct {
	EntryBase
	TargetID string  `json:"targetId"`
	Label    *string `json:"label,omitempty"`
}

LabelEntry records a user-defined label on an entry.

type LeftBehindEntry

type LeftBehindEntry struct {
	// Name is the entry name relative to the session directory.
	Name string
	// Directory reports whether the entry is a directory.
	Directory bool
	// Bytes is the entry size, summed recursively for directories. Symbolic
	// links are not followed.
	Bytes int64
}

LeftBehindEntry is one session-directory entry that outlives a reset.

type ListOption

type ListOption func(*listOptions)

func WithLimit

func WithLimit(limit int) ListOption

func WithMessagesOnly

func WithMessagesOnly() ListOption

WithMessagesOnly limits session listings to sessions containing at least one persisted conversation message. This avoids loading transient empty sessions during history pagination.

func WithOffset

func WithOffset(offset int) ListOption

func WithSearch

func WithSearch(search string) ListOption

WithSearch filters sessions by ID, work directory, channel metadata, or persisted message/session-info content. It is intended for session listings.

type Manager

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

Manager manages a single session's state and persistence.

func ContinueRecent

func ContinueRecent(cwd, sessionDir string) (*Manager, error)

ContinueRecent continues the most recent session for a directory, or creates new.

func CreateBound

func CreateBound(workDir, sessionDir, channelType, channelID string) (*Manager, error)

func New

func New(cwd, sessionDir string) *Manager

New creates a new session manager for a new session.

func NewSubAgent

func NewSubAgent(cwd, sessionDir string) *Manager

NewSubAgent creates a session manager whose records are stored separately from user-continuable sessions.

func Open

func Open(path string) (*Manager, error)

Open opens an existing session file.

func OpenByID

func OpenByID(cwd, sessionDir, sessionID string) (*Manager, error)

OpenByID opens the session for cwd whose session ID matches sessionID. Supports prefix matching — if sessionID matches multiple sessions, an error is returned.

func OpenByIDExact

func OpenByIDExact(sessionDir, sessionID string) (*Manager, error)

OpenByIDExact opens a session by exact session ID regardless of cwd.

func OpenByPathOrID

func OpenByPathOrID(cwd, sessionDir, value string) (*Manager, error)

OpenByPathOrID opens a session using either an explicit file path or a session ID for the supplied working directory.

func RotateBoundSession

func RotateBoundSession(workDir, sessionDir, channelType, channelID, oldSessionID string) (*Manager, error)

RotateBoundSession atomically creates a new bound session and clears the old one.

func (*Manager) AppendAdditionalDirectories

func (m *Manager) AppendAdditionalDirectories(directories []string) (string, error)

AppendAdditionalDirectories records a complete replacement of the session's additional directory roots.

func (*Manager) AppendCompaction

func (m *Manager) AppendCompaction(summary, firstKeptEntryID string, tokensBefore int) (string, error)

AppendCompaction records a context compaction.

func (*Manager) AppendContentOverride

func (m *Manager) AppendContentOverride(targetEntryID string, msg provider.Message, reason, code string) (string, error)

AppendContentOverride records an append-only replacement of a persisted message entry's content. Replay substitutes msg for the target entry while the original entry stays in the log for audit. It is the durable half of the provider content-rejection recovery: when a provider permanently refuses an image, the Runtime strips it in memory and records the override so every later replay (this process or a reload) never re-sends the refused content.

func (*Manager) AppendMessage

func (m *Manager) AppendMessage(msg provider.Message) (string, error)

AppendMessage adds a message entry.

func (*Manager) AppendMessages

func (m *Manager) AppendMessages(msgs []provider.Message) ([]string, error)

AppendMessages persists an ordered batch of conversation messages, folding one agent iteration's worth of tool results into a bounded number of write transactions (see maxEntriesPerTransaction) instead of one transaction per message. Entries are chained parent-to-child in order; the lease fence and the leaf-conflict check run once per transaction and provide the same guarantees AppendMessage provides per entry. On failure no entry of the failing transaction is persisted while messages committed by earlier chunk transactions stay durable — the same contract as a sequence of AppendMessage calls failing halfway through.

func (*Manager) AppendModeChange

func (m *Manager) AppendModeChange(mode string) (string, error)

AppendModeChange records a session execution mode change.

func (*Manager) AppendModelChange

func (m *Manager) AppendModelChange(providerName, modelID string) (string, error)

AppendModelChange records a model change.

func (*Manager) AppendSessionInfo

func (m *Manager) AppendSessionInfo(name string) (string, error)

AppendSessionInfo records a session display name. It is retained for compatibility; new callers should use AppendSessionTitle with a source.

func (*Manager) AppendSessionTitle

func (m *Manager) AppendSessionTitle(name, source string) (string, error)

AppendSessionTitle records a session display name and its origin.

func (*Manager) AppendThinkingLevelChange

func (m *Manager) AppendThinkingLevelChange(level string) (string, error)

AppendThinkingLevelChange records a thinking level change.

func (*Manager) EndConversationTurn

func (m *Manager) EndConversationTurn(turnID, status, stopReason string) error

EndConversationTurn closes the durable boundary used by Session fork resolution. It is safe for callers to report failed, cancelled and incomplete outcomes; all are terminal turn states.

func (*Manager) GetExpertID

func (m *Manager) GetExpertID() string

GetExpertID returns the bound expert bundle name ("" when unbound).

func (*Manager) GetFile

func (m *Manager) GetFile() string

GetFile returns the session file path.

func (*Manager) GetHeader

func (m *Manager) GetHeader() *Header

GetHeader returns the session header.

func (*Manager) GetLatestAdditionalDirectories

func (m *Manager) GetLatestAdditionalDirectories() (AdditionalDirectoriesEntry, bool)

GetLatestAdditionalDirectories returns the latest complete directory-root binding persisted in this session.

func (*Manager) GetLatestCompaction

func (m *Manager) GetLatestCompaction() (CompactionEntry, bool)

GetLatestCompaction returns the newest compaction entry in the current session.

func (*Manager) GetLatestModeChange

func (m *Manager) GetLatestModeChange() (ModeChangeEntry, bool)

GetLatestModeChange returns the newest session mode in the session.

func (*Manager) GetLatestModelChange

func (m *Manager) GetLatestModelChange() (ModelChangeEntry, bool)

GetLatestModelChange returns the newest model binding in the session.

func (*Manager) GetLatestThinkingLevelChange

func (m *Manager) GetLatestThinkingLevelChange() (ThinkingLevelChangeEntry, bool)

GetLatestThinkingLevelChange returns the newest thinking level in the session.

func (*Manager) GetLeafID

func (m *Manager) GetLeafID() *string

GetLeafID returns the current leaf entry ID.

func (*Manager) GetMessages

func (m *Manager) GetMessages() []provider.Message

GetMessages extracts all messages from the current branch.

func (*Manager) GetReplayState

func (m *Manager) GetReplayState() ReplayState

GetReplayState returns the current branch after applying compaction entries.

func (*Manager) GetSessionDir

func (m *Manager) GetSessionDir() string

GetSessionDir returns the root directory containing this manager's shared sessions database. Runtime extensions use it for auxiliary session tables.

func (*Manager) Init

func (m *Manager) Init() error

Init initializes a new session with an auto-generated session ID. Must be called before appending entries.

func (*Manager) InitWithBinding

func (m *Manager) InitWithBinding(channelType, channelID string) error

InitWithBinding initializes a new session with a channel binding.

func (*Manager) InitWithID

func (m *Manager) InitWithID(id string) error

InitWithID initializes a new session using the provided session ID. If id is empty, a new random ID is generated.

func (*Manager) InitWithIDAndBinding

func (m *Manager) InitWithIDAndBinding(id, channelType, channelID string) error

InitWithIDAndBinding initializes a session with a specific ID and channel binding.

func (*Manager) RecordUsage

func (m *Manager) RecordUsage(provider, protocol, model string, inputTokens, outputTokens, totalTokens, durationMs int) error

RecordUsage records a single LLM request's token usage and timing.

func (*Manager) RecordUsageFromProviderUsage

func (m *Manager) RecordUsageFromProviderUsage(provider, protocol, model string, usage *provider.Usage, durationMs int) error

RecordUsageFromProviderUsage records usage from a provider.Usage struct.

func (*Manager) Reload

func (m *Manager) Reload() error

Reload refreshes a manager from the shared SQLite session database. Serve entry points may retain a Manager while another UI writes the same session; reload after acquiring the session runtime lock so the next append uses the current leaf instead of an old optimistic-lock parent.

func (*Manager) SetExpertBinding

func (m *Manager) SetExpertBinding(expertID string) error

SetExpertBinding updates the session's expert binding (empty string unbinds). It patches the in-memory header and persists the sessions row so reloads restore the identity; callers rebuild the Agent afterwards (same lifecycle as capability toggles such as /delegate).

func (*Manager) SetSessionBinding

func (m *Manager) SetSessionBinding(channelType, channelID string) error

SetSessionBinding updates a Manager's in-memory header after a binding change.

func (*Manager) SetWorkDir

func (m *Manager) SetWorkDir(cwd string) error

SetWorkDir changes the persisted working directory of an idle session. The caller is responsible for ensuring that the new directory is authorized and for rebuilding any Runtime resources that were assembled for the old one.

func (*Manager) StartConversationTurn

func (m *Manager) StartConversationTurn(turnID, intentID, runID string) error

StartConversationTurn opens the durable boundary used by Session fork resolution. It is intentionally optional on session.Store so transient and in-memory agents do not need a SQLite turn index.

type MemoryStore

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

MemoryStore is an in-memory implementation of Store for testing. It does not persist data to disk.

func NewMemoryStore

func NewMemoryStore() *MemoryStore

NewMemoryStore creates a new in-memory session store.

func (*MemoryStore) AppendAdditionalDirectories

func (m *MemoryStore) AppendAdditionalDirectories(directories []string) (string, error)

func (*MemoryStore) AppendCompaction

func (m *MemoryStore) AppendCompaction(summary, firstKeptEntryID string, tokensBefore int) (string, error)

func (*MemoryStore) AppendMessage

func (m *MemoryStore) AppendMessage(msg provider.Message) (string, error)

func (*MemoryStore) AppendModeChange

func (m *MemoryStore) AppendModeChange(mode string) (string, error)

func (*MemoryStore) AppendModelChange

func (m *MemoryStore) AppendModelChange(providerName, modelID string) (string, error)

func (*MemoryStore) AppendSessionInfo

func (m *MemoryStore) AppendSessionInfo(name string) (string, error)

func (*MemoryStore) AppendThinkingLevelChange

func (m *MemoryStore) AppendThinkingLevelChange(level string) (string, error)

func (*MemoryStore) GetFile

func (m *MemoryStore) GetFile() string

func (*MemoryStore) GetHeader

func (m *MemoryStore) GetHeader() *Header

func (*MemoryStore) GetLatestAdditionalDirectories

func (m *MemoryStore) GetLatestAdditionalDirectories() (AdditionalDirectoriesEntry, bool)

func (*MemoryStore) GetLatestCompaction

func (m *MemoryStore) GetLatestCompaction() (CompactionEntry, bool)

func (*MemoryStore) GetLatestModeChange

func (m *MemoryStore) GetLatestModeChange() (ModeChangeEntry, bool)

func (*MemoryStore) GetLatestModelChange

func (m *MemoryStore) GetLatestModelChange() (ModelChangeEntry, bool)

func (*MemoryStore) GetLatestThinkingLevelChange

func (m *MemoryStore) GetLatestThinkingLevelChange() (ThinkingLevelChangeEntry, bool)

func (*MemoryStore) GetLeafID

func (m *MemoryStore) GetLeafID() *string

func (*MemoryStore) GetMessages

func (m *MemoryStore) GetMessages() []provider.Message

func (*MemoryStore) GetReplayState

func (m *MemoryStore) GetReplayState() ReplayState

func (*MemoryStore) Init

func (m *MemoryStore) Init() error

func (*MemoryStore) InitWithID

func (m *MemoryStore) InitWithID(id string) error

type MessageEntry

type MessageEntry struct {
	EntryBase
	Message provider.Message `json:"message"`
}

MessageEntry contains a conversation message.

type ModeChangeEntry

type ModeChangeEntry struct {
	EntryBase
	Mode string `json:"mode"`
}

ModeChangeEntry records a session execution mode change.

type ModelChangeEntry

type ModelChangeEntry struct {
	EntryBase
	Provider string `json:"provider"`
	ModelID  string `json:"modelId"`
}

ModelChangeEntry records a model switch.

func LatestModelChangeByID

func LatestModelChangeByID(sessionDir, sessionID string) (ModelChangeEntry, bool, error)

LatestModelChangeByID reads the replayed provider/model binding for a session without exposing SQLite details to protocol adapters.

type Project

type Project struct {
	ID        string    `json:"id"`
	Name      string    `json:"name"`
	CreatedAt time.Time `json:"createdAt"`
	UpdatedAt time.Time `json:"updatedAt"`
}

func CreateProject

func CreateProject(sessionDir, name string) (Project, error)

func ListProjects

func ListProjects(sessionDir string) ([]Project, error)

func RenameProject

func RenameProject(sessionDir, id, name string) (Project, error)

type ReplayState

type ReplayState struct {
	Messages []provider.Message
	EntryIDs []string
}

ReplayState is the reconstructed conversation state after applying compactions.

type ResetReport

type ResetReport struct {
	// DatabaseBackup is the renamed sessions.db. It is empty when no database
	// file existed before the reset.
	DatabaseBackup string
	// Archived lists every file the reset moved aside, database first then each
	// sidecar, so a caller can report what left the directory without deriving
	// the archive naming itself.
	Archived []ArchivedFile
	// LeftBehind lists the session-directory entries a reset does not archive.
	// Attachment, channel, and knowledge-base storage each derive their own
	// paths elsewhere, so the reset reports everything beside sessions.db
	// instead of restating those rules.
	LeftBehind []LeftBehindEntry
}

ResetReport describes what one sessions database reset did, and what it deliberately did not do.

func ResetDatabase

func ResetDatabase(sessionDir string) (ResetReport, error)

ResetDatabase moves the shared sessions database aside and creates a fresh, migrated one in its place. The previous database and its sidecars are renamed (never deleted) next to the new file, so the old sessions remain recoverable. A sidecar that outlived its database - an interrupted reset, or a database deleted by hand - is archived under the same name as well: leaving it in place would let the fresh database inherit it and make SQLite's own handling of the leftover decide whether startup succeeds.

Callers must ensure no other process is running against the session directory: a database moved while another process still holds it open keeps being written there, and this process cannot detect that. ActiveRuntimeLeases reports the processes known to hold a run in the database being archived.

type ResponseItemArchive

type ResponseItemArchive struct {
	ID            int64
	SessionID     string
	LocalTurnID   string
	ResponseID    string
	ItemID        string
	OutputIndex   int
	ItemType      string
	ItemStatus    string
	ItemKey       string
	SanitizedJSON json.RawMessage
	CreatedAt     time.Time
}

ResponseItemArchive stores one sanitized normalized item. Raw provider request/response bodies must not be passed here.

func ListResponseItems

func ListResponseItems(sessionDir, sessionID, localTurnID string) ([]ResponseItemArchive, error)

type ResponseReplayTurn

type ResponseReplayTurn struct {
	LocalTurnID string
	Items       []json.RawMessage
}

ResponseReplayTurn groups the native output items belonging to one local Responses turn. It lets callers place those items at the corresponding assistant position while rebuilding a complete local conversation.

func ListResponseReplayTurns

func ListResponseReplayTurns(sessionDir, sessionID string, limit int) ([]ResponseReplayTurn, error)

ListResponseReplayTurns returns completed native output grouped by local turn, ordered by their original completion order.

type ResponseRun

type ResponseRun struct {
	ID                int64     `json:"id"`
	SessionID         string    `json:"sessionId"`
	LocalRunID        string    `json:"localRunId"`
	LocalTurnID       string    `json:"localTurnId,omitempty"`
	MessageID         *int64    `json:"messageId,omitempty"`
	ResponseID        string    `json:"responseId,omitempty"`
	Provider          string    `json:"provider"`
	API               string    `json:"api"`
	State             string    `json:"state"`
	PollingURL        string    `json:"pollingUrl,omitempty"`
	LastEventSequence *int64    `json:"lastEventSequence,omitempty"`
	CancelRequested   bool      `json:"cancelRequested,omitempty"`
	CreatedAt         time.Time `json:"createdAt"`
	UpdatedAt         time.Time `json:"updatedAt"`
}

ResponseRun is the durable state for a Responses background run.

func GetResponseRun

func GetResponseRun(sessionDir, sessionID, localRunID string) (*ResponseRun, error)

func ListResponseRuns

func ListResponseRuns(sessionDir, sessionID string, limit int) ([]ResponseRun, error)

type ResponseSessionState

type ResponseSessionState struct {
	SessionID          string
	StateMode          string
	PreviousResponseID string
	ConversationID     string
	Provider           string
	API                string
	Model              string
	Version            int64
	UpdatedAt          time.Time
}

ResponseSessionState is the compare-and-swap protected remote lineage for a single local session. Provider config supplies defaults; this record keeps concurrent sessions and concurrent turns from sharing mutable remote state.

func GetResponseSessionState

func GetResponseSessionState(sessionDir, sessionID string) (*ResponseSessionState, error)

GetResponseSessionState returns the durable remote lineage for a local session. A missing record means the caller must use its configured default, normally replay mode.

type ResponseTurn

type ResponseTurn struct {
	ID                 int64
	SessionID          string
	LocalTurnID        string
	MessageID          *int64
	RequestID          string
	ResponseID         string
	PreviousResponseID string
	ConversationID     string
	Provider           string
	API                string
	Model              string
	StateMode          string
	Status             string
	IncompleteReason   string
	RequestSummary     json.RawMessage
	ResponseSummary    json.RawMessage
	CreatedAt          time.Time
	CompletedAt        *time.Time
}

ResponseTurn is the durable lineage and lifecycle summary for one Responses API turn. It intentionally contains summaries, not a second transcript.

func GetResponseTurn

func GetResponseTurn(sessionDir, sessionID, localTurnID string) (*ResponseTurn, error)

type RuntimeLeaseBinding

type RuntimeLeaseBinding struct {
	DatabaseIdentity string
	SessionID        string
	RunID            string
	OwnerInstanceID  string
	TokenHash        string
	Epoch            int64
	Purpose          RuntimeLeasePurpose
}

RuntimeLeaseBinding is the Runtime-owned identity of an acquired Session lease. It is safe to expose to trusted in-process code for diagnostics and matching, but must never be accepted from an adapter or client as authority.

func BindRuntimeLeaseToExistingRun

func BindRuntimeLeaseToExistingRun(sessionDir, sessionID, runID string) (RuntimeLeaseBinding, error)

BindRuntimeLeaseToExistingRun promotes a recovery/legacy lease to execution only while the expected Run is still the Session's sole non-terminal Run. Reattach paths call this before registering an in-memory execution.

func CurrentRuntimeLeaseBinding

func CurrentRuntimeLeaseBinding(sessionDir, sessionID string) (RuntimeLeaseBinding, bool)

CurrentRuntimeLeaseBinding returns the lease identity held by this process. It is intended for internal/agentruntime registration and diagnostics only; durable control operations must still revalidate the database row.

func RetainRuntimeLease

func RetainRuntimeLease(sessionDir, sessionID, runID string) (RuntimeLeaseBinding, func(), bool, error)

RetainRuntimeLease adds a Runtime-owned reference to the current execution lease. The caller-owned RuntimeLeaseGuard may be released independently; the durable lease remains active until the returned release function is called. This is intentionally an in-process handoff primitive, never a client-facing authorization mechanism.

type RuntimeLeaseGroup

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

RuntimeLeaseGroup owns an ordered set of Session leases acquired for one multi-Session mutation.

func AcquireMutations

func AcquireMutations(sessionDir string, sessionIDs []string) (*RuntimeLeaseGroup, error)

AcquireMutations reserves multiple idle Sessions in stable order so a cross-Session mutation cannot deadlock another caller taking the same set.

func (*RuntimeLeaseGroup) Guard

func (g *RuntimeLeaseGroup) Guard(sessionID string) *RuntimeLeaseGuard

Guard returns the mutation guard this group holds for sessionID. It is used by one shared multi-session operation to fence each per-session write inside its own transaction without attempting to reacquire the process-local lock.

func (*RuntimeLeaseGroup) Release

func (g *RuntimeLeaseGroup) Release()

Release relinquishes grouped leases in reverse acquisition order.

type RuntimeLeaseGuard

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

RuntimeLeaseGuard owns both the process-local mutex and the durable SQLite lease. Release is idempotent and must be called after every successful acquisition.

func AcquireExecutionAdmission

func AcquireExecutionAdmission(sessionDir, sessionID string) (*RuntimeLeaseGuard, error)

AcquireExecutionAdmission reserves an existing idle Session for a new Run. The durable admission transaction must subsequently bind the new run ID and transition this same lease to purpose=execution.

func AcquireFork

func AcquireFork(sessionDir, sessionID string) (*RuntimeLeaseGuard, error)

AcquireFork reserves an idle source Session while a child snapshot is made.

func AcquireMutation

func AcquireMutation(sessionDir, sessionID string) (*RuntimeLeaseGuard, error)

AcquireMutation reserves an idle Session for a short non-execution change.

func AcquireRecovery

func AcquireRecovery(sessionDir, sessionID, expectedRunID string) (*RuntimeLeaseGuard, error)

AcquireRecovery claims an unowned or expired active Run for fenced recovery.

func AcquireRecoveryContext

func AcquireRecoveryContext(ctx context.Context, sessionDir, sessionID, expectedRunID string) (*RuntimeLeaseGuard, error)

AcquireRecoveryContext bounds the lease acquisition transaction by the recovery attempt deadline.

func (*RuntimeLeaseGuard) Binding

Binding returns the exact identity acquired by this process.

func (*RuntimeLeaseGuard) Lost

func (g *RuntimeLeaseGuard) Lost() <-chan struct{}

Lost reports when the durable lease can no longer be renewed.

func (*RuntimeLeaseGuard) Release

func (g *RuntimeLeaseGuard) Release()

Release relinquishes the durable lease and then the process-local mutex.

type RuntimeLeaseNotification

type RuntimeLeaseNotification struct {
	Version   int    `json:"version"`
	MessageID string `json:"messageId"`
	Type      string `json:"type"`
	SessionID string `json:"sessionId,omitempty"`
	// Path names the database file for the database_rebuilt wake-up; lease
	// notifications leave it empty because they are session-scoped.
	Path             string `json:"path,omitempty"`
	Origin           string `json:"origin,omitempty"`
	OriginInstanceID string `json:"originInstanceId"`
	OwnerInstanceID  string `json:"ownerInstanceId,omitempty"`
	Epoch            int64  `json:"epoch,omitempty"`
	ExpiresAt        int64  `json:"expiresAt,omitempty"`
}

RuntimeLeaseNotification is a best-effort local-process wake-up signal. SQLite leases and durable Run rows remain the sole authority: receivers must always re-read the database before projecting any state to a client.

Threat model: the UDP bus is unauthenticated. Any process on the same host can send spoofed notifications (only the loopback source address is checked). This is acceptable because notifications are advisory only; every receiver re-validates against the authoritative SQLite lease and Run rows before acting, so a forged packet can at most trigger a redundant database re-read (or, for a rebuild notice, retire a cached connection and log a warning), never an ownership or content change. The bus is deliberately host-only: it is a directed broadcast on the loopback network, so it never reaches another machine.

type RuntimeLeasePurpose

type RuntimeLeasePurpose string

RuntimeLeasePurpose describes why a process owns the Session-wide lease. Legacy rows use RuntimeLeasePurposeLegacyRun until all callers have migrated to an explicit purpose.

const (
	RuntimeLeasePurposeLegacyRun RuntimeLeasePurpose = "run"
	RuntimeLeasePurposeAdmission RuntimeLeasePurpose = "admission"
	RuntimeLeasePurposeExecution RuntimeLeasePurpose = "execution"
	RuntimeLeasePurposeRecovery  RuntimeLeasePurpose = "recovery"
	RuntimeLeasePurposeMutation  RuntimeLeasePurpose = "mutation"
	RuntimeLeasePurposeFork      RuntimeLeasePurpose = "fork"
)

type RuntimeLeaseSnapshot

type RuntimeLeaseSnapshot struct {
	SessionID       string
	OwnerInstanceID string
	OwnerPID        int
	OwnerKind       string
	TokenHash       string
	Epoch           int64
	RunID           string
	Purpose         RuntimeLeasePurpose
	State           string
	AcquiredAt      time.Time
	HeartbeatAt     time.Time
	ExpiresAt       time.Time
	UpdatedAt       time.Time
	Valid           bool
}

RuntimeLeaseSnapshot is an immutable database view of one Session lease. TokenHash is an internal identity component used only for matching a Runtime-owned binding; callers must never accept it back as authorization.

type RuntimeSubmission

type RuntimeSubmission struct {
	ID                 string
	SessionID          string
	Scope              string
	KeyHash            string
	RequestFingerprint string
	IntentID           string
	RunID              string
	CreatedAt          time.Time
}

RuntimeSubmission is the durable admission identity for one original or retry submission. Only a digest of the transport key is persisted.

func GetRuntimeSubmission

func GetRuntimeSubmission(ctx context.Context, sessionDir, sessionID, scope, keyHash string) (*RuntimeSubmission, error)

type RuntimeSubmissionError

type RuntimeSubmissionError struct {
	Existing RuntimeSubmission
	Conflict bool
}

RuntimeSubmissionError carries the canonical Run identity selected by a competing or replayed admission.

func (*RuntimeSubmissionError) Error

func (e *RuntimeSubmissionError) Error() string

func (*RuntimeSubmissionError) Unwrap

func (e *RuntimeSubmissionError) Unwrap() error

type SequencedMessage

type SequencedMessage struct {
	Seq     int64
	EntryID string
	Message provider.Message
}

SequencedMessage is a persisted conversation message with its entries.seq cursor.

func ListSessionMessagesAfter

func ListSessionMessagesAfter(sessionDir, sessionID string, afterSeq int64, limit int) ([]SequencedMessage, error)

ListSessionMessagesAfter returns persisted message rows after entries.seq.

func ListSessionMessagesBefore

func ListSessionMessagesBefore(sessionDir, sessionID string, beforeSeq int64, limit int) ([]SequencedMessage, error)

ListSessionMessagesBefore returns messages with seq < beforeSeq, newest first limited to `limit`.

func ListSessionMessagesLatest

func ListSessionMessagesLatest(sessionDir, sessionID string, limit int) ([]SequencedMessage, error)

ListSessionMessagesLatest returns the latest N message entries (highest seq first).

func ListSessionMessagesWithSeq

func ListSessionMessagesWithSeq(sessionDir, sessionID string) ([]SequencedMessage, error)

ListSessionMessagesWithSeq returns the visible replay messages for a session, preserving each message row's entries.seq cursor.

type SequencedSessionCapabilityEvent

type SequencedSessionCapabilityEvent struct {
	Seq   int64
	Event SessionCapabilityEvent
}

SequencedSessionCapabilityEvent is a capability event with its table cursor.

func ListSessionCapabilityEventsAfter

func ListSessionCapabilityEventsAfter(sessionDir, sessionID string, afterSeq int64, limit int) ([]SequencedSessionCapabilityEvent, error)

ListSessionCapabilityEventsAfter returns capability events after session_capability_events.seq.

func ListSessionCapabilityEventsWithSeq

func ListSessionCapabilityEventsWithSeq(sessionDir, sessionID string) ([]SequencedSessionCapabilityEvent, error)

ListSessionCapabilityEventsWithSeq returns capability events with their seq cursor.

type SequencedSessionRunEvent

type SequencedSessionRunEvent struct {
	Seq   int64
	Event SessionRunEvent
}

SequencedSessionRunEvent is a run lifecycle event with its table cursor.

func ListSessionRunEventsAfter

func ListSessionRunEventsAfter(sessionDir, sessionID string, afterSeq int64, limit int) ([]SequencedSessionRunEvent, error)

ListSessionRunEventsAfter returns run events after session_run_events.seq.

func ListSessionRunEventsWithSeq

func ListSessionRunEventsWithSeq(sessionDir, sessionID string) ([]SequencedSessionRunEvent, error)

ListSessionRunEventsWithSeq returns run events with their session_run_events.seq cursor.

type SessionCapabilities

type SessionCapabilities struct {
	SessionID    string
	Mode         string
	DisplayMode  string
	DelegateMode bool
	MultiAgent   bool
	Workflows    bool
	WebSearch    bool
	Browser      bool
	A2AMaster    bool
	UpdatedAt    time.Time
}

SessionCapabilities stores persisted per-session runtime capability state.

func LoadSessionCapabilities

func LoadSessionCapabilities(sessionDir, sessionID string) (*SessionCapabilities, bool, error)

LoadSessionCapabilities loads persisted capabilities for a session.

type SessionCapabilityEvent

type SessionCapabilityEvent struct {
	ID         string
	SessionID  string
	RunID      string
	EventType  string
	Source     string
	Actor      string
	Capability string
	OldValue   string
	NewValue   string
	Timestamp  time.Time
	Data       json.RawMessage
}

SessionCapabilityEvent records one capability state transition.

func ListSessionCapabilityEvents

func ListSessionCapabilityEvents(sessionDir, sessionID string) ([]SessionCapabilityEvent, error)

ListSessionCapabilityEvents returns capability events for a session, ordered by insertion.

type SessionDetail

type SessionDetail struct {
	SessionInfo
	ID           string
	MessageCount int
	Preview      string // first user message (truncated)
}

SessionDetail contains detailed metadata about a session for display.

func ListAllDetailed

func ListAllDetailed(sessionDir string, opts ...ListOption) ([]SessionDetail, error)

ListAllDetailed lists sessions with details across all working directories.

func ListForDirDetailed

func ListForDirDetailed(cwd, sessionDir string) ([]SessionDetail, error)

ListForDirDetailed lists sessions with details (ID, message count, preview).

type SessionExecutionFacts

type SessionExecutionFacts struct {
	DatabaseIdentity string
	SessionID        string
	SessionExists    bool
	DatabaseNow      time.Time
	ActiveRuns       []SessionRun
	Lease            *RuntimeLeaseSnapshot
	Recovery         *SessionRunRecovery
	RemoteRun        *ResponseRun
}

SessionExecutionFacts contains the durable Run and lease rows observed from one SQLite read transaction and one SQLite clock sample. ActiveRuns normally contains at most one row; retaining the slice lets Runtime surface corrupted or legacy databases with multiple active rows as inconsistent.

func ReadSessionExecutionFacts

func ReadSessionExecutionFacts(sessionDir, sessionID string) (SessionExecutionFacts, error)

ReadSessionExecutionFacts reads the durable execution facts for one Session from a single transaction. It deliberately does not consult process-local runtime state; internal/agentruntime combines this immutable view with its own registered execution bindings.

func ReadSessionExecutionFactsContext

func ReadSessionExecutionFactsContext(ctx context.Context, sessionDir, sessionID string) (SessionExecutionFacts, error)

ReadSessionExecutionFactsContext is the cancellable form used by bounded recovery attempts. The transaction and every query in the snapshot share the caller's deadline.

type SessionInfo

type SessionInfo struct {
	Path            string
	ModTime         time.Time
	Name            string
	Cwd             string
	ChannelType     string
	ChannelID       string
	ParentSession   string
	ForkBoundarySeq int64
	SeedLength      int64
	ForkKind        string
	ExpertID        string
}

SessionInfo contains metadata about a session file.

func ListAll

func ListAll(sessionDir string, opts ...ListOption) ([]SessionInfo, error)

ListAll lists session files across all working directories.

func ListForDir

func ListForDir(cwd, sessionDir string) ([]SessionInfo, error)

ListForDir lists session files for a given working directory.

type SessionInfoEntry

type SessionInfoEntry struct {
	EntryBase
	Name   string `json:"name"`
	Source string `json:"source,omitempty"` // "manual" or "auto"
}

SessionInfoEntry stores session metadata.

type SessionMetadata

type SessionMetadata struct {
	ProjectID string `json:"projectId,omitempty"`
	Pinned    bool   `json:"pinned"`
	// UpdatedAt is the persisted revision time of the metadata row. It is
	// read-only output; SetSessionMetadata always stamps the write time itself.
	UpdatedAt time.Time `json:"updatedAt,omitempty"`
}

func GetSessionMetadata

func GetSessionMetadata(sessionDir, sessionID string) (SessionMetadata, error)

type SessionRun

type SessionRun struct {
	ID           string
	SessionID    string
	IntentID     string
	RetryOf      string
	Attempt      int
	WorkDir      string
	Source       string
	Model        string
	Mode         string
	Status       string
	StartedAt    time.Time
	UpdatedAt    time.Time
	FinishedAt   *time.Time
	Error        string
	ErrorInfo    json.RawMessage
	Progress     json.RawMessage
	Usage        json.RawMessage
	ContextUsage json.RawMessage
	// InputResourceIDs are Runtime-prepared resources admitted with this Run.
	// They are bound by the same transaction as the intent/run/start event.
	InputResourceIDs []string
	// Submission fields are admission-only digests. They are reserved in the
	// same transaction as the intent, Run, turn, resources, and start event.
	SubmissionKeyHash     string
	SubmissionScope       string
	SubmissionFingerprint string
	// UserMessage is the canonical user entry admitted with a conversation
	// Run. It is admission-only; transcript replay remains the source of truth.
	UserEntryID string
	UserMessage *provider.Message
	// AssistantMessage is the final assistant entry held by the Runtime until
	// terminalization. It is intentionally transient and is committed together
	// with the terminal Run/turn and delivery plan.
	AssistantEntryID string
	AssistantMessage *provider.Message
	// DeliveryPlan is terminal-only. The terminal transaction creates its
	// outbox rows together with the Run, turn, and terminal event transition.
	DeliveryPlan *DeliveryPlan
}

SessionRun is the durable lifecycle record for one agent execution.

func GetActiveSessionRun

func GetActiveSessionRun(sessionDir, sessionID string) (*SessionRun, error)

func GetActiveSessionRunContext

func GetActiveSessionRunContext(ctx context.Context, sessionDir, sessionID string) (*SessionRun, error)

func GetSessionRun

func GetSessionRun(sessionDir, runID string) (*SessionRun, error)

func GetSessionRunContext

func GetSessionRunContext(ctx context.Context, sessionDir, runID string) (*SessionRun, error)

func LatestSessionRunForIntent

func LatestSessionRunForIntent(sessionDir, sessionID, intentID string) (*SessionRun, error)

LatestSessionRunForIntent returns the highest-attempt Run in an immutable intent chain. Retry admission uses it to prevent two callers from retrying an older terminal attempt after a newer attempt already exists.

func ListOrphanedSessionRuns

func ListOrphanedSessionRuns(sessionDir string) ([]SessionRun, error)

ListOrphanedSessionRuns returns all runs that are in a non-terminal state. This is used during server startup to recover runs that were active when the previous server instance stopped.

func ListOrphanedSessionRunsContext

func ListOrphanedSessionRunsContext(ctx context.Context, sessionDir string) ([]SessionRun, error)

func ListSessionRuns

func ListSessionRuns(sessionDir, sessionID string, limit int) ([]SessionRun, error)

type SessionRunEvent

type SessionRunEvent struct {
	ID        string
	SessionID string
	RunID     string
	EventType string
	Source    string
	Status    string
	Model     string
	Mode      string
	Timestamp time.Time
	Data      json.RawMessage
}

SessionRunEvent records one lifecycle event for a single chat/run execution.

func ListSessionRunEvents

func ListSessionRunEvents(sessionDir, sessionID string) ([]SessionRunEvent, error)

ListSessionRunEvents returns run events for a session, ordered by insertion.

func ListSessionRunEventsContext

func ListSessionRunEventsContext(ctx context.Context, sessionDir, sessionID string) ([]SessionRunEvent, error)

ListSessionRunEventsContext is the cancellable event replay query used by bounded recovery and reconnect paths.

type SessionRunRecovery

type SessionRunRecovery struct {
	RunID              string
	SessionID          string
	State              SessionRunRecoveryState
	TriggerSource      string
	ReasonCode         string
	Attempt            int
	PreviousLeaseEpoch int64
	LastError          string
	NextRetryAt        *time.Time
	StartedAt          time.Time
	UpdatedAt          time.Time
	CompletedAt        *time.Time
}

SessionRunRecovery is the durable diagnostic and retry state for orphan reconciliation. It never grants ownership; the recovery lease remains the sole authority for changing a Run.

func BeginSessionRunRecovery

func BeginSessionRunRecovery(sessionDir, sessionID, runID, triggerSource, reasonCode string, previousLeaseEpoch int64) (*SessionRunRecovery, error)

BeginSessionRunRecovery records an attempt while verifying the exact purpose=recovery lease and target Run in the same transaction.

func BeginSessionRunRecoveryContext

func BeginSessionRunRecoveryContext(ctx context.Context, sessionDir, sessionID, runID, triggerSource, reasonCode string, previousLeaseEpoch int64) (*SessionRunRecovery, error)

BeginSessionRunRecoveryContext is the cancellable form used by the bounded Runtime recovery coordinator.

func GetSessionRunRecovery

func GetSessionRunRecovery(sessionDir, runID string) (*SessionRunRecovery, error)

GetSessionRunRecovery returns the last durable recovery disposition for a Run. A missing row is represented by (nil, nil).

type SessionRunRecoveryState

type SessionRunRecoveryState string
const (
	SessionRunRecoveryRunning  SessionRunRecoveryState = "recovering"
	SessionRunRecoveryFailed   SessionRunRecoveryState = "failed"
	SessionRunRecoveryComplete SessionRunRecoveryState = "completed"
	SessionRunRecoveryDetached SessionRunRecoveryState = "detached_remote"
)

type Store

type Store interface {
	// Init initializes the session store, creating the underlying
	// database or storage if needed.
	Init() error

	// InitWithID initializes the session with a specific ID.
	// An empty id generates a new one.
	InitWithID(id string) error

	// AppendMessage persists a conversation message and returns its entry ID.
	AppendMessage(msg provider.Message) (string, error)

	// AppendCompaction records a context compaction event.
	AppendCompaction(summary, firstKeptEntryID string, tokensBefore int) (string, error)

	// AppendModelChange records a model switch.
	AppendModelChange(providerName, modelID string) (string, error)

	// AppendModeChange records a session execution mode change.
	AppendModeChange(mode string) (string, error)

	// AppendThinkingLevelChange records a thinking level change.
	AppendThinkingLevelChange(level string) (string, error)
	AppendAdditionalDirectories(directories []string) (string, error)

	// AppendSessionInfo records session metadata.
	AppendSessionInfo(name string) (string, error)

	// GetMessages returns all messages in the current branch,
	// with compaction summaries applied.
	GetMessages() []provider.Message

	// GetReplayState returns the full replay state including
	// messages and their entry IDs.
	GetReplayState() ReplayState

	// GetLeafID returns the current leaf entry ID, or nil if empty.
	GetLeafID() *string

	// GetLatestCompaction returns the most recent compaction entry,
	// or (zero, false) if none exists.
	GetLatestCompaction() (CompactionEntry, bool)

	// GetLatestModelChange returns the most recent persisted model binding.
	GetLatestModelChange() (ModelChangeEntry, bool)

	// GetLatestModeChange returns the most recent persisted session mode.
	GetLatestModeChange() (ModeChangeEntry, bool)

	// GetLatestThinkingLevelChange returns the most recent persisted thinking level.
	GetLatestThinkingLevelChange() (ThinkingLevelChangeEntry, bool)
	GetLatestAdditionalDirectories() (AdditionalDirectoriesEntry, bool)

	// GetFile returns the session file path (handle file for SQLite).
	GetFile() string

	// GetHeader returns the session header with metadata.
	GetHeader() *Header
}

Store is the interface for session persistence backends. Manager implements this interface using SQLite. Alternative backends (in-memory for testing, cloud storage, etc.) can implement Store to swap the persistence layer without changing agent or UI code.

type ThinkingLevelChangeEntry

type ThinkingLevelChangeEntry struct {
	EntryBase
	ThinkingLevel string `json:"thinkingLevel"`
}

ThinkingLevelChangeEntry records a thinking level change.

type ToolExecutionRecord

type ToolExecutionRecord struct {
	ID               int64
	SessionID        string
	LocalTurnID      string
	ExecutionKey     string
	Provider         string
	API              string
	ResponseID       string
	ProviderCallID   string
	ToolKind         string
	ToolName         string
	ArgsHash         string
	ExecutionState   string
	ResultSummary    json.RawMessage
	ProviderMetadata json.RawMessage
	SideEffecting    bool
	CreatedAt        time.Time
	CompletedAt      *time.Time
}

ToolExecutionRecord is the cross-protocol idempotency record for a tool invocation. ExecutionKey is local and remains the deduplication authority.

func ClaimToolExecutionRecord

func ClaimToolExecutionRecord(sessionDir string, record ToolExecutionRecord) (*ToolExecutionRecord, bool, error)

ClaimToolExecutionRecord atomically claims an execution key. A false created result means another request already owns the key and its record must be consulted before executing a side effect.

func RequestToolExecutionRecoveryRecords

func RequestToolExecutionRecoveryRecords(sessionDir, sessionID, localTurnID string, providerCallIDs []string) ([]ToolExecutionRecord, int64, error)

RequestToolExecutionRecoveryRecords records explicit user confirmation and returns only matching interrupted calls. The records are retained as audit evidence while recovery starts as a fresh execution; terminal Runs are never reactivated to consume these records.

type TurnEndEntry

type TurnEndEntry struct {
	EntryBase
	TurnID     string `json:"turnId"`
	IntentID   string `json:"intentId,omitempty"`
	RunID      string `json:"runId,omitempty"`
	Status     string `json:"status"`
	StopReason string `json:"stopReason,omitempty"`
}

TurnEndEntry marks the durable terminal boundary of a logical conversation turn. It is persisted for fork resolution and recovery, not model replay.

type TurnStartEntry

type TurnStartEntry struct {
	EntryBase
	TurnID   string `json:"turnId"`
	IntentID string `json:"intentId,omitempty"`
	RunID    string `json:"runId,omitempty"`
	Attempt  int    `json:"attempt,omitempty"`
}

TurnStartEntry marks the durable beginning of a logical conversation turn. It is persisted for boundary recovery but is excluded from provider replay.

Jump to

Keyboard shortcuts

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