Skip to content

Sync session preferences and approval state across desktop, Feishu, and WeChat#274

Merged
code-JDS merged 5 commits intoScience-Discovery:devfrom
yqmaphy:session-pref
Apr 11, 2026
Merged

Sync session preferences and approval state across desktop, Feishu, and WeChat#274
code-JDS merged 5 commits intoScience-Discovery:devfrom
yqmaphy:session-pref

Conversation

@yqmaphy
Copy link
Copy Markdown
Collaborator

@yqmaphy yqmaphy commented Apr 11, 2026

Summary

  • add shared session preference APIs and server-side in-memory state so desktop, Feishu, and WeChat read and update the same agent, model, variant, and approval settings
  • update desktop preference and permission handling to react to session preference change events and keep approval state in sync across clients
  • move Feishu and WeChat session overrides onto shared session preferences for consistent cross-client behavior

Closes #265

@code-JDS
Copy link
Copy Markdown
Collaborator

/oc review

@github-actions
Copy link
Copy Markdown

This PR replaces per-client in-memory preference state (model, agent, variant, approval) with a shared server-side SessionPreference store, enabling cross-client sync for desktop, Feishu, and WeChat. Overall direction is good, but there are several issues worth addressing:

  • Medium — WeChat _cmd_set_model uses fire-and-forget asyncio.create_task (aether_wechat_agent.py ~line 842): Unlike _cmd_agent, _cmd_variant, and _cmd_approval which all await _set_preference(...), the model setter dispatches the HTTP call via asyncio.get_event_loop().create_task(...) and immediately returns success. If the PUT fails, the user sees "✅ 已切换模型" but the preference was never persisted. This should await like the other commands.

  • Medium — addPreferenceMethods does not check HTTP status (packages/app/src/utils/server.ts): Both get and set call resp.json() without checking resp.ok. A 4xx/5xx response will parse error JSON as if it were valid preference data, and the caller gets a misleading { data: ... } wrapper. At minimum, check resp.ok and throw or return null on failure.

  • Low — _approval_mode is now dead code (aether_wechat_agent.py): It unconditionally returns "ask" and is no longer called anywhere meaningful — the actual approval check in _auto_approve was rewritten to use the preference API directly. Consider removing it to avoid confusion.

  • Low — addPreferenceMethods bypasses SDK middleware (packages/app/src/utils/server.ts): These methods use raw fetch with manually constructed Authorization headers, duplicating auth logic from createSdkForServer. This is fragile — any future change to the auth flow (e.g., token refresh, header format) must be updated in two places. Consider routing through the SDK client or at least extracting a shared header builder.

  • Low — Race potential in desktop preference sync (packages/app/src/context/local.tsx): syncPreferenceToServer fires on every setSaved call and the SSE listener writes back into saved on every session.preference.changed event. With a rapid sequence of local changes and server echoes, there's a feedback loop risk: a local write -> server sync -> SSE echo -> re-set into saved. The .catch(() => {}) on both sides silently swallows errors, making this hard to debug if it manifests. Consider adding a guard (e.g., comparing current state before writing back from SSE) to break potential echo loops.

@code-JDS code-JDS merged commit bd9c9b2 into Science-Discovery:dev Apr 11, 2026
6 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Sync session preferences and approval state across desktop, Feishu, and WeChat

3 participants