folding

package
v0.3.4 Latest Latest
Warning

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

Go to latest
Published: Jan 14, 2026 License: GPL-3.0 Imports: 16 Imported by: 0

Documentation

Overview

Package folding provides context-folding for LLM agent context management.

Package folding provides context-folding for LLM agent context management.

Package folding implements context-folding for LLM agent context management. It provides branch() and return() MCP tools for isolated subtask execution.

Index

Constants

View Source
const (
	// Branch lifecycle errors (FOLD001-FOLD007)
	ErrCodeBranchNotFound       = "FOLD001"
	ErrCodeBranchAlreadyExists  = "FOLD002"
	ErrCodeBranchNotActive      = "FOLD003"
	ErrCodeMaxDepthExceeded     = "FOLD004"
	ErrCodeInvalidTransition    = "FOLD005"
	ErrCodeCannotReturnFromRoot = "FOLD006"
	ErrCodeActiveChildBranches  = "FOLD007"

	// Budget errors (FOLD008-FOLD011)
	ErrCodeBudgetExhausted = "FOLD008"
	ErrCodeBudgetNotFound  = "FOLD009"
	ErrCodeInvalidBudget   = "FOLD010"
	ErrCodeBudgetOverflow  = "FOLD011"

	// Rate limiting errors (FOLD012-FOLD013)
	ErrCodeRateLimitExceeded     = "FOLD012"
	ErrCodeMaxConcurrentBranches = "FOLD013"

	// Secret scrubbing errors (FOLD014)
	ErrCodeScrubbingFailed = "FOLD014"

	// Validation errors (FOLD015-FOLD021)
	ErrCodeEmptySessionID     = "FOLD015"
	ErrCodeEmptyDescription   = "FOLD016"
	ErrCodeDescriptionTooLong = "FOLD017"
	ErrCodeEmptyPrompt        = "FOLD018"
	ErrCodePromptTooLong      = "FOLD019"
	ErrCodeEmptyBranchID      = "FOLD020"
	ErrCodeMessageTooLong     = "FOLD021"

	// Authorization errors (FOLD022) - SEC-004
	ErrCodeSessionUnauthorized = "FOLD022"
)

Error codes for structured error handling. These codes are stable and can be used for programmatic error handling.

View Source
const (
	MaxDescriptionLength = 500
	MaxPromptLength      = 10000
	MaxReturnMsgLength   = 50000
	DefaultBudget        = 8192
	DefaultTimeout       = 300
)

Input validation constants (from SEC-001).

View Source
const (
	// InstrumentationName is the name used for OTEL instrumentation.
	InstrumentationName = "github.com/fyrsmithlabs/contextd/internal/folding"
)

Variables

View Source
var (
	ErrEmptySessionID     = errors.New("session_id is required")
	ErrEmptyDescription   = errors.New("description is required")
	ErrDescriptionTooLong = errors.New("description exceeds maximum length")
	ErrEmptyPrompt        = errors.New("prompt is required")
	ErrPromptTooLong      = errors.New("prompt exceeds maximum length")
	ErrEmptyBranchID      = errors.New("branch_id is required")
	ErrMessageTooLong     = errors.New("message exceeds maximum length")
)

Validation errors (SEC-001) - kept for backward compatibility.

View Source
var (
	ErrBranchNotFound       = errors.New("branch not found")
	ErrBranchAlreadyExists  = errors.New("branch already exists")
	ErrBranchNotActive      = errors.New("branch is not active")
	ErrMaxDepthExceeded     = errors.New("maximum branch depth exceeded")
	ErrInvalidTransition    = errors.New("invalid state transition")
	ErrCannotReturnFromRoot = errors.New("cannot return from root session context")
	ErrActiveChildBranches  = errors.New("branch has active children")
)

Branch lifecycle errors - kept for backward compatibility.

View Source
var (
	ErrBudgetExhausted = errors.New("budget exhausted")
	ErrBudgetNotFound  = errors.New("budget not found for branch")
	ErrInvalidBudget   = errors.New("invalid budget amount")
	ErrBudgetOverflow  = errors.New("token consumption would overflow budget")
)

Budget errors - kept for backward compatibility.

