deck

package
v0.1.0 Latest Latest
Warning

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

Go to latest
Published: Mar 6, 2026 License: AGPL-3.0 Imports: 27 Imported by: 0

Documentation

Index

Constants

View Source
const (
	StatusCompleted = "completed"
	StatusFailed    = "failed"
	StatusAbandoned = "abandoned"
	StatusUnknown   = "unknown"
)
View Source
const DemoSQLitePath = "tapes.demo.sqlite"

Variables

This section is empty.

Functions

func CostForTokens

func CostForTokens(pricing Pricing, inputTokens, outputTokens int64) (float64, float64, float64)

CostForTokens calculates cost using base input/output pricing. For cache-aware cost calculation, use CostForTokensWithCache.

func CostForTokensWithCache

func CostForTokensWithCache(pricing Pricing, inputTokens, outputTokens, cacheCreation, cacheRead int64) (float64, float64, float64)

CostForTokensWithCache calculates cost accounting for prompt caching. When cache token counts are available, base input tokens are calculated as: baseInput = totalInput - cacheCreation - cacheRead Each token type is priced at its respective rate.

func HasLLMCredentials

func HasLLMCredentials(cfg LLMCallerConfig) bool

HasLLMCredentials checks whether an API key can be resolved from the config without creating a caller. Used for auto-enabling insights.

func SeedDemo

func SeedDemo(ctx context.Context, path string, overwrite bool) (int, int, error)

func SortSessions

func SortSessions(sessions []SessionSummary, sortKey, sortDir string)

SortSessions sorts session summaries in place by the given key and direction.

func StripTaggedSection

func StripTaggedSection(text, tag string) string

StripTaggedSection removes all occurrences of a given XML-like tagged section (e.g. <system-reminder>…</system-reminder>) from text.

Types

type AnalyticsOverview

type AnalyticsOverview struct {
	TotalSessions     int                `json:"total_sessions"`
	AvgSessionCost    float64            `json:"avg_session_cost"`
	AvgDurationNs     int64              `json:"avg_duration_ns"`
	TopTools          []ToolMetric       `json:"top_tools"`
	ActivityByDay     []DayActivity      `json:"activity_by_day"`
	DurationBuckets   []Bucket           `json:"duration_buckets"`
	CostBuckets       []Bucket           `json:"cost_buckets"`
	ModelPerformance  []ModelPerformance `json:"model_performance"`
	ProviderBreakdown map[string]int     `json:"provider_breakdown"`
}

AnalyticsOverview holds cross-session analytics.

type Bucket

type Bucket struct {
	Label string `json:"label"`
	Count int    `json:"count"`
}

type DayActivity

type DayActivity struct {
	Date     string  `json:"date"`
	Sessions int     `json:"sessions"`
	Cost     float64 `json:"cost"`
	Tokens   int64   `json:"tokens"`
}

type EntFacetStore

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

EntFacetStore implements FacetStore using ent.

func NewEntFacetStore

func NewEntFacetStore(client *ent.Client) *EntFacetStore

NewEntFacetStore creates a new EntFacetStore.

func (*EntFacetStore) GetFacet

func (s *EntFacetStore) GetFacet(ctx context.Context, sessionID string) (*SessionFacet, error)

func (*EntFacetStore) ListFacets

func (s *EntFacetStore) ListFacets(ctx context.Context) ([]*SessionFacet, error)

func (*EntFacetStore) SaveFacet

func (s *EntFacetStore) SaveFacet(ctx context.Context, f *SessionFacet) error

type FacetAnalytics

type FacetAnalytics struct {
	GoalDistribution    map[string]int `json:"goal_distribution"`
	OutcomeDistribution map[string]int `json:"outcome_distribution"`
	SessionTypes        map[string]int `json:"session_types"`
	TopFriction         []FrictionItem `json:"top_friction"`
	RecentSummaries     []FacetSummary `json:"recent_summaries"`
}

FacetAnalytics holds aggregated facet data across sessions.

type FacetExtractor

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

FacetExtractor extracts qualitative facets from session transcripts.

func NewFacetExtractor

