Files
Agent-System/internal/sysadmin/features.go
T
weichenandCursor 8b84ee4ecf chore(config): declare WORKFLOW_SCOPE_MODE with a strict default
The flag reaches all three compose app services and the sysadmin catalog, and unknown values stay on the existing hard block.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-21 09:26:03 +00:00

160 lines
8.2 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
package sysadmin
import "os"
// Feature 功能开关视图。value / effectiveValue 是进程实际读到的配置,
// 不等于能力已经接入;是否可用看 implementationState 与 adapterReadiness。
type Feature struct {
Key string `json:"key"`
Label string `json:"label"`
Group string `json:"group"`
Value string `json:"value"`
ConfiguredValue string `json:"configuredValue"`
EffectiveValue string `json:"effectiveValue"`
ImplementationState string `json:"implementationState"`
AdapterReadiness string `json:"adapterReadiness"`
AdapterReason string `json:"adapterReason,omitempty"`
RolloutScope string `json:"rolloutScope"`
Source string `json:"source"`
RequiresRestart bool `json:"requiresRestart"`
Description string `json:"description"`
}
const (
implPlaceholder = "placeholder"
implDryRun = "dry_run"
implShadow = "shadow"
implLive = "live"
adapterReady = "ready"
adapterUnavailable = "unavailable"
adapterDegraded = "degraded"
rolloutEnvironment = "environment"
)
type featureMaturity struct {
state string
adapter string
reason string
}
// featureMaturityCatalog 是源码接线事实,不随环境变量翻转。
// 未列出的开关视为已接入的环境级能力;列出的项即使配置为 true 也保持此处状态。
var featureMaturityCatalog = map[string]featureMaturity{
"FAV_PUBLISHER_ENABLED": {
state: implDryRun, adapter: adapterUnavailable,
reason: "观察窗未授权,禁止 live",
},
"FAV_DEGRADED_READ": {
state: implDryRun, adapter: adapterUnavailable,
reason: "降级读保持关闭",
},
"MULTI_INTENT_PLAN_TIER": {
state: implDryRun, adapter: adapterUnavailable,
reason: "持久计划生产路径仍使用 Fake query owner,confirm 后缺少调度接线;调高档位不会变成可用",
},
"MULTI_INTENT_U9_SEGMENT": {
state: implDryRun, adapter: adapterUnavailable,
reason: "仅有 PI proposer,尚未进入真实聊天分段;提议请求已使用 reasoning profile",
},
"MULTI_INTENT_U10_MUTATE": {
state: implDryRun, adapter: adapterUnavailable,
reason: "适配器仍是 dry-run/validated-only",
},
"MULTI_INTENT_U11_DOCGOV": {
state: implDryRun, adapter: adapterUnavailable,
reason: "适配器仍是 dry-run/validated-only",
},
"MULTI_INTENT_U12_RUN_CONTROL": {
state: implDryRun, adapter: adapterUnavailable,
reason: "适配器仍是 dry-run/validated-only",
},
"SEMANTIC_SUMMARY_SHADOW": {
state: implShadow, adapter: adapterDegraded,
reason: "影子组件默认关闭;00058 尚未在运行环境执行。摘要请求已使用 reasoning profile,但当前容器要等镜像或挂载更新后 argv 才变成 --no-tools",
},
"SEMANTIC_SUMMARY_REPLACE": {
state: implPlaceholder, adapter: adapterUnavailable,
reason: "替换路径明确未接线,打开开关不会替换叙事",
},
"PI_CHANGE_REPORT_NARRATIVE": {
state: implShadow, adapter: adapterDegraded,
reason: "只读事实已含截断后的差异片段和影响说明,不含整篇文档。开关默认关闭。叙事请求已使用 reasoning profile,运行中的容器尚未切到 --no-tools",
},
}
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: "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: "WORKFLOW_SCOPE_MODE", label: "工作流作用域裁决", group: "intent", fallback: "strict", description: "文档命中裁决:strict 命中他流即拦截;weighted 按工作流关系权重打分"},
{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
}
}
maturity := featureMaturity{state: implLive, adapter: adapterReady}
if known, ok := featureMaturityCatalog[spec.key]; ok {
maturity = known
}
out = append(out, Feature{
Key: spec.key,
Label: spec.label,
Group: spec.group,
Value: value,
ConfiguredValue: value,
EffectiveValue: value,
ImplementationState: maturity.state,
AdapterReadiness: maturity.adapter,
AdapterReason: maturity.reason,
RolloutScope: rolloutEnvironment,
Source: "env",
RequiresRestart: true,
Description: spec.description,
})
}
return out
}