storage

package
v0.14.0 Latest Latest
Warning

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

Go to latest
Published: Jun 15, 2026 License: MIT Imports: 8 Imported by: 0

Documentation

Overview

Package storage provides session state persistence for voice calls.

The package defines a SessionStore interface for storing and retrieving session state, enabling features like call recovery and session resumption.

Available Implementations

  • MemoryStore: In-memory storage for development and testing
  • RedisStore: Redis-backed storage for production deployments

Usage

store := storage.NewMemoryStore()

// Save session state
state := &storage.SessionState{
    ID:       "session-123",
    Provider: "twilio",
    From:     "+15551234567",
    To:       "+15559876543",
    Status:   storage.StatusActive,
}
err := store.Save(ctx, state)

// Load session state
loaded, err := store.Load(ctx, "session-123")

Redis Configuration

For production deployments, use RedisStore with connection pooling:

store, err := storage.NewRedisStore("redis://localhost:6379",
    storage.WithPrefix("voicecall:"),
    storage.WithTTL(24 * time.Hour),
)

Index

Constants

This section is empty.

Variables

View Source
var ErrNotFound = errors.New("session not found")

ErrNotFound is returned when a session does not exist.

View Source
var ErrStoreClosed = errors.New("store is closed")

ErrStoreClosed is returned when operating on a closed store.

Functions

This section is empty.

Types

type Direction

type Direction string

Direction represents the direction of a call.

const (
	// DirectionInbound indicates an incoming call.
	DirectionInbound Direction = "inbound"

	// DirectionOutbound indicates an outgoing call.
	DirectionOutbound Direction = "outbound"
)

type HealthChecker

type HealthChecker interface {
	// Ping checks if the store is healthy and reachable.
	Ping(ctx context.Context) error
}

HealthChecker is an optional interface for stores that support health checks.

type MemoryStore

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

MemoryStore is an in-memory implementation of SessionStore. It is suitable for development, testing, and single-instance deployments. Note: Data is not persisted across restarts.

func NewMemoryStore

func NewMemoryStore() *MemoryStore

NewMemoryStore creates a new in-memory session store.

func (*MemoryStore) Close

func (m *MemoryStore) Close() error

Close releases the store's resources.

func (*MemoryStore) Count

func (m *MemoryStore) Count() int

Count returns the number of stored sessions (useful for testing).

func (*MemoryStore) Delete

func (m *MemoryStore) Delete(_ context.Context, sessionID string) error

Delete removes a session state.

func (*MemoryStore) ListActive

func (m *MemoryStore) ListActive(_ context.Context) ([]string, error)

ListActive returns IDs of all active sessions.

func (*MemoryStore) Load

func (m *MemoryStore) Load(_ context.Context, sessionID string) (*SessionState, error)

Load retrieves a session state by ID.

func (*MemoryStore) Name

func (m *MemoryStore) Name() string

Name returns the store implementation name.

func (*MemoryStore) Ping

func (m *MemoryStore) Ping(_ context.Context) error

Ping checks if the store is healthy.

func (*MemoryStore) Save

func (m *MemoryStore) Save(_ context.Context, session *SessionState) error

Save persists or updates a session state.

func (*MemoryStore) UpdateHeartbeat

func (m *MemoryStore) UpdateHeartbeat(_ context.Context, sessionID string) error

UpdateHeartbeat updates the session's timestamp.

type Namer

type Namer interface {
	Name() string
}

Namer is an optional interface for stores that have a name.

type RedisOption

type RedisOption func(*RedisStore)

RedisOption configures a RedisStore.

func WithPrefix

func WithPrefix(prefix string) RedisOption

WithPrefix sets the key prefix for all session keys.

func WithTTL

func WithTTL(ttl time.Duration) RedisOption

WithTTL sets the time-to-live for session keys.

type RedisStore

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

RedisStore is a Redis-backed implementation of SessionStore. It is suitable for production deployments requiring persistence and multi-instance coordination.

func NewRedisStore

func NewRedisStore(addr string, opts ...RedisOption) (*RedisStore, error)

NewRedisStore creates a new Redis-backed session store. The addr should be in the form "redis://host:port" or "host:port".

func NewRedisStoreFromClient

func NewRedisStoreFromClient(client *redis.Client, opts ...RedisOption) *RedisStore

NewRedisStoreFromClient creates a RedisStore from an existing client.

func (*RedisStore) Close

func (r *RedisStore) Close() error

Close releases the store's resources.

func (*RedisStore) Delete

func (r *RedisStore) Delete(ctx context.Context, sessionID string) error

Delete removes a session state.

func (*RedisStore) ListActive

func (r *RedisStore) ListActive(ctx context.Context) ([]string, error)

ListActive returns IDs of all active sessions.

func (*RedisStore) Load

func (r *RedisStore) Load(ctx context.Context, sessionID string) (*SessionState, error)

