fix(acp): preserve options for workspace agents (#704)

This commit is contained in:
xxb authored and GitHub committed 2026-04-27 14:28:28 +08:00
1 parent 558d48b511
commit d068ea44a2
2 files changed
+97 -1

No files matched your search

+52
View File
@@ -22,6 +22,7 @@ type Agent struct {
workDir string
command string
args []string
staticEnv map[string]string
extraEnv []string
sessionEnv []string
authMethod string // optional, e.g. "cursor_login" for Cursor CLI (see authenticate RPC)
@@ -81,6 +82,7 @@ func New(opts map[string]any) (core.Agent, error) {
}
args := parseStringSlice(opts["args"])
staticEnv := envMapFromOpts(opts)
extra := envPairsFromOpts(opts)
authMethod, _ := opts["auth_method"].(string)
authMethod = strings.TrimSpace(authMethod)
@@ -96,6 +98,7 @@ func New(opts map[string]any) (core.Agent, error) {
workDir: workDir,
command: cmdStr,
args: args,
staticEnv: staticEnv,
extraEnv: extra,
authMethod: authMethod,
displayName: displayName,
@@ -103,6 +106,29 @@ func New(opts map[string]any) (core.Agent, error) {
}, nil
}
func envMapFromOpts(opts map[string]any) map[string]string {
raw, ok := opts["env"]
if !ok || raw == nil {
return nil
}
switch m := raw.(type) {
case map[string]string:
out := make(map[string]string, len(m))
for k, v := range m {
out[k] = v
}
return out
case map[string]any:
out := make(map[string]string, len(m))
for k, v := range m {
out[k] = fmt.Sprint(v)
}
return out
default:
return nil
}
}
func envPairsFromOpts(opts map[string]any) []string {
raw, ok := opts["env"]
if !ok || raw == nil {
@@ -163,6 +189,32 @@ func (a *Agent) GetWorkDir() string {
return a.workDir
}
func (a *Agent) WorkspaceAgentOptions() map[string]any {
a.mu.RLock()
defer a.mu.RUnlock()
opts := map[string]any{
"command": a.command,
}
if len(a.args) > 0 {
opts["args"] = append([]string(nil), a.args...)
}
if len(a.staticEnv) > 0 {
env := make(map[string]string, len(a.staticEnv))
for k, v := range a.staticEnv {
env[k] = v
}
opts["env"] = env
}
if a.authMethod != "" {
opts["auth_method"] = a.authMethod
}
if a.displayName != "" {
opts["display_name"] = a.displayName
}
return opts
}
func (a *Agent) SetSessionEnv(env []string) {
a.mu.Lock()
a.sessionEnv = env
+45 -1
View File
@@ -1,6 +1,10 @@
package acp
import "testing"
import (
"testing"
"github.com/chenhg5/cc-connect/core"
)
func TestNew_DisplayNameDefault(t *testing.T) {
a, err := New(map[string]any{"command": "true"})
@@ -26,3 +30,43 @@ func TestNew_DisplayNameCustom(t *testing.T) {
t.Fatalf("CLIDisplayName = %q, want Copilot ACP", got)
}
}
func TestWorkspaceAgentOptions(t *testing.T) {
a, err := New(map[string]any{
"command": "true",
"args": []any{"--acp", "--stdio"},
"env": map[string]any{"FOO": "bar", "COPILOT_VALUE": "a=b"},
"auth_method": "cursor_login",
"display_name": "Copilot ACP",
})
if err != nil {
t.Fatal(err)
}
agent := a.(*Agent)
agent.SetSessionEnv([]string{"SESSION_ONLY=1"})
snapshotter, ok := a.(core.WorkspaceAgentOptionSnapshotter)
if !ok {
t.Fatalf("agent does not implement WorkspaceAgentOptionSnapshotter")
}
opts := snapshotter.WorkspaceAgentOptions()
if got, _ := opts["command"].(string); got != "true" {
t.Fatalf("command = %q, want true", got)
}
gotArgs, _ := opts["args"].([]string)
if len(gotArgs) != 2 || gotArgs[0] != "--acp" || gotArgs[1] != "--stdio" {
t.Fatalf("args = %#v, want [--acp --stdio]", gotArgs)
}
gotEnv, _ := opts["env"].(map[string]string)
if len(gotEnv) != 2 || gotEnv["FOO"] != "bar" || gotEnv["COPILOT_VALUE"] != "a=b" {
t.Fatalf("env = %#v, want config env only", gotEnv)
}
if got, _ := opts["auth_method"].(string); got != "cursor_login" {
t.Fatalf("auth_method = %q, want cursor_login", got)
}
if got, _ := opts["display_name"].(string); got != "Copilot ACP" {
t.Fatalf("display_name = %q, want Copilot ACP", got)
}
}