dashboard

package
v0.2.3 Latest Latest
Warning

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

Go to latest
Published: Jul 13, 2026 License: MIT Imports: 30 Imported by: 0

Documentation

Overview

Package dashboard provides the embedded web dashboard for AgentPaaS. The dashboard is a Preact/TypeScript SPA compiled to static assets and embedded via go:embed. It is served by the daemon on a configurable port with strict Content-Security-Policy (no inline scripts, no CDN dependencies). API access requires a Bearer token; mutating routes require a CSRF token.

Index

Constants

View Source
const PriceTableVersion = "p1-v1.0"

PriceTableVersion is the version of the built-in P1 price table.

Variables

This section is empty.

Functions

This section is empty.

Types

type AgentResource

type AgentResource struct {
	ID           string            `json:"id"`
	Name         string            `json:"name"`
	Status       string            `json:"status"`
	ImageDigest  string            `json:"image_digest,omitempty"`
	ContainerID  string            `json:"container_id,omitempty"`
	Network      string            `json:"network,omitempty"`
	Health       string            `json:"health"`
	RestartCount int               `json:"restart_count"`
	CreatedAt    time.Time         `json:"created_at"`
	Labels       map[string]string `json:"labels,omitempty"`
	MemoryBytes  int64             `json:"memory_bytes,omitempty"`
	PidsLimit    int               `json:"pids_limit,omitempty"`
}

AgentResource represents a managed agent in the dashboard inventory.

type AuditRecordView

type AuditRecordView struct {
	Seq            int64             `json:"seq"`
	Timestamp      string            `json:"timestamp"`
	EventType      string            `json:"event_type"`
	DeploymentMode string            `json:"deployment_mode"`
	Actor          string            `json:"actor"`
	Payload        map[string]string `json:"payload"`
}

AuditRecordView is a sanitized audit record for API display.

type AuditSearchView

type AuditSearchView struct {
	TotalCount int               `json:"total_count"`
	Records    []AuditRecordView `json:"records"`
	SeqRange   [2]int64          `json:"seq_range"`
	Indexed    bool              `json:"indexed"`
}

AuditSearchView is the sanitized API response for audit record search.

type AuditTimelineRow

type AuditTimelineRow struct {
	EventType string `json:"event_type"`
	Seq       int64  `json:"seq"`
	Actor     string `json:"actor"`
}

AuditTimelineRow represents an audit marker in the timeline.

type AuditVerifyView

type AuditVerifyView struct {
	Verified               bool     `json:"verified"`
	AuditRecordCount       int64    `json:"audit_record_count"`
	AuditHeadSeq           int64    `json:"audit_head_seq"`
	AuditHeadHash          string   `json:"audit_head_hash"`
	CheckpointCount        int      `json:"checkpoint_count"`
	LatestAnchorSeq        int64    `json:"latest_anchor_seq"`
	LatestAnchorHash       string   `json:"latest_anchor_hash"`
	TrustAnchorFingerprint string   `json:"trust_anchor_fingerprint"`
	VerificationCommand    string   `json:"verification_command"`
	IssuesCount            int      `json:"issues_count"`
	IssueSummaries         []string `json:"issue_summaries,omitempty"`
}

AuditVerifyView is the sanitized API response for audit verification.

type BudgetTimelineRow

type BudgetTimelineRow struct {
	Type     string  `json:"type"` // token_limit, wall_clock, iteration_limit
	Current  float64 `json:"current"`
	Limit    float64 `json:"limit"`
	Exceeded bool    `json:"exceeded"`
}

BudgetTimelineRow represents a budget marker in the timeline.

type CostView

type CostView struct {
	Provider          string  `json:"provider"`
	Model             string  `json:"model"`
	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"`
	PriceTableVersion string  `json:"price_table_version"`
	Estimated         bool    `json:"estimated"`
	ComputedAt        string  `json:"computed_at"`
}

CostView is the sanitized API response for cost data.

func ComputeCost

func ComputeCost(provider, model string, inputTokens, outputTokens int64) CostView

ComputeCost calculates cost from token counts and provider/model.

type DiffSection

type DiffSection struct {
	Section string `json:"section"`
	Status  string `json:"status"`
	Summary string `json:"summary"`
}