func NewFacetExtractor(query Querier, llmCall LLMCallFunc, store FacetStore, log *slog.Logger) *FacetExtractor

NewFacetExtractor creates a new FacetExtractor.

func (*FacetExtractor) AggregateFacets

func (f *FacetExtractor) AggregateFacets(ctx context.Context) (*FacetAnalytics, error)

AggregateFacets computes aggregated analytics from all stored facets.

func (*FacetExtractor) Extract

func (f *FacetExtractor) Extract(ctx context.Context, sessionID string) (*SessionFacet, error)

Extract runs facet extraction for a single session. It retries up to 2 times on JSON parse failures with a stricter prompt.

type FacetStore

type FacetStore interface {
	SaveFacet(ctx context.Context, facet *SessionFacet) error
	GetFacet(ctx context.Context, sessionID string) (*SessionFacet, error)
	ListFacets(ctx context.Context) ([]*SessionFacet, error)
}

FacetStore is the interface for persisting and retrieving facets.

type FacetSummary

type FacetSummary struct {
	SessionID      string `json:"session_id"`
	UnderlyingGoal string `json:"underlying_goal"`
	BriefSummary   string `json:"brief_summary"`
	GoalCategory   string `json:"goal_category"`
	Outcome        string `json:"outcome"`
}

FacetSummary is a brief summary for display.

type FacetWorker

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

FacetWorker processes sessions in the background to extract facets.

func NewFacetWorker

func NewFacetWorker(extractor *FacetExtractor, store FacetStore, query Querier, log *slog.Logger) *FacetWorker

NewFacetWorker creates a new FacetWorker.

func (*FacetWorker) Progress

func (w *FacetWorker) Progress() (done, total int)

Progress returns the number of sessions processed and total to process.

func (*FacetWorker) Run

func (w *FacetWorker) Run(ctx context.Context)

Run starts background facet extraction. It queries all sessions, skips those with existing facets, and processes the rest with bounded concurrency. It blocks until all sessions are processed or the context is cancelled.

type Filters

type Filters struct {
	Since   time.Duration
	From    *time.Time
	To      *time.Time
	Model   string
	Status  string
	Project string
	Sort    string
	SortDir string
	Session string
}

type FrictionItem

type FrictionItem struct {
	Type  string `json:"type"`
	Count int    `json:"count"`
}

FrictionItem represents a friction type with its count.

type LLMCallFunc

type LLMCallFunc func(ctx context.Context, prompt string) (string, error)

LLMCallFunc is the signature for an LLM inference call.

func NewLLMCaller

func NewLLMCaller(cfg LLMCallerConfig) (LLMCallFunc, error)

NewLLMCaller creates a LLMCallFunc based on the provided configuration. Resolution order for API key:

  1. Explicit APIKey in config
  2. credentials.Manager (from tapes auth)
  3. Environment variables (OPENAI_API_KEY / ANTHROPIC_API_KEY)
  4. Fall back to Ollama at localhost:11434

type LLMCallerConfig

type LLMCallerConfig struct {
	Provider string               // "openai", "anthropic", or "ollama"
	Model    string               // e.g. "gpt-4o-mini", "claude-haiku-4-5-20251001"
	APIKey   string               // explicit API key (highest priority)
	BaseURL  string               // override base URL
	CredMgr  *credentials.Manager // credentials from tapes auth
	Logger   *slog.Logger         // optional logger; defaults to noop
}

LLMCallerConfig holds configuration for creating an LLM caller.

type ModelCost

type ModelCost struct {
	Model        string  `json:"model"`
	InputTokens  int64   `json:"input_tokens"`
	OutputTokens int64   `json:"output_tokens"`
	InputCost    float64 `json:"input_cost"`
	OutputCost   float64 `json:"output_cost"`
	TotalCost    float64 `json:"total_cost"`
	SessionCount int     `json:"session_count"`
}

type ModelPerformance