View Source
var (
	ErrRateLimitExceeded     = errors.New("rate limit exceeded")
	ErrMaxConcurrentBranches = errors.New("maximum concurrent branches reached")
)

Rate limiting errors (SEC-003) - kept for backward compatibility.

View Source
var (
	ErrScrubbingFailed = errors.New("secret scrubbing failed")
)

Secret scrubbing errors (SEC-002) - kept for backward compatibility.

View Source
var (
	ErrSessionUnauthorized = errors.New("session access unauthorized")
)

Authorization errors (SEC-004) - kept for backward compatibility.

ValidTransitions defines allowed state transitions.

Functions

func IsAuthorizationError

func IsAuthorizationError(err error) bool

IsAuthorizationError returns true if the error indicates an authorization failure. SEC-004: These errors should result in HTTP 403 Forbidden responses.

func IsNotFoundError

func IsNotFoundError(err error) bool

IsNotFoundError returns true if the error indicates a resource was not found. CORR-008: Added missing categorization for not-found errors.

func IsRetryable

func IsRetryable(err error) bool

IsRetryable returns true if the error represents a transient condition that may succeed on retry (e.g., rate limiting, resource exhaustion).

func IsSystemError

func IsSystemError(err error) bool

IsSystemError returns true if the error represents an internal system failure that is not caused by user input.

func IsUserError

func IsUserError(err error) bool

IsUserError returns true if the error was caused by invalid user input or policy violations that the user can correct.

func RecordError

func RecordError(ctx context.Context, err error, attrs ...attribute.KeyValue)

RecordError records an error on the current span.

func SetSpanStatus

func SetSpanStatus(ctx context.Context, code codes.Code, description string)

SetSpanStatus sets the status on the current span.

func SpanAttributes

func SpanAttributes(branchID, sessionID string, depth int) []attribute.KeyValue

SpanAttributes returns common span attributes for a branch.

func SpanFromContext

func SpanFromContext(ctx context.Context) trace.Span

SpanFromContext returns the current span from context.

func StartSpan

func StartSpan(ctx context.Context, name string, branchID, sessionID string, depth int, opts ...trace.SpanStartOption) (context.Context, trace.Span)

StartSpan starts a new span with branch context.

func Tracer

func Tracer() trace.Tracer

Tracer returns a tracer for the folding package.

func WrapError

func WrapError(code, message string, cause error, branchID, sessionID string) error

WrapError wraps an existing error with folding context. This is a convenience function that creates a FoldingError with a cause.

Types

type Branch

type Branch struct {
	ID                string       `json:"id"`
	SessionID         string       `json:"session_id"`
	ProjectID         string       `json:"project_id,omitempty"`
	ParentID          *string      `json:"parent_id,omitempty"`
	Depth             int          `json:"depth"`
	Description       string       `json:"description"`
	Prompt            string       `json:"prompt"`
	BudgetTotal       int          `json:"budget_total"`
	BudgetUsed        int          `json:"budget_used"`
	TimeoutSeconds    int          `json:"timeout_seconds"`
	Status            BranchStatus `json:"status"`
	Result            *string      `json:"result,omitempty"`
	Error             *string      `json:"error,omitempty"`
	InjectedMemoryIDs []string     `json:"injected_memory_ids,omitempty"`
	CreatedAt         time.Time    `json:"created_at"`
	CompletedAt       *time.Time   `json:"completed_at,omitempty"`
}

Branch represents an isolated context branch for subtask execution.

func (*Branch) BudgetRemaining

func (b *Branch) BudgetRemaining() int

BudgetRemaining returns the remaining token budget.

type BranchCompletedEvent

type BranchCompletedEvent struct {
	TokensUsed int
	Success    bool
	// contains filtered or unexported fields
}

BranchCompletedEvent is emitted when a branch completes normally.

func (BranchCompletedEvent) BranchID

func (e BranchCompletedEvent) BranchID() string

func (BranchCompletedEvent) Type

func (e BranchCompletedEvent) Type() string

type BranchEvent

type BranchEvent interface {
	// Type returns the event type identifier.
	Type() string
	// BranchID returns the branch this event relates to.
	BranchID() string
}

BranchEvent represents an event in the branch lifecycle.

