feat(gateway): 配置只读事实面 + 后台思考行「档位/穿透」(契约 v0.68)

- 新增 GET /api/v1/admin/config-facts:记忆整理 7 键 + 安静时段 2 键的**进程生效值** + 声明默认值(反射读 default 标签,不读 .env)
- 面板:记忆整理卡 + 安静时段卡(Miuix 只读),文案按新语义「只服务主动搭话,不静默回复」
- 后台思考行加 urgency(**只能是下限**,存档不可分 high/critical)+ quietHoursBypassed(与既有 bypassed 是两件事)
- 红线实测:往响应里塞 JWT ⇒ TestAdminConfigFacts_NeverLeaksSecretValues 打红(连断言消息都把整个响应打出来了)
- 前端:configFacts 24 checks / ConfigFactsCards 29 / BackthinkUrgencyTags 19 全过
- 契约 v0.68(纯增量:B12 新端点 + B8 两字段 + §4.10 形状与语义 + §7.4-17 下限限定)
This commit is contained in:
AskaEth committed 2026-10-05 13:54:56 +08:00
1 parent a057a0f61f
commit 34cef95e17
25 files changed
+1741 -14

No files matched your search

+21 -1
View File
@@ -301,7 +301,27 @@ export function parseBackthinkItem(v: unknown): BackthinkItem | null {
const detail = firstPushText(pr.Detail, pr.detail, r.detail, r.push_detail);
const bypassedRaw = pr.Bypassed ?? pr.bypassed ?? r.bypassed ?? r.push_bypassed;
const bypassed = typeof bypassedRaw === "boolean" ? bypassedRaw : undefined;
return { id: String(idRaw), trigger, conclusion, shouldNotify, pushed, route, detail, bypassed, at };
// v0.68 的档位/穿透:**防御性读取**(兼容 camelCase 与 Go 字段名)。当前 bus 上发布的
// 是原始 `backthink.Record`,它**不带**这两个字段 ⇒ 今天恒为 undefined(本次会话新到
// 的行显示「档位未知」,重开页面由历史拉取补真值)。一旦后端把这两个事实放进帧里,
// 这里无需改动就会显示出来 —— 但绝不因为「帧里没有」就编一个值。
const urgencyRaw = r.urgency ?? r.Urgency ?? r.urgency_level ?? r.urgencyLevel;
const urgency = typeof urgencyRaw === "string" && urgencyRaw ? urgencyRaw : undefined;
const qhRaw = r.quietHoursBypassed ?? r.QuietHoursBypassed;
const quietHoursBypassed = typeof qhRaw === "boolean" ? qhRaw : undefined;
return {
id: String(idRaw),
trigger,
conclusion,
shouldNotify,
pushed,
route,
detail,
bypassed,
urgency,
quietHoursBypassed,
at,
};
}
/** 取 PushResult 文本字段的第一个非空值(先 Go 字段名,再 camelCase)。空串按