httpapi

package
v0.24.5 Latest Latest
Warning

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

Go to latest
Published: Sep 3, 2026 License: MIT Imports: 15 Imported by: 0

Documentation

Overview

Package httpapi serves the 2dph brain over HTTP.

Async by design: every request runs on its own goroutine, and CPU-heavy searches are serialized through a bounded worker pool so N requests can't spawn N backends at once.

Used by bin/brain/serve.go. Tests inject a fake API (no exec, no ladybug).

Index

Constants

View Source
const (
	PathHealth  = "/health"
	PathSearch  = "/search"
	PathGet     = "/get"
	PathStats   = "/stats"
	PathAudit   = "/audit"
	PathIngest  = "/ingest"
	PathLeafs   = "/leafs"
	PathEdges   = "/edges"
	PathAddEdge = "/addedge"
	PathPath    = "/path"
	PathOpenAPI = "/openapi.json"
	PathMCP     = "/mcp"
)

Variables

View Source
var Ops = []Op{
	{Path: PathHealth, Method: "get", ID: "health", Summary: "liveness"},
	{
		Path: PathSearch, Method: "get", ID: "search", Summary: "deduction search (facts → info → web)",
		MCP: true,
		Params: []Param{
			{Name: "q", In: "query", Type: "string", Description: "search query", Required: true},
			{Name: "n", In: "query", Type: "integer", Description: "hit limit 1..100 (default 10)"},
			{Name: "root", In: "query", Type: "string", Description: "facts or info (default: all roots)"},
			{Name: "noweb", In: "query", Type: "boolean", Description: "skip the web second source (D17)"},
			{Name: "as_of", In: "query", Type: "string", Description: "YYYY-MM-DD; keep facts active on that day (D24)"},
			{Name: "sort", In: "query", Type: "string", Description: "order by date (date, date:asc, date:desc)"},
		},
	},
	{
		Path: PathGet, Method: "get", ID: "get", Summary: "read one leaf by id",
		MCP: true,
		Params: []Param{
			{Name: "id", In: "query", Type: "string", Description: "leaf id", Required: true},
			{Name: "body", In: "query", Type: "boolean", Description: "include full text"},
		},
	},
	{Path: PathStats, Method: "get", ID: "stats", Summary: "index health"},
	{Path: PathAudit, Method: "get", ID: "audit", Summary: "facts confidence histogram", MCP: true},
	{
		Path: PathIngest, Method: "post", ID: "ingest", Summary: "add a leaf without rebuild",
		Params: []Param{
			{Name: "text", In: "query", Type: "string", Description: "leaf text (omit for CLI hint)"},
			{Name: "root", In: "query", Type: "string", Description: "facts or info (default info)"},
			{Name: "source", In: "query", Type: "string", Description: "evidence pointer; facts need two sources"},
			{Name: "valid_from", In: "query", Type: "string", Description: "fact interval start YYYY-MM-DD (D24)"},
			{Name: "valid_to", In: "query", Type: "string", Description: "fact interval end YYYY-MM-DD inclusive (D24)"},
		},
	},
	{
		Path: PathLeafs, Method: "get", ID: "leafs", Summary: "query leafs by root/type/source/text",
		MCP: true,
		Params: []Param{
			{Name: "root", In: "query", Type: "string", Description: "facts or info"},
			{Name: "type", In: "query", Type: "string", Description: "leaf type (fact/reference/...)  exact match"},
			{Name: "source", In: "query", Type: "string", Description: "evidence pointer exact match, e.g. pc-agent"},
			{Name: "q", In: "query", Type: "string", Description: "full-text search over leaf text"},
			{Name: "n", In: "query", Type: "integer", Description: "limit 1..100 (default 10)"},
		},
	},
	{
		Path: PathEdges, Method: "get", ID: "edges", Summary: "adjacency: synapses of one leaf",
		MCP: true,
		Params: []Param{
			{Name: "id", In: "query", Type: "string", Description: "leaf id (sha256[:16])", Required: true},
		},
	},
	{
		Path: PathAddEdge, Method: "post", ID: "addedge", Summary: "add a synapse (leaf A → leaf B)",
		MCP: true,
		Params: []Param{
			{Name: "from", In: "body", Type: "string", Description: "source leaf id", Required: true},
			{Name: "to", In: "body", Type: "string", Description: "target leaf id", Required: true},
			{Name: "type", In: "body", Type: "string", Description: "edge label, default synapse"},
		},
	},
	{
		Path: PathPath, Method: "get", ID: "path", Summary: "shortest path between two leafs",
		MCP: true,
		Params: []Param{
			{Name: "from", In: "query", Type: "string", Description: "source leaf id", Required: true},
			{Name: "to", In: "query", Type: "string", Description: "target leaf id", Required: true},
			{Name: "max", In: "query", Type: "integer", Description: "max path length (default 6, max 10)"},
		},
	},
	{Path: PathOpenAPI, Method: "get", ID: "openapi", Summary: "OpenAPI 3 document for this server"},
}