type BranchManager

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

BranchManager orchestrates branch lifecycle.

func NewBranchManager

func NewBranchManager(
	repo BranchRepository,
	budget *BudgetTracker,
	scrubber SecretScrubber,
	emitter EventEmitter,
	config *FoldingConfig,
	opts ...BranchManagerOption,
) *BranchManager

NewBranchManager creates a new branch manager.

func (*BranchManager) CleanupSession

func (m *BranchManager) CleanupSession(ctx context.Context, sessionID string) error

CleanupSession force-returns all active branches for a session (FR-010).

func (*BranchManager) ConsumeTokens

func (m *BranchManager) ConsumeTokens(ctx context.Context, branchID string, tokens int) error

ConsumeTokens records token consumption for a branch.

func (*BranchManager) Create

Create creates a new branch.

func (*BranchManager) ForceReturn

func (m *BranchManager) ForceReturn(ctx context.Context, branchID string, reason string) error

ForceReturn terminates a branch with the given reason.

func (*BranchManager) Get

func (m *BranchManager) Get(ctx context.Context, branchID string) (*Branch, error)

Get retrieves a branch by ID.

func (*BranchManager) GetActive

func (m *BranchManager) GetActive(ctx context.Context, sessionID string) (*Branch, error)

GetActive returns the currently active branch for a session.

func (*BranchManager) Health

func (m *BranchManager) Health() HealthStatus

Health returns the current health status of the manager.

func (*BranchManager) IsShutdown

func (m *BranchManager) IsShutdown() bool

IsShutdown returns true if the manager has been shut down.

func (*BranchManager) ListBySession

func (m *BranchManager) ListBySession(ctx context.Context, sessionID string) ([]*Branch, error)

ListBySession returns all branches for a session.

func (*BranchManager) Return

Return completes a branch with results.

func (*BranchManager) Shutdown

func (m *BranchManager) Shutdown(ctx context.Context) error

Shutdown gracefully shuts down the manager, canceling all timeout watchers and force-returning all active branches.

type BranchManagerOption

type BranchManagerOption func(*BranchManager)

BranchManagerOption configures BranchManager.

func WithLogger

func WithLogger(l *Logger) BranchManagerOption

WithLogger sets a custom logger for the manager.

func WithMetrics

func WithMetrics(m *Metrics) BranchManagerOption

WithMetrics sets custom metrics for the manager.

func WithSessionValidator

func WithSessionValidator(v SessionValidator) BranchManagerOption

WithSessionValidator sets a session validator for authorization (SEC-004). If not set, PermissiveSessionValidator is used (allows all access).

type BranchRepository

type BranchRepository interface {
	// Create stores a new branch.
	Create(ctx context.Context, branch *Branch) error
	// Get retrieves a branch by ID.
	Get(ctx context.Context, id string) (*Branch, error)
	// Update modifies an existing branch.
	Update(ctx context.Context, branch *Branch) error
	// Delete removes a branch.
	Delete(ctx context.Context, id string) error
	// ListBySession returns all branches for a session.
	ListBySession(ctx context.Context, sessionID string) ([]*Branch, error)
	// ListByParent returns all child branches of a parent.
	ListByParent(ctx context.Context, parentID string) ([]*Branch, error)
	// GetActiveBySession returns the currently active branch for a session.
	GetActiveBySession(ctx context.Context, sessionID string) (*Branch, error)
	// CountActiveBySession returns the count of active branches in a session.
	CountActiveBySession(ctx context.Context, sessionID string) (int, error)
}

BranchRepository provides persistence for branches.

type BranchRequest

type BranchRequest struct {
	SessionID      string `json:"session_id"`
	ProjectID      string `json:"project_id,omitempty"` // Project context for metrics
	CallerID       string `json:"caller_id,omitempty"`  // SEC-004: Caller identity for authorization
	Description    string `json:"description"`
	Prompt         string `json:"prompt"`
	Budget         int    `json:"budget,omitempty"`
	InjectMemories bool   `json:"inject_memories,omitempty"`
	TimeoutSeconds int    `json:"timeout_seconds,omitempty"`
}

BranchRequest represents a request to create a new branch.

