- turnId 由编排器生成、loop Run 复用(硬前提:否则 turn_begin 与流帧各铸一个,客户端两级分桶立即失配) - StateSink 增带 turnId 的变体(未接线时退化为现签名,不丢状态帧) - 上行 chat.parallel(WS chat 帧 + REST 三入口同形;省略 = 逐字不变) - 单会话额度默认 2 / 硬上限 3 / <2 关闭;额度满或未声明 ⇒ 落回既有排队语义 - I1′:checkpoint 归属、历史配对、忙态计数三处从会话级单例升为路级 - session_idle 收紧为「所有在途路收尾且 pending 空」(仅并行时生效;单路逐字不变) - 预留接口(形状定死、无实现无接线):tool/legfile.go 的 FileClaimer / ErrFileBusy / WithLegID - 顺手修一个真 bug:并行路 ctx 派生自提交请求作用域,REST 同步入口一写响应就把它连坐杀死(改 context.WithoutCancel 派生) - 23 个新用例(含 -race -count=3);变异 6 条(turnId 复用 / idle 时点 / 并行升级 / checkpoint 键 / 编排器交 id / pending_ack reason) - 契约变更点 10 条待监工升 v0.65(本人未改 Docs/**)
152 lines
7.6 KiB
Go
152 lines
7.6 KiB
Go
package gateway
|
||
|
||
import (
|
||
"database/sql"
|
||
"io/fs"
|
||
"log/slog"
|
||
"net/http"
|
||
|
||
"git.yeij.top/AskaEth/Cyrene_v2/internal/bus"
|
||
pluginmgr "git.yeij.top/AskaEth/Cyrene_v2/internal/capability/plugin"
|
||
"git.yeij.top/AskaEth/Cyrene_v2/internal/runtime/model"
|
||
)
|
||
|
||
// VectorState 是组合根报告的向量增强(pgvector)运行状态,供管理侧
|
||
// 「存储状态」端点回答「PG 到底有没有生效」(design/03 §3)。
|
||
//
|
||
// 它是**复用**而非探测:网关不读环境变量、不新开 PG 连接、不
|
||
// 自行 ping —— 真相只有组合根知道(DB_PG_URL 是否配置 + 活的向量
|
||
// 索引是哪个后端),因此由它注入,避免面板看到与运行时不一致的
|
||
// 第二个判断。
|
||
type VectorState struct {
|
||
// Configured 报告 DB_PG_URL 是否已配置(非空即算),即
|
||
// 增强开关在不在。
|
||
Configured bool
|
||
// Live 报告当前活的向量索引确实是 PostgreSQL+pgvector 后端。
|
||
// 配置了但连接/schema 准备失败时为 false —— 此时语义检索已降级,
|
||
// 面板必须显示「未就绪」而不是假装增强生效。
|
||
Live bool
|
||
}
|
||
|
||
// Deps 承载网关被注入的依赖。除 Auth 外每个字段都容忍
|
||
// nil,Auth 是必需的(认证支撑登录与每一个 RBAC
|
||
// 决策)。Registry/Loop 由具体的 *capability.Registry 与
|
||
// *loop.Loop 满足;Sessions/Personas/Memories 由具体的会话
|
||
// 管理器、人格注册表与记忆存储满足,只有当依赖留为
|
||
// nil 时 handler 才返回 []。
|
||
type Deps struct {
|
||
// Log 是基础 logger。为 nil 时使用丢弃型 logger。
|
||
Log *slog.Logger
|
||
// Auth 是 JWT/RBAC 服务。必需。
|
||
Auth Authenticator
|
||
// Bus 是 WS hub 所订阅的进程内事件总线。可选。
|
||
Bus bus.Bus
|
||
// Registry 枚举能力/插件/渠道。可选。
|
||
Registry CapabilityStore
|
||
// Loop 运行聊天回合。可选(未设置时 chat 返回错误)。
|
||
Loop Chatter
|
||
// Session 列出渠道会话。可选。
|
||
Session SessionStore
|
||
// Personas 列出人格。可选。
|
||
Personas PersonaStore
|
||
// Memories 列出记忆条目。可选。
|
||
Memories MemoryStore
|
||
// History 是持久化聊天历史存储(design/16)。可选;为 nil 时
|
||
// 会话/消息端点退化(列出回退到渠道会话,其余 501)。
|
||
History HistoryStore
|
||
// IoT 列出 IoT 设备。可选。
|
||
IoT IoTStore
|
||
// Scheduler 为 subagent_ask WS 路由审计子代理上下文。
|
||
// 可选(未设置时 subagent_ask 返回明确的错误)。
|
||
Scheduler SubagentAuditor
|
||
// Tasks 为 task_output_query WS 路由查询任务输出。
|
||
// 可选(未设置时 task_output_query 返回明确的错误)。
|
||
Tasks TaskOutputStore
|
||
// Automations 列出自动化与提醒。可选。
|
||
Automations AutomationStore
|
||
// Users 列出账号与 API key。可选(回退到已配置的
|
||
// 单个管理账号)。
|
||
Users UserStore
|
||
// Refresh 是非透明 refresh token 存储。可选:为 nil 时登录省略
|
||
// refreshToken,/auth/refresh + /auth/logout 返回 not-configured。
|
||
Refresh RefreshGrantStore
|
||
// Backthink 列出后台思考记录。可选。
|
||
Backthink BackthinkStore
|
||
// RAG 支撑管理侧知识库 RAG 模块。可选;未设置时列出/搜索
|
||
// 返回空,写端点报告明确的 501。
|
||
RAG RagStore
|
||
// LLM 是可热切换的 provider 栈(models.json,design/04 §3.1)。
|
||
// 可选:为 nil 时管理 /llm 端点回退到环境配置,使
|
||
// 既有的网关测试继续可用。
|
||
LLM *model.RuntimeLLM
|
||
// EnvPath 是进程启动时解析的 `.env` 文件路径(组合根传给 config.Load 的同一个)。
|
||
// 「重置为 env 默认」动作(切片 R1)按**既有 config 解析入口**重读 env 默认层,
|
||
// 网关自己绝不 fopen `.env`。空表示只看进程环境变量(与 config.Load("") 的
|
||
// 约定一致,生产走 systemd/env_file 时就是这种形态)。可选。
|
||
EnvPath string
|
||
// Channels 是运行时可编辑的渠道适配器配置(channels.json)。
|
||
// 可选:为 nil 时管理 /channels/config 端点返回明确的
|
||
// not-configured 错误,与 LLM 栈未设置时的行为一致。
|
||
Channels ChannelConfigStore
|
||
// Plugins 是运行时可安装的外部工具 provider 管理器
|
||
// (plugins.json + 活的 MCP server)。可选:为 nil 时安装返回
|
||
// 明确的 not-implemented 错误,卸载回退为普通的能力
|
||
// 移除,使既有的网关测试继续可用。
|
||
Plugins *pluginmgr.Manager
|
||
// OwnerRegistrar 把扫码登录绑定的主人 id 盖进主人
|
||
// 白名单(configs/users/owner.yaml)并热更新活的 profile。
|
||
// 可选:为 nil 时 weixin 确认流程仍会持久化 channels.json,但
|
||
// 跳过白名单登记(按设计即为尽力而为)。
|
||
OwnerRegistrar OwnerRegistrar
|
||
// AuditStore 持久化管理审计链(observability → audit)。为 nil 时
|
||
// 网关退化为内存存储,使端点仍能返回
|
||
// 数据;组合根注入基于 a.db 的 NewSQLiteAuditStore 以获得真实
|
||
// 持久化。可选。
|
||
AuditStore AuditStore
|
||
// DatabasePath 是组合根实际打开的 SQLite 数据库文件解析后
|
||
// 路径(由 resolveSQLitePath 推导的值,当数据目录默认值
|
||
// 生效时可能与 cfg.DB.SQLitePath 不同)。它支撑
|
||
// 管理备份/恢复端点。可选;为空时那些端点诚实作答,
|
||
// 返回明确的 not-configured 错误。
|
||
DatabasePath string
|
||
// DataDir 是解析后的数据目录(resolveDataDir 返回的值,当操作系统
|
||
// 默认值生效时可能与 cfg.DataDir 不同)。它支撑
|
||
// 图片上传存储(<DataDir>/uploads)及其静态路由。可选;
|
||
// 为空时上传 handler 回退到 cfg.DataDir。
|
||
DataDir string
|
||
// Database 是组合根已打开的活 SQLite 连接池。管理侧的
|
||
// 「存储状态」只读端点用它读页级统计与 documents 表 ——
|
||
// 复用既有池,端点自身不另开连接或连接池。可选;为 nil 时
|
||
// 该端点诚实作答(500 storage_unavailable),绝不假装
|
||
// 拿到了数据。
|
||
Database *sql.DB
|
||
// Vector 是组合根报告的向量增强(pgvector)运行时状态,
|
||
// 见 VectorState。网关只读它,绝不自行探测。可选;零值
|
||
// 表示「未配置」(kind:"none"),与未启用增强的部署一致。
|
||
Vector VectorState
|
||
// Streaming 标记注入的 Loop 具备流式能力(其 OnStream
|
||
// 已接线为发布 ws.stream_chunk)。设置后 hub 会跳过它自己的
|
||
// 单次最终 stream_chunk 发送,因为增量已通过 OnStream 流出。
|
||
Streaming bool
|
||
// Frontend 是为所有非 API、非 WS 路由提供的 SPA 文件系统。
|
||
// 为 nil 时网关不提供任何静态资产(只有 API 与 WS)。
|
||
// 使用内嵌的 dist(internal/webui)或外部 dist 目录。
|
||
Frontend fs.FS
|
||
// Webhooks 是外部挂载的入站 HTTP handler(端点路径 →
|
||
// handler),通常来自接收 webhook 回调的渠道适配器
|
||
// (例如 webhook)。每个都挂到 ServeMux 上且不经网关认证;
|
||
// handler 自身强制其签名/授权(webhook HMAC)。
|
||
// 可选。
|
||
Webhooks map[string]http.Handler
|
||
// Usage 是 LLM 用量汇总的只读出口(切片 U1)。可选;为 nil 时
|
||
// GET /api/v1/admin/llm/usage 诚实作答 500 usage_unavailable,
|
||
// 绝不回一份全 0 的假汇总。
|
||
Usage LlmUsageStore
|
||
// MaxParallelTurns 是单会话在途并行路数的上限(design/15 §2.5.7)。
|
||
// 零值/负数 ⇒ 编排器用默认 2;1 ⇒ 关闭真并行(恒 1 路,完全回落到
|
||
// queue + 回合内 steer 的现状);超过硬上限 3 ⇒ 钳到 3。
|
||
// 它刻意是编排器的构造期旋钮而不是一个全局:真并行只由显式声明
|
||
// (上行 `chat.parallel`)触发,因此调大它不会改变任何未声明并行的客户端行为。
|
||
MaxParallelTurns int
|
||
}
|