feat(ai): redesign the Jev triage state and add JEV_MODE=enforce review rules

第 2 回キャンペーンの突き合わせ結果を反映した。triage の state にコードで計算した
最新値の要約(now: プローブ、1 分 p95、1 分エラー率、再起動数、slo_now_ok)と
直近 5 分のエラーログ抜粋を加え、recovering は slo_now_ok を読むだけにした。
layer の choice を irreversible_needed の noul に置き換え、target_valid は
カタログ action のときだけ尋ねる。JEV_MODE=enforce では review の 2 ルール
(best_action 不一致かつ確信度 0.9 以上、target_valid 0.5 未満)で提案を
escalate に格下げし、判断を res.jev.enforced に記録する。既定は shadow のまま。
This commit is contained in:
seon committed 2026-10-08 17:45:28 +09:00
1 parent 795be156d9
commit 13797e5741
5 files changed
+178 -30

No files matched your search

+6 -5
View File
@@ -95,11 +95,11 @@ func main() {
HitlURL: env("HITL_URL", "http://hitl:8081"),
}
ag := agent.New(acfg, oai, tr, hc, store, enums, pv)
jevMode := env("JEV_MODE", "off") // off | shadow (shadow: Jev answers are recorded next to the LLM diagnosis, never acted on)
jevMode := env("JEV_MODE", "off") // off | shadow | enforce (shadow records Jev answers next to the diagnosis; enforce also applies the two review rules)
var jc *jev.Client
if jevMode == "shadow" {
if jevMode == "shadow" || jevMode == "enforce" {
jc = jev.New(env("JEV_BASE_URL", ""), env("JEV_MODEL", "jev-1.13.0"), keyReader(env("JEV_KEY_FILE", "/run/secrets/typesafe-api-key")))
ag.EnableShadow(jc)
ag.EnableShadow(jc, jevMode == "enforce")
}
log.Printf("agent up: model=%s prompt=%s labels=%d actions=%d jev=%s", acfg.Model, pv, len(enums.Labels), len(enums.Actions), jevMode)
if jc != nil && !jc.KeyPresent() {
@@ -173,10 +173,11 @@ func main() {
return
}
rev := ag.ShadowReview(c, req, res)
ag.Dispose(c, req, res)
if tri != nil || rev != nil {
res.Jev = map[string]any{"mode": "shadow", "triage": tri, "review": rev}
res.Jev = map[string]any{"mode": jevMode, "triage": tri, "review": rev}
}
ag.Enforce(res, rev) // no-op unless JEV_MODE=enforce
ag.Dispose(c, req, res)
ag.SaveShadow(context.Background(), req, res.SessionID, res, tri, rev)
writeJSON(w, 200, res)
})