mirror of
https://gitcode.com/JianFeeeee/HomeAgent.git
synced 2026-09-22 18:08:04 +00:00
fix: LLM 工具循环 400、中断消息注入、ConPTY 终端支持
- agent: 工具轮请求尾部补 user 占位(zen 网关强制),tool 消息正确配对 - agent: 工具提醒/中断以 system 角色注入并带 [中断消息] 前缀,不进用户履历;系统提示词说明中断消息格式 - agentcli: 基于 ConPTY 的交互式终端(ptywin fork),terminal_create/read/write/resize/close/watch - webui: server 输出通道适配器(保留 reasoning_content/disable_thinking) - GUI: 沉浸式标题栏、icon 圆角重制、mascot 等打磨
This commit is contained in:
@ -6,6 +6,7 @@ import (
|
||||
"log"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
"sort"
|
||||
"strings"
|
||||
"sync"
|
||||
@ -30,6 +31,8 @@ type Plugin struct {
|
||||
baseDir string // L0 写前留档根目录(<data>/file_baseline 的父目录),空则禁用
|
||||
}
|
||||
|
||||
var isWindowsBuild = runtime.GOOS == "windows"
|
||||
|
||||
func New(name string) *Plugin {
|
||||
return &Plugin{name: name}
|
||||
}
|
||||
@ -178,12 +181,41 @@ func (p *Plugin) resolvePath(userPath string) (string, error) {
|
||||
return "", fmt.Errorf("resolve path: %w", err)
|
||||
}
|
||||
base := filepath.Clean(p.filesDir)
|
||||
if base != "/" && !strings.HasPrefix(abs, base+string(filepath.Separator)) && abs != base {
|
||||
if !pathWithinSandbox(abs, base) {
|
||||
return "", fmt.Errorf("path outside sandbox: %s", userPath)
|
||||
}
|
||||
return abs, nil
|
||||
}
|
||||
|
||||
// pathWithinSandbox 判断 abs 是否位于沙箱 base 之内。
|
||||
// Windows 文件系统大小写不敏感,且卷根目录(如 C:\)应放行全盘路径。
|
||||
func pathWithinSandbox(abs, base string) bool {
|
||||
lower := func(s string) string {
|
||||
if isWindowsBuild {
|
||||
return strings.ToLower(s)
|
||||
}
|
||||
return s
|
||||
}
|
||||
abs = filepath.Clean(abs)
|
||||
base = filepath.Clean(base)
|
||||
if equalFoldPath(abs, base) {
|
||||
return true
|
||||
}
|
||||
// 卷根沙箱(C:\、D:\ 等)表示整机可访问
|
||||
if isWindowsBuild && len(base) == 3 && base[1] == ':' && base[2] == '\\' {
|
||||
return true
|
||||
}
|
||||
prefix := lower(base) + string(filepath.Separator)
|
||||
return strings.HasPrefix(lower(abs), prefix)
|
||||
}
|
||||
|
||||
func equalFoldPath(a, b string) bool {
|
||||
if isWindowsBuild {
|
||||
return strings.EqualFold(a, b)
|
||||
}
|
||||
return a == b
|
||||
}
|
||||
|
||||
func (p *Plugin) handleRead(args map[string]interface{}) (interface{}, error) {
|
||||
path, _ := args["path"].(string)
|
||||
if path == "" {
|
||||
|
||||
Reference in New Issue
Block a user