docs(gateway): gateway 剩余文件注释改中文(逐行 1:1,代码零字节改动)
CI / Backend (build / vet / test / cross-compile) (push) Has been cancelled
CI / Frontend (tsc + vite build) (push) Has been cancelled

主人 2026-10-03 拍板「注释一律中文」;gateway 至此整包注释中文化完成(本会话共 3 批:
已推库 16 个文件 + 本批剩余文件)。
校验:机械校验(非注释改动行)= 空;剥注释后代码文本逐行比对全等(不一致文件数 0);
全树 go test ./... 58 包 ok / 0 FAIL;交叉编译绿。
This commit is contained in:
AskaEth committed 2026-10-03 22:28:25 +08:00
1 parent 91e8d7a029
commit 074ffc4ebf
73 files changed
+2529 -2529

No files matched your search

+121 -121
View File
@@ -24,225 +24,225 @@ import (
"git.yeij.top/AskaEth/Cyrene_v2/internal/services/backthink"
)
// This file declares the dependency contracts the gateway consumes. Every one is
// a narrow interface satisfied by a concrete backend the composition root injects
// (see Deps in deps.go), so the gateway never reaches for a concrete
// implementation and tests can substitute a stub.
// 本文件声明网关所消费的依赖契约。每一个都是窄接口,
// 由组合根注入的具体后端满足(见 deps.go 中的
// Deps),因此网关绝不直接取用具体实现,
// 测试也能替换成桩。
// Authenticator abstracts the credential + RBAC service. *auth.JWTService is the
// production implementation; it is an interface so tests substitute a mock.
// Authenticator 抽象凭据 + RBAC 服务。*auth.JWTService 是
// 生产实现;它是接口,因此测试可替换为 mock。
type Authenticator interface {
// Sign issues a token for sub with the given role and lifetime.
// Sign 为 sub 签发一个带给定角色与生命周期的 token。
Sign(sub string, role auth.Role, ttl time.Duration) (string, error)
// Verify validates a token and returns its claims.
// Verify 校验一个 token 并返回其 claims。
Verify(token string) (*auth.Claims, error)
// Authorize returns an HTTP middleware enforcing at least one required role.
// Authorize 返回一个 HTTP 中间件,强制至少一个所需角色。
Authorize(required ...auth.Role) func(http.Handler) http.Handler
}
// CapabilityStore abstracts the global capability registry used to enumerate
// plugins and channels in the admin API. *capability.Registry is the production
// implementation.
// CapabilityStore 抽象管理 API 中用于枚举插件与渠道的全局
// 能力注册表。*capability.Registry 是生产
// 实现。
type CapabilityStore interface {
// List returns every capability whose Kind matches, or all when kind is
// empty.
// List 返回 Kind 匹配的每一个能力,kind 为空时
// 返回全部。
List(kind capreg.Kind) []capreg.Capability
// SetPolicy replaces the reachability markers for the named capability.
// SetPolicy 替换指定能力的可达性标记。
SetPolicy(name string, p capreg.ToolPolicy) error
}
// Chatter runs a single agent turn. *loop.Loop is the production implementation.
// Chatter 运行单次 agent 回合。*loop.Loop 是生产实现。
type Chatter interface {
// Run drives one turn for sessionID and returns the final answer.
// Run 为 sessionID 驱动一个回合并返回最终答案。
Run(ctx context.Context, sessionID string, messages []model.Message) (*loop.Result, error)
}
// SessionStore lists known channel sessions. *session.SessionManager is the
// production implementation.
// SessionStore 列出已知的渠道会话。*session.SessionManager 是
// 生产实现。
type SessionStore interface {
List(ctx context.Context) ([]session.Session, error)
}
// PersonaStore lists registered characters (each bound one-to-one to a persona).
// *persona/registry.Registry is the production implementation. The gateway maps
// each Character to its wire summary; the interface deliberately returns the
// domain type so the wire shape stays out of the store contract.
// PersonaStore 列出已注册角色(每个与一个人格一一绑定)。
// *persona/registry.Registry 是生产实现。网关把
// 每个 Character 映射为其线上摘要;该接口刻意返回
// 领域类型,使线上结构不进入存储契约。
type PersonaStore interface {
List() []personareg.Character
// Persona returns the persona with the given id (to read its visual assets).
// The production registry implements it; the wire summary reads Avatar /
// ChatBackground from it so each role's visuals stay role-scoped.
// Persona 返回给定 id 的人格(用于读取其视觉资产)。
// 生产注册表实现了它;线上摘要从它读取 Avatar /
// ChatBackground,使每个角色的视觉保持角色作用域。
Persona(id string) (*loader.Persona, bool)
}
// PersonaMoodStore is the *optional* capability of a persona store that also owns
// the per-persona emotion state (design/01 §2: emotion follows the persona). The
// production *personareg.Registry implements it; the gateway reads a role's mood
// through an assertion on this narrow interface so a store that only lists
// personas (a test double, a future read-only catalog) keeps satisfying
// PersonaStore without owning an emotion machine. When a store does not implement
// it, a role's mood simply reads as "" rather than being invented.
// PersonaMoodStore 是人格存储的*可选*能力,该存储同时持有
// 每人格的情绪状态(design/01 §2:情绪跟随人格)。
// 生产实现 *personareg.Registry 实现了它;网关通过对这个窄
// 接口做断言来读取某角色的 mood,因此只列出人格的存储
// (测试替身、未来的只读目录)无需持有情绪机
// 就能继续满足 PersonaStore。当存储未实现它时,
// 某角色的 mood 只读作 "",而不是被凭空造出。
type PersonaMoodStore interface {
Emotions() *emotion.Manager
}
// MemoryStore lists memory entries. *runtime/memory.Store is the production
// implementation. The gateway maps each MemoryItem to its wire summary.
// MemoryStore 列出记忆条目。*runtime/memory.Store 是生产
// 实现。网关把每个 MemoryItem 映射为其线上摘要。
type MemoryStore interface {
List(ctx context.Context) ([]memory.MemoryItem, error)
}
// HistoryStore is the persistent chat-history store (design/16). *runtime/history.Store
// is the production implementation. When nil the session/message endpoints degrade: list
// sessions falls back to the channel-session view, and the create/messages/delete
// endpoints answer with a clear 501.
// HistoryStore 是持久化聊天历史存储(design/16)。*runtime/history.Store
// 是生产实现。为 nil 时会话/消息端点退化:列出
// 会话回退到渠道会话视图,而创建/取消息/删除
// 端点返回明确的 501。
type HistoryStore interface {
Append(ctx context.Context, msg history.Message) error
// AppendFull persists msg like Append but returns the complete stored message
// (with the assigned id/timestamp) so the orchestrator can broadcast it for
// cross-end realtime sync (design/16 §4.2).
// AppendFull 像 Append 一样持久化 msg,但返回完整的已存消息
// (含分配的 id/时间戳),使编排器能广播它以进行
// 跨端实时同步(design/16 §4.2)。
AppendFull(ctx context.Context, msg history.Message) (history.Message, error)
List(ctx context.Context, sessionID string, before int64, limit int, platform string) ([]history.Message, error)
// ListAfter returns up to limit messages strictly newer than after in
// oldest-first order, for forward incremental catch-up after a reconnect
// (the "before" cursor can only walk backwards). platform filters as in List.
// ListAfter 按最旧优先返回至多 limit 条严格新于 after 的消息,
// 用于重连后的前向增量追赶("before" 游标只能
// 向后走)。platform 的过滤同 List。
ListAfter(ctx context.Context, sessionID string, after int64, limit int, platform string) ([]history.Message, error)
Recent(ctx context.Context, sessionID string, n int) ([]history.Message, error)
ListPlatformLog(ctx context.Context, platform string, before int64, limit int) ([]history.Message, error)
ListAdapterLog(ctx context.Context, adapterID string, before int64, limit int) ([]history.Message, error)
ListAllLog(ctx context.Context, before int64, limit int) ([]history.Message, error)
DeleteSession(ctx context.Context, sessionID string) error
// Search returns session-scoped content matches (newest first) for the
// ?q= message-search path. An empty query yields an empty slice.
// Search 为 ?q= 消息搜索路径返回会话作用域的内容匹配
// (最新优先)。空查询得到空切片。
Search(ctx context.Context, sessionID, query string, before int64, limit int) ([]history.Message, error)
// UpdateMessage edits a single message's content and returns the updated
// message. An unknown id returns history.ErrMessageNotFound.
// UpdateMessage 编辑单条消息的内容并返回更新后的
// 消息。未知 id 返回 history.ErrMessageNotFound。
UpdateMessage(ctx context.Context, id, content string) (history.Message, error)
// DeleteMessage removes a single message. An unknown id returns
// history.ErrMessageNotFound.
// DeleteMessage 移除单条消息。未知 id 返回
// history.ErrMessageNotFound。
DeleteMessage(ctx context.Context, id string) error
// RenameSession sets a session's display title (main or sub). An unknown id
// returns history.ErrSessionNotFound.
// RenameSession 设置会话的显示标题(main 或 sub)。未知 id
// 返回 history.ErrSessionNotFound。
RenameSession(ctx context.Context, sessionID, title string) error
// SetPinned pins/unpins a session (main or sub). An unknown id returns
// history.ErrSessionNotFound.
// SetPinned 置顶/取消置顶一个会话(main 或 sub)。未知 id 返回
// history.ErrSessionNotFound。
SetPinned(ctx context.Context, sessionID string, pinned bool) error
NewSubSession(ctx context.Context, ownerID string) (string, error)
// MarkSessionRead advances a session's read cursor (D4) to before and returns
// the resulting cursor as a Unix millisecond timestamp; a zero before means
// "now". The cursor only moves forward. An unknown id returns
// history.ErrSessionNotFound.
// MarkSessionRead 把会话的读游标(D4)推进到 before 并返回
// 结果游标作为 Unix 毫秒时间戳;before 为零意味着
// 「现在」。游标只向前移动。未知 id 返回
// history.ErrSessionNotFound。
MarkSessionRead(ctx context.Context, sessionID string, before time.Time) (int64, error)
ListSessions(ctx context.Context) ([]history.SessionMeta, error)
}
// IoTStore lists IoT devices. *iot.Manager is the production implementation.
// IoTStore 列出 IoT 设备。*iot.Manager 是生产实现。
type IoTStore interface {
List(ctx context.Context) ([]iot.Device, error)
}
// SubagentAuditor audits a sub-agent's conversation context for the subagent_ask
// WS route. *orchestration.Scheduler is the production implementation.
// SubagentAuditor 为 subagent_ask WS 路由审计子代理的对话
// 上下文。*orchestration.Scheduler 是生产实现。
type SubagentAuditor interface {
AuditContext(ctx context.Context, id string, mode orchestration.AuditMode, n int, query string) (*orchestration.AuditResult, error)
}
// TaskOutputStore queries a task's output for the task_output_query WS route.
// *task.Manager is the production implementation.
// TaskOutputStore 为 task_output_query WS 路由查询任务输出。
// *task.Manager 是生产实现。
type TaskOutputStore interface {
TaskOutput(ctx context.Context, id string) (task.OutputEvent, error)
}
// AutomationStore enumerates the automations and reminders for the admin list.
// *automations.Service is the production implementation. The gateway maps each
// record to its wire shape.
// AutomationStore 为管理列表枚举自动化与提醒。
// *automations.Service 是生产实现。网关把每条
// 记录映射为其线上结构。
type AutomationStore interface {
List() []automations.AutomationRecord
}
// UserStore enumerates the accounts and API keys visible to the admin panel.
// The production implementation reads the configured admin account plus the
// auth.APIKey table. The gateway maps each summary to its wire shape.
// UserStore 枚举管理面板可见的账号与 API key。
// 生产实现读取已配置的管理账号加上
// auth.APIKey 表。网关把每个摘要映射为其线上结构。
type UserStore interface {
List() []auth.UserSummary
}
// RefreshGrantStore manages opaque refresh tokens (auth.RefreshStore is the
// production implementation). It is the credential behind the refreshToken
// returned by login and the POST /auth/refresh, /auth/logout endpoints. Only
// hashes are persisted; the plaintext token crosses this interface exactly once
// per issue/rotate. Optional: when nil login omits refreshToken and the refresh
// and logout endpoints report a clear not-configured error.
// RefreshGrantStore 管理非透明 refresh token(auth.RefreshStore 是
// 生产实现)。它是登录与 POST /auth/refresh、/auth/logout 端点
// 所返回 refreshToken 背后的凭据。只持久化哈希;
// 明文 token 每次签发/轮换恰好穿过该接口一次。
// 可选:为 nil 时登录省略 refreshToken,
// refresh 与 logout 端点返回明确的 not-configured 错误。
type RefreshGrantStore interface {
// Issue mints a refresh token for userID/role and returns its plaintext
// (visible once) plus its expiry.
// Issue 为 userID/role 铸造一个 refresh token,返回其明文
// (仅可见一次)及其过期时间。
Issue(ctx context.Context, userID string, role auth.Role, ttl time.Duration) (string, time.Time, error)
// Rotate validates plaintext and, when opts.Rotate is set, revokes it and
// returns a replacement. It returns auth.ErrInvalidGrant for an unknown,
// revoked, or expired token.
// Rotate 校验 plaintext,并在 opts.Rotate 设置时吊销它并
// 返回替代品。对未知、已吊销或已过期的 token 返回
// auth.ErrInvalidGrant 错误。
Rotate(ctx context.Context, plaintext string, opts auth.RotateOptions) (auth.RefreshToken, string, error)
// Revoke marks the token matching plaintext revoked, returning whether a
// live token was found. It is idempotent.
// Revoke 把匹配 plaintext 的 token 标记为已吊销,并返回是否
// 找到了存活的 token。它是幂等的。
Revoke(ctx context.Context, plaintext string) (bool, error)
// RevokeAll deletes every refresh token (global invalidation on secret
// rotation) and returns how many were removed.
// RevokeAll 删除每一个 refresh token(秘密轮换时的全局
// 失效)并返回移除了多少个。
RevokeAll(ctx context.Context) (int64, error)
// RevokeByUser deletes every refresh token for userID (logout by access
// token, where the individual grant is unknown) and returns how many were
// removed.
// RevokeByUser 删除 userID 的每一个 refresh token(按访问
// 令牌登出,此时不知道具体是哪一份授权)并返回
// 移除了多少个。
RevokeByUser(ctx context.Context, userID string) (int64, error)
}
// BackthinkStore enumerates the persisted background-think records for the
// M9/M10 monitor panel. *backthink.Backthink is the production implementation.
// BackthinkStore 为 M9/M10 监控面板枚举持久化的后台思考
// 记录。*backthink.Backthink 是生产实现。
type BackthinkStore interface {
List(ctx context.Context, limit int) ([]backthink.Record, error)
}
// ChannelConfigStore is the runtime-editable channel-adapter configuration
// (channels.json, design/04 §3.1). It is implemented by the composition root's
// channel store: Load returns the effective per-platform accounts (file → env
// fallback), Path reports the channels.json path, and Reload hot-replaces a
// platform's running adapters after a panel save (Bridge.Reload). Load returns
// account configs with real tokens so the owner write path can persist them; the
// admin read path masks them before returning to the client.
// ChannelConfigStore 是运行时可编辑的渠道适配器配置
// (channels.json,design/04 §3.1)。它由组合根的渠道存储
// 实现:Load 返回按平台生效的账号(文件 → 环境变量
// 回退),Path 报告 channels.json 路径,Reload 在面板保存后
// 热替换某平台运行中的适配器(Bridge.Reload)。Load 返回
// 带真实 token 的账号配置,使 owner 写路径能持久化它们;
// 管理读路径在返回客户端前对它们脱敏。
type ChannelConfigStore interface {
Path() string
// Load returns the effective per-platform accounts (file → env fallback),
// including the secret tokens needed to persist them.
// Load 返回按平台生效的账号(文件 → 环境变量回退),
// 含持久化它们所需的秘密 token。
Load() map[string][]config.ChannelAccount
// Reload rebuilds and hot-replaces the running adapters for platform.
// Reload 重建并热替换该平台运行中的适配器。
Reload(platform string) error
}
// OwnerRegistrar registers a channel account id into the owner whitelist
// (configs/users/owner.yaml). It is the structural identity red line: a scan-login
// confirmation stamps the scanner's bound ilink_user_id into the whitelist so the
// channel bridge recognizes it as the owner via actor metadata, never a prompt.
// The composition root implements it (cmd/cyrene's ownerRegistrar) to persist the
// whitelist and hot-update the live owner profile. Registration is best-effort:
// a failure is logged by the caller but does not fail the already-applied
// channels.json persist.
// OwnerRegistrar 把一个渠道账号 id 登记进主人白名单
// (configs/users/owner.yaml)。它是结构化的身份红线:扫码登录
// 确认会把扫码者绑定的 ilink_user_id 盖进白名单,使
// 渠道 bridge 经 actor 元数据认出它是主人,绝不是提示词。
// 组合根实现了它(cmd/cyrene 的 ownerRegistrar)以持久化
// 白名单并热更新活的 owner profile。登记是尽力而为:
// 失败由调用方记日志,但不会让已经施加的
// channels.json 持久化失败。
type OwnerRegistrar interface {
RegisterChannelOwner(ctx context.Context, platform, accountID string) error
}
// RagStore backs the admin knowledge-base RAG module (design/10 §3.12 module 8).
// *runtime/knowledge.Store is the production implementation: it lists/searches
// the project index, imports a document (chunk + index) and deletes one
// (project entry + cascaded chapters). An implementation that cannot write
// reports a clear error (knowledge.ErrWriteUnsupported) rather than a fabricated
// success; the handlers map a missing document to 404.
// RagStore 支撑管理侧知识库 RAG 模块(design/10 §3.12 module 8)。
// *runtime/knowledge.Store 是生产实现:它列出/搜索
// 项目索引、导入文档(切分 + 索引)、删除文档
// (项目条目 + 级联章节)。不能写入的实现
// 会报告明确的错误(knowledge.ErrWriteUnsupported),而不是编造
// 成功;handler 把文档缺失映射为 404。
type RagStore interface {
// ListDocuments enumerates the knowledge-base documents (project-index
// entries).
// ListDocuments 枚举知识库文档(项目索引
// 条目)。
ListDocuments(ctx context.Context) ([]knowledge.Doc, error)
// Search answers a knowledge-base query (line-level hierarchy + optional
// semantic/vector ranking).
// Search 应答一次知识库查询(行级层级 + 可选
// 语义/向量排序)。
Search(ctx context.Context, query string) ([]knowledge.Hit, error)
// IndexDocument uploads/chunks/embeds a document into the project index.
// IndexDocument 把一份文档上传/切分/嵌入进项目索引。
IndexDocument(ctx context.Context, doc knowledge.Doc) error
// DeleteDocument removes a document (and its chapters) by id, returning
// knowledge.ErrDocumentNotFound when no such document exists.
// DeleteDocument 按 id 移除一份文档(及其章节),在
// 不存在该文档时返回 knowledge.ErrDocumentNotFound。
DeleteDocument(ctx context.Context, id string) error
}