精简动作审查输入并支持审批来源定位 (#125)

* fix: 精简审查背景并区分人工消息与调度输入

* fix: 模型审查仅提交当前调用与选定背景

* feat: 审批来源定位原会话并移除 Worker 审查背景
This commit is contained in:
RuoJi6 authored and GitHub committed 2026-09-15 23:51:37 +08:00
1 parent 0d6fa880b8
commit 04d25eb133
30 files changed
+1143 -465

No files matched your search

+48
View File
@@ -49,6 +49,54 @@ func TestInterceptDetailHTTP(t *testing.T) {
if r := do(http.MethodGet, path, "", false); r.Code != 401 {
t.Fatalf("unprotected detail: %d", r.Code)
}
executionPath := path + "/execution"
if r := do(http.MethodGet, executionPath, "", false); r.Code != 401 {
t.Fatal("unprotected execution source")
}
if r := do(http.MethodGet, executionPath, "", true); r.Code != 409 {
t.Fatalf("legacy source: %d", r.Code)
}
for _, tc := range []struct {
path string
status int
}{{"/api/intercept/history/0/execution", 400}, {"/api/intercept/history/not-a-number/execution", 400}, {"/api/intercept/history/9223372036854775807/execution", 404}} {
if r := do(http.MethodGet, tc.path, "", true); r.Code != tc.status {
t.Fatalf("%s: %d", tc.path, r.Code)
}
}
conv, err := d.CreateConversation("test", "approval navigation", nil)
if err != nil {
t.Fatal(err)
}
t.Cleanup(func() { _, _ = d.Exec(`DELETE FROM conversations WHERE id=$1`, conv.ID) })
seq, err := d.AppendConvActivity(conv.ID, db.Activity{Worker: "test", Kind: "tool_use", Tool: "Bash", ToolUseID: "http-source", Summary: "pwd"})
if err != nil {
t.Fatal(err)
}
sourceID, err := d.CreateInterceptPending(0, conv.ID, "", "test", "Bash", []byte(`{"command":"pwd"}`), "review", &db.InterceptAudit{ToolUseID: "http-source", Correlation: "exact"})
if err != nil {
t.Fatal(err)
}
t.Cleanup(func() { _, _ = d.Exec(`DELETE FROM intercept_pending WHERE id=$1`, sourceID) })
sourceReply := do(http.MethodGet, fmt.Sprintf("/api/intercept/history/%d/execution", sourceID), "", true)
var execution struct {
Seq int64 `json:"seq"`
ConversationID int64 `json:"conversation_id"`
Items []ActivityDTO `json:"items"`
}
if sourceReply.Code != 200 || json.Unmarshal(sourceReply.Body.Bytes(), &execution) != nil || execution.Seq != seq || execution.ConversationID != conv.ID || len(execution.Items) != 1 || execution.Items[0].Seq != seq {
t.Fatalf("source reply: %d %s", sourceReply.Code, sourceReply.Body.String())
}
if err := d.DeleteConversation(conv.ID); err != nil {
t.Fatal(err)
}
deletedReply := do(http.MethodGet, fmt.Sprintf("/api/intercept/history/%d/execution?conversation=%d", sourceID, conv.ID), "", true)
if deletedReply.Code != 410 || !strings.Contains(deletedReply.Body.String(), "对话已被删除") {
t.Fatalf("deleted conversation: %d %s", deletedReply.Code, deletedReply.Body.String())
}
r := do(http.MethodGet, path, "", true)
var detail db.InterceptDetail
if r.Code != 200 || json.Unmarshal(r.Body.Bytes(), &detail) != nil || detail.Audit == nil || detail.Audit.UserMessage != "snapshot" {