DiffSection represents a single changed section between two policies.

type DockerArtifact

type DockerArtifact struct {
	ContainerID string
	ImageDigest string
	Labels      map[string]string
	Network     string
	Health      string
	Exists      bool
}

DockerArtifact is Docker metadata associated with a run.

type DockerArtifactProvider

type DockerArtifactProvider interface {
	ListDockerArtifacts(ctx context.Context, runID string) ([]DockerArtifact, error)
}

DockerArtifactProvider provides Docker artifact metadata for the dashboard.

type DockerArtifactView

type DockerArtifactView struct {
	ContainerID string            `json:"container_id"`
	ImageDigest string            `json:"image_digest"`
	Labels      map[string]string `json:"labels,omitempty"`
	Network     string            `json:"network"`
	Health      string            `json:"health"`
	State       string            `json:"state"`
}

DockerArtifactView is a sanitized Docker artifact API response.

type EgressTimelineRow

type EgressTimelineRow struct {
	SpanID      string        `json:"span_id"`
	Destination string        `json:"destination"`
	Method      string        `json:"method"`
	StatusCode  int           `json:"status_code"`
	Allowed     bool          `json:"allowed"`
	DenyReason  string        `json:"deny_reason,omitempty"`
	Duration    time.Duration `json:"duration"`
}

EgressTimelineRow represents an egress request in the timeline.

type GatewayResource

type GatewayResource struct {
	ID           string    `json:"id"`
	AgentID      string    `json:"agent_id"`
	Status       string    `json:"status"`
	ImageDigest  string    `json:"image_digest,omitempty"`
	ContainerID  string    `json:"container_id,omitempty"`
	Network      string    `json:"network,omitempty"`
	EgressNet    string    `json:"egress_network,omitempty"`
	Health       string    `json:"health"`
	RestartCount int       `json:"restart_count"`
	CreatedAt    time.Time `json:"created_at"`
}

GatewayResource represents a managed gateway sidecar.

type LLMTimelineRow

type LLMTimelineRow struct {
	SpanID            string        `json:"span_id"`
	Model             string        `json:"model"`
	Provider          string        `json:"provider"`
	InputTokens       int           `json:"input_tokens"`
	OutputTokens      int           `json:"output_tokens"`
	InputCost         float64       `json:"input_cost,omitempty"`
	OutputCost        float64       `json:"output_cost,omitempty"`
	TotalCost         float64       `json:"total_cost,omitempty"`
	Cost              float64       `json:"cost"`
	PriceTableVersion string        `json:"price_table_version,omitempty"`
	Estimated         bool          `json:"estimated"`
	Latency           time.Duration `json:"latency"`
	Status            string        `json:"status"`
}

LLMTimelineRow represents an LLM call in the timeline.

type LogViewEntry

type LogViewEntry struct {
	Timestamp  string            `json:"timestamp"`
	Severity   string            `json:"severity"`
	Body       string            `json:"body"`
	Attributes map[string]string `json:"attributes,omitempty"`
	Resource   map[string]string `json:"resource,omitempty"`
	Truncated  bool              `json:"truncated,omitempty"`
}

LogViewEntry is a single log entry in the API response.

type LogViewerHandler

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

LogViewerHandler serves log data from the OTel store for the dashboard.

func NewLogViewerHandler

func NewLogViewerHandler(store *otel.Store) *LogViewerHandler

NewLogViewerHandler creates a log viewer handler.

func (*LogViewerHandler) ServeDockerArtifacts

func (h *LogViewerHandler) ServeDockerArtifacts(w http.ResponseWriter, r *http.Request)

ServeDockerArtifacts handles GET /api/runs/:runID/artifacts.

func (*LogViewerHandler) ServeLogs

func (h *LogViewerHandler) ServeLogs(w http.ResponseWriter, r *http.Request)

ServeLogs handles GET /api/runs/:runID/logs.

func (*LogViewerHandler) ServeSpans

func (h *LogViewerHandler) ServeSpans(w http.ResponseWriter, r *http.Request)

ServeSpans handles GET /api/runs/:runID/spans.

type MCPServerResource

