shell: support Windows cmd /C; normalize date/time; allow all commands; add tests
This commit is contained in:
@@ -2,28 +2,70 @@ package agent
|
||||
|
||||
import "testing"
|
||||
|
||||
func TestParseDecisionPlainJSON(t *testing.T) {
|
||||
raw := `{"thought":"t","action":"none","action_input":"","final":"ok"}`
|
||||
// TestParseDecisionFinalAnswer 测试 is_final_answer=true 时能正确解析 final_answer
|
||||
func TestParseDecisionFinalAnswer(t *testing.T) {
|
||||
raw := `{"thought":"直接回答","action":"none","action_input":"","is_final_answer":true,"final_answer":"你好!"}`
|
||||
got, err := parseDecision(raw)
|
||||
if err != nil {
|
||||
t.Fatalf("parseDecision error: %v", err)
|
||||
}
|
||||
if got.Action != "none" || got.Final != "ok" {
|
||||
t.Fatalf("unexpected decision: %+v", got)
|
||||
if !got.IsFinalAnswer {
|
||||
t.Fatal("expected is_final_answer=true")
|
||||
}
|
||||
if got.FinalAnswer == nil || *got.FinalAnswer != "你好!" {
|
||||
t.Fatalf("unexpected final_answer: %v", got.FinalAnswer)
|
||||
}
|
||||
}
|
||||
|
||||
// TestParseDecisionToolCall 测试需要调工具时的解析
|
||||
func TestParseDecisionToolCall(t *testing.T) {
|
||||
raw := `{"thought":"需要搜索","action":"web_search","action_input":"NVIDIA stock price","is_final_answer":false,"final_answer":null}`
|
||||
got, err := parseDecision(raw)
|
||||
if err != nil {
|
||||
t.Fatalf("parseDecision error: %v", err)
|
||||
}
|
||||
if got.IsFinalAnswer {
|
||||
t.Fatal("expected is_final_answer=false")
|
||||
}
|
||||
if got.Action != "web_search" {
|
||||
t.Fatalf("expected action=web_search, got %s", got.Action)
|
||||
}
|
||||
input := got.GetActionInputString()
|
||||
if input != "NVIDIA stock price" {
|
||||
t.Fatalf("expected action_input string, got %q", input)
|
||||
}
|
||||
}
|
||||
|
||||
// TestParseDecisionStructuredActionInput 测试 action_input 为结构化对象时的解析
|
||||
func TestParseDecisionStructuredActionInput(t *testing.T) {
|
||||
raw := `{"thought":"搜索","action":"web_search","action_input":{"query":"test","context":"dev"},"is_final_answer":false,"final_answer":null}`
|
||||
got, err := parseDecision(raw)
|
||||
if err != nil {
|
||||
t.Fatalf("parseDecision error: %v", err)
|
||||
}
|
||||
input := got.GetActionInputString()
|
||||
if input == "" {
|
||||
t.Fatal("expected non-empty action_input")
|
||||
}
|
||||
// 结构化对象应保留 JSON 原文
|
||||
if input[0] != '{' {
|
||||
t.Fatalf("expected JSON object string, got %q", input)
|
||||
}
|
||||
}
|
||||
|
||||
// TestParseDecisionCodeFence 测试被 markdown code fence 包裹的 JSON
|
||||
func TestParseDecisionCodeFence(t *testing.T) {
|
||||
raw := "```json\n{\"thought\":\"t\",\"action\":\"shell\",\"action_input\":\"ls\",\"final\":\"\"}\n```"
|
||||
raw := "```json\n{\"thought\":\"t\",\"action\":\"shell\",\"action_input\":\"ls\",\"is_final_answer\":false,\"final_answer\":null}\n```"
|
||||
got, err := parseDecision(raw)
|
||||
if err != nil {
|
||||
t.Fatalf("parseDecision error: %v", err)
|
||||
}
|
||||
if got.Action != "shell" || got.ActionInput != "ls" {
|
||||
t.Fatalf("unexpected decision: %+v", got)
|
||||
if got.Action != "shell" {
|
||||
t.Fatalf("unexpected action: %s", got.Action)
|
||||
}
|
||||
}
|
||||
|
||||
// TestParseDecisionInvalid 测试非 JSON 输入时返回错误
|
||||
func TestParseDecisionInvalid(t *testing.T) {
|
||||
_, err := parseDecision("not json")
|
||||
if err == nil {
|
||||
|
||||
Reference in New Issue
Block a user