api

package
v0.0.0-...-673a93f Latest Latest
Warning

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

Go to latest
Published: Mar 29, 2026 License: GPL-2.0, GPL-3.0 Imports: 40 Imported by: 0

README

web/backend/api — HTTP API

MoonHub Web 后端 HTTP API 实现。路由由 router.go 中的 Handler.RegisterRoutes 注册到 http.ServeMux

相关文档web/README.md(整体 Web 架构)、docs/implementation/lan-discovery-status.mddocs/implementation/lan-pairing-status.md。配套前端应用见独立仓库 MoonHub-PWA(与主仓库同工作区时常为 MoonHub-PWA/)。

文件结构(摘要)

文件 职责
router.go 汇总注册各子模块路由;NewHandler(configPath, deviceStore, pairingManager)
discovery.go 单设备发现:/api/ping/api/system/info
discover.go 局域网 mDNS 扫描:GET /api/discover(LAN 限定)
devices.go 已配对设备列表:GET /api/devices(LAN 限定)
auth_pair.go 授权码配对与 Token 校验
lan.go / lan_client.go 局域网来源校验与客户端 IP 工具
channels.go 频道目录等(如 GET /api/channels/catalog
channels_crud.go 频道实例 CRUD + 状态(挂载在 Handler 上)
config.go GET / PUT / PATCH /api/config
session.go 对话与会话历史
gateway.go / events.go 网关生命周期与 SSE
models.go / skills.go / tools.go 模型、技能、工具 API
dynamic_tools.go 动态工具:/api/dynamic-tools(SQLite + SchemaEngine,LAN 限定)
oauth.go / provisioning.go / startup.go / … 其余子系统

局域网访问控制

与发现、配对、设备列表、频道 CRUD、动态工具 等相关的多个端点通过 requireLANClient / lan.go 仅允许来自私网或本机的请求。允许的地址范围与实现细节见 lan.go

API 端点分类

设备发现(无需 Token)
端点 方法 说明 文件
/api/ping GET 设备在线检测 discovery.go
/api/system/info GET 设备 / 系统信息 discovery.go
局域网发现与设备列表(无需 Token,LAN 限定)
端点 方法 说明 文件
/api/discover GET 通过 mDNS 扫描局域网内 MoonHub 服务 discover.go
/api/devices GET 返回已配对客户端列表 devices.go
配对与认证(无需 Token,LAN 限定)
端点 方法 说明 文件
/api/auth/status GET 当前授权码状态 auth_pair.go
/api/auth/pair POST 使用授权码配对,返回 Token auth_pair.go
/api/auth/verify POST 校验 Token(Authorization: Bearer 或 JSON {"token"} auth_pair.go
频道(LAN 限定;部分操作依赖配置读写)
端点 方法 说明 文件
/api/channels GET 已配置频道实例列表(含状态摘要) channels_crud.go
/api/channels POST 新增频道配置 channels_crud.go
/api/channels/{id} PATCH 更新频道配置 channels_crud.go
/api/channels/{id} DELETE 删除频道配置 channels_crud.go
/api/channels/{id}/status GET 单个频道运行时状态 channels_crud.go

目录类接口(与具体实现对齐)见 channels.go(例如 GET /api/channels/catalog)。

动态工具(LAN 限定)

dynamic_tools.go 注册;数据库位于 <MOONHUB_HOME>/dynamic_tools.db。若初始化失败(如 SQLite 不可用),router.go不注册 下列路由。

端点 方法 说明
/api/dynamic-tools GET 列表;可选查询参数 source(如 source=ai
/api/dynamic-tools/generate POST 根据自然语言 prompt 生成或复用(按 content hash 去重)工具定义
/api/dynamic-tools/{id}/execute POST 执行工具;请求体含 modechat / space)与可选 params
/api/dynamic-tools/{id}/schema GET 获取指定 mode 下的 UI schema
/api/dynamic-tools/{id} DELETE 删除工具
/api/dynamic-tools/{id}/home PATCH 设置是否在 Space 首页展示(is_on_home

实现细节与状态见 pkg/dynamictools/docs/README.mddocs/implementation/dynamic-tools-status.md

配置与其它(需 Token 或按各 handler 约定)
区域 端点示例 文件
配置 GET / PUT / PATCH /api/config config.go
对话 POST /api/chatPOST /api/chat/stream session.go
模型 / 技能 / 工具 /api/models/*/api/skills/api/tools models.goskills.gotools.go
网关 /api/gateway/statusstartstop/api/gateway/events gateway.goevents.go

路由注册说明

Handler.RegisterRoutes 在内部依次调用 registerConfigRoutesregisterGatewayRoutesregisterChannelCRUDRoutes 等,并在末尾注册 discoverydiscoverdevicesauth 的 LAN 相关路由;若 dynamicTools != nil,再注册动态工具路由。配网相关路由在设置了 SetProvisioningHandler 时由 provisioning 子 handler 注册。

认证示例

Bearer Token
curl -H "Authorization: Bearer <token>" http://127.0.0.1:18800/api/config
仅局域网可访问的端点
curl http://192.168.1.100:18800/api/auth/status
curl -X POST http://192.168.1.100:18800/api/auth/pair \
  -H "Content-Type: application/json" \
  -d '{"code":"AB1234"}'

测试

cd /path/to/MoonHub
go test ./web/backend/api/... -v

相关文档

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func ClientIPFromRequest

func ClientIPFromRequest(r *http.Request) net.IP

ClientIPFromRequest 返回用于访问策略的客户端 IP。 默认仅使用 RemoteAddr;开启 MOONHUB_TRUST_PROXY 后才会读取转发头。

func IsLANScopeIP

func IsLANScopeIP(ip net.IP) bool

IsLANScopeIP 判断 IP 是否属于当前阶段允许的「局域网直连」范围:回环、私网/CGNAT/ULA、链路本地(含 IPv4 APIPA)。

Types

type AuthHandler

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

AuthHandler handles device pairing and authentication API requests.

func NewAuthHandler

func NewAuthHandler(pairingManager *devices.PairingManager, deviceStore *devices.DeviceStore) *AuthHandler

NewAuthHandler creates a new auth API handler.

func (*AuthHandler) RegisterRoutes

func (h *AuthHandler) RegisterRoutes(mux *http.ServeMux)

RegisterRoutes registers auth routes with the mux.

type AuthStatusResponse

type AuthStatusResponse struct {
	Success bool `json:"success"`
	Data    struct {
		Code   string `json:"code"`
		Paired bool   `json:"paired"`
	} `json:"data"`
}

AuthStatusResponse represents the auth status response.

type DevicesHandler

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

DevicesHandler handles paired devices API requests.

func NewDevicesHandler

func NewDevicesHandler(store *devices.DeviceStore) *DevicesHandler

NewDevicesHandler creates a new devices API handler.

func (*DevicesHandler) RegisterRoutes

func (h *DevicesHandler) RegisterRoutes(mux *http.ServeMux)

RegisterRoutes registers devices routes with the mux.

type DiscoverHandler

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

DiscoverHandler handles mDNS device discovery API requests.

func NewDiscoverHandler

func NewDiscoverHandler(client *mdns.Client) *DiscoverHandler

NewDiscoverHandler creates a new discover API handler.

func (*DiscoverHandler) RegisterRoutes

func (h *DiscoverHandler) RegisterRoutes(mux *http.ServeMux)

RegisterRoutes registers discovery routes with the mux.

type DiscoveryHandler

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

DiscoveryHandler handles device discovery API requests.

func NewDiscoveryHandler

func NewDiscoveryHandler(deviceStore *devices.DeviceStore) *DiscoveryHandler

NewDiscoveryHandler creates a new discovery API handler.

func (*DiscoveryHandler) RegisterRoutes

func (h *DiscoveryHandler) RegisterRoutes(mux *http.ServeMux)

RegisterRoutes registers discovery routes with the mux.

type DynamicToolsHandler

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

DynamicToolsHandler handles dynamic tools API requests.

func NewDynamicToolsHandler

func NewDynamicToolsHandler(configPath string) (*DynamicToolsHandler, error)

NewDynamicToolsHandler creates a DynamicToolsHandler with a SQLite-backed ToolManager and a SchemaEngine. The database is stored at <moonhub-home>/dynamic_tools.db.

func (*DynamicToolsHandler) Close

func (h *DynamicToolsHandler) Close()

Close releases the underlying database connection.

func (*DynamicToolsHandler) RegisterRoutes

func (h *DynamicToolsHandler) RegisterRoutes(mux *http.ServeMux)

RegisterRoutes registers dynamic tools routes on the given ServeMux.

type EventBroadcaster

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

EventBroadcaster manages SSE client subscriptions and broadcasts events.

func NewEventBroadcaster

func NewEventBroadcaster() *EventBroadcaster

NewEventBroadcaster creates a new broadcaster.

func (*EventBroadcaster) Broadcast

func (b *EventBroadcaster) Broadcast(event GatewayEvent)

Broadcast sends a GatewayEvent to all connected SSE clients.

func (*EventBroadcaster) Subscribe

func (b *EventBroadcaster) Subscribe() chan string

Subscribe adds a new listener channel and returns it. The caller must call Unsubscribe when done.

func (*EventBroadcaster) Unsubscribe

func (b *EventBroadcaster) Unsubscribe(ch chan string)

Unsubscribe removes a listener channel and closes it.

type GatewayEvent

type GatewayEvent struct {
	Status             string `json:"gateway_status"` // "running", "starting", "restarting", "stopped", "error"
	PID                int    `json:"pid,omitempty"`
	BootDefaultModel   string `json:"boot_default_model,omitempty"`
	ConfigDefaultModel string `json:"config_default_model,omitempty"`
	RestartRequired    bool   `json:"gateway_restart_required,omitempty"`
}

GatewayEvent represents a state change event for the gateway process.

type Handler

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

Handler serves HTTP API requests.

func NewHandler

func NewHandler(configPath string, deviceStore *devices.DeviceStore, pairingManager *devices.PairingManager) *Handler

NewHandler creates an instance of the API handler.

func (*Handler) RegisterRoutes

func (h *Handler) RegisterRoutes(mux *http.ServeMux)

RegisterRoutes binds all API endpoint handlers to the ServeMux.

func (*Handler) SetProvisioningHandler

func (h *Handler) SetProvisioningHandler(handler *ProvisioningHandler)

SetProvisioningHandler sets the provisioning handler for device management.

func (*Handler) SetServerOptions

func (h *Handler) SetServerOptions(port int, public bool, publicExplicit bool, allowedCIDRs []string)

SetServerOptions stores current backend listen options for fallback behavior.

func (*Handler) TryAutoStartGateway

func (h *Handler) TryAutoStartGateway()

TryAutoStartGateway checks whether gateway start preconditions are met and starts it when possible. Intended to be called by the backend at startup.

type LANHandler

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

LANHandler handles LAN API requests for chat functionality.

func NewLANHandler

func NewLANHandler(
	deviceStore *devices.DeviceStore,
	agentLoop *agent.AgentLoop,
	deviceID, deviceName, version string,
) *LANHandler

NewLANHandler creates a new LAN API handler.

func NewLANHandlerWithConfig

func NewLANHandlerWithConfig(
	deviceStore *devices.DeviceStore,
	agentLoop *agent.AgentLoop,
	deviceID, deviceName string,
) *LANHandler

NewLANHandlerWithConfig creates a LAN handler with config-based version.

func (*LANHandler) GetSessionManager

func (h *LANHandler) GetSessionManager() *social.SessionManager

GetSessionManager returns the session manager for testing purposes.

func (*LANHandler) RegisterRoutes

func (h *LANHandler) RegisterRoutes(mux *http.ServeMux)

RegisterRoutes registers LAN API routes with the mux.

func (*LANHandler) SetAgentLoop

func (h *LANHandler) SetAgentLoop(loop *agent.AgentLoop)

SetAgentLoop updates the agent loop reference. This is useful when the agent is initialized after the handler is created.

type LogBuffer

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

LogBuffer is a thread-safe ring buffer that stores the most recent N log lines. It supports incremental reads via LinesSince and tracks a runID that increments whenever the buffer is reset or cleared so clients can detect log history resets.

func NewLogBuffer

func NewLogBuffer(capacity int) *LogBuffer

NewLogBuffer creates a LogBuffer with the given capacity.

func (*LogBuffer) Append

func (b *LogBuffer) Append(line string)

Append adds a line to the buffer. If the buffer is full, the oldest line is evicted.

func (*LogBuffer) Clear

func (b *LogBuffer) Clear()

Clear removes all buffered lines and increments the runID so clients treat subsequent reads as a new log stream.

func (*LogBuffer) LinesSince

func (b *LogBuffer) LinesSince(offset int) (lines []string, total int, runID int)

LinesSince returns lines appended after the given offset, the current total count, and the runID. If offset >= total, no lines are returned. If offset is too old (evicted), all buffered lines are returned.

func (*LogBuffer) Reset

func (b *LogBuffer) Reset()

Reset clears the buffer and increments the runID. Call this when starting a new gateway process.

func (*LogBuffer) RunID

func (b *LogBuffer) RunID() int

RunID returns the current run identifier.

type PairRequest

type PairRequest struct {
	Code       string `json:"code"`
	DeviceID   string `json:"deviceId,omitempty"`
	DeviceName string `json:"deviceName,omitempty"`
}

PairRequest represents a pairing request.

func (*PairRequest) UnmarshalJSON

func (p *PairRequest) UnmarshalJSON(data []byte) error

UnmarshalJSON accepts camelCase fields and snake_case aliases (device_id, device_name).

type PairResponse

type PairResponse struct {
	Success bool `json:"success"`
	Data    struct {
		Token          string                `json:"token,omitempty"`
		TokenExpiresAt time.Time             `json:"tokenExpiresAt,omitempty"`
		Device         *devices.PairedDevice `json:"device,omitempty"`
	} `json:"data,omitempty"`
	Error string `json:"error,omitempty"`
}

PairResponse represents a pairing response.

type ProvisioningHandler

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

ProvisioningHandler handles device provisioning API requests.

func NewProvisioningHandler

func NewProvisioningHandler(manager *provisioning.DeviceManager) *ProvisioningHandler

NewProvisioningHandler creates a new provisioning API handler.

func (*ProvisioningHandler) RegisterRoutes

func (h *ProvisioningHandler) RegisterRoutes(mux *http.ServeMux)

RegisterRoutes registers provisioning routes with the mux.

type VerifyResponse

type VerifyResponse struct {
	Success bool `json:"success"`
	Data    struct {
		Valid     bool       `json:"valid"`
		DeviceID  string     `json:"deviceId,omitempty"`
		ExpiresAt *time.Time `json:"expiresAt,omitempty"`
	} `json:"data"`
}

VerifyResponse represents a token verification response.

Jump to

Keyboard shortcuts

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