func (*BranchRequest) ApplyDefaults

func (r *BranchRequest) ApplyDefaults()

ApplyDefaults sets default values for optional fields.

func (*BranchRequest) Validate

func (r *BranchRequest) Validate() error

Validate checks the request against SEC-001 requirements. Trims whitespace before checking for empty values to prevent whitespace-only inputs.

type BranchResponse

type BranchResponse struct {
	BranchID        string         `json:"branch_id"`
	InjectedContext []InjectedItem `json:"injected_context,omitempty"`
	BudgetAllocated int            `json:"budget_allocated"`
	Depth           int            `json:"depth"`
}

BranchResponse is returned when a branch is created.

type BranchStatus

type BranchStatus string

BranchStatus represents the lifecycle state of a branch.

const (
	BranchStatusCreated   BranchStatus = "created"
	BranchStatusActive    BranchStatus = "active"
	BranchStatusCompleted BranchStatus = "completed"
	BranchStatusTimeout   BranchStatus = "timeout"
	BranchStatusFailed    BranchStatus = "failed"
)

func (BranchStatus) CanTransitionTo

func (s BranchStatus) CanTransitionTo(target BranchStatus) bool

CanTransitionTo checks if a transition from current status to target is valid.

func (BranchStatus) IsTerminal

func (s BranchStatus) IsTerminal() bool

IsTerminal returns true if this is a terminal state.

type BudgetExhaustedEvent

type BudgetExhaustedEvent struct {
	BudgetUsed  int
	BudgetTotal int
	// contains filtered or unexported fields
}

BudgetExhaustedEvent is emitted when a branch exhausts its budget.

func (BudgetExhaustedEvent) BranchID

func (e BudgetExhaustedEvent) BranchID() string

func (BudgetExhaustedEvent) Type

func (e BudgetExhaustedEvent) Type() string

type BudgetTracker

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

BudgetTracker tracks token budgets per branch and emits events on exhaustion. It does NOT directly call BranchManager to avoid circular dependencies. Instead, it emits events that BranchManager subscribes to.

func NewBudgetTracker

func NewBudgetTracker(emitter EventEmitter) *BudgetTracker

NewBudgetTracker creates a new budget tracker with the given event emitter.

func (*BudgetTracker) Allocate

func (t *BudgetTracker) Allocate(branchID string, budget int) error

Allocate initializes budget tracking for a branch.

func (*BudgetTracker) Consume

func (t *BudgetTracker) Consume(branchID string, tokens int) error

Consume attempts to consume tokens from a branch's budget. Returns ErrBudgetExhausted if the budget would be exceeded. Emits BudgetWarningEvent at 80% usage, BudgetExhaustedEvent when exceeded. NOTE: Events are emitted AFTER releasing the lock to prevent deadlocks when event handlers call back into BudgetTracker methods.

func (*BudgetTracker) Deallocate

func (t *BudgetTracker) Deallocate(branchID string)

Deallocate removes budget tracking for a branch.

func (*BudgetTracker) IsExhausted

func (t *BudgetTracker) IsExhausted(branchID string) bool

IsExhausted returns true if a branch's budget is exhausted.

func (*BudgetTracker) Remaining

func (t *BudgetTracker) Remaining(branchID string) (int, error)

Remaining returns the remaining tokens for a branch.

func (*BudgetTracker) Used

func (t *BudgetTracker) Used(branchID string) (int, error)

Used returns the used tokens for a branch.

type BudgetWarningEvent

type BudgetWarningEvent struct {
	BudgetUsed  int
	BudgetTotal int
	Percentage  float64
	// contains filtered or unexported fields
}

BudgetWarningEvent is emitted when a branch reaches 80% budget usage.

func (BudgetWarningEvent) BranchID

func (e BudgetWarningEvent) BranchID() string

func (BudgetWarningEvent) Type

func (e BudgetWarningEvent) Type() string

type EventEmitter

type EventEmitter interface {
	// Emit sends an event to all subscribers.
	Emit(event BranchEvent)
	// Subscribe registers a handler for events.
	Subscribe(handler func(BranchEvent))
}

EventEmitter emits and routes branch events.

type FoldingConfig

