shell: support Windows cmd /C; normalize date/time; allow all commands; add tests

This commit is contained in:
2026-03-05 17:44:19 +08:00
parent 47b6059773
commit e2f806edb3
19 changed files with 989 additions and 350 deletions

View File

@@ -6,6 +6,36 @@ import (
"strings"
)
// reactDecision 是 LLM 在统一 ReAct 循环中返回的结构化 JSON 决策。
// 每轮 LLM 调用都返回这个结构,由 agent 判断是否继续循环。
type reactDecision struct {
// Thought 是 LLM 的当前推理过程描述
Thought string `json:"thought"`
// Action 是需要调用的工具名称(如 "file"、"shell"、"web_search"),不需要工具时为 "none" 或空
Action string `json:"action"`
// ActionInput 是传给工具的输入参数,可以是字符串或结构化对象
ActionInput json.RawMessage `json:"action_input"`
// IsFinalAnswer 标记本轮是否为最终回答。true 表示 ReAct 循环结束。
IsFinalAnswer bool `json:"is_final_answer"`
// FinalAnswer 当 IsFinalAnswer 为 true 时,包含给用户的最终回复内容
FinalAnswer *string `json:"final_answer"`
}
// GetActionInputString 将 ActionInput 转为字符串,用于传递给工具的 Call 方法。
// 如果 ActionInput 是 JSON 字符串则去掉引号;如果是对象/数组则保持 JSON 原文。
func (d *reactDecision) GetActionInputString() string {
if len(d.ActionInput) == 0 {
return ""
}
// 尝试解析为字符串
var s string
if err := json.Unmarshal(d.ActionInput, &s); err == nil {
return s
}
// 非字符串则直接返回 JSON 原文
return strings.TrimSpace(string(d.ActionInput))
}
func parseDecision(raw string) (reactDecision, error) {
raw = normalizeJSON(raw)
start := strings.Index(raw, "{")