Files
GenericAgent/frontends
dd3xp e5b80d1003 feat(desktop): preset/composer/topbar restructure + conductor persistence + TUI-style session naming
UI restructure (frontend static):
- PLAN moved from sticky toggle chip to a preset card (BUILTIN_PRESETS) that
  one-shot-sends `presetPrompt.plan`, now pointing at the real
  memory/plan_sop.md (Auto was considered too but dropped — it semantically
  overlaps with the existing "自主探索" preset). All plan/auto toggle
  plumbing removed: state, chip listeners, applyToggleClass, ga_plan/ga_auto
  localStorage, planPrefix/autoPrefix injection.
- Chat composer: model chip moved out of the joined .cb-left pill group to
  sit next to the send button (composer-bot is now right-aligned model+send).
- Conductor composer: gained its own #collab-model-chip + #collab-model-menu;
  openModelMenu/renderModelMenu/updateModelChip refactored to be ctx-aware
  (both chips share the model list; each pops its menu into its own
  composer; updateModelChip syncs both names).
- Topbar dissolved into per-page headers: the global .topbar was removed
  from <main>; the run-state moved into a .page-top inside the chat page,
  so the "topbar" now switches with the page instead of persisting.
- Removed the conductor "{n} 个任务进行中" sticky banner (#collab-sticky);
  the same info is already in the progress panel and the sidebar badge.

Conductor persistence (conductor.py + frontend wiring):
- conductor.py: add_chat() carries files/images on each chat item; WS
  receive passes data.files/data.images through; hello includes a
  running flag (any subagent with status="running"). 5 net edits.
- app.js: ws.send now posts {msg, files, images} (was msg only); onWsData
  hello/chat branches map files/images and set S.conductorTyping from
  data.running so attachments + run animation survive a page refresh.

Session naming (mirror TUI continue_cmd._preview_text):
- New helper displayTitle(sess): if user manually renamed, use sess.title;
  otherwise scan messages — prefer the last <summary>…</summary> in any
  assistant reply, fall back to the first user message text (≤40 chars,
  attachment placeholders stripped), final fallback t('conv.defaultTitle').
- newSession() now defaults sess.title to '' instead of '新对话'; the
  earlier "first message → title" auto-rename block in submitInput is
  gone — titles only get written when the user renames explicitly.
- isAutoTitle() recognises '新对话'/'New chat'/'agent-N' as placeholder so
  legacy sessions and the brief agent-N experiment get re-derived live
  in the sidebar without losing user renames.
- Sidebar render + search filter now go through displayTitle.

Note: requires a one-time restart of conductor.py for its part to take
effect; the static frontend changes are just a refresh.
2026-05-29 02:22:16 +08:00
..