type FoldingConfig struct {
	DefaultBudget            int     `json:"default_budget" koanf:"default_budget"`
	MaxBudget                int     `json:"max_budget" koanf:"max_budget"`
	MaxDepth                 int     `json:"max_depth" koanf:"max_depth"`
	DefaultTimeoutSeconds    int     `json:"default_timeout_seconds" koanf:"default_timeout_seconds"`
	MaxTimeoutSeconds        int     `json:"max_timeout_seconds" koanf:"max_timeout_seconds"`
	InjectionBudgetRatio     float64 `json:"injection_budget_ratio" koanf:"injection_budget_ratio"`
	MemoryMinConfidence      float64 `json:"memory_min_confidence" koanf:"memory_min_confidence"`
	MemoryMaxItems           int     `json:"memory_max_items" koanf:"memory_max_items"`
	MaxConcurrentPerSession  int     `json:"max_concurrent_per_session" koanf:"max_concurrent_per_session"`
	MaxConcurrentPerInstance int     `json:"max_concurrent_per_instance" koanf:"max_concurrent_per_instance"`
}

FoldingConfig holds configuration for context-folding.

func DefaultFoldingConfig

func DefaultFoldingConfig() *FoldingConfig

DefaultFoldingConfig returns sensible defaults.

type FoldingError

type FoldingError struct {
	Code      string // Error code for categorization (e.g., "FOLD001")
	Message   string // Human-readable error message
	Cause     error  // Underlying cause (if any)
	BranchID  string // Branch ID context (if applicable)
	SessionID string // Session ID context (if applicable)
}

FoldingError represents a structured error with context and categorization. It implements the error interface and supports error wrapping via Unwrap.

func NewFoldingError

func NewFoldingError(code, message string, cause error, branchID, sessionID string) *FoldingError

NewFoldingError creates a new FoldingError with the given parameters.

func (*FoldingError) Error

func (e *FoldingError) Error() string

Error implements the error interface.

func (*FoldingError) Unwrap

func (e *FoldingError) Unwrap() error

Unwrap implements the errors.Unwrap interface for error chaining.

type HealthStatus

type HealthStatus struct {
	Healthy      bool   `json:"healthy"`
	ActiveCount  int64  `json:"active_count"`
	IsShutdown   bool   `json:"is_shutdown"`
	ErrorMessage string `json:"error_message,omitempty"`
}

HealthStatus represents the health state of the BranchManager.

type InjectedItem

type InjectedItem struct {
	Type    string `json:"type"` // "memory", "policy", "standard"
	ID      string `json:"id"`
	Title   string `json:"title"`
	Content string `json:"content"`
	Tokens  int    `json:"tokens"`
}

InjectedItem represents a memory or other context injected into a branch.

type Logger

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

Logger wraps zap.Logger with folding-specific structured logging.

func NewLogger

func NewLogger(logger *zap.Logger) *Logger

NewLogger creates a new Logger. If logger is nil, uses a no-op logger.

func (*Logger) BranchCreated

func (l *Logger) BranchCreated(ctx context.Context, branchID, sessionID string, depth, budget int)

BranchCreated logs a branch creation event.

func (*Logger) BranchFailed

func (l *Logger) BranchFailed(ctx context.Context, branchID, sessionID string, depth int, reason string, tokensUsed, budget int, duration time.Duration)

BranchFailed logs a branch failure.

func (*Logger) BranchReturned

func (l *Logger) BranchReturned(ctx context.Context, branchID, sessionID string, depth, tokensUsed, budget int, duration time.Duration)

BranchReturned logs a successful branch return.

func (*Logger) BranchTimeout

func (l *Logger) BranchTimeout(ctx context.Context, branchID, sessionID string, depth, tokensUsed, budget int, timeoutSeconds int, duration time.Duration)

BranchTimeout logs a branch timeout.

func (*Logger) BudgetExhausted

func (l *Logger) BudgetExhausted(ctx context.Context, branchID string, budgetUsed, budgetTotal int)

BudgetExhausted logs a budget exhaustion event.

func (*Logger) BudgetWarning

func (l *Logger) BudgetWarning(ctx context.Context, branchID string, budgetUsed, budgetTotal int, percentage float64)

