Versions in this module Expand all Collapse all v1 v1.4.0 Oct 20, 2026 Changes in this version + var ErrEffectAlreadyCommitted = errors.New("effect has already been committed") + var ErrEffectExecuting = errors.New("effect is currently executing by another active attempt") + var ErrEffectExpired = errors.New("effect request deadline expired") + var ErrEffectFenced = errors.New("effect rejected by fencing: attempt is stale or superseded") + var ErrEffectNotFound = errors.New("effect record not found") + var ErrEffectUnknown = errors.New(...) + var ErrInvalidRequest = errors.New("invalid effect request") + var ErrInvalidStatusTransition = errors.New("invalid effect status transition") + var ErrPayloadMismatch = errors.New("idempotency key conflict: payload hash does not match previous request") + var ErrProviderFailed = errors.New("effect provider execution failed") + var ErrProviderNotFound = errors.New("effect provider not registered") + func ComputePayloadHash(payload []byte) string + func IsAmbiguous(err error) bool + func MarkAmbiguous(err error) error + type AmbiguousError struct + Err error + func (e *AmbiguousError) Error() string + func (e *AmbiguousError) Unwrap() error + type EffectReceipt struct + AttemptID string + CompletedAt time.Time + EffectID string + ErrorMessage string + FencingToken int64 + ProviderReceipt []byte + ResultHash string + StartedAt time.Time + Status EffectStatus + TenantID string + type EffectRecord struct + CreatedAt time.Time + Receipt *EffectReceipt + Request EffectRequest + Status EffectStatus + UpdatedAt time.Time + Version int64 + type EffectRequest struct + AgentID string + AttemptID string + CreatedAt time.Time + Deadline *time.Time + FencingToken int64 + ID string + IdempotencyKey string + Operation string + Payload []byte + PayloadHash string + Provider string + RunID string + TenantID string + TraceID string + func (r *EffectRequest) Validate() error + type EffectStatus string + const EffectStatusCommitted + const EffectStatusExecuting + const EffectStatusFailed + const EffectStatusPending + const EffectStatusUnknown + func (s EffectStatus) IsTerminal() bool + type Fencer interface + ValidateFencingToken func(ctx context.Context, tenantID, agentID, runID, attemptID string, ...) error + type MemoryFencer struct + func NewMemoryFencer() *MemoryFencer + func (f *MemoryFencer) SetActiveToken(tenantID, agentID, runID string, token int64) + func (f *MemoryFencer) ValidateFencingToken(ctx context.Context, tenantID, agentID, runID, attemptID string, ...) error + type MemoryMetrics struct + CommittedCount int64 + ExecutedCount int64 + FailedCount int64 + FencedCount int64 + IdempotentHits int64 + UnknownCount int64 + func NewMemoryMetrics() *MemoryMetrics + func (m *MemoryMetrics) RecordCommitted(ctx context.Context, tenantID, provider, operation string) + func (m *MemoryMetrics) RecordExecuted(ctx context.Context, tenantID, provider, operation string) + func (m *MemoryMetrics) RecordFailed(ctx context.Context, tenantID, provider, operation, reason string) + func (m *MemoryMetrics) RecordFenced(ctx context.Context, tenantID, provider string) + func (m *MemoryMetrics) RecordIdempotentHit(ctx context.Context, tenantID, provider, operation string) + func (m *MemoryMetrics) RecordUnknown(ctx context.Context, tenantID, provider, operation string) + type MemoryStore struct + func NewMemoryStore() *MemoryStore + func (s *MemoryStore) CreateRecord(ctx context.Context, record *EffectRecord) error + func (s *MemoryStore) ForceStatus(ctx context.Context, tenantID, effectID string, newStatus EffectStatus, ...) (*EffectRecord, error) + func (s *MemoryStore) GetByIdempotencyKey(ctx context.Context, tenantID, agentID, key string) (*EffectRecord, error) + func (s *MemoryStore) GetEffect(ctx context.Context, tenantID, effectID string) (*EffectRecord, error) + func (s *MemoryStore) TransitionStatus(ctx context.Context, tenantID, effectID string, expectedStatus EffectStatus, ...) (*EffectRecord, error) + type Metrics interface + RecordCommitted func(ctx context.Context, tenantID, provider, operation string) + RecordExecuted func(ctx context.Context, tenantID, provider, operation string) + RecordFailed func(ctx context.Context, tenantID, provider, operation, reason string) + RecordFenced func(ctx context.Context, tenantID, provider string) + RecordIdempotentHit func(ctx context.Context, tenantID, provider, operation string) + RecordUnknown func(ctx context.Context, tenantID, provider, operation string) + type NoopMetrics struct + func (NoopMetrics) RecordCommitted(context.Context, string, string, string) + func (NoopMetrics) RecordExecuted(context.Context, string, string, string) + func (NoopMetrics) RecordFailed(context.Context, string, string, string, string) + func (NoopMetrics) RecordFenced(context.Context, string, string) + func (NoopMetrics) RecordIdempotentHit(context.Context, string, string, string) + func (NoopMetrics) RecordUnknown(context.Context, string, string, string) + type Provider interface + Execute func(ctx context.Context, req *EffectRequest) ([]byte, error) + Name func() string + type Service struct + func NewService(store Store, fencer Fencer, metrics Metrics) *Service + func (s *Service) ExecuteEffect(ctx context.Context, req *EffectRequest) (*EffectReceipt, error) + func (s *Service) GetEffect(ctx context.Context, tenantID, effectID string) (*EffectRecord, error) + func (s *Service) GetEffectByIdempotencyKey(ctx context.Context, tenantID, agentID, idempotencyKey string) (*EffectRecord, error) + func (s *Service) RegisterProvider(provider Provider) error + func (s *Service) ResolveUnknownEffect(ctx context.Context, tenantID, effectID string, forceStatus EffectStatus, ...) (*EffectReceipt, error) + type Store interface + CreateRecord func(ctx context.Context, record *EffectRecord) error + ForceStatus func(ctx context.Context, tenantID, effectID string, newStatus EffectStatus, ...) (*EffectRecord, error) + GetByIdempotencyKey func(ctx context.Context, tenantID, agentID, idempotencyKey string) (*EffectRecord, error) + GetEffect func(ctx context.Context, tenantID, effectID string) (*EffectRecord, error) + TransitionStatus func(ctx context.Context, tenantID, effectID string, expectedStatus EffectStatus, ...) (*EffectRecord, error)