HTTP 网关详解

wesgine HTTP Gateway 是引擎的 HTTP 服务层,提供单 Cell 和多 Cell 两种模式,包含完整的中间件链、Token 认证和错误处理。

概览

HTTP 请求
    │
    ▼
Gateway(单 Cell 或多 Cell 模式)
    │
    ▼ 中间件链
    path parse → cell exist → auth → state → quota → dispatch
    │
    ▼
Cell Handle(Runtime / Memory / Sessions / ...)
    │
    ▼
HTTP 响应 / SSE 流

单 Cell 模式(ServeSingleCell)

适用于桌面应用、单租户场景:

cell, _ := hyp.Cells().GetOrCreate(ctx, wesgine.CellSpec{ID: "main"})

// 单 Cell 无 cellID 路径
// 所有业务端点直接挂在根路径
router := gateway.ServeSingleCell(cell, gateway.Options{
    Addr:       ":9091",
    AdminToken: adminToken,
})
router.Start(ctx)

路由结构:

GET  /run                     SSE 流式 Run
POST /chat                    同步 Chat
GET  /sessions                会话列表
GET  /memory                  记忆列表
POST /memory/search           记忆搜索
...                           (无 /cells/{id} 前缀)

GET  /health                  健康检查
GET  /metrics                 Prometheus 指标

使用场景:


多 Cell 模式(ServeMultiCell)

适用于多租户、企业部署:

hyp, _ := wesgine.NewHypervisor(ctx, wesgine.HypervisorConfig{
    DataDir: dataDir,
})
hyp.Start(ctx)

// 多 Cell 模式,所有业务端点在 /cells/{id}/* 路径
router := gateway.ServeMultiCell(hyp, gateway.Options{
    Addr:       ":9091",
    AdminToken: adminToken,
})
router.Start(ctx)

路由结构:

# Cell 业务路由
POST /cells/{cellID}/run              SSE 流式 Run
POST /cells/{cellID}/chat             同步 Chat
GET  /cells/{cellID}/sessions         会话列表
GET  /cells/{cellID}/memory           记忆列表
...

# Admin 路由
GET  /admin/cells                     列出所有 Cell
POST /admin/cells                     创建 Cell
GET  /admin/cells/{id}                获取 Cell 详情
...

# 基础设施
GET  /health                          健康检查
GET  /metrics                         Prometheus 指标

使用场景:


中间件链

HTTP 请求经过六层中间件处理:

1. Path Parse(路径解析)

从 URL 提取 cellID 和业务路径:

/cells/dept-legal/sessions → cellID="dept-legal", path="/sessions"

2. Cell Exist(Cell 存在性)

验证 cellID 对应的 Cell 是否存在:

3. Auth(认证)

验证请求携带的 Token:

Authorization: Bearer <token>

Token 类型:

类型签发权限用途
Admin Tokenhyp.Tokens().IssueAdminToken(ttl)所有 Cell 全权限管理工具
Cell Tokencell.Tokens().Issue(roles)单 Cell 指定角色应用集成

权限作用域:

cell:admin  → 完整管理权限
cell:chat   → 对话和会话变更
cell:read   → 只读访问

4. State(状态检查)

检查 Cell 当前温度状态:

温度行为
Hot / Warm直接通过
Cool自动 WarmUp(同步,~100-500ms)
Cold返回 503 + Retry-After: 5 + 异步唤醒

INV-SERVE-REACHABLE-01:wesgine serve 到达"可被探活"的时间是有界常数,不随租户数或数据库体积增长。

5. Quota(配额检查)

检查 Cell 配额:

6. Dispatch(分发)

将请求分发到对应的 Cell Handle 方法。


Token 签发与验证

Admin Token

// 签发 Admin Token
token := hyp.Tokens().IssueAdminToken(24 * time.Hour)

// 使用
curl -H "Authorization: Bearer ${token}" \
    http://localhost:9091/admin/cells

bootstrap admin token:wesgine serve --admin-token-bootstrap 在启动时签发并输出到 stderr(不走 logger,因为 journal 常被转发出机器)。

Cell Token

// 签发 Cell Token
token, _ := cell.Tokens().Issue(wesgine.TokenRoles{
    Scopes: []string{"cell:chat", "cell:read"},
    Actor:  "alice",
})

// 吊销
cell.Tokens().Revoke(ctx, tokenID)

Token 认证中间件行为

请求到达
    │
    ├── 无 Authorization header → /health, /metrics 放行;其他 401
    │
    ├── Bearer <token>
    │   ├── Admin Token → 全权限,actor 可由 ?actor= 指定
    │   └── Cell Token → 检查作用域
    │       ├── 路径需要 cell:admin(如 /memory POST)→ 无权 403
    │       ├── 路径需要 cell:chat(如 /sessions 变更)→ 检查
    │       └── 路径需要 cell:read(默认)→ 通过
    │
    └── 无效 Token → 401

错误处理

错误响应格式

{
    "error": {
        "code": "cell_not_found",
        "message": "Cell 'dept-xxx' not found",
        "details": {}
    }
}

常见错误码

HTTPcode说明
400invalid_request请求参数错误
400model_required未指定 model(INV-MODEL-01)
400actor_required未指定 actor
401unauthorizedToken 无效或缺失
403forbidden权限不足
404cell_not_foundCell 不存在
404session_not_found会话不存在
409degraded_secret_overwrite降级态密钥保护
429quota_exceeded配额超限
503cell_coldCell 冷态,Retry-After: 5

SSE 错误

SSE 流中的错误通过事件传递:

event: error
data: {"kind":"cognitive_error","message":"...","recoverable":true}

event: done
data: {"reason":"cognitive_error"}

Run 生命周期与 HTTP 解耦(INV-RUN-DETACH)

SSE 断开不取消 Run。 取消 Run 的唯一途径:

SSE 断开后可重连续播:

GET /cells/{id}/runs/{runID}/events?from_seq=42

启动流程

wesgine serve

wesgine serve \
    --data-dir /var/lib/wesgine \
    --addr :9091 \
    --admin-token-bootstrap

启动顺序:

1. router.Start(绑端口)
2. sdnotify.Ready()(通知 systemd)
3. ActivatePersisted(后台 goroutine 热 Cell)

INV-SERVE-REACHABLE-01:绑端口在前,热 Cell 在后。确保进程可探活的时间不随数据增长。

Gateway Options

gateway.Options{
    Addr:           ":9091",
    AdminToken:     "bootstrap-token",
    CORSOrigins:    []string{"http://localhost:3000"},
    ReadTimeout:    30 * time.Second,
    WriteTimeout:   0,  // SSE 需要长连接
    IdleTimeout:    120 * time.Second,
    MaxHeaderBytes: 1 << 20,
}

最佳实践

  1. 生产环境使用多 Cell 模式:即使只有一个 Cell,多 Cell 模式便于后续扩展
  2. 使用 Cell Token 而非 Admin Token:最小权限原则
  3. 配置 CORS:明确允许的前端来源
  4. 监控 503 频率:Cold Cell 的 503 频率反映温度管理是否合理
  5. SSE 重连:客户端实现指数退避重连,使用 from_seq 续播
  6. Nginx 超时对齐:反向代理的超时必须 > 引擎的超时

相关端点

完整端点列表见 wesgine AGENTS.md §7.4 HTTP Gateway,包含 Cell 路由(25 组)和 Admin 路由(4 组)的完整定义。