Functions

func OpenAPI

func OpenAPI() map[string]any

func Run

func Run(api API, c *config.Config)

Run starts the HTTP server with an injected API (in-process brain, or ExecSearcher) using the typed config for host/port/workers/pprof/search-cmd.

func RunSynapse

func RunSynapse(api API, c *config.Config)

RunSynapse serves the Synapse Matrix surface (leafs/edges/path/addedge) for pc-agent. Auth policy (#82): when a token is configured every route except /health requires `Authorization: Bearer <token>`; without a token the server refuses to bind anything but a loopback address, so the graph stays machine-local unless explicitly guarded.

func SkillMarkdown

func SkillMarkdown() string

SkillMarkdown is the Cursor skill fragment generated from Ops/MCPTools.

Types

type API

type API interface {
	Search(ctx context.Context, query string, limit int, asOf, root, sort string, noWeb bool) ([]byte, error)
	Get(ctx context.Context, id string, body bool) ([]byte, error)
	Stats(ctx context.Context) ([]byte, error)
	Audit(ctx context.Context) ([]byte, error)
	Ingest(ctx context.Context, body []byte) ([]byte, error)
	// Synapse Matrix surface (issue #82): leafs + edges as a service.
	Leafs(ctx context.Context, root, typ, source, text string, limit int) ([]byte, error)
	Edges(ctx context.Context, id string) ([]byte, error)
	AddEdge(ctx context.Context, body []byte) ([]byte, error)
	Path(ctx context.Context, from, to string, max int) ([]byte, error)
}

API is the in-process brain surface. Production serve.go wires internal/brain.

type ExecSearcher

type ExecSearcher struct {
	CmdPath string
	Root    string
	Timeout time.Duration
}

ExecSearcher shells out to var/bin/brain-search. Fallback when the serve binary is built without ladybug cgo (CI / tags=brain_serve only).

func (ExecSearcher) AddEdge

func (ExecSearcher) AddEdge(context.Context, []byte) ([]byte, error)

func (ExecSearcher) Audit

func (ExecSearcher) Audit(context.Context) ([]byte, error)

func (ExecSearcher) Edges

func (ExecSearcher) Get

func (ExecSearcher) Ingest

func (b ExecSearcher) Ingest(ctx context.Context, body []byte) ([]byte, error)

func (ExecSearcher) Leafs

func (ExecSearcher) Path

func (ExecSearcher) Search

func (b ExecSearcher) Search(ctx context.Context, query string, limit int, asOf, root, sort string, noWeb bool) ([]byte, error)

func (ExecSearcher) Stats

func (ExecSearcher) Stats(context.Context) ([]byte, error)

type MCPTool

type MCPTool struct {
	Name        string         `json:"name"`
	Description string         `json:"description"`
	InputSchema map[string]any `json:"inputSchema"`
}

func MCPTools

func MCPTools() []MCPTool

type Op

type Op struct {
	Path, Method, ID, Summary string
	Params                    []Param
	MCP                       bool
}

type Param

type Param struct {
	Name, In, Type, Description string
	Required                    bool
}

type Server

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

func NewServer

func NewServer(api API, workers int) *Server

func (*Server) ServeHTTP

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

func (*Server) SetToken

func (s *Server) SetToken(token string) *Server

SetToken enables Bearer-token auth on every route except /health. A zero token leaves the server open (safe when bound to 127.0.0.1 only).

Jump to

Keyboard shortcuts

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