api

package
v0.9.0 Latest Latest
Warning

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

Go to latest
Published: May 19, 2026 License: AGPL-3.0 Imports: 28 Imported by: 0

Documentation

Overview

Package api provides an HTTP API server for inspecting and managing the Merkle DAG.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Config

type Config struct {
	// ListenAddr is the address to listen on (e.g., ":8081")
	ListenAddr string

	// VectorDriver for semantic search (optional, enables MCP server)
	VectorDriver vector.Driver

	// Embedder for converting query text to vectors (optional, enables MCP server)
	Embedder embeddings.Embedder

	// Pricing is the model pricing table used by /v1/sessions/summary to
	// compute per-session cost. When nil, sessions.DefaultPricing() is used.
	Pricing sessions.PricingTable

	// EnableWebUI serves the minimal browser UI at /. It is disabled by default
	// so API-only servers do not expose a human-facing development UI unless
	// explicitly requested.
	EnableWebUI bool
}

Config is the API server configuration.

type GraphLink struct {
	Source string `json:"source"`
	Target string `json:"target"`
}

GraphLink is a directed parent -> child edge between two included GraphNode IDs.

type GraphNode added in v0.8.0

type GraphNode struct {
	ID            string     `json:"id"`
	ParentID      *string    `json:"parent_id,omitempty"`
	ParentHash    *string    `json:"parent_hash,omitempty"`
	Type          string     `json:"type,omitempty"`
	Role          string     `json:"role,omitempty"`
	Preview       string     `json:"preview,omitempty"`
	Model         string     `json:"model,omitempty"`
	Provider      string     `json:"provider,omitempty"`
	AgentName     string     `json:"agent_name,omitempty"`
	Project       string     `json:"project,omitempty"`
	StopReason    string     `json:"stop_reason,omitempty"`
	Usage         *llm.Usage `json:"usage,omitempty"`
	CreatedAt     time.Time  `json:"created_at,omitzero"`
	Depth         int        `json:"depth"`
	ChildrenCount int        `json:"children_count"`
	IsRoot        bool       `json:"is_root"`
	IsLeaf        bool       `json:"is_leaf"`
	IsBranchPoint bool       `json:"is_branch_point"`
	Selected      bool       `json:"selected"`
}

GraphNode is the per-node shape used by the web UI graph visualization.

type GraphResponse added in v0.8.0

type GraphResponse struct {
	// Hash is the session/node hash requested by the caller.
	Hash string `json:"hash"`

	// RootHash is the top-most resolvable node included in the response.
	RootHash string `json:"root_hash"`

	// Scope describes which portion of the graph was loaded: root, branch, or ancestry.
	Scope string `json:"scope"`

	// NodeLimit is the maximum number of nodes the server will include.
	NodeLimit int `json:"node_limit"`

	// Nodes is the flat node list consumed by graph visualizers.
	Nodes []GraphNode `json:"nodes"`

	// Links contains parent -> child edges between included nodes.
	Links []GraphLink `json:"links"`

	// Leaves names included nodes that have no children in storage.
	Leaves []string `json:"leaves"`

	// BranchPoints names included nodes with more than one child in storage.
	BranchPoints []string `json:"branch_points"`

	// Truncated is true when the graph hit NodeLimit or the ancestry chain is incomplete.
	Truncated bool `json:"truncated,omitempty"`

	// MissingParent names the unresolved parent hash when the ancestry is incomplete.
	MissingParent string `json:"missing_parent,omitempty"`

	// CycleDetected is true when storage guarded the ancestry walk out of a cycle.
	CycleDetected bool `json:"cycle_detected,omitempty"`
}

GraphResponse is the graph-shaped projection for GET /v1/sessions/:hash/graph.

type Metrics added in v0.7.0

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

Metrics is the Prometheus surface for the Tapes API server. Each Server owns its own registry so tests can scrape in isolation; the production path mounts /metrics on the Fiber app via NewServer.

func NewMetrics added in v0.7.0

func NewMetrics() *Metrics

NewMetrics constructs the Tapes API server's RED metrics. Labels stay templated (`route`) rather than per-URL so :hash path params don't blow up cardinality.

func (*Metrics) Handler added in v0.7.0

func (m *Metrics) Handler() fiber.Handler

Handler returns a Fiber handler that serves Prometheus text exposition from this Metrics instance's registry. Mount it at /metrics with no auth. The handler is built once at NewMetrics time and cached — see the scrapeHandler field comment for why.

func (*Metrics) Middleware added in v0.7.0

func (m *Metrics) Middleware() fiber.Handler

Middleware returns a Fiber handler that records request count + duration per (route template, method, status). Templates like /v1/sessions/:hash stay as the label value so the :hash path param never expands cardinality.

Register this OUTSIDE recover.New() (i.e. via app.Use before recover) — see resolveStatus for why.

func (*Metrics) Registry added in v0.7.0

func (m *Metrics) Registry() *prometheus.Registry

Registry exposes the *prometheus.Registry so tests can scrape against the same registry the middleware writes to.

type Server

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

Server is the API server for managing and querying the Tapes system

func NewServer

func NewServer(config Config, driver storage.Driver, log *slog.Logger) (*Server, error)

NewServer creates a new API server. The storer is injected to allow sharing with other components (e.g., the proxy when not run as a singleton).

func (*Server) Run

func (s *Server) Run() error

Run starts the API server on the configured address.

func (*Server) RunWithListener

func (s *Server) RunWithListener(listener net.Listener) error