type MCPServerResource struct {
	ID           string    `json:"id"`
	AgentID      string    `json:"agent_id"`
	Status       string    `json:"status"`
	ServerType   string    `json:"type"`
	ContainerID  string    `json:"container_id,omitempty"`
	AllowedTools []string  `json:"allowed_tools"`
	Health       string    `json:"health"`
	RestartCount int       `json:"restart_count"`
	CreatedAt    time.Time `json:"created_at"`
}

MCPServerResource represents a managed MCP server.

type MCPTimelineRow

type MCPTimelineRow struct {
	SpanID   string        `json:"span_id"`
	Server   string        `json:"server"`
	Tool     string        `json:"tool"`
	Duration time.Duration `json:"duration"`
	Status   string        `json:"status"` // success, denied, error
}

MCPTimelineRow represents an MCP tool call in the timeline.

type PolicyDiffView

type PolicyDiffView struct {
	DigestA      string            `json:"digest_a"`
	DigestB      string            `json:"digest_b"`
	Identical    bool              `json:"identical"`
	CanonicalA   map[string]string `json:"canonical_a"`
	CanonicalB   map[string]string `json:"canonical_b"`
	DiffSections []DiffSection     `json:"diff_sections,omitempty"`
	WarningsA    []string          `json:"warnings_a,omitempty"`
	WarningsB    []string          `json:"warnings_b,omitempty"`
}

PolicyDiffView is the sanitized API response for a policy diff.

type PriceEntry

type PriceEntry struct {
	Provider       string  `json:"provider"`
	Model          string  `json:"model"`
	InputPerToken  float64 `json:"input_per_token"`
	OutputPerToken float64 `json:"output_per_token"`
	Estimated      bool    `json:"estimated"`
}

PriceEntry maps a provider/model pair to per-token pricing in USD.

type ResourceManager

type ResourceManager interface {
	ListAgents(ctx context.Context) ([]AgentResource, error)
	ListGateways(ctx context.Context) ([]GatewayResource, error)
	ListMCPServers(ctx context.Context) ([]MCPServerResource, error)
}

ResourceManager provides inventory data for the dashboard. Implemented by the daemon (not the dashboard package itself).

type RunCostView

type RunCostView struct {
	RunID             string     `json:"run_id"`
	TotalCost         float64    `json:"total_cost"`
	TotalInputTokens  int64      `json:"total_input_tokens"`
	TotalOutputTokens int64      `json:"total_output_tokens"`
	ByModel           []CostView `json:"by_model"`
	PriceTableVersion string     `json:"price_table_version"`
	Estimated         bool       `json:"estimated"`
}

RunCostView aggregates cost across all spans in a run.

type Server

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

Server serves the dashboard SPA and JSON API.

func NewServer

func NewServer(addr, apiKey string, store *otel.Store, mgr ResourceManager) *Server

NewServer creates a new dashboard server. apiKey is required for API access; if empty, API returns 401.

func NewServerWithAudit

func NewServerWithAudit(addr, apiKey string, store *otel.Store, mgr ResourceManager, indexer *audit.SQLiteIndexer) *Server

NewServerWithAudit creates a dashboard server with an audit SQLite indexer.

func NewServerWithTimeline

func NewServerWithTimeline(addr, apiKey string, store *otel.Store, mgr ResourceManager, bus *trigger.EventBus) *Server

NewServerWithTimeline creates a dashboard server with live run timeline support.

func (*Server) ListenAndServe

func (s *Server) ListenAndServe() error

ListenAndServe starts the HTTP server.

func (*Server) ServeAuditExport

func (s *Server) ServeAuditExport(w http.ResponseWriter, r *http.Request)

ServeAuditExport handles POST /api/audit/export.

func (*Server) ServeAuditSearch

func (s *Server) ServeAuditSearch(w http.ResponseWriter, r *http.Request)

ServeAuditSearch handles GET /api/audit/search.

func (*Server) ServeAuditVerify

func (s *Server) ServeAuditVerify(w http.ResponseWriter, r *http.Request)

ServeAuditVerify handles GET /api/audit/verify?audit=<path>&checkpoints=<path>.

func (*Server) ServePolicyDiff

