Files
Agent-System-Backend/internal/runmgr/perm_test.go
T
weichen f1302ed5b3 Enable canonical versioned Go module consumption
Why: Allow consumers to download an immutable module revision without nested source checkouts or local path replacements.

Evidence: SELF package tests and the prior canonical-path rejection are recorded in the Dev dependency-workspace task card; remote consumption is replayed against the committed candidate.

Impact: Change the module identity and its Go imports while preserving API behavior. Existing historical submodule revisions remain buildable.

Refs: Versioned dependencies U1/U3; feature/dependency-workspace
2026-10-13 15:47:16 +00:00

91 lines
3.3 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 runmgr
import (
"context"
"testing"
agentllm "git-ssh.u1680832.nyat.app/weichen/Agent-Native.git/runtime/llm"
agentpolicy "git-ssh.u1680832.nyat.app/weichen/Agent-Native.git/runtime/policy"
core "git-ssh.u1680832.nyat.app/weichen/Agent-System-Core.git"
)
func TestPlanModeRejectsWriteAndKeepsRead(t *testing.T) {
c, st := newExecEnv(t)
if err := st.SetPermissionMode("alice", c.run.ConversationID, "plan"); err != nil {
t.Fatal(err)
}
c.permissionMode = "plan"
res := c.ExecuteTool(core.ToolCallRequest{CallID: "c1", Name: "write_artifact", Arguments: []byte(`{"name":"a.md","content":"x"}`)})
if res.Status != "error" || res.Output == "" {
t.Fatalf("write in plan mode: %+v", res)
}
ok := c.ExecuteTool(core.ToolCallRequest{CallID: "c2", Name: "time_now", Arguments: []byte(`{}`)})
if ok.Status != "ok" {
t.Fatalf("read in plan mode: %+v", ok)
}
names := map[string]bool{}
for _, tool := range c.Tools() {
names[tool.Name] = true
}
if names["write_artifact"] || !names["time_now"] || !names["ask_user"] || !names["exit_plan_mode"] {
t.Fatalf("plan tool list: %v", names)
}
}
func TestDefaultModeStillRunsWrite(t *testing.T) {
c, _ := newExecEnv(t)
res := c.ExecuteTool(core.ToolCallRequest{CallID: "c1", Name: "write_artifact", Arguments: []byte(`{"name":"a.md","content":"x"}`)})
if res.Status != "ok" {
t.Fatalf("default write: %+v", res)
}
}
// TestConvAllowStoreKeysByName:SessionAllows 端口的键控口径保持「会话 × 工具名」,
// 不区分参数——与旧 sessionAllows 布尔参数的行为一致。
func TestConvAllowStoreKeysByName(t *testing.T) {
c, _ := newExecEnv(t)
conv := c.run.ConversationID
store := convAllowStore{mgr: c.mgr, conv: conv}
pol := agentpolicy.Policy{
Rules: []agentpolicy.Rule{{Effect: agentpolicy.EffectAsk, Tool: "run_shell"}},
SessionAllows: store,
}
if got := pol.Decide("run_shell", `{"command":"ls"}`, agentpolicy.Traits{}); got != agentpolicy.EffectAsk {
t.Fatalf("before remember: %q, want ask", got)
}
store.Remember("run_shell", `{"command":"ls"}`)
if got := pol.Decide("run_shell", `{"command":"rm -rf /tmp/x"}`, agentpolicy.Traits{}); got != agentpolicy.EffectAllow {
t.Fatalf("after remember, other args: %q, want allow(按名放行)", got)
}
if !c.mgr.sessionAllows(conv, "run_shell") {
t.Fatal("remember did not reach the manager table")
}
}
// TestPermissionAskRoutesToHITL:内核 ask 决策经 HITL 确认卡裁决;
// session 选项落会话放行,取消给出可读理由。
func TestPermissionAskRoutesToHITL(t *testing.T) {
c, _ := newExecEnv(t)
c.h = &runHandle{hitlCh: make(chan hitlAnswer, 1)}
call := agentllm.ToolCall{ID: "c1", Name: "run_shell", Arguments: `{"command":"ls"}`}
c.h.hitlCh <- hitlAnswer{resp: core.HITLResponse{ChoiceID: "yes"}}
if v := c.PermissionAsk(context.Background(), call); !v.Allow {
t.Fatalf("yes verdict = %+v", v)
}
c.h.hitlCh <- hitlAnswer{resp: core.HITLResponse{ChoiceID: "session"}}
if v := c.PermissionAsk(context.Background(), call); !v.Allow {
t.Fatalf("session verdict = %+v", v)
}
if !c.mgr.sessionAllows(c.run.ConversationID, "run_shell") {
t.Fatal("session choice did not remember the allow")
}
c.h.hitlCh <- hitlAnswer{resp: core.HITLResponse{ChoiceID: "no"}}
if v := c.PermissionAsk(context.Background(), call); v.Allow || v.Reason == "" {
t.Fatalf("no verdict = %+v", v)
}
}