Files
agent-radar 2ed3415fb7
Publish Claude Code Binaries / Stage and publish binaries (push) Canceled after 0s
Publish Tutti App Runtime / Build darwin-arm64 (push) Canceled after 0s
Publish Tutti App Runtime / Build darwin-amd64 (push) Canceled after 0s
Publish Tutti App Runtime / Build linux-amd64 (push) Canceled after 0s
Publish Tutti App Runtime / Build windows-amd64 (push) Canceled after 0s
Sync Tutti Agent Skills / sync (push) Canceled after 0s
Windows Agent Adapters / Test Windows agent adapters (push) Canceled after 0s
Windows Daemon Adapters / Test Windows daemon adapters (push) Canceled after 0s
Publish Tutti App Runtime / Publish runtime catalog (push) Canceled after 0s
源码快照 @ 2026-09-01 (source-only, 剔除非源码素材)
2026-09-01 20:17:27 +08:00

825 lines
29 KiB
Go

// Package storesqlite provides an embeddable SQLite persistence layer for
// agent activity (sessions, messages, rail sections, generated files) and
// agent targets. It operates on an injected *sql.DB, keeps its own schema
// migration ledger, and makes no assumptions about the host schema beyond
// the tables it owns; host concerns (workspace existence, project paths,
// target normalization) are injected through Options.
package storesqlite
import (
"context"
"encoding/json"
"github.com/tutti-os/tutti/packages/agent/store-sqlite/canonical"
)
// Repository is the public persistence contract for agent activity.
// All methods are scoped by a host-defined workspace ID.
type Repository interface {
ClearSessions(context.Context, string) (ClearSessionsResult, error)
PlanClearSessions(context.Context, string) (DeleteSessionsPlan, error)
PlanDeleteSessions(context.Context, DeleteSessionsBatchInput) (DeleteSessionsPlan, error)
DeleteSessionsBatch(context.Context, DeleteSessionsBatchInput) (DeleteSessionsBatchResult, error)
ListDeletedSessions(context.Context, ListDeletedSessionsInput) (DeletedSessionPage, error)
RestoreDeletedSession(context.Context, RestoreDeletedSessionInput) (RestoreDeletedSessionResult, error)
PurgeDeletedSessionTrees(context.Context, PurgeDeletedSessionTreesInput) (PurgeDeletedSessionTreesResult, error)
ListRecoverableDeletedSessionResources(context.Context) ([]DeletedSessionResource, error)
GetSession(context.Context, string, string) (Session, bool, error)
ListChildSessions(context.Context, string, string) ([]Session, error)
SessionDeleted(context.Context, string, string) (bool, error)
GetLatestTurn(context.Context, string, string) (Turn, bool, error)
GetTurn(context.Context, string, string, string) (Turn, bool, error)
ListSessionInteractions(context.Context, ListSessionInteractionsInput) ([]Interaction, error)
ListLatestTurns(context.Context, string, []string) (map[string]Turn, error)
ListLatestTurnInteractions(context.Context, string, []string) (map[string][]Interaction, error)
ListTurnsBySession(context.Context, string, map[string]string) (map[string]Turn, error)
ListPendingInteractionsBySession(context.Context, string, []string) (map[string][]Interaction, error)
ListSessionSection(context.Context, ListSessionSectionInput) (SessionSectionPage, bool, error)
ListSessionSections(context.Context, ListSessionSectionsInput) (SessionSectionsPage, bool, error)
ListSessionSectionDeletionCandidates(context.Context, ListSessionSectionDeletionCandidatesInput) (SessionSectionDeletionCandidates, bool, error)
ListSessionsPage(context.Context, ListSessionsPageInput) (SessionListPage, bool, error)
ListSessionTurns(context.Context, string, string) ([]Turn, error)
ListSessions(context.Context, string) ([]Session, bool, error)
ListWorkspaceGeneratedFileTurns(context.Context, ListWorkspaceGeneratedFileTurnsInput) (GeneratedFileTurnList, bool, error)
ListSessionMessages(context.Context, ListSessionMessagesInput) (MessagePage, bool, error)
ReportActivityState(context.Context, ActivityStateReport) (ActivityStateReportResult, error)
ReportSessionMessages(context.Context, SessionMessageReport) (MessageReportResult, error)
ReportSessionState(context.Context, SessionStateReport) (StateReportResult, error)
PrepareRuntimeOperation(context.Context, RuntimeOperationPrepare) (RuntimeOperation, bool, error)
PrepareInteractiveRuntimeOperation(context.Context, RuntimeOperationPrepare) (RuntimeOperation, Interaction, InteractionTransitionResult, error)
GetRuntimeOperation(context.Context, string, string) (RuntimeOperation, bool, error)
ListClaimableRuntimeOperations(context.Context, ListClaimableRuntimeOperationsInput) ([]RuntimeOperation, error)
ClaimRuntimeOperationLease(context.Context, ClaimRuntimeOperationLeaseInput) (RuntimeOperation, bool, error)
ReleaseOrFailRuntimeOperation(context.Context, ReleaseOrFailRuntimeOperationInput) (RuntimeOperation, bool, error)
RequeueLeasedRuntimeOperationsOnStartup(context.Context, int64) (int64, error)
CompleteInteractiveRuntimeOperation(context.Context, CompleteInteractiveRuntimeOperationInput) (RuntimeOperationCompletion, bool, error)
CompleteCancelRuntimeOperation(context.Context, CompleteCancelRuntimeOperationInput) (RuntimeOperationCompletion, bool, error)
ListPendingRuntimeOperationEvents(context.Context, string, int) ([]RuntimeOperationEvent, error)
MarkRuntimeOperationEventPublished(context.Context, string, int64, int64) (bool, error)
SettleStaleTurns(context.Context) ([]StaleTurnSettlement, error)
UpdateSessionPinned(context.Context, string, string, bool) (Session, bool, error)
UpdateSessionSettings(context.Context, string, string, string, map[string]any) (Session, bool, error)
UpdateSessionTitle(context.Context, string, string, string) (Session, bool, error)
}
// SessionTurnSummaryReader is a narrow optional read seam for consumers that
// need bounded Turn discovery without broadening the canonical write
// repository contract.
type SessionTurnSummaryReader interface {
ListSessionTurnSummaries(context.Context, ListSessionTurnSummariesInput) (SessionTurnSummaryPage, error)
}
// EffectiveSessionTurnReader is the current-history projection. The ordinary
// audit read deliberately remains complete.
type EffectiveSessionTurnReader interface {
ListEffectiveSessionTurns(context.Context, string, string) ([]Turn, error)
}
// GoalProvenanceLedger is a narrow optional persistence capability. It stays
// separate from Repository so read-only/custom activity repositories do not
// need to implement provider-specific Goal attribution.
type GoalProvenanceLedger interface {
BindGoalProvenance(context.Context, BindGoalProvenanceInput) (GoalProvenanceBinding, error)
LookupGoalProvenance(context.Context, LookupGoalProvenanceInput) (GoalProvenanceBinding, bool, error)
}
// AgentStateReader exposes the durable, canonical workspace activity read
// model without coupling consumers to daemon/activity's in-memory relay state.
// Presence and host-owned execution attribution are deliberately outside this
// contract and remain the responsibility of the composing host.
type AgentStateReader interface {
GetAgentState(context.Context, string) (AgentState, bool, error)
}
// AgentState is a workspace-scoped canonical activity snapshot.
// AgentSessionState composes the existing Session and Turn entities instead of
// copying their fields into another presentation DTO.
type AgentState struct {
WorkspaceID string
Sessions []AgentSessionState
}
type AgentSessionState struct {
Session Session
LatestTurn *Turn
}
type ClearSessionsResult struct {
TransactionID string `json:"-"`
CommitDelta TransactionDelta `json:"-"`
RemovedMessages int
RemovedSessions int
RemovedSessionIDs []string
}
type DeleteSessionResult struct {
TransactionID string `json:"-"`
CommitDelta TransactionDelta `json:"-"`
RemovedMessages int
RemovedSessions int
RemovedSessionIDs []string
}
const (
DeletedSessionUnavailableLegacyData = "legacyDataUnavailable"
DeletedSessionUnavailableIncompleteTree = "incompleteSessionTree"
recoverableDeleteVersionCurrent int64 = 1
)
// ListDeletedSessionsInput selects topmost tombstones in one workspace. A
// topmost tombstone has no tombstoned parent, so it may anchor either a root
// tree or a deleted child subtree. A nil RailSectionKey means every section;
// a non-nil value selects that exact persisted rail section key, including the
// fixed conversations key.
type ListDeletedSessionsInput struct {
WorkspaceID string
SearchQuery string
RailSectionKey *string
CursorUpdatedAtUnixMS int64
CursorAgentSessionID string
Limit int
}
type DeletedSessionSummary struct {
AgentSessionID string
Title string
RailSectionKey string
ProjectPath string
UpdatedAtUnixMS int64
DeletedAtUnixMS int64
Restorable bool
UnavailableReason string
}
type DeletedSessionRailSection struct {
RailSectionKey string
ProjectPath string
}
type DeletedSessionPage struct {
WorkspaceID string
Sessions []DeletedSessionSummary
RailSections []DeletedSessionRailSection
TotalCount int
WorkspaceTotalCount int
HasMore bool
NextCursor string
}
type RestoreDeletedSessionInput struct {
WorkspaceID string
AgentSessionID string
}
type RestoreDeletedSessionResult struct {
TransactionID string `json:"-"`
CommitDelta TransactionDelta `json:"-"`
Restored bool
RestoredSessionIDs []string
}
// PurgeDeletedSessionTreesInput permanently removes topmost deleted components
// whose full reachable tree is tombstoned. RootSessionIDs is retained for
// compatibility, but each value is a component anchor and may identify a root
// or child Session. An empty slice selects every topmost tombstone in the
// workspace. Recoverability metadata is deliberately not required, so legacy
// or incomplete components remain explicitly purgeable.
type PurgeDeletedSessionTreesInput struct {
WorkspaceID string
RootSessionIDs []string
}
type PurgeDeletedSessionTreesResult struct {
PurgedRootSessionIDs []string
PurgedSessionIDs []string
RemovedSessions int
RemovedMessages int
PayloadBytes int64
}
// DeletedSessionResource is the minimum canonical identity needed by a host's
// filesystem policy to protect recoverable state from background GC.
type DeletedSessionResource struct {
WorkspaceID string
AgentSessionID string
Cwd string
}
// PurgeDeletedSessionsInput bounds one permanent-removal transaction. The
// caller owns retention policy and supplies an absolute cutoff.
type PurgeDeletedSessionsInput struct {
CutoffUnixMS int64
MaxSessions int
MaxPayloadBytes int64
}
// PurgedSession is the content-free descriptor returned after a successful
// canonical commit for aggregate accounting and bounded maintenance progress.
type PurgedSession struct {
WorkspaceID string
AgentSessionID string
DeletedAtUnixMS int64
PayloadBytes int64
}
type PurgeDeletedSessionsResult struct {
Sessions []PurgedSession
RemovedMessages int
PayloadBytes int64
HasMore bool
}
type MessageOrder string
const (
MessageOrderAsc MessageOrder = "asc"
MessageOrderDesc MessageOrder = "desc"
)
type ListSessionMessagesInput struct {
WorkspaceID string
AgentSessionID string
MessageID string
TurnID string
// AfterVersion and BeforeVersion are per-session change cursors. Current
// message snapshots may skip cursor values when the same message is updated.
AfterVersion uint64
BeforeVersion uint64
Limit int
Order MessageOrder
}
type ListWorkspaceGeneratedFileTurnsInput struct {
WorkspaceID string
SectionKey string
}
type GeneratedFileTurnChange struct {
Path string
Change string
}
type GeneratedFileTurn struct {
AgentSessionID string
AgentTargetID string
TurnID string
CWD string
RailSectionKind string
RailProjectPath string
SettledAtUnixMS int64
Changes []GeneratedFileTurnChange
}
type GeneratedFileTurnList struct {
WorkspaceID string
Turns []GeneratedFileTurn
}
type ListSessionSectionInput struct {
WorkspaceID string
SectionKey string
AgentTargetID string
IncludedSessionIDs []string
CursorSortTimeUnixMS int64
CursorSessionID string
Limit int
}
// ListSessionSectionsInput describes the first-page bootstrap for every rail
// section in one workspace query. SectionKeys includes the synthetic pinned
// page key when the caller needs pinned conversations.
type ListSessionSectionsInput struct {
WorkspaceID string
SectionKeys []string
AgentTargetID string
IncludedSessionIDs []string
LimitPerSection int
}
type ListSessionSectionDeletionCandidatesInput struct {
WorkspaceID string
SectionKey string
AgentTargetID string
IncludedSessionIDs []string
ExcludePinned bool
}
type ListSessionsPageInput struct {
WorkspaceID string
AgentTargetID string
SearchQuery string
IncludedSessionIDs []string
CursorSortTimeUnixMS int64
CursorSessionID string
Limit int
}
type SessionListPage struct {
WorkspaceID string
Sessions []Session
HasMore bool
NextCursor string
}
type SessionSectionDeletionCandidates struct {
WorkspaceID string
SectionKey string
AgentTargetID string
ExcludePinned bool
SessionIDs []string
}
type DeleteSessionsBatchInput struct {
WorkspaceID string
SessionIDs []string
ExpectedSessionIDs []string
RequiredRootRailSectionKey string
ExcludePinnedRoots bool
}
type DeleteSessionsPlan struct {
WorkspaceID string
SessionIDs []string
}
type DeleteSessionsBatchResult struct {
TransactionID string `json:"-"`
CommitDelta TransactionDelta `json:"-"`
RemovedMessages int
RemovedSessions int
RemovedSessionIDs []string
}
const PinnedSessionPageKey = "pinned"
type SessionSectionPage struct {
WorkspaceID string
SectionKey string
Sessions []Session
HasMore bool
TotalCount int
NextCursor string
}
type SessionSectionsPage struct {
WorkspaceID string
Sections []SessionSectionPage
}
type Session struct {
// CommitTransactionID is populated only by a successful mutating call and
// is not persisted as canonical session state.
CommitTransactionID string `json:"-"`
CommitDelta TransactionDelta `json:"-"`
ID string
WorkspaceID string
Kind string
RootAgentSessionID string
RootTurnID string
ParentAgentSessionID string
ParentTurnID string
ParentToolCallID string
Origin string
UserID string
AgentTargetID string
Provider string
ProviderSessionID string
Model string
Settings map[string]any
Capabilities *canonical.CapabilitySnapshot
Metadata SessionMetadata
InternalRuntimeContext map[string]any
Cwd string
RailSectionKind string
RailProjectPath string
RailSectionKey string
Title string
// ActiveTurnID is the protocol v2 turn reference: the id of the turn
// currently in flight, empty when the session is idle.
ActiveTurnID string
// MessageVersion is the latest accepted per-session message change cursor.
// It is a high-water mark, not a count of current message rows.
MessageVersion uint64
LastEventUnixMS int64
StartedAtUnixMS int64
EndedAtUnixMS int64
PinnedAtUnixMS int64
CreatedAtUnixMS int64
UpdatedAtUnixMS int64
}
const (
SessionKindRoot = canonical.SessionKindRoot
SessionKindChild = canonical.SessionKindChild
)
// ActivityStateReport persists the session projection and its optional v2
// turn/interaction/message entities as one atomic unit. Child entities must
// identify the same workspace and session as Session. Messages must reference
// a turn that already exists in the transaction; unlike the standalone
// message report, this boundary never synthesizes a missing turn.
type ActivityStateReport struct {
Session SessionStateReport
Turn *TurnTransition
RootProviderTurn *RootProviderTurnTransition
Interaction *InteractionUpsert
Messages []MessageUpdate
}
type ActivityStateReportResult struct {
TransactionID string `json:"-"`
CommitDelta TransactionDelta `json:"-"`
State StateReportResult
Turn Turn
TurnAccepted bool
RootTurn Turn
RootTurnAccepted bool
// RootProviderTurnAccepted reports a durable provider projection update even
// when the canonical root turn was already settled. Callers must not use it
// to publish a second canonical lifecycle transition.
RootProviderTurnAccepted bool
Interaction Interaction
InteractionResult InteractionTransitionResult
Messages MessageReportResult
}
// Closed protocol v2 turn phase vocabulary. The storage CHECK constraints
// mirror this list; keep both in sync with the openapi WorkspaceAgentTurnPhase
// enum.
const (
TurnPhaseSubmitted = canonical.TurnPhaseSubmitted
TurnPhaseRunning = canonical.TurnPhaseRunning
TurnPhaseWaiting = canonical.TurnPhaseWaiting
TurnPhaseSettling = canonical.TurnPhaseSettling
TurnPhaseSettled = canonical.TurnPhaseSettled
)
// Closed protocol v2 turn outcome vocabulary; mirrors the openapi
// WorkspaceAgentTurnOutcome enum.
const (
TurnOutcomeCompleted = canonical.TurnOutcomeCompleted
TurnOutcomeFailed = canonical.TurnOutcomeFailed
TurnOutcomeCanceled = canonical.TurnOutcomeCanceled
TurnOutcomeInterrupted = canonical.TurnOutcomeInterrupted
TurnOriginUserPrompt = canonical.TurnOriginUserPrompt
TurnOriginGoalArm = canonical.TurnOriginGoalArm
TurnOriginGoalContinuation = canonical.TurnOriginGoalContinuation
TurnOriginProviderInitiated = canonical.TurnOriginProviderInitiated
TurnOriginLegacyUnknown = canonical.TurnOriginLegacyUnknown
)
// Turn is the protocol v2 execution entity inside either a root or child
// session. It may originate from a user prompt, Goal control, or an explicit
// provider-initiated interaction and carries both Goal provenance and the
// root-provider completion projection.
type Turn struct {
WorkspaceID string
AgentSessionID string
TurnID string
// IdentityAnchorTurnID is the canonical Turn whose externally projected
// identity this Turn inherits. Empty means the Turn anchors itself. The
// field never replaces TurnID for lifecycle, provider, or interaction
// operations.
IdentityAnchorTurnID string
CapabilityRefs []CapabilityReference
Phase string
Outcome string
ErrorMessage string
ErrorCode string
FileChanges map[string]any
CompletedCommandKind string
CompletedCommandStatus string
FinalAssistantMessageID string
FinalAssistantMessageResolved bool
Backfilled bool
StartedAtUnixMS int64
SettledAtUnixMS int64
CreatedAtUnixMS int64
UpdatedAtUnixMS int64
Origin string
SourceGoalOperationID string
SourceGoalRevision int64
SourceGoalRepairEpoch int64
RootProviderTurnID string
ProviderTurnBindingJSON json.RawMessage
ProviderForkBindingAvailable bool
RootProviderTurnPhase string
RootProviderTurnOutcome string
RootProviderTurnErrorMessage string
RootProviderTurnErrorCode string
RootProviderTurnCompletedCommandKind string
RootProviderTurnCompletedCommandStatus string
RootProviderTurnUpdatedAtUnixMS int64
}
// SessionTurnCursor is the stable position immediately before a descending
// session-Turn page. StartedAtUnixMS alone is not unique, so TurnID is the
// deterministic tie-breaker.
type SessionTurnCursor struct {
StartedAtUnixMS int64
TurnID string
}
// ListSessionTurnSummariesInput bounds one metadata-only session-Turn read.
// Before is exclusive; nil selects the newest page.
type ListSessionTurnSummariesInput struct {
WorkspaceID string
AgentSessionID string
Before *SessionTurnCursor
Limit int
}
// SessionTurnSummary contains only the canonical fields needed to discover
// and render a Turn without loading error, file-change, or provider payloads.
type SessionTurnSummary struct {
TurnID string
Phase string
Outcome string
FinalAssistantMessageID string
StartedAtUnixMS int64
SettledAtUnixMS int64
Origin string
}
type SessionTurnSummaryPage struct {
Turns []SessionTurnSummary
HasMore bool
}
type CapabilityReference struct {
Capability string `json:"capability"`
Source string `json:"source"`
}
const (
RootProviderTurnPhaseRunning = canonical.RootProviderTurnPhaseRunning
RootProviderTurnPhaseCompleted = canonical.RootProviderTurnPhaseCompleted
)
type RootProviderTurnTransition struct {
WorkspaceID string
RootAgentSessionID string
RootTurnID string
ProviderTurnID string
ProviderTurnBindingJSON json.RawMessage
Phase string
Outcome string
ErrorMessage string
ErrorCode string
CompletedCommandKind string
CompletedCommandStatus string
OccurredAtUnixMS int64
}
// TurnTransition records one turn phase transition. Transitions are written
// synchronously per phase change (no batching); a settled turn is terminal
// and rejects further transitions, which makes replays and cancel races
// idempotent. A transition with an empty Phase and non-empty CapabilityRefs is
// a metadata-only merge for an existing turn and must not alter lifecycle.
type TurnTransition struct {
WorkspaceID string
AgentSessionID string
TurnID string
CapabilityRefs []CapabilityReference
Phase string
Outcome string
ErrorMessage string
ErrorCode string
FileChanges map[string]any
CompletedCommandKind string
CompletedCommandStatus string
FinalAssistantMessageID string
Origin string
SourceGoalOperationID string
SourceGoalRevision int64
SourceGoalRepairEpoch int64
StartedAtUnixMS int64
SettledAtUnixMS int64
OccurredAtUnixMS int64
}
// Closed protocol v2 interaction vocabulary; mirrors the openapi
// WorkspaceAgentInteractionKind / WorkspaceAgentInteractionStatus enums.
const (
InteractionKindApproval = canonical.InteractionKindApproval
InteractionKindQuestion = canonical.InteractionKindQuestion
InteractionKindPlan = canonical.InteractionKindPlan
InteractionStatusPending = canonical.InteractionStatusPending
InteractionStatusAnswered = canonical.InteractionStatusAnswered
InteractionStatusSuperseded = canonical.InteractionStatusSuperseded
)
// Interaction is the protocol v2 interaction entity: an agent-initiated
// approval, question, or plan confirmation raised during a turn. Pending
// means present with status pending; there is no tri-state null protocol.
type Interaction struct {
WorkspaceID string
AgentSessionID string
RequestID string
TurnID string
Kind string
Status string
ToolName string
Input map[string]any
Output map[string]any
Metadata map[string]any
CreatedAtUnixMS int64
UpdatedAtUnixMS int64
}
// SessionInteractionTreeQuery selects the interaction projection rooted at
// one root Session. An empty RootTurnID resolves the root Session's latest
// non-retracted Turn inside the same read transaction as the projection.
type SessionInteractionTreeQuery struct {
WorkspaceID string
RootAgentSessionID string
RootTurnID string
}
// SessionInteractionTreeSnapshot is one transactionally consistent view of
// the root Turn and every descendant Session's latest Turn.
type SessionInteractionTreeSnapshot struct {
RootTurnID string
Interactions []Interaction
PendingInteractions []Interaction
}
type InteractionUpsert struct {
WorkspaceID string
AgentSessionID string
RequestID string
TurnID string
Kind string
Status string
ToolName string
Input map[string]any
Output map[string]any
Metadata map[string]any
OccurredAtUnixMS int64
}
type InteractionTransitionResult string
const (
InteractionTransitionApplied InteractionTransitionResult = "applied"
InteractionTransitionAlreadyApplied InteractionTransitionResult = "already_applied"
InteractionTransitionConflict InteractionTransitionResult = "conflict"
)
type ListSessionInteractionsInput struct {
WorkspaceID string
AgentSessionID string
// TurnID and RequestID select one exact canonical Interaction when both are set.
TurnID string
RequestID string
// Status filters by interaction status when non-empty.
Status string
}
// StaleTurnSettlement identifies one turn that startup reconciliation
// force-settled with outcome interrupted.
type StaleTurnSettlement struct {
TransactionID string `json:"-"`
CommitDelta TransactionDelta `json:"-"`
// Turn is the complete canonical row after startup reconciliation commits
// its settled/interrupted transition. Consumers must use this copy instead
// of reconstructing provenance from the scalar notification identity.
Turn Turn
WorkspaceID string
AgentSessionID string
TurnID string
Provider string
IsChildSession bool
StartedAtUnixMS int64
SettledAtUnixMS int64
}
type SessionStateReport struct {
WorkspaceID string
AgentSessionID string
Kind string
RootAgentSessionID string
RootTurnID string
ParentAgentSessionID string
ParentTurnID string
ParentToolCallID string
Origin string
UserID string
AgentTargetID string
Provider string
ProviderSessionID string
Model string
Settings map[string]any
Capabilities *canonical.CapabilitySnapshot
RuntimeContext map[string]any
RuntimeContextPatch *canonical.RuntimeContextPatch
Cwd string
// ImportProjectPath is the canonical selected project for a historical
// import. The store accepts it only for imported, project-backed sessions.
ImportProjectPath string
// RailPlacement is an explicit caller-selected placement for a newly
// created session. The first accepted value is immutable.
RailPlacement *RailSection
// RailPlacementAuthoritative accepts an explicit project placement even
// when it is absent from this store's local project registry. It does not
// permit changing an existing session's immutable placement.
RailPlacementAuthoritative bool
Title string
Status string
CurrentPhase string
LastError string
OccurredAtUnixMS int64
StartedAtUnixMS int64
EndedAtUnixMS int64
CreatedAtUnixMS int64
}
type StateReportResult struct {
TransactionID string `json:"-"`
CommitDelta TransactionDelta `json:"-"`
Accepted bool
StateApplied bool
LastEventUnixMS int64
RequestBodyBytes int
Session Session
}
type SessionMessageReport struct {
WorkspaceID string
AgentSessionID string
Origin string
Provider string
// HistoricalImport is the internal-only write boundary for read-only
// external transcripts. Messages with a trustworthy reconstructed TurnID
// create settled backfilled Turns; messages without one remain session
// scoped. It must never be populated from runtime/API report payloads.
HistoricalImport bool
Messages []MessageUpdate
}
type MessageUpdate struct {
MessageID string
TurnID string
Role string
Kind string
Status string
Semantics *MessageSemantics
ContentDelta string
Payload map[string]any
OccurredAtUnixMS int64
StartedAtUnixMS int64
CompletedAtUnixMS int64
}
type MessageReportResult struct {
TransactionID string `json:"-"`
CommitDelta TransactionDelta `json:"-"`
AcceptedCount int
LatestVersion uint64
Messages []Message
// StatusTransitionedMessageIDs lists the accepted messages that actually
// moved to a new status in this report. Messages replays a stored snapshot
// unchanged as well, so observers that treat a terminal status as an
// incident must key on this list instead.
StatusTransitionedMessageIDs []string
RequestBodyBytes int
}
type Message struct {
ID uint64
AgentSessionID string
MessageID string
// Version is a per-session change cursor for this mutable snapshot. Updating
// the same MessageID assigns a newer version, so current rows may have gaps.
Version uint64
TurnID string
Role string
Kind string
Status string
Semantics *MessageSemantics
Payload map[string]any
OccurredAtUnixMS int64
StartedAtUnixMS int64
CompletedAtUnixMS int64
CreatedAtUnixMS int64
UpdatedAtUnixMS int64
}
type MessageSemantics struct {
UserVisibleAssistantResponse bool `json:"userVisibleAssistantResponse"`
TurnSettling bool `json:"turnSettling,omitempty"`
NoticeCommand string `json:"noticeCommand,omitempty"`
NoticeCommandStatus string `json:"noticeCommandStatus,omitempty"`
}
type MessagePage struct {
AgentSessionID string
Messages []Message
// LatestVersion is the largest cursor delivered by this page, or the input
// AfterVersion when an ascending page contains no newer snapshots.
LatestVersion uint64
HasMore bool
}