server

package
v0.3.0-alpha.3 Latest Latest
Warning

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

Go to latest
Published: May 10, 2026 License: Apache-2.0 Imports: 34 Imported by: 0

Documentation

Overview

Package server provides the Gramaton HTTP server (daemon). It wraps a core.Engine with HTTP handlers, concurrency control via the engine's RWMutex, and lifecycle management (idle timeout, graceful shutdown).

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func IsProcessAlive

func IsProcessAlive(pid int) bool

IsProcessAlive reports whether a process with the given PID exists. On Unix, os.FindProcess always succeeds for any PID, so we probe liveness by sending signal 0: the kernel validates the PID exists and we have permission to signal it, but delivers nothing.

func RemoveServerInfo

func RemoveServerInfo(cfgDir string)

RemoveServerInfo removes the server info file from a config directory.

Types

type Config

type Config struct {
	Port        int           `yaml:"port"`
	Bind        string        `yaml:"bind"`
	IdleTimeout time.Duration `yaml:"idle_timeout"`
	ConfigDir   string        // runtime, not from YAML
	StoreName   string        // runtime, empty = default unnamed store
}

Config holds server configuration.

func DefaultConfig

func DefaultConfig() Config

DefaultConfig returns server config with sensible defaults.

type CurationStatus

type CurationStatus struct {
	PendingCount      int        `json:"pending_count"`
	Overdue           bool       `json:"overdue"`
	ConceptCandidates int        `json:"concept_candidates,omitempty"`
	StaleCount        int        `json:"stale_count,omitempty"`
	OrphanCount       int        `json:"orphan_count,omitempty"`
	LastCurated       *time.Time `json:"last_curated,omitempty"`
	Autonomous        bool       `json:"autonomous,omitempty"`
	LLMCallsToday     int        `json:"llm_calls_today,omitempty"`
	LLMDailyCap       int        `json:"llm_daily_cap,omitempty"`
	LLMCapPct         int        `json:"llm_cap_pct,omitempty"`
	Paused            bool       `json:"paused,omitempty"`
	PauseReason       string     `json:"pause_reason,omitempty"`
}

CurationStatus reports pending curation state.

type ErrorDetail

type ErrorDetail struct {
	Code      string `json:"code"`
	Message   string `json:"message"`
	Retryable bool   `json:"retryable"`
}

ErrorDetail contains error information.

func (*ErrorDetail) Error

func (e *ErrorDetail) Error() string

Error makes ErrorDetail satisfy the error interface so CLI clients can return it verbatim (rather than collapsing to a plain fmt.Errorf) and downstream code can recover Code/Retryable via errors.As. Transports that care only about a human string still get one via "%s: %s".

type ErrorResponse

type ErrorResponse struct {
	Error    ErrorDetail    `json:"error"`
	Curation CurationStatus `json:"curation,omitzero"`
}

ErrorResponse is the standard error wrapper. Includes the curation envelope so error responses carry the same backlog signal as successful ones.

type ResponseEnvelope

type ResponseEnvelope struct {
	Data     any            `json:"data"`
	Curation CurationStatus `json:"curation"`
	Meta     ResponseMeta   `json:"meta"`
}

ResponseEnvelope is the standard response wrapper.

type ResponseMeta

type ResponseMeta struct {
	DurationMs int64  `json:"duration_ms,omitempty"`
	Version    string `json:"version"`
}

ResponseMeta contains response metadata.

type Server

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

Server is the Gramaton HTTP daemon.

func New

func New(engine *core.Engine, cfg Config, logger *slog.Logger) (*Server, error)

New creates a server. An engine without a configured LLM provider is fine: autonomous curation (classification, summarization, contradiction detection, concept synthesis) silently skips when nil and the store falls back to the deterministic-only curation pipeline (lifecycle transitions, orphan linking, duplicate consolidation, concept candidate detection). See CLAUDE.md's "without LLM, curation runs in deterministic-only mode" contract. Downstream code already guards every LLM() use with a nil check; this function imposes no additional requirement.

Historical note: prior to the wizard shipping, server.New refused to construct without LLM. That constraint contradicted the documented deterministic-only contract and made the wizard's Skip-LLM option silently lead to a broken `gramaton serve` (CLI swallowed the server's startup error behind its 10s timeout). Removed.

func (*Server) Handler

func (s *Server) Handler() http.Handler

Handler returns the HTTP handler for use with httptest.NewServer or other test infrastructure.

func (*Server) Log

func (s *Server) Log() *slog.Logger

Log returns the server's structured logger.

func (*Server) MCPHandler

func (s *Server) MCPHandler() http.Handler

MCPHandler returns an HTTP handler that serves the MCP protocol via Streamable HTTP transport.

func (*Server) MCPServer

func (s *Server) MCPServer() *mcp.Server

MCPServer returns a configured MCP server for use with stdio transport.

func (*Server) RequestShutdown

func (s *Server) RequestShutdown()

RequestShutdown triggers a graceful shutdown from an API call. Caller is responsible for any response flushing -- this function only queues a shutdown reason on s.shutdownCh, which the main loop selects on. Portable across Unix and Windows (the earlier syscall.SIGTERM-to-self approach didn't work on Windows because Go only implements os.Kill for self-signaling there).

Non-blocking: if a shutdown is already pending, this request is dropped. First-reason-wins.

func (*Server) Run

func (s *Server) Run() error

Run starts the server and blocks until shutdown. It handles signals (SIGTERM, SIGINT), idle timeout, and writes the server info file for CLI discovery.

func (*Server) Shutdown

func (s *Server) Shutdown()

Shutdown gracefully stops the HTTP server, access flusher, prepared- sessions sweeper, and curation runner.

func (*Server) StartHTTP

func (s *Server) StartHTTP() error

StartHTTP starts the HTTP server and curation runner in background goroutines without blocking. Use Shutdown to stop. Designed for the MCP stdio process which needs the HTTP server running alongside the stdio transport.

type ServerInfo

type ServerInfo struct {
	PID       int       `json:"pid"`
	Port      int       `json:"port"`
	Bind      string    `json:"bind"`
	StartedAt time.Time `json:"started_at"`
	StoreDir  string    `json:"store_dir"`
	StoreName string    `json:"store_name,omitempty"`
	Version   string    `json:"version"`
}

ServerInfo is written to server.json for CLI discovery.

func ReadServerInfo

func ReadServerInfo(cfgDir string) (*ServerInfo, error)

ReadServerInfo reads the server info file from a config directory. Returns the info and nil error if the file exists and is valid.

Jump to

Keyboard shortcuts

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