fix(acp): preserve options for workspace agents (#704)
This commit is contained in:
2 files changed
+97
-1
No files matched your search
@@ -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
@@ -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)
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user