RunWithListener starts the API server using the provided listener.

func (*Server) Shutdown

func (s *Server) Shutdown() error

Shutdown gracefully shuts down the API server.

type SessionListItem added in v0.4.0

type SessionListItem struct {
	Hash      string    `json:"hash"`
	HeadRole  string    `json:"head_role,omitempty"`
	UpdatedAt time.Time `json:"updated_at,omitzero"`
	Project   string    `json:"project,omitempty"`
	AgentName string    `json:"agent_name,omitempty"`
	Model     string    `json:"model,omitempty"`
	Provider  string    `json:"provider,omitempty"`
	Preview   string    `json:"preview,omitempty"`
}

SessionListItem is the per-item shape returned by GET /v1/sessions.

It deliberately omits fields that would require an ancestry walk per item (e.g. started_at, depth, per-session aggregates). Callers that need those should fetch /v1/sessions/:hash for the specific session.

type SessionListResponse added in v0.4.0

type SessionListResponse struct {
	Items      []SessionListItem `json:"items"`
	NextCursor string            `json:"next_cursor,omitempty"`
}

SessionListResponse is the response envelope for GET /v1/sessions.

type SessionResponse added in v0.4.0

type SessionResponse struct {
	// Hash is the head of the returned chain (== the requested hash).
	Hash string `json:"hash"`

	// Depth is the total number of turns in the full ancestry of Hash.
	// When the client passes ?depth=N, the Turns array may contain fewer
	// than Depth items.
	Depth int `json:"depth"`

	// Turns contains the chain in chronological order (root-first).
	// When ?depth=N is supplied, only the last N turns (head + N-1 ancestors)
	// are returned, still in chronological order.
	Turns []Turn `json:"turns"`

	// Truncated is true when the ancestry walk stopped at a parent_hash
	// that could not be resolved in the current store. MissingParent
	// names that hash. This is an expected edge case on stores that
	// trim older data, merge foreign content, or offload history to
	// another source — not an error.
	Truncated     bool   `json:"truncated,omitempty"`
	MissingParent string `json:"missing_parent,omitempty"`
}

SessionResponse is the response for GET /v1/sessions/:hash.

type SessionSummaryListResponse added in v0.4.0

type SessionSummaryListResponse struct {
	Items      []sessions.SessionSummary `json:"items"`
	NextCursor string                    `json:"next_cursor,omitempty"`
}

SessionSummaryListResponse is the response envelope for GET /v1/sessions/summary. Items carry the rich per-session aggregates computed by pkg/sessions.BuildSummary.

type StatsResponse added in v0.4.0

type StatsResponse struct {
	SessionCount    int     `json:"session_count"`
	TurnCount       int     `json:"turn_count"`
	RootCount       int     `json:"root_count"`
	CompletedCount  int     `json:"completed_count"`
	TotalCost       float64 `json:"total_cost"`
	InputTokens     int64   `json:"input_tokens"`
	OutputTokens    int64   `json:"output_tokens"`
	TotalDurationNs int64   `json:"total_duration_ns"`
	ToolCalls       int     `json:"tool_calls"`
}

StatsResponse is the response for GET /v1/stats.

All fields are computed by a single storage-driver aggregate over the matching node set — no per-session chain walk. This means:

  • InputTokens / OutputTokens / ToolCalls are SUMs over every node matching the filter, NOT per-chain folds. Each piece of work (each token billed, each tool_use invoked) is counted exactly once regardless of how many leaves share its ancestor. This deliberately diverges from /v1/sessions/summary's per-chain numbers, which multi-count shared ancestors when leaves descend from a common branch.
  • TotalCost is folded in the handler from the per-model token rollup returned by the driver, using the configured pricing table.
  • TotalDurationNs is the wall-clock span MAX(created_at) − MIN(created_at) across matching nodes, in nanoseconds. It is NOT a sum of per-call durations. The underlying nodes.total_duration_ns column is now populated by the proxy with per-call wall-clock duration (PCC-514); switching this endpoint to SUM(total_duration_ns) is a separate decision since it changes the visible semantic.
  • CompletedCount uses leaf-status-only classification: an assistant leaf with a terminal stop_reason ("stop", "end_turn", "end-turn", "eos"). This is an approximation of pkg/sessions.DetermineStatus, which also considers tool errors and git activity from the full chain. Sessions where the agent shipped work (e.g. `git commit`) but the leaf is not itself terminal will undercount here. PCC-515 tracks the durable fix (denormalize derived_status on Put + backfill).

type Turn added in v0.4.0

type Turn struct {
	Hash       string             `json:"hash"`
	ParentHash *string            `json:"parent_hash,omitempty"`
	Role       string             `json:"role"`
	Content    []llm.ContentBlock `json:"content"`
	Model      string             `json:"model,omitempty"`
	Provider   string             `json:"provider,omitempty"`
	AgentName  string             `json:"agent_name,omitempty"`
	StopReason string             `json:"stop_reason,omitempty"`
	Usage      *llm.Usage         `json:"usage,omitempty"`
	CreatedAt  time.Time          `json:"created_at,omitzero"`
}

Turn is a single message in a session's chain.

Directories

Path Synopsis
Package mcp provides an MCP (Model Context Protocol) server for the Tapes system.
Package mcp provides an MCP (Model Context Protocol) server for the Tapes system.
Package search provides shared search types and logic for semantic search over stored LLM sessions.
Package search provides shared search types and logic for semantic search over stored LLM sessions.

Jump to

Keyboard shortcuts

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