feat(config): 运行时配置体系②——渠道配置落 channels.json + 面板落盘 + 热更新
- runtimeconfig/channels.go: channels.json 承载 map[platform][]ChannelAccount(token/baseURL/黑白名单/群聊限流), LoadChannels 优先文件/回退env, SaveChannels(0600+tmp原子写), Upsert/Delete/Masked脱敏
- channelbridge/reload.go: adapterManager 热替换——工厂重建新adapter先连接, 再原子断旧adapter(独立readCtx/进行中不中断); Bridge.Reload(platform) 逐账号增删
- 面板 PUT/DELETE /admin/channels/{platform}/config(owner+审计) 落盘channels.json+Reload热更新; GET /admin/channels 附账号掩码不泄裸token
- 前端 Channels.tsx 配置表单(id/token/baseURL/黑白名单/限流+config JSON)+保存热更新提示+掩码展示/删除
- .gitignore 加 channels.json; .env 退兜底(.env.example注明); token不打印/Config()脱敏
- channelbridge.go 拆 logic→reload.go(742→731); 全仓 go build/vet/test绿+前端build绿
- 未做真token端到端(需渠道凭据,不读.env)——如实标注待凭据
This commit is contained in:
1 parent
2d7151f979
commit
aedae2190b
18 files changed
+1743
-126
No files matched your search
@@ -157,6 +157,22 @@ 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.
|
||||
type ChannelConfigStore interface {
|
||||
Path() string
|
||||
// Load returns the effective per-platform accounts (file → env fallback),
|
||||
// including the secret tokens needed to persist them.
|
||||
Load() map[string][]config.ChannelAccount
|
||||
// Reload rebuilds and hot-replaces the running adapters for platform.
|
||||
Reload(platform string) error
|
||||
}
|
||||
|
||||
// RagStore backs the admin knowledge-base RAG module (design/10 §3.12 module 8).
|
||||
// *runtime/knowledge.Store is the production implementation. Every method is
|
||||
// read-only for this milestone: IndexDocument/DeleteDocument return a clear
|
||||
@@ -222,6 +238,10 @@ type Deps struct {
|
||||
// Optional: when nil the admin /llm endpoints fall back to the env config so
|
||||
// pre-existing gateway tests keep working.
|
||||
LLM *model.RuntimeLLM
|
||||
// Channels is the runtime-editable channel-adapter config (channels.json).
|
||||
// Optional: when nil the admin /channels/config endpoints return a clear
|
||||
// not-configured error, matching how the LLM stack behaves when unset.
|
||||
Channels ChannelConfigStore
|
||||
// AuditStore persists the admin audit trail (observability → audit). When nil
|
||||
// the gateway degrades to an in-memory store so the endpoint still returns
|
||||
// data; the composition root injects NewSQLiteAuditStore over a.db for real
|
||||
@@ -270,6 +290,7 @@ type Server struct {
|
||||
// admin /llm endpoints fall back to the env config. It is optional so tests
|
||||
// that do not wire it keep working.
|
||||
llm *model.RuntimeLLM
|
||||
channels ChannelConfigStore
|
||||
webhooks map[string]http.Handler
|
||||
log *slog.Logger
|
||||
hub *hub
|
||||
@@ -306,6 +327,7 @@ func New(cfg *config.Config, deps Deps) (*Server, error) {
|
||||
streaming: deps.Streaming,
|
||||
frontend: deps.Frontend,
|
||||
llm: deps.LLM,
|
||||
channels: deps.Channels,
|
||||
webhooks: deps.Webhooks,
|
||||
log: sourcedLog(deps.Log),
|
||||
}
|
||||
@@ -385,6 +407,8 @@ func (s *Server) Handler() http.Handler {
|
||||
mux.Handle("POST /api/v1/admin/channels/open", ownerAuth(http.HandlerFunc(s.adminChannelOpen)))
|
||||
mux.Handle("POST /api/v1/admin/channels/close", ownerAuth(http.HandlerFunc(s.adminChannelClose)))
|
||||
mux.Handle("POST /api/v1/admin/channels/test", ownerAuth(http.HandlerFunc(s.adminChannelTest)))
|
||||
mux.Handle("PUT /api/v1/admin/channels/{platform}/config", ownerAuth(http.HandlerFunc(s.adminSaveChannelConfig)))
|
||||
mux.Handle("DELETE /api/v1/admin/channels/{platform}/config", ownerAuth(http.HandlerFunc(s.adminDeleteChannelAccount)))
|
||||
mux.Handle("POST /api/v1/admin/plugins/install", ownerAuth(http.HandlerFunc(s.adminPluginInstall)))
|
||||
mux.Handle("POST /api/v1/admin/plugins/uninstall", ownerAuth(http.HandlerFunc(s.adminPluginUninstall)))
|
||||
mux.Handle("POST /api/v1/admin/memories", ownerAuth(http.HandlerFunc(s.adminAddMemory)))
|
||||
|
||||
Reference in new issue
Block a user