From a656f3526f4a6c16aadc5d6325a2d7b5d0b99ccc Mon Sep 17 00:00:00 2001 From: Wojtek Date: Thu, 16 Apr 2026 14:52:02 -0400 Subject: [PATCH] fix: ignore CONFIGURE config-set flags --- internal/driver/shared/config.go | 24 +++++++++++++++-- internal/driver/shared/config_test.go | 39 +++++++++++++++++++++++++++ 2 files changed, 61 insertions(+), 2 deletions(-) diff --git a/internal/driver/shared/config.go b/internal/driver/shared/config.go index 2b29376..86cc98d 100644 --- a/internal/driver/shared/config.go +++ b/internal/driver/shared/config.go @@ -57,12 +57,23 @@ func ParseConfigSetCommand(line, driverPrefix string) (path string, value any, e ) } - path = strings.TrimSpace(parts[3]) + args := parts[3:] + for len(args) > 0 && isConfigSetFlag(args[0]) { + args = args[1:] + } + for len(args) > 0 && isConfigSetFlag(args[len(args)-1]) { + args = args[:len(args)-1] + } + if len(args) < 2 { + return "", nil, fmt.Errorf("unrecognized CONFIGURE command: %q (expected ' ')", line) + } + + path = strings.TrimSpace(args[0]) if path == "" { return "", nil, fmt.Errorf("unrecognized CONFIGURE command: %q (expected non-empty path)", line) } - valueText := strings.TrimSpace(strings.Join(parts[4:], " ")) + valueText := strings.TrimSpace(strings.Join(args[1:], " ")) if valueText == "" { return "", nil, fmt.Errorf("unrecognized CONFIGURE command: %q (expected non-empty value)", line) } @@ -75,6 +86,15 @@ func ParseConfigSetCommand(line, driverPrefix string) (path string, value any, e return path, valueText, nil } +func isConfigSetFlag(token string) bool { + switch token { + case "--json", "--strict-json": + return true + default: + return false + } +} + func PrimaryModelRef(models map[string]string) (string, error) { if models == nil { return "", fmt.Errorf("missing MODEL primary (set `MODEL primary ` in Clawfile)") diff --git a/internal/driver/shared/config_test.go b/internal/driver/shared/config_test.go index 6db7197..2ca83b0 100644 --- a/internal/driver/shared/config_test.go +++ b/internal/driver/shared/config_test.go @@ -61,6 +61,45 @@ func TestParseConfigSetCommandPreservesStringValue(t *testing.T) { } } +func TestParseConfigSetCommandIgnoresTrailingJSONFlag(t *testing.T) { + path, value, err := ParseConfigSetCommand(`openclaw config set agents.defaults.contextTokens 20000 --json`, "openclaw") + if err != nil { + t.Fatalf("ParseConfigSetCommand returned error: %v", err) + } + if path != "agents.defaults.contextTokens" { + t.Fatalf("unexpected path: %q", path) + } + if contextTokens, ok := value.(float64); !ok || contextTokens != 20000 { + t.Fatalf("expected numeric 20000, got %#v", value) + } +} + +func TestParseConfigSetCommandIgnoresLeadingJSONFlag(t *testing.T) { + path, value, err := ParseConfigSetCommand(`openclaw config set --json agents.defaults.contextTokens 20000`, "openclaw") + if err != nil { + t.Fatalf("ParseConfigSetCommand returned error: %v", err) + } + if path != "agents.defaults.contextTokens" { + t.Fatalf("unexpected path: %q", path) + } + if contextTokens, ok := value.(float64); !ok || contextTokens != 20000 { + t.Fatalf("expected numeric 20000, got %#v", value) + } +} + +func TestParseConfigSetCommandIgnoresStrictJSONFlag(t *testing.T) { + path, value, err := ParseConfigSetCommand(`openclaw config set --strict-json agents.defaults.contextTokens 20000`, "openclaw") + if err != nil { + t.Fatalf("ParseConfigSetCommand returned error: %v", err) + } + if path != "agents.defaults.contextTokens" { + t.Fatalf("unexpected path: %q", path) + } + if contextTokens, ok := value.(float64); !ok || contextTokens != 20000 { + t.Fatalf("expected numeric 20000, got %#v", value) + } +} + func TestParseConfigSetCommandRejectsUnexpectedPrefix(t *testing.T) { _, _, err := ParseConfigSetCommand(`picoclaw config set agents.defaults.model_name "fallback"`, "hermes") if err == nil {