You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Commit 7d728e2
Browse filesBrowse the repository at this point in the historyBrowse files
fix(webui): persist persona, coder auto-compact, LSP autostart and UI language settings
- Persona: store the active persona in [Persona] Active (project over global,
default assistant, "auto" sentinel) and restore it on startup; WebUI, TUI
and ACP changes persist through SetAndPersistActivePersona.
- Auto-compact: Agent.AutoCompact is now *bool and overrides the global
AutoCompact when set; model switches no longer rebuild the agent and drop
AutoCompact, threshold, thinking mode or context window override.
- LSP: UpdateLSP keeps Autostart, Languages and Filenames; PUT keeps stored
Options the UI never sends.
- UI language: saved as a server-side UI preference with a localStorage
cache, applied immediately and no longer reset by fetchSettings.
- Drop the stale per-agent AutoCompact = false overrides from .pando.toml.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015JsuQ7suHKMiaZUTB9K6qQ
Four reported bugs, analysed by parallel subagents; key lines spot-checked. NOT FIXED YET.
16
+
17
+
## 1. Persona selector lost after restarting pando desktop (backend)
18
+
-`PersonaSelector.tsx` -> PUT `/api/v1/personas/active` -> `handleSetActivePersona` (`internal/api/handlers_personas.go`) -> `agent.SetActivePersona` only sets the in-memory global `activePersonaName` (`internal/llm/agent/persona_selector.go:33`). Nothing is written to disk.
19
+
- On startup `internal/app/app.go:857-860` resets it to "assistant" (and "Auto"/empty also becomes "assistant").
20
+
- Fix: persist in `webui-prefs.json` (UIPrefs `activePersona *string`, the chatMode pattern in `handlers_ui_prefs.go`) or in config with json+toml tags; restore it in app.go before the "assistant" default; TUI/ACP setters too. Decide global vs per-project.
21
+
22
+
## 2. Coder autoCompact reverts (backend)
23
+
- WebUI PUT `/api/v1/config/agents` + `UpdateAgent` work (round-trip verified).
24
+
-`setAgentModel` (`internal/config/config.go:~4650`) rebuilds `Agent{Model, MaxTokens, ReasoningEffort}`, dropping AutoCompact, AutoCompactThreshold, ThinkingMode, ContextWindowOverride, and writes it to the TOML. `agentInheritingModel` (`config.go:3961`) does the same for propagated agents. Any model change (chat picker, /model, setup, TUI) wipes the toggle.
25
+
- Fix: copy the existing agent and set Model only; add a regression test.
26
+
- Side issue: the runtime (`agent.go:~2335`) ORs global `AutoCompact` with the per-agent flag, so turning coder off does nothing while the global is true.
27
+
28
+
## 3. LSP Autostart not saved (backend)
29
+
-`LSPSettings.tsx` modal -> PUT `/api/v1/config/lsp` -> `handlePutConfigLSP` copies the fields correctly, but `UpdateLSP` (`config.go:5538`) builds `LSPConfig{Disabled, Command, Args, Options}`, dropping Autostart, Languages and Filenames. The TUI has the same bug.
30
+
- Fix: copy those fields; preserve the old Options when the request sends none; add a test.
31
+
32
+
## 4. Language reverts even when switching settings sections (frontend + backend gap)
33
+
- UI-only i18n language. `settingsStore.ts` comment: "UI-only, not persisted". The backend `SettingsResponse`/`SettingsUpdateRequest` have no language field.
34
+
-`GeneralSettings.tsx:41-43` runs `fetchSettings()` on mount, which merges `{...DEFAULTS, ...data}` and resets it to 'en'; `useLanguageSync` then applies 'en'. `i18n/index.ts:34` hardcodes `lng: 'en'`.
35
+
- Fix: a dedicated `setLanguage` that applies immediately, with a server-side UI pref (`/api/v1/ui/preferences`, like chatMode) and a localStorage cache; `fetchSettings` must not overwrite it; i18n init reads the saved value.
36
+
37
+
## Common pattern
38
+
Three are Go functions that rebuild structs field by field and silently drop newer fields (UpdateLSP, setAgentModel, agentInheritingModel). Prefer copying the existing struct and mutating it. UI state that must persist in desktop must live server-side (the random port breaks localStorage).
User rule for persona + autoCompact: the effective value is the project `.pando.toml` value if set, else the global value; changes persist per project (through `updateCfgFile`, which writes the project file when it exists).
18
+
19
+
## Persona
20
+
- New `internal/config/persona_active.go`: `PersonaConfig{Active}` (`[Persona] Active`, json `persona.active`), sentinel `"auto"` = explicit Auto, empty = never chosen; `ActivePersonaChoice`, `EffectiveActivePersona` (fallback `assistant`), `UpdateActivePersona` (rolls back on write error).
21
+
-`Config.Persona` field added in config.go.
22
+
-`agent.SetAndPersistActivePersona` (persona_selector.go) used by the TUI (`tui.go`), ACP adapters (`cmd/root.go`, `internal/app/app.go`) and the API PUT handler (`handlers_personas.go`, 500 on persist failure).
23
+
- Startup (`app.go`) restores the effective persona; if it is unknown, logs a warning and falls back to assistant.
24
+
-`PersonaSelector.tsx` shows an error toast when the PUT fails.
25
+
26
+
## Coder autoCompact
27
+
-`Agent.AutoCompact` is now `*bool` (nil = inherit global). `config.ResolveAutoCompact(global, agent)`: the per-agent value OVERRIDES the global one (was OR).
28
+
-`setAgentModel` and `agentInheritingModel` copy the existing Agent and change only Model (they used to drop AutoCompact/Threshold/ThinkingMode/ContextWindowOverride on every model switch).
29
+
- Runtime: `agent.go` shouldCompact and the `tui.go` 95% trigger use the resolver. TUI settings shows the resolved value.
30
+
- API `handlers_config.go`: GET returns the effective value; PUT stores an explicit per-agent value only when it differs from the effective one.
31
+
- Init templates (`internal/config/init.go`, `cmd/init.go`) no longer write `AutoCompact = false` for coder.
32
+
- CAVEAT: existing TOMLs with `AutoCompact = false` per agent (written by the old bug, e.g. this repo's .pando.toml) are now explicit overrides that beat global true. Delete those lines to inherit.
33
+
34
+
## LSP
35
+
-`UpdateLSP` now copies Autostart, Languages and Filenames (clones the slices).
36
+
-`handlePutConfigLSP` preserves the stored Options (the UI never sends them).
37
+
38
+
## UI language
39
+
-`UIPrefs.Language` (`json:"language"`) in `handlers_ui_prefs.go` -> `~/.config/pando/webui-prefs.json` (global per machine); empty is ignored, >16 chars returns 400.
40
+
- settingsStore: `setLanguage` (applies immediately, not dirty, localStorage `pando_language` cache, fire-and-forget PUT `/api/v1/ui/preferences`), `hydrateLanguage` with a `languageChosen` guard (called in MainLayout after hydrateChatMode); `fetchSettings` preserves language; `saveSettings` no longer sends it.
41
+
-`GeneralSettings.tsx` uses setLanguage; `i18n/index.ts` reads the cached value at init.
42
+
43
+
## Tests / verification
44
+
New tests: `internal/config/agent_persistence_test.go`, `internal/config/persona_active_test.go`, `internal/api/handlers_config_lsp_persist_test.go`, `internal/api/handlers_personas_persist_test.go`, `TestUIPrefsLanguageRoundTrip`.
45
+
`go build ./...`, `go vet`, `go test ./internal/config ./internal/api ./internal/llm/agent ./internal/app ./internal/tui/...` all ok; `web-ui npx tsc --noEmit` ok. Not run: manual desktop check, `npm run build`.
0 commit comments