- new internal/sysadmin package (overview/kb/features/settings) with small
port interfaces; business packages stay unaware of sysadmin
- new routes /api/v1/admin/system/{overview,kb,features,settings} guarded
by requireSystemAdmin
- goose 00049: system_settings table (key/jsonb value, updated_by/at)
- SettingSpec whitelist registry with DB > env > default precedence
- register sysadmin in module-boundaries.yaml (archtest rules)
79 lines
5.0 KiB
Go
79 lines
5.0 KiB
Go
package sysadmin
|
||
|
||
import "os"
|
||
|
||
// Feature 功能开关视图;value 统一用字符串表示。
|
||
type Feature struct {
|
||
Key string `json:"key"`
|
||
Label string `json:"label"`
|
||
Group string `json:"group"`
|
||
Value string `json:"value"`
|
||
Source string `json:"source"`
|
||
RequiresRestart bool `json:"requiresRestart"`
|
||
Description string `json:"description"`
|
||
}
|
||
|
||
type featureSpec struct {
|
||
key string // 环境变量名
|
||
label string
|
||
group string
|
||
fallback string // 组合根未提供生效值时的兜底
|
||
description string
|
||
}
|
||
|
||
// featureCatalog 覆盖 config.Config 主要开关与各业务包灰度 flag(宁全勿缺)。
|
||
// 生效值由组合根(app)解析后注入,避免本包反向依赖业务模块。
|
||
var featureCatalog = []featureSpec{
|
||
{key: "AGENT_BACKEND", label: "Agent 执行后端", group: "agent", fallback: "pi-agent", description: "对话与任务执行的 Agent 后端(stub / cursor / pi-agent)"},
|
||
{key: "MAX_CONCURRENT_AGENTS", label: "Agent 全局并发上限", group: "agent", fallback: "8", description: "保护 pi-agent / GPU / API 的并发闸"},
|
||
{key: "PI_AGENT_RUNNER_URL", label: "PI Runner 地址", group: "agent", fallback: "", description: "产品内 PI Agent Runner 服务地址;空表示未接入"},
|
||
{key: "ALLOW_IN_MEMORY", label: "允许内存降级模式", group: "system", fallback: "false", description: "数据库不可用时降级内存模式(仅限本地 Demo)"},
|
||
{key: "AUTH_REGISTRATION_ENABLED", label: "开放注册", group: "auth", fallback: "true", description: "是否允许用户自主注册"},
|
||
{key: "AUTH_REQUIRE_APPROVAL", label: "注册需审核", group: "auth", fallback: "false", description: "新注册用户是否需要管理员审核后激活"},
|
||
{key: "FAV_PUBLISHER_ENABLED", label: "FAV 发布器", group: "artifact-vault", fallback: "false", description: "Final Artifact Vault 后台发布器;默认关闭"},
|
||
{key: "FAV_DEGRADED_READ", label: "FAV 降级读", group: "artifact-vault", fallback: "false", description: "FAV 缺失时允许降级读取;默认关闭"},
|
||
{key: "INTENT_V2_SHADOW", label: "意图 V2 影子模式", group: "intent", fallback: "false", description: "V2 意图识别影子运行,仅观测不接管"},
|
||
{key: "INTENT_V2_DECISION", label: "意图 V2 决策", group: "intent", fallback: "false", description: "V2 意图识别接管路由决策"},
|
||
{key: "INTENT_V2_DECISION_TIER", label: "意图 V2 决策档位", group: "intent", fallback: "none", description: "V2 灰度风险档位:none/query/generate/write_low/write_high/all"},
|
||
{key: "WORKFLOW_INTENTS_ENABLED", label: "工作流意图", group: "intent", fallback: "true", description: "识别工作流类意图"},
|
||
{key: "MULTI_INTENT_ENABLED", label: "多意图识别", group: "intent", fallback: "true", description: "单条消息多意图拆解"},
|
||
{key: "SEMANTIC_FALLBACK_ENABLED", label: "语义兜底", group: "intent", fallback: "false", description: "规则意图未命中时的语义兜底"},
|
||
{key: "MULTI_INTENT_PLAN_TIER", label: "多意图计划档位", group: "intentflow", fallback: "legacy", description: "意图计划灰度:legacy/shadow/auto_read/confirm/full"},
|
||
{key: "MULTI_INTENT_U9_SEGMENT", label: "U9 LLM 分段", group: "intentflow", fallback: "false", description: "LLM 意图分段提议"},
|
||
{key: "MULTI_INTENT_U10_MUTATE", label: "U10 变更适配器", group: "intentflow", fallback: "false", description: "低/中风险 mutate 动作适配器"},
|
||
{key: "MULTI_INTENT_U11_DOCGOV", label: "U11 文档治理适配器", group: "intentflow", fallback: "false", description: "docgov 动作适配器"},
|
||
{key: "MULTI_INTENT_U12_RUN_CONTROL", label: "U12 运行控制适配器", group: "intentflow", fallback: "false", description: "workflow/run-control 动作适配器"},
|
||
{key: "SEMANTIC_SUMMARY_SHADOW", label: "语义摘要影子", group: "ctxmgr", fallback: "false", description: "上下文语义摘要影子生成"},
|
||
{key: "SEMANTIC_SUMMARY_REPLACE", label: "语义摘要替换", group: "ctxmgr", fallback: "false", description: "语义摘要替换确定性叙事(保留位,未接线)"},
|
||
{key: "PI_CHANGE_REPORT_NARRATIVE", label: "PI 变更报告叙事", group: "docrevision", fallback: "false", description: "变更报告 PI 叙事增强;默认仅确定性回退"},
|
||
}
|
||
|
||
// Features 返回功能开关快照;source 恒为 env,均需重启生效。
|
||
func (s *Service) Features() []Feature {
|
||
values := map[string]string{}
|
||
if s.featureValues != nil {
|
||
values = s.featureValues()
|
||
}
|
||
out := make([]Feature, 0, len(featureCatalog))
|
||
for _, spec := range featureCatalog {
|
||
value, ok := values[spec.key]
|
||
if !ok {
|
||
if env, set := os.LookupEnv(spec.key); set {
|
||
value = env
|
||
} else {
|
||
value = spec.fallback
|
||
}
|
||
}
|
||
out = append(out, Feature{
|
||
Key: spec.key,
|
||
Label: spec.label,
|
||
Group: spec.group,
|
||
Value: value,
|
||
Source: "env",
|
||
RequiresRestart: true,
|
||
Description: spec.description,
|
||
})
|
||
}
|
||
return out
|
||
}
|