BudgetWarning logs a budget warning event (80% usage).

func (*Logger) Debug

func (l *Logger) Debug(ctx context.Context, msg string, fields ...zap.Field)

Debug logs a debug message with context.

func (*Logger) Error

func (l *Logger) Error(ctx context.Context, msg string, err error, fields ...zap.Field)

Error logs an error with context.

func (*Logger) ForceReturn

func (l *Logger) ForceReturn(ctx context.Context, branchID, sessionID string, depth int, reason string)

ForceReturn logs a force return event.

func (*Logger) SessionCleanup

func (l *Logger) SessionCleanup(ctx context.Context, sessionID string, branchCount int)

SessionCleanup logs a session cleanup event.

func (*Logger) Warn

func (l *Logger) Warn(ctx context.Context, msg string, fields ...zap.Field)

Warn logs a warning message with context.

type MemoryBranchRepository

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

MemoryBranchRepository is an in-memory implementation of BranchRepository. It is thread-safe and suitable for single-instance deployments.

func NewMemoryBranchRepository

func NewMemoryBranchRepository() *MemoryBranchRepository

NewMemoryBranchRepository creates a new in-memory branch repository.

func (*MemoryBranchRepository) CountActiveBySession

func (r *MemoryBranchRepository) CountActiveBySession(ctx context.Context, sessionID string) (int, error)

CountActiveBySession returns the count of active branches in a session.

func (*MemoryBranchRepository) Create

func (r *MemoryBranchRepository) Create(ctx context.Context, branch *Branch) error

Create stores a new branch.

func (*MemoryBranchRepository) Delete

func (r *MemoryBranchRepository) Delete(ctx context.Context, id string) error

Delete removes a branch.

func (*MemoryBranchRepository) Get

Get retrieves a branch by ID.

func (*MemoryBranchRepository) GetActiveBySession

func (r *MemoryBranchRepository) GetActiveBySession(ctx context.Context, sessionID string) (*Branch, error)

GetActiveBySession returns the currently active branch for a session. Returns the deepest active branch (highest depth) to correctly calculate depth when creating nested branches. Ties are broken by most recent CreatedAt. Returns nil if no active branch exists.

func (*MemoryBranchRepository) ListByParent

func (r *MemoryBranchRepository) ListByParent(ctx context.Context, parentID string) ([]*Branch, error)

ListByParent returns all child branches of a parent.

func (*MemoryBranchRepository) ListBySession

func (r *MemoryBranchRepository) ListBySession(ctx context.Context, sessionID string) ([]*Branch, error)

ListBySession returns all branches for a session.

func (*MemoryBranchRepository) Update

func (r *MemoryBranchRepository) Update(ctx context.Context, branch *Branch) error

Update modifies an existing branch.

type MemorySearcher

type MemorySearcher interface {
	// Search finds memories relevant to the query.
	Search(ctx context.Context, query string, limit int, minConfidence float64) ([]InjectedItem, error)
}

MemorySearcher searches for relevant memories.

type Metrics

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

Metrics provides OpenTelemetry metrics for the folding package.

func NewMetrics

func NewMetrics(meter metric.Meter) (*Metrics, error)

NewMetrics creates a new Metrics instance with the provided meter. If meter is nil, uses the global meter provider.

func (*Metrics) RecordBranchCreated

func (m *Metrics) RecordBranchCreated(ctx context.Context, sessionID string, depth int, budget int, projectID string)

RecordBranchCreated records a branch creation. Note: session_id is intentionally omitted from metrics to prevent cardinality explosion (SEC-FOLD-001). Session correlation is available via trace context and structured logs.

func (*Metrics) RecordBranchFailed

func (m *Metrics) RecordBranchFailed(ctx context.Context, sessionID string, depth int, reason string, tokensUsed int, budget int, duration time.Duration, projectID string)

RecordBranchFailed records a branch failure. Note: session_id is intentionally omitted from metrics to prevent cardinality explosion (SEC-FOLD-001).

func (*Metrics) RecordBranchReturned

func (m *Metrics) RecordBranchReturned(ctx context.Context, sessionID string, depth int, tokensUsed int, budget int, duration time.Duration, projectID string)