type ModelPerformance struct {
	Model          string  `json:"model"`
	Provider       string  `json:"provider"`
	Sessions       int     `json:"sessions"`
	AvgCost        float64 `json:"avg_cost"`
	AvgDurationNs  int64   `json:"avg_duration_ns"`
	AvgTokens      int64   `json:"avg_tokens"`
	TotalCost      float64 `json:"total_cost"`
	SuccessRate    float64 `json:"success_rate"`
	CompletedCount int     `json:"completed_count"`
}

type Overview

type Overview struct {
	Sessions       []SessionSummary     `json:"sessions"`
	TotalCost      float64              `json:"total_cost"`
	TotalTokens    int64                `json:"total_tokens"`
	InputTokens    int64                `json:"input_tokens"`
	OutputTokens   int64                `json:"output_tokens"`
	TotalDuration  time.Duration        `json:"total_duration_ns"`
	TotalToolCalls int                  `json:"total_tool_calls"`
	SuccessRate    float64              `json:"success_rate"`
	Completed      int                  `json:"completed"`
	Failed         int                  `json:"failed"`
	Abandoned      int                  `json:"abandoned"`
	CostByModel    map[string]ModelCost `json:"cost_by_model"`
	PreviousPeriod *PeriodComparison    `json:"previous_period,omitempty"`
}

type PeriodComparison

type PeriodComparison struct {
	TotalCost      float64       `json:"total_cost"`
	TotalTokens    int64         `json:"total_tokens"`
	TotalDuration  time.Duration `json:"total_duration_ns"`
	TotalToolCalls int           `json:"total_tool_calls"`
	SuccessRate    float64       `json:"success_rate"`
	Completed      int           `json:"completed"`
}

type Pricing

type Pricing struct {
	Input      float64 `json:"input"`
	Output     float64 `json:"output"`
	CacheRead  float64 `json:"cache_read"`
	CacheWrite float64 `json:"cache_write"`
}

func PricingForModel

func PricingForModel(pricing PricingTable, model string) (Pricing, bool)

type PricingTable

type PricingTable map[string]Pricing

func DefaultPricing

func DefaultPricing() PricingTable

DefaultPricing returns hardcoded pricing per million tokens for supported models.

Last verified: 2026-02-15 Sources:

Anthropic cache multipliers: CacheWrite = 1.25x input, CacheRead = 0.10x input. OpenAI cache: CacheWrite = 1x input (no surcharge), CacheRead = 0.50x input (except o3-mini).

To override at runtime, use --pricing with a JSON file. See LoadPricing.

func LoadPricing

func LoadPricing(path string) (PricingTable, error)

type Querier

type Querier interface {
	Overview(ctx context.Context, filters Filters) (*Overview, error)
	SessionDetail(ctx context.Context, sessionID string) (*SessionDetail, error)
	AnalyticsOverview(ctx context.Context, filters Filters) (*AnalyticsOverview, error)
	SessionAnalytics(ctx context.Context, sessionID string) (*SessionAnalytics, error)
}

Querier is an interface for querying session data. This allows for mock implementations in testing and sandboxes.

type Query

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

func NewQuery

func NewQuery(ctx context.Context, dbPath string, pricing PricingTable) (*Query, func() error, error)

func (*Query) AnalyticsOverview

func (q *Query) AnalyticsOverview(ctx context.Context, filters Filters) (*AnalyticsOverview, error)

func (*Query) EntClient

func (q *Query) EntClient() *ent.Client

EntClient returns the underlying ent client for use by subsystems like the facet store.

func (*Query) Overview

func (q *Query) Overview(ctx context.Context, filters Filters) (*Overview, error)

func (*Query) SessionAnalytics

func (q *Query) SessionAnalytics(ctx context.Context, sessionID string) (*SessionAnalytics, error)

func (*Query) SessionDetail

func (q *Query) SessionDetail(ctx context.Context, sessionID string) (*SessionDetail, error)

type SessionAnalytics

