From 1208c740306dcffad6fe288e7f740a21bfbbeb93 Mon Sep 17 00:00:00 2001 From: WeiCHEN Date: Mon, 7 Sep 2026 17:15:16 +0800 Subject: [PATCH] fix(agent): pass absolute workDir and parse bridge JSON response Co-authored-by: Cursor --- .env.example | 12 ++++++------ internal/agent/cursor.go | 39 ++++++++++++++++++++++++++++++++++++--- internal/agent/piagent.go | 39 ++++++++++++++++++++++++++++++++++++--- 3 files changed, 78 insertions(+), 12 deletions(-) diff --git a/.env.example b/.env.example index 1b770665..2d6f3fb4 100644 --- a/.env.example +++ b/.env.example @@ -28,12 +28,12 @@ CURSOR_BRIDGE_BIN=tools/cursor-bridge/index.mjs PI_AGENT_BIN=/opt/homebrew/bin/pi # pi-bridge 脚本路径 PI_AGENT_BRIDGE_BIN=tools/pi-bridge/index.mjs -# pi 底层 provider (如 anthropic, openai, cc-switch-kimi-for-coding 等) -PI_AGENT_PROVIDER=anthropic -# pi 所用模型标识 (如 claude-3-7-sonnet, MiniMax-M3, claude-sonnet-4-5 等) -PI_AGENT_MODEL=claude-3-7-sonnet -# pi 运行时的额外环境变量或 token -ANTHROPIC_API_KEY= +# pi 底层 provider (如 cc-switch-mini-max, anthropic, cc-switch-kimi-for-coding 等) +PI_AGENT_PROVIDER=cc-switch-mini-max +# pi 所用模型标识 (如 MiniMax-M3, MiniMax-M2.7, claude-3-7-sonnet 等) +PI_AGENT_MODEL=MiniMax-M3 +# pi 运行时的额外环境变量或 token (若通过 ~/.pi/agent/models.json 配置则可留空) +MINIMAX_API_KEY= # --- 5. 法规知识库配置 (当前复用已有 agent-regkb Docker 容器) --- KB_DB_HOST=127.0.0.1 diff --git a/internal/agent/cursor.go b/internal/agent/cursor.go index 809c52f0..da78d50c 100644 --- a/internal/agent/cursor.go +++ b/internal/agent/cursor.go @@ -8,6 +8,7 @@ import ( "os" "os/exec" "path/filepath" + "strings" "chat-agent-system/internal/config" ) @@ -23,8 +24,14 @@ func (c *CursorCLIBackend) Execute(ctx context.Context, req Request) (*Result, e req.Targets = []string{"output.md"} } + workDir := req.WorkDir + if !filepath.IsAbs(workDir) { + wd, _ := os.Getwd() + workDir = filepath.Join(wd, workDir) + } + payload, _ := json.Marshal(map[string]any{ - "workspace": req.WorkDir, + "workspace": workDir, "api_key": c.cfg.CursorAPIKey, "model": c.cfg.CursorModel, "prompt": req.Prompt, @@ -46,7 +53,7 @@ func (c *CursorCLIBackend) Execute(ctx context.Context, req Request) (*Result, e defer cancel() cmd := exec.CommandContext(runCtx, bridgeBin) - cmd.Dir = req.WorkDir + cmd.Dir = workDir cmd.Stdin = bytes.NewReader(payload) cmd.Env = append(os.Environ(), "CURSOR_API_KEY="+c.cfg.CursorAPIKey, @@ -65,9 +72,35 @@ func (c *CursorCLIBackend) Execute(ctx context.Context, req Request) (*Result, e }, nil } + type bridgeResponse struct { + OK bool `json:"ok"` + FallbackReason string `json:"fallback_reason"` + Stderr string `json:"stderr"` + } + var bResp bridgeResponse + lines := strings.Split(strings.TrimSpace(stdout.String()), "\n") + if len(lines) > 0 { + _ = json.Unmarshal([]byte(lines[len(lines)-1]), &bResp) + } + + if !bResp.OK { + errMsg := bResp.FallbackReason + if bResp.Stderr != "" { + errMsg += " (" + bResp.Stderr + ")" + } + if errMsg == "" { + errMsg = "cursor bridge reported task failed" + } + return &Result{ + Success: false, + ErrorReason: errMsg, + Logs: stdout.String(), + }, nil + } + patches := make(map[string][]byte) for _, t := range req.Targets { - p := filepath.Join(req.WorkDir, t) + p := filepath.Join(workDir, t) if b, err := os.ReadFile(p); err == nil { patches[t] = b } diff --git a/internal/agent/piagent.go b/internal/agent/piagent.go index 0ee03b61..22d17255 100644 --- a/internal/agent/piagent.go +++ b/internal/agent/piagent.go @@ -8,6 +8,7 @@ import ( "os" "os/exec" "path/filepath" + "strings" "chat-agent-system/internal/config" ) @@ -23,8 +24,14 @@ func (p *PiAgentBackend) Execute(ctx context.Context, req Request) (*Result, err req.Targets = []string{"output.md"} } + workDir := req.WorkDir + if !filepath.IsAbs(workDir) { + wd, _ := os.Getwd() + workDir = filepath.Join(wd, workDir) + } + payload, _ := json.Marshal(map[string]any{ - "workspace": req.WorkDir, + "workspace": workDir, "model": p.cfg.PiAgentModel, "provider": p.cfg.PiAgentProvider, "prompt": req.Prompt, @@ -46,7 +53,7 @@ func (p *PiAgentBackend) Execute(ctx context.Context, req Request) (*Result, err defer cancel() cmd := exec.CommandContext(runCtx, bridgeBin) - cmd.Dir = req.WorkDir + cmd.Dir = workDir cmd.Stdin = bytes.NewReader(payload) cmd.Env = append(os.Environ(), "PI_AGENT_BIN="+p.cfg.PiAgentBin, @@ -67,9 +74,35 @@ func (p *PiAgentBackend) Execute(ctx context.Context, req Request) (*Result, err }, nil } + type bridgeResponse struct { + OK bool `json:"ok"` + FallbackReason string `json:"fallback_reason"` + Stderr string `json:"stderr"` + } + var bResp bridgeResponse + lines := strings.Split(strings.TrimSpace(stdout.String()), "\n") + if len(lines) > 0 { + _ = json.Unmarshal([]byte(lines[len(lines)-1]), &bResp) + } + + if !bResp.OK { + errMsg := bResp.FallbackReason + if bResp.Stderr != "" { + errMsg += " (" + bResp.Stderr + ")" + } + if errMsg == "" { + errMsg = "pi bridge reported task failed" + } + return &Result{ + Success: false, + ErrorReason: errMsg, + Logs: stdout.String(), + }, nil + } + patches := make(map[string][]byte) for _, t := range req.Targets { - p := filepath.Join(req.WorkDir, t) + p := filepath.Join(workDir, t) if b, err := os.ReadFile(p); err == nil { patches[t] = b }