RecordBranchReturned records a successful branch return. Note: session_id is intentionally omitted from metrics to prevent cardinality explosion (SEC-FOLD-001).

func (*Metrics) RecordBranchTimeout

func (m *Metrics) RecordBranchTimeout(ctx context.Context, sessionID string, depth int, tokensUsed int, budget int, duration time.Duration, projectID string)

RecordBranchTimeout records a branch timeout. Note: session_id is intentionally omitted from metrics to prevent cardinality explosion (SEC-FOLD-001).

type PermissiveSessionValidator

type PermissiveSessionValidator struct{}

PermissiveSessionValidator allows all session access (for single-user deployments).

func (*PermissiveSessionValidator) ValidateSession

func (v *PermissiveSessionValidator) ValidateSession(ctx context.Context, sessionID string, callerID string) error

ValidateSession always returns nil (allows all access).

type ReturnRequest

type ReturnRequest struct {
	BranchID      string `json:"branch_id"`
	CallerID      string `json:"caller_id,omitempty"` // SEC-004: Caller identity for authorization
	Message       string `json:"message"`
	ExtractMemory bool   `json:"extract_memory,omitempty"`
}

ReturnRequest represents a request to complete a branch.

func (*ReturnRequest) Validate

func (r *ReturnRequest) Validate() error

Validate checks the return request.

type ReturnResponse

type ReturnResponse struct {
	Success      bool   `json:"success"`
	TokensUsed   int    `json:"tokens_used"`
	MemoryQueued bool   `json:"memory_queued"`
	ScrubbedMsg  string `json:"scrubbed_message"` // Message after secret scrubbing
}

ReturnResponse is returned when a branch completes.

type SecretScrubber

type SecretScrubber interface {
	// Scrub removes secrets from the content, returning scrubbed version.
	Scrub(content string) (string, error)
}

SecretScrubber removes secrets from content.

type SessionValidator

type SessionValidator interface {
	// ValidateSession checks if the caller (identified by callerID) has access to sessionID.
	// Returns nil if access is allowed, ErrSessionUnauthorized if not.
	// The callerID can be extracted from MCP context, JWT claims, or other auth mechanisms.
	ValidateSession(ctx context.Context, sessionID string, callerID string) error
}

SessionValidator validates that a caller has access to a session. This interface enables authentication/authorization enforcement (SEC-004).

type SimpleEventEmitter

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

SimpleEventEmitter is a basic implementation of EventEmitter for testing.

func NewSimpleEventEmitter

func NewSimpleEventEmitter() *SimpleEventEmitter

NewSimpleEventEmitter creates a new simple event emitter.

func (*SimpleEventEmitter) Clear

func (e *SimpleEventEmitter) Clear()

Clear clears all recorded events (for testing).

func (*SimpleEventEmitter) Emit

func (e *SimpleEventEmitter) Emit(event BranchEvent)

Emit sends an event to all subscribers.

func (*SimpleEventEmitter) Events

func (e *SimpleEventEmitter) Events() []BranchEvent

Events returns all emitted events (for testing).

func (*SimpleEventEmitter) Subscribe

func (e *SimpleEventEmitter) Subscribe(handler func(BranchEvent))

Subscribe registers a handler for events.

type StrictSessionValidator

type StrictSessionValidator struct{}

StrictSessionValidator requires session ownership match.

func (*StrictSessionValidator) ValidateSession

func (v *StrictSessionValidator) ValidateSession(ctx context.Context, sessionID string, callerID string) error

ValidateSession requires callerID to match sessionID prefix or be the session owner. Sessions are expected to follow format: "user_<userID>_<sessionID>" or callerID must match exactly.

type TimeoutEvent

type TimeoutEvent struct {
	TimeoutSeconds int
	// contains filtered or unexported fields
}

TimeoutEvent is emitted when a branch times out.

func (TimeoutEvent) BranchID

func (e TimeoutEvent) BranchID() string

func (TimeoutEvent) Type

func (e TimeoutEvent) Type() string

type TokenCounter

type TokenCounter interface {
	// Count returns the token count for the given content.
	Count(content string) (int, error)
}

TokenCounter counts tokens in text content.

Jump to

Keyboard shortcuts

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