diff --git a/web/backend/api/gateway.go b/web/backend/api/gateway.go index f9b454ffa..67b055236 100644 --- a/web/backend/api/gateway.go +++ b/web/backend/api/gateway.go @@ -915,6 +915,11 @@ func (h *Handler) startGatewayLocked(initialStatus string, existingPid int) (int // Already holding gateway.mu from caller. if changed { refreshPicoTokensLocked(h.configPath) + cfg, err = config.LoadConfig(h.configPath) + if err != nil { + return 0, fmt.Errorf("failed to reload config after ensuring pico channel: %w", err) + } + defaultModelName = strings.TrimSpace(cfg.Agents.Defaults.GetModelName()) } if err := cmd.Start(); err != nil { diff --git a/web/backend/api/gateway_test.go b/web/backend/api/gateway_test.go index 647e40ee5..1d9352972 100644 --- a/web/backend/api/gateway_test.go +++ b/web/backend/api/gateway_test.go @@ -286,6 +286,61 @@ func TestStartGatewayLocked_ForwardsWildcardHostForPublicLauncher(t *testing.T) } } +func TestStartGatewayLocked_UsesReloadedConfigForBootSignature(t *testing.T) { + if runtime.GOOS == "windows" { + t.Skip("sleep command differs on Windows") + } + + resetGatewayTestState(t) + + configPath := filepath.Join(t.TempDir(), "config.json") + cfg := config.DefaultConfig() + delete(cfg.Channels, "pico") + if err := config.SaveConfig(configPath, cfg); err != nil { + t.Fatalf("SaveConfig() error = %v", err) + } + + h := NewHandler(configPath) + h.SetServerOptions(18800, false, false, nil) + gatewayExecCommand = func(_ string, _ ...string) *exec.Cmd { + return exec.Command("sleep", "30") + } + + originalSignature := computeConfigSignature(cfg) + pid, err := h.startGatewayLocked("starting", 0) + if err != nil { + t.Fatalf("startGatewayLocked() error = %v", err) + } + if pid <= 0 { + t.Fatalf("startGatewayLocked() pid = %d, want > 0", pid) + } + + gateway.mu.Lock() + cmd := gateway.cmd + bootSignature := gateway.bootConfigSignature + gateway.mu.Unlock() + t.Cleanup(func() { + if cmd != nil && cmd.Process != nil { + _ = cmd.Process.Kill() + } + if cmd != nil { + _ = cmd.Wait() + } + }) + + updatedCfg, err := config.LoadConfig(configPath) + if err != nil { + t.Fatalf("LoadConfig() error = %v", err) + } + expectedSignature := computeConfigSignature(updatedCfg) + if expectedSignature == originalSignature { + t.Fatal("expected EnsurePicoChannel() to change the config signature during gateway start") + } + if bootSignature != expectedSignature { + t.Fatalf("bootConfigSignature = %q, want %q", bootSignature, expectedSignature) + } +} + func TestGatewayStartReady_NoDefaultModel(t *testing.T) { configPath := filepath.Join(t.TempDir(), "config.json") h := NewHandler(configPath)