Documentation
¶
Index ¶
- Constants
- Variables
- func NewID() string
- type AgentEventStore
- func (s *AgentEventStore) AppendCanonicalEvents(ctx context.Context, streamID, executionID string, ...) ([]api.CanonicalAgentEvent, error)
- func (s *AgentEventStore) AppendCanonicalEventsWithCheckpoint(ctx context.Context, streamID, executionID string, ...) ([]api.CanonicalAgentEvent, error)
- func (s *AgentEventStore) BeginCanonicalCommand(ctx context.Context, executionID, commandID, fingerprint string) (CanonicalCommandRecord, bool, error)
- func (s *AgentEventStore) CanonicalCheckpoint(ctx context.Context, streamID string) (api.AgentProjectionCheckpoint, bool, error)
- func (s *AgentEventStore) CanonicalExecution(ctx context.Context, streamID string) (api.AgentExecution, bool, error)
- func (s *AgentEventStore) Close() error
- func (s *AgentEventStore) CompleteCanonicalCommand(ctx context.Context, executionID, commandID, fingerprint string, result any, ...) error
- func (s *AgentEventStore) GetCanonicalCommand(ctx context.Context, executionID, commandID string) (CanonicalCommandRecord, bool, error)
- func (s *AgentEventStore) LatestUsageIntervalDay(ctx context.Context, fromDay, toDay string) (string, error)
- func (s *AgentEventStore) QueryCanonicalEvents(ctx context.Context, streamID string, afterSequence, beforeSequence uint64, ...) (api.AgentEventsHistoryResult, error)
- func (s *AgentEventStore) QueryUsageDaily(ctx context.Context, fromDay, toDay string) ([]UsageDailyRow, error)
- func (s *AgentEventStore) QueryUsageIntervals(ctx context.Context, fromDay, toDay string) ([]UsageIntervalRow, error)
- func (s *AgentEventStore) RebuildUsageRollups(ctx context.Context) (UsageRebuildResult, error)
- func (s *AgentEventStore) RebuildUsageRollupsFromObservations(ctx context.Context, observations []UsageRebuildObservation) (UsageRebuildResult, error)
- func (s *AgentEventStore) ReconcilePendingCanonicalCommands(ctx context.Context, now time.Time, maxAge time.Duration) (int64, error)
- func (s *AgentEventStore) RepriceUsageDaily(ctx context.Context, table *usage.PriceTable) (int, error)
- func (s *AgentEventStore) SetUsageAttributionResolver(resolver UsageAttributionResolver)
- type CanonicalCommandRecord
- type CanonicalHistoryBoundary
- type StateResetError
- type Store
- type UsageAttribution
- type UsageAttributionResolver
- type UsageDailyRow
- type UsageIntervalRow
- type UsageRebuildObservation
- type UsageRebuildResult
Constants ¶
const ( CanonicalCommandPending = "pending" CanonicalCommandCompleted = "completed" CanonicalCommandFailed = "failed" // CanonicalCommandUnknown means the Host stopped after durable admission // but before recording a result. It must never be re-executed implicitly: // the provider side effect may already have happened. CanonicalCommandUnknown = "unknown" )
Variables ¶
var ( ErrCanonicalSequenceConflict = errors.New("canonical agent event sequence conflict") ErrCanonicalEventConflict = errors.New("canonical agent event identity conflict") ErrCanonicalHistoryBoundary = errors.New("canonical agent history boundary") ErrCanonicalCommandConflict = errors.New("canonical agent command identity conflict") ErrCanonicalCommandPending = errors.New("canonical agent command is pending") ErrCanonicalCommandUnknown = errors.New("canonical agent command outcome is unknown") )
Functions ¶
Types ¶
type AgentEventStore ¶ added in v0.12.0
type AgentEventStore struct {
// contains filtered or unexported fields
}
AgentEventStore is the durable Host-owned canonical Agent journal.
Protocol 4 starts a clean data boundary: canonical stream rows and command admission records are the only persisted Agent state.
func OpenAgentEventStore ¶ added in v0.12.0
func OpenAgentEventStore(dbPath string) (*AgentEventStore, error)
OpenAgentEventStore opens the canonical Agent journal database.
func (*AgentEventStore) AppendCanonicalEvents ¶ added in v0.12.0
func (s *AgentEventStore) AppendCanonicalEvents( ctx context.Context, streamID, executionID string, events []api.CanonicalAgentEvent, ) ([]api.CanonicalAgentEvent, error)
AppendCanonicalEvents appends one batch atomically. A zero sequence is assigned by the Host; explicit sequences are accepted only when they match an existing immutable row. Replayed event IDs and positions are idempotent, while a different payload at either identity is a hard integrity error.
func (*AgentEventStore) AppendCanonicalEventsWithCheckpoint ¶ added in v0.12.0
func (s *AgentEventStore) AppendCanonicalEventsWithCheckpoint( ctx context.Context, streamID, executionID string, events []api.CanonicalAgentEvent, checkpoint map[string]any, ) ([]api.CanonicalAgentEvent, error)
AppendCanonicalEventsWithCheckpoint commits the immutable event batch and the replaceable projection checkpoint in the same SQLite transaction. A checkpoint is only written when the argument is non-nil; callers that do not have a projection update retain the last durable checkpoint.
func (*AgentEventStore) BeginCanonicalCommand ¶ added in v0.12.0
func (s *AgentEventStore) BeginCanonicalCommand( ctx context.Context, executionID, commandID, fingerprint string, ) (CanonicalCommandRecord, bool, error)
BeginCanonicalCommand atomically admits a command. The caller becomes the leader only when it inserted a new pending row. A completed or failed row is returned for idempotent replay; a pending row belongs to another attempt.
func (*AgentEventStore) CanonicalCheckpoint ¶ added in v0.12.0
func (s *AgentEventStore) CanonicalCheckpoint( ctx context.Context, streamID string, ) (api.AgentProjectionCheckpoint, bool, error)
CanonicalCheckpoint returns the last checkpoint committed with a stream. It is deliberately separate from the event page so subscription code can establish a coherent snapshot while holding its broadcast fence.
func (*AgentEventStore) CanonicalExecution ¶ added in v0.12.0
func (s *AgentEventStore) CanonicalExecution(ctx context.Context, streamID string) (api.AgentExecution, bool, error)
func (*AgentEventStore) Close ¶ added in v0.12.0
func (s *AgentEventStore) Close() error
Close closes the underlying database.
func (*AgentEventStore) CompleteCanonicalCommand ¶ added in v0.12.0
func (s *AgentEventStore) CompleteCanonicalCommand( ctx context.Context, executionID, commandID, fingerprint string, result any, callErr error, ) error
CompleteCanonicalCommand records the immutable result of an admitted command. Completion is intentionally independent from the request context: a disconnected client must not leave a successful provider call pending.
func (*AgentEventStore) GetCanonicalCommand ¶ added in v0.12.0
func (s *AgentEventStore) GetCanonicalCommand( ctx context.Context, executionID, commandID string, ) (CanonicalCommandRecord, bool, error)
GetCanonicalCommand returns the durable admission record for one command. The boolean is false when the command has never been admitted.
func (*AgentEventStore) LatestUsageIntervalDay ¶ added in v0.14.0
func (s *AgentEventStore) LatestUsageIntervalDay(ctx context.Context, fromDay, toDay string) (string, error)
LatestUsageIntervalDay returns the most recent local day with five-minute rows in the inclusive range, or "" when none. It lets the Service choose the default detail day without loading every bucket in the range.
func (*AgentEventStore) QueryCanonicalEvents ¶ added in v0.12.0
func (s *AgentEventStore) QueryCanonicalEvents( ctx context.Context, streamID string, afterSequence, beforeSequence uint64, limit int, ) (api.AgentEventsHistoryResult, error)
QueryCanonicalEvents returns an ascending page. afterSequence is exclusive; beforeSequence is exclusive. With neither bound the newest page is returned.
func (*AgentEventStore) QueryUsageDaily ¶ added in v0.14.0
func (s *AgentEventStore) QueryUsageDaily(ctx context.Context, fromDay, toDay string) ([]UsageDailyRow, error)
QueryUsageDaily returns rows for the inclusive local-day range, ascending by day. Both bounds are YYYY-MM-DD; an empty bound is unconstrained.
func (*AgentEventStore) QueryUsageIntervals ¶ added in v0.14.0
func (s *AgentEventStore) QueryUsageIntervals(ctx context.Context, fromDay, toDay string) ([]UsageIntervalRow, error)
QueryUsageIntervals returns the canonical 5-minute rows for an inclusive local-day range, ordered by day and bucket. Both bounds are YYYY-MM-DD; an empty bound is unconstrained.
func (*AgentEventStore) RebuildUsageRollups ¶ added in v0.14.0
func (s *AgentEventStore) RebuildUsageRollups(ctx context.Context) (UsageRebuildResult, error)
RebuildUsageRollups replaces the daily and intraday Usage projections from every canonical event retained in the Agent journal. It is an explicit maintenance operation rather than a normal write path: callers should warn the user that the current Usage aggregates are discarded, while the journal and every other Host database remain unchanged.
The whole replacement is one SQLite transaction. A failed or cancelled rebuild therefore leaves the previous Usage projections intact, and running it again is idempotent because the source journal is immutable.
func (*AgentEventStore) RebuildUsageRollupsFromObservations ¶ added in v0.14.0
func (s *AgentEventStore) RebuildUsageRollupsFromObservations( ctx context.Context, observations []UsageRebuildObservation, ) (UsageRebuildResult, error)
RebuildUsageRollupsFromObservations replaces Usage projections from parser output collected from historical transcript files. Only the derived Usage tables are touched; the canonical journal and every other database remain unchanged.
func (*AgentEventStore) ReconcilePendingCanonicalCommands ¶ added in v0.12.0
func (s *AgentEventStore) ReconcilePendingCanonicalCommands( ctx context.Context, now time.Time, maxAge time.Duration, ) (int64, error)
ReconcilePendingCanonicalCommands marks commands left pending by an older Host process as indeterminate. Admission is durable before the provider is called, so replaying such a row could duplicate a turn or an attachment; callers must surface the state and ask the client to issue a new command ID. Only rows older than maxAge are touched, so a long-running command in the current process is never converted while it is still executing.
func (*AgentEventStore) RepriceUsageDaily ¶ added in v0.14.0
func (s *AgentEventStore) RepriceUsageDaily(ctx context.Context, table *usage.PriceTable) (int, error)
RepriceUsageDaily recomputes the cached cost of every rollup row from the supplied price table and returns how many rows changed.
Cost is recomputed rather than accrued per call because unit prices change. The tokens are the durable fact; the money is a projection of them, so a price correction has to be able to restate history rather than only affect new spend. Rows keep their tokens either way.
priced_calls records how many of a row's calls had a fully known price. When it trails calls, the row's cost is a lower bound and every aggregate built from it must be presented as such.
func (*AgentEventStore) SetUsageAttributionResolver ¶ added in v0.14.0
func (s *AgentEventStore) SetUsageAttributionResolver(resolver UsageAttributionResolver)
SetUsageAttributionResolver installs the project attribution lookup. Usage accumulation is inert until a resolver is set, which keeps stores constructed by tests and embedders free of a host-state dependency.
type CanonicalCommandRecord ¶ added in v0.12.0
type CanonicalCommandRecord struct {
ExecutionID string
CommandID string
Fingerprint string
Status string
Result any
Error string
CreatedAt int64
}
CanonicalCommandRecord is the durable admission record for one mutation. Result is decoded as generic JSON because command result types belong to the wire method, not to the journal. A pending row means another Host process may still be executing the command; it is never re-run implicitly.
type CanonicalHistoryBoundary ¶ added in v0.12.0
type CanonicalHistoryBoundary struct {
StreamID string
RetainedFromSequence uint64
HeadSequence uint64
CheckpointSequence uint64
Checkpoint map[string]any
}
CanonicalHistoryBoundary carries the first sequence still retained by the Host. Callers should return this as a structured history_boundary error and install a replacement checkpoint rather than guessing a cursor.
func (*CanonicalHistoryBoundary) Error ¶ added in v0.12.0
func (e *CanonicalHistoryBoundary) Error() string
type StateResetError ¶ added in v0.12.0
StateResetError is returned for unknown or future state files. Known older schemas are upgraded in place because their fields remain compatible.
func (*StateResetError) Error ¶ added in v0.12.0
func (e *StateResetError) Error() string
type Store ¶
type Store struct {
// contains filtered or unexported fields
}
func (*Store) ChangesSince ¶
type UsageAttribution ¶ added in v0.14.0
type UsageAttribution struct {
// ProjectID is empty when the stream cannot be attributed to a project.
// An empty value is filed as unattributed rather than dropped, because
// dropping it would make the panel total disagree with reality.
ProjectID string
}
UsageAttribution is the ownership context a spend row is filed under. The journal does not know about projects, so the Service supplies this through SetUsageAttributionResolver rather than the store reaching into host state.
type UsageAttributionResolver ¶ added in v0.14.0
type UsageAttributionResolver func(streamID string) UsageAttribution
UsageAttributionResolver maps a canonical stream to its ownership context.
type UsageDailyRow ¶ added in v0.14.0
type UsageDailyRow struct {
LocalDay string `json:"localDay"`
Provider string `json:"provider"`
Model string `json:"model"`
ModelRaw string `json:"modelRaw"`
ProjectID string `json:"projectId,omitempty"`
Calls int64 `json:"calls"`
FreshInput int64 `json:"freshInput"`
CacheWrite int64 `json:"cacheWrite"`
CacheRead int64 `json:"cacheRead"`
Output int64 `json:"output"`
Reasoning int64 `json:"reasoning,omitempty"`
CostNanoUSD int64 `json:"costNanoUsd"`
PricedCalls int64 `json:"pricedCalls"`
}
UsageDailyRow is one aggregated spend row.
type UsageIntervalRow ¶ added in v0.14.0
type UsageIntervalRow struct {
LocalDay string `json:"localDay"`
BucketStartMin int `json:"bucketStartMin"`
Provider string `json:"provider"`
Model string `json:"model"`
ModelRaw string `json:"modelRaw"`
ProjectID string `json:"projectId,omitempty"`
Calls int64 `json:"calls"`
FreshInput int64 `json:"freshInput"`
CacheWrite int64 `json:"cacheWrite"`
CacheRead int64 `json:"cacheRead"`
Output int64 `json:"output"`
Reasoning int64 `json:"reasoning,omitempty"`
CostNanoUSD int64 `json:"costNanoUsd"`
PricedCalls int64 `json:"pricedCalls"`
}
UsageIntervalRow is one 5-minute intraday aggregate. BucketStartMin is the bucket's local-minute offset from midnight, always a multiple of 5.
type UsageRebuildObservation ¶ added in v0.14.0
type UsageRebuildObservation struct {
Provider string
Model string
ProjectID string
OccurredAt time.Time
Usage api.AgentUsage
}
UsageRebuildObservation is one provider usage observation read directly from a historical transcript. It is deliberately separate from the canonical journal event: rebuilding Usage must be able to correct an old parser's duplicate rows without rewriting that immutable journal.
type UsageRebuildResult ¶ added in v0.14.0
UsageRebuildResult describes a completed replacement of the Usage projections. The canonical Agent journal is intentionally left untouched; only the two derived Usage tables are cleared and rebuilt.