func (s *Server) ServePolicyDiff(w http.ResponseWriter, r *http.Request)

ServePolicyDiff handles GET /api/policy/diff?a=<path>&b=<path>.

func (*Server) ServeRunCost

func (s *Server) ServeRunCost(w http.ResponseWriter, r *http.Request)

ServeRunCost handles GET /api/runs/{runID}/cost.

func (*Server) SetAuditIndexer

func (s *Server) SetAuditIndexer(indexer *audit.SQLiteIndexer)

SetAuditIndexer sets the audit SQLite indexer used by audit search routes.

func (*Server) SetAuditSigningKey

func (s *Server) SetAuditSigningKey(key *ecdsa.PrivateKey, pubKeyDER []byte)

SetAuditSigningKey sets the key material used for signed audit exports.

func (*Server) SetAuditTrustAnchor

func (s *Server) SetAuditTrustAnchor(pubKeyDER []byte)

SetAuditTrustAnchor sets the public key DER used for trust-anchor display.

func (*Server) SetEventBus

func (s *Server) SetEventBus(bus *trigger.EventBus)

SetEventBus sets the event bus for live run timeline events. If the timeline handler was not created at construction time (because both bus and store were nil), this creates it now.

func (*Server) SetPolicyDir

func (s *Server) SetPolicyDir(policyDir string)

SetPolicyDir sets the base directory used to resolve relative policy paths.

func (*Server) SetResourceManager

func (s *Server) SetResourceManager(mgr ResourceManager)

SetResourceManager sets the resource inventory provider for dashboard APIs.

func (*Server) Shutdown

func (s *Server) Shutdown(ctx context.Context) error

Shutdown gracefully shuts down the server.

type SpanBatcher

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

SpanBatcher collects spans and sends them in batches to avoid flooding the SSE connection. When the number of pending spans exceeds maxBatchSize, a batch event is sent containing multiple spans.

func NewSpanBatcher

func NewSpanBatcher(maxBatchSize int, flushTimeout time.Duration) *SpanBatcher

NewSpanBatcher creates a batcher for virtualizing large span sets.

func (*SpanBatcher) Add

func (b *SpanBatcher) Add(event TimelineEvent) bool

Add adds a span to the batcher. Returns true if a flush is needed.

func (*SpanBatcher) Flush

func (b *SpanBatcher) Flush() []TimelineEvent

Flush returns all pending events and resets the batcher.

func (*SpanBatcher) Pending

func (b *SpanBatcher) Pending() int

Pending returns the number of pending events.

type SpanViewEntry

type SpanViewEntry struct {
	TraceID      string            `json:"trace_id"`
	SpanID       string            `json:"span_id"`
	ParentSpanID string            `json:"parent_span_id,omitempty"`
	Name         string            `json:"name"`
	Kind         string            `json:"kind"`
	StartTime    string            `json:"start_time"`
	EndTime      string            `json:"end_time"`
	Attributes   map[string]string `json:"attributes,omitempty"`
	Status       string            `json:"status"`
	StatusCode   string            `json:"status_code"`
	Resource     map[string]string `json:"resource,omitempty"`
	Scope        map[string]string `json:"scope,omitempty"`
}

SpanViewEntry is a single sanitized span in the API response.

type TimelineEvent

type TimelineEvent struct {
	Type      string          `json:"type"` // llm_call, mcp_call, egress_allowed, egress_denied, budget, audit, run_event
	RunID     string          `json:"run_id"`
	Timestamp time.Time       `json:"timestamp"`
	Data      json.RawMessage `json:"data"` // type-specific payload
}

TimelineEvent is a single event in the timeline SSE stream.

type TimelineHandler

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

TimelineHandler serves live run timeline events via SSE. It proxies the Block 9 EventBus SSE stream and enriches it with OTel span data.

func NewTimelineHandler

func NewTimelineHandler(bus *trigger.EventBus, store *otel.Store) *TimelineHandler

NewTimelineHandler creates a timeline handler.

func (*TimelineHandler) ServeSSE

func (h *TimelineHandler) ServeSSE(w http.ResponseWriter, r *http.Request)

ServeSSE handles GET /api/runs/:runID/timeline.

Jump to

Keyboard shortcuts

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