type SessionAnalytics struct {
	SessionID         string  `json:"session_id"`
	UserMessageCount  int     `json:"user_message_count"`
	AssistantMsgCount int     `json:"assistant_message_count"`
	AvgResponseTimeNs int64   `json:"avg_response_time_ns"`
	LongestPauseNs    int64   `json:"longest_pause_ns"`
	UniqueTools       int     `json:"unique_tools"`
	ToolErrorCount    int     `json:"tool_error_count"`
	TokensPerMinute   float64 `json:"tokens_per_minute"`
	AvgPromptLength   int     `json:"avg_prompt_length"`
	AvgResponseLength int     `json:"avg_response_length"`
	FirstPrompt       string  `json:"first_prompt"`
}

SessionAnalytics holds per-session computed analytics.

type SessionDetail

type SessionDetail struct {
	Summary         SessionSummary        `json:"summary"`
	Messages        []SessionMessage      `json:"messages"`
	GroupedMessages []SessionMessageGroup `json:"grouped_messages,omitempty"`
	ToolFrequency   map[string]int        `json:"tool_frequency"`
	SubSessions     []SessionSummary      `json:"sub_sessions,omitempty"`
}

type SessionFacet

type SessionFacet struct {
	SessionID      string    `json:"session_id"`
	UnderlyingGoal string    `json:"underlying_goal"`
	GoalCategory   string    `json:"goal_category"`
	Outcome        string    `json:"outcome"`
	SessionType    string    `json:"session_type"`
	FrictionTypes  []string  `json:"friction_types"`
	BriefSummary   string    `json:"brief_summary"`
	ExtractedAt    time.Time `json:"extracted_at"`
}

SessionFacet holds LLM-extracted qualitative data about a session.

type SessionMessage

type SessionMessage struct {
	Hash         string        `json:"hash"`
	Role         string        `json:"role"`
	Model        string        `json:"model"`
	Timestamp    time.Time     `json:"timestamp"`
	Delta        time.Duration `json:"delta_ns"`
	InputTokens  int64         `json:"input_tokens"`
	OutputTokens int64         `json:"output_tokens"`
	TotalTokens  int64         `json:"total_tokens"`
	InputCost    float64       `json:"input_cost"`
	OutputCost   float64       `json:"output_cost"`
	TotalCost    float64       `json:"total_cost"`
	ToolCalls    []string      `json:"tool_calls"`
	Text         string        `json:"text"`
}

type SessionMessageGroup

type SessionMessageGroup struct {
	Role         string        `json:"role"`
	StartTime    time.Time     `json:"start_time"`
	EndTime      time.Time     `json:"end_time"`
	Delta        time.Duration `json:"delta_ns"`
	InputTokens  int64         `json:"input_tokens"`
	OutputTokens int64         `json:"output_tokens"`
	TotalTokens  int64         `json:"total_tokens"`
	InputCost    float64       `json:"input_cost"`
	OutputCost   float64       `json:"output_cost"`
	TotalCost    float64       `json:"total_cost"`
	ToolCalls    []string      `json:"tool_calls"`
	Text         string        `json:"text"`
	Count        int           `json:"count"`
	StartIndex   int           `json:"start_index"`
	EndIndex     int           `json:"end_index"`
}

type SessionSummary

type SessionSummary struct {
	ID           string        `json:"id"`
	Label        string        `json:"label"`
	Model        string        `json:"model"`
	Project      string        `json:"project"`
	AgentName    string        `json:"agent_name,omitempty"`
	Status       string        `json:"status"`
	StartTime    time.Time     `json:"start_time"`
	EndTime      time.Time     `json:"end_time"`
	Duration     time.Duration `json:"duration_ns"`
	InputTokens  int64         `json:"input_tokens"`
	OutputTokens int64         `json:"output_tokens"`
	InputCost    float64       `json:"input_cost"`
	OutputCost   float64       `json:"output_cost"`
	TotalCost    float64       `json:"total_cost"`
	ToolCalls    int           `json:"tool_calls"`
	MessageCount int           `json:"message_count"`
	SessionCount int           `json:"session_count,omitempty"`
}

type ToolMetric

type ToolMetric struct {
	Name       string `json:"name"`
	Count      int    `json:"count"`
	ErrorCount int    `json:"error_count"`
	Sessions   int    `json:"sessions"`
}

Jump to

Keyboard shortcuts

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