Load retrieves a session state by ID.

func (*RedisStore) Name

func (r *RedisStore) Name() string

Name returns the store implementation name.

func (*RedisStore) Ping

func (r *RedisStore) Ping(ctx context.Context) error

Ping checks if the store is healthy.

func (*RedisStore) Save

func (r *RedisStore) Save(ctx context.Context, session *SessionState) error

Save persists or updates a session state.

func (*RedisStore) UpdateHeartbeat

func (r *RedisStore) UpdateHeartbeat(ctx context.Context, sessionID string) error

UpdateHeartbeat updates the session's timestamp.

type SessionMetrics

type SessionMetrics struct {
	// TurnCount is the total number of conversational turns.
	TurnCount int `json:"turn_count"`

	// InterruptionCount is how many times the user interrupted the agent.
	InterruptionCount int `json:"interruption_count"`

	// UserSpeechDurationMs is total user speech time in milliseconds.
	UserSpeechDurationMs int `json:"user_speech_duration_ms"`

	// AgentSpeechDurationMs is total agent speech time in milliseconds.
	AgentSpeechDurationMs int `json:"agent_speech_duration_ms"`

	// FirstResponseMs is latency to first agent response in milliseconds.
	FirstResponseMs int `json:"first_response_ms,omitempty"`

	// AverageResponseMs is average agent response latency in milliseconds.
	AverageResponseMs int `json:"average_response_ms,omitempty"`
}

SessionMetrics tracks statistics for a voice session.

type SessionState

type SessionState struct {
	// ID uniquely identifies this session.
	ID string `json:"id"`

	// CreatedAt is when the session was first created.
	CreatedAt time.Time `json:"created_at"`

	// UpdatedAt is when the session was last modified.
	UpdatedAt time.Time `json:"updated_at"`

	// Call metadata
	CallID    string        `json:"call_id,omitempty"`
	Provider  string        `json:"provider"`
	Direction Direction     `json:"direction"`
	From      string        `json:"from"`
	To        string        `json:"to"`
	Status    SessionStatus `json:"status"`

	// Conversation history
	History []Turn `json:"history"`

	// Metrics for the session
	Metrics SessionMetrics `json:"metrics"`

	// RecoveryData holds provider-specific data needed to recover a session.
	RecoveryData map[string]any `json:"recovery_data,omitempty"`
}

SessionState represents the persistent state of a voice session.

func NewSessionState

func NewSessionState(id string) *SessionState

NewSessionState creates a new session state with initialized fields.

func (*SessionState) AddTurn

func (s *SessionState) AddTurn(role, content string, durationMs int)

AddTurn appends a conversational turn and updates metrics.

func (*SessionState) Duration

func (s *SessionState) Duration() time.Duration

Duration returns the total session duration.

func (*SessionState) RecordInterruption

func (s *SessionState) RecordInterruption()

RecordInterruption increments the interruption counter.

type SessionStatus

type SessionStatus string

SessionStatus represents the current state of a voice session.

const (
	// StatusPending indicates the session is waiting to be established.
	StatusPending SessionStatus = "pending"

	// StatusActive indicates the session is currently in progress.
	StatusActive SessionStatus = "active"

	// StatusOnHold indicates the session is on hold.
	StatusOnHold SessionStatus = "on_hold"

	// StatusTransferring indicates the session is being transferred.
	StatusTransferring SessionStatus = "transferring"

	// StatusEnded indicates the session has concluded.
	StatusEnded SessionStatus = "ended"
)

type SessionStore

type SessionStore interface {
	// Save persists or updates a session state.
	// If the session already exists, it will be overwritten.
	Save(ctx context.Context, session *SessionState) error

	// Load retrieves a session state by ID.
	// Returns ErrNotFound if the session does not exist.
	Load(ctx context.Context, sessionID string) (*SessionState, error)

	// Delete removes a session state.
	// Returns ErrNotFound if the session does not exist.
	Delete(ctx context.Context, sessionID string) error

	// ListActive returns IDs of all active sessions.
	// A session is considered active if its status is not StatusEnded.
	ListActive(ctx context.Context) ([]string, error)

	// UpdateHeartbeat updates the session's timestamp to indicate activity.
	// This is used to track session liveness and enable cleanup of stale sessions.
	UpdateHeartbeat(ctx context.Context, sessionID string) error

	// Close releases any resources held by the store.
	Close() error
}

SessionStore defines the interface for session persistence.

type Turn

type Turn struct {
	// Role is the speaker: "user" or "agent".
	Role string `json:"role"`

	// Content is the transcript of what was said.
	Content string `json:"content"`

	// Timestamp is when this turn occurred.
	Timestamp time.Time `json:"timestamp"`

	// DurationMs is the speech duration in milliseconds.
	DurationMs int `json:"duration_ms"`
}

Turn represents a single conversational turn.

Jump to

Keyboard shortcuts

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