1437 Commits
Author SHA1 Message Date
yiqi-017 8ea039724f feat(desktop): thin-shell over external core via GA_ROOT (方案三)
Run the bundle's own bridge + frontend but drive an external GenericAgent
核 injected via GA_ROOT, instead of swapping to the external bridge or
copying files into 本体. New UI + external核/data, no mutation, logs
naturally unified with the核's other frontends.

- desktop_bridge.py: find_default_ga_root() honors --ga-root / GA_ROOT
  (validated), else derives as before; conductor now spawned from the
  BUNDLE (APP_DIR/conductor.py) with GA_ROOT in env; scheduler stays核-side
- conductor.py: ROOT prefers GA_ROOT env, else own-path derivation
- lib.rs: override no longer changes project_dir (always bundle bridge);
  sanitize_bundle_env injects GA_ROOT; takeover compares effective ga_root;
  set_ga_source drops file-copy sync and instead runs a contract probe
  before committing; removed copy_dir_all/sync_desktop_files
- ga_contract_probe.py (new): subprocess, introspect-only (no GenericAgent
  instantiation) symbol/signature check of the核's bridge/conductor/
  cost_tracker contract; doubles as a dependency check
- GA桌面壳-参考方案.md: plan + feasibility review + probe checklist
2026-07-10 09:53:21 +08:00
yiqi-017 17b87f1c6a Merge origin/main into main 2026-07-09 22:49:05 +08:00
yiqi-017 377e437d85 Merge branch 'yiqi_source_sync' into main
On connect-to-source, push the shell's own (new) desktop files into the
本体 (backing up its originals) before restarting the bridge, so it
serves the new frontend + bridge while keeping the 本体 agent/data.
2026-07-09 22:45:43 +08:00
Liang Jiaqing a195bdc101 Handle Claude refusal without retry 2026-07-09 13:45:43 +08:00
dd3xp ea4bf591cb docs: mention Windows Defender loopback issue 2026-07-08 00:47:24 -04:00
yiqi-017 da5fbef965 feat(desktop): sync shell desktop files into 本体 on connect
When connecting to a separate GA source (design A), the bridge and the
served frontend come from that 本体 — so an older 本体 showed an old
desktop UI. set_ga_source now pushes this shell's own (new) desktop
files into the 本体 before restarting the bridge, so it serves the new
UI + bridge while keeping the 本体 agent/data.

- copy_dir_all + sync_desktop_files: back up 本体 originals into
  temp/desktop_sync_backup_<ts>/, then copy the shell version over
- synced set: frontends/desktop/static/, desktop_bridge.py,
  plan_state.py, cost_tracker.py (NOT src-tauri / build artifacts)
- skipped when the source is the shell's own code location (dev tree)
2026-07-08 00:55:09 +08:00
dd3xp dd174cfd01 Merge origin/main into main 2026-07-07 10:37:48 -04:00
bcda218cda chore: update WeChat group QR code (#670)
Replace the existing GenericAgent experience group QR image with the latest version while keeping the same filename and README reference intact.

Co-authored-by: Shen Hao <shenhao-stu@users.noreply.github.com>
Co-authored-by: GenericAgent <bot@gaagent.ai>
2026-07-07 20:56:59 +08:00
yanghang 40efb4412d fix(desktop): statically link MSVC CRT into the Windows exe
GenericAgent.exe linked the Universal CRT dynamically, so on stripped/older
Windows images the shell itself could fail to load before the (already
UCRT-bundled) embedded python ever ran. Enable +crt-static via a
target-scoped .cargo/config.toml — macOS/Linux builds never read the
x86_64-pc-windows-msvc section. Verified locally: built exe imports no
api-ms-win-crt-*/vcruntime140/ucrtbase (kernel32 control present).
2026-07-07 20:00:53 +08:00
yanghang 86615d4f1e fix(desktop): capture installer stderr/stdout tail in prepare errors
run_offline_prepare discarded the script's stderr (Stdio::null) and only
parsed stdout for progress markers, so a failed install surfaced nothing
but 'prepare exited with status Some(N)'. Pipe stderr (drained on a helper
thread to avoid pipe-buffer deadlock), keep the last 40 lines of each
stream, and append them to the error shown in the setup window and written
to prepare_error.log — the actual pip failure is now visible.
2026-07-07 19:47:29 +08:00
yanghang f34cbe633a Merge fix/desktop-i18n-prepare-error-ucrt into main
- restore corrupted zh i18n (loading/setup blocks)
- surface first-run prepare errors in the setup window + prepare_error.log
- bundle app-local UCRT in the Windows portable package
- restore memory/import rpc case lost in merge 8bb91aa
2026-07-07 19:29:06 +08:00
yanghang 66843bef44 chore(desktop): bump app.js cache version for memory/import rpc fix 2026-07-07 19:00:52 +08:00
Liang Jiaqing 15853775c9 Add model extra system prompt config support 2026-07-07 18:52:35 +08:00
yanghang 716b22f97e fix(desktop): restore memory/import rpc case lost in merge 8bb91aa
The 8bb91aa merge (RoundSquisheen UI rewrite x main) resolved app.js by
dropping exactly one rpc dispatcher case — 'memory/import' — while keeping
the importMemory caller and the settings button. Result: clicking import
always threw 'Unknown RPC method: memory/import'. Re-add the case; the
bridge endpoint (POST /memory/import) was never lost.
2026-07-07 18:45:01 +08:00
abraxas914 79366ea6fb Merge pull request #21 from abraxas914/fix/conductor-error-feedback
fix(conductor): push error to frontend on LLM failure
2026-07-07 16:48:47 +08:00
abraxas914 3219fc1806 fix(conductor): push error chat to frontend when LLM call fails
When all LLM nodes timeout/fail, the conductor's except block only
printed to stdout — users saw their message disappear with no feedback.
Now broadcasts a role="error" chat item via the existing WebSocket
pipeline so the frontend renders a red error bubble inline.
2026-07-07 16:46:03 +08:00
yanghang 4799271943 fix(desktop): restore corrupted zh i18n, surface prepare errors, bundle UCRT
- i18n.js: the zh block (loading.*/setup.*) shipped with every Chinese
  character mangled into literal '?' (a non-UTF-8 save when the file was
  first added in 1bcb41d). Restore all 22 keys from the intact en block.
- Surface first-run prepare failures instead of silently opening the setup
  window: store the error, expose it via get_prepare_error, show it in
  fallback.html, and write runtime/prepare_error.log.
- Windows CI: deploy app-local UCRT (api-ms-win-crt-*.dll + ucrtbase.dll
  from the SDK redist) next to the embedded python so python.exe loads on
  images lacking an in-box Universal CRT. Pure SDK source, hard-fail if absent.
2026-07-07 15:28:30 +08:00
nianyucatfish 14d8df3ddd feat(worldline): persistent checkpoint-tree rewind for tui_v2 (/rewind + /worldline) (#667)
* feat(worldline): integrate checkpoint-tree rewind into tui_v2

- tuiapp_v2.py: /rewind durable inline picker + /worldline three-pane
  checkpoint tree (tree UI inlined; colors follow the v2 theme) with a
  per-node diff viewport; conv-only /rewind restores via the persistent store.
- worldline.py (new): UI-agnostic backend — RewindStore (persistent
  checkpoint tree + content-addressed blobs), reconcile, restore_plan,
  node_diff, native-log projection.
- continue_cmd.py: gated worldline support — list_sessions(rewind_root=),
  continue_inplace/copy(allow_empty=); default-off, other UIs byte-identical.
- tui_v3.py: status line shows concrete model id (unrelated minor tweak).

* feat(worldline): /rewind reuses the restore-mode picker (conv/code/both)

After picking a turn, /rewind now opens the same RestoreModeScreen as
/worldline to choose conversation / code / both, then restores via the
persistent store — making /rewind a true lite view of /worldline (linear
list, no tree/diff) over the identical restore backend.

* feat(worldline): sync working memory (history_info/key_info) on rewind

树节点除 conv 外,再存 history_info 增量(与 conv 同构)+ key_info 快照。
restore_plan 重建二者,_rw_sync_working_memory 在 rewind 时就地写回
handler.history_info / working['key_info'],使注入的 WORKING MEMORY 与
回退后的对话一致,消除旧 rewind「历史回退、纪要串味」缺陷。

向后兼容:老树无 WM 记录 → path_has_wm=False → 恢复时跳过 WM 同步,
不动现场纪要。单测 21/21 + 真机(363580)端到端验证(call_013→014
v2 痕迹 ×3→×0)通过。

* fix(worldline): reconcile against the log, only on /continue; rebuild working memory on absorb

- reconcile now takes the log-parsed full history, never the compressed
  backend.history. Compressed memory is a lossy derivative; reconciling the
  full tree against it made the tree adopt a front-trimmed suffix as a new
  trunk (false divergence). Contract pinned in the docstring.
- drop in-session reconcile from /rewind and /worldline: the tree is kept
  current every turn by _rw_commit, and live history there is compressed.
  reconcile now runs only on /continue, where backend.history is the freshly
  loaded full log.
- reconcile rebuilds history_info/key_info from the absorbed log so resumed
  and external-UI sessions also carry working memory on rewind.

* fix(worldline): feed commit the full log; derive deltas from the tree's real length

_rw_commit fed the compressed backend.history, so once a long session front-trims,
commit's absolute hist_len delta drops turns. Now:
- _rw_commit feeds the log-parsed full history (fallback to backend.history).
- commit derives the delta start from len(rebuild_history(parent)) /
  len(rebuild_hist_info(parent)) instead of the stored hist_len, so a poisoned
  count can't drop turns and a previously-lost turn self-heals on the next commit
  (the log is append-only, always a superset of the tree).

* chore(worldline): mark in-memory _do_rewind as the non-persistent degraded fallback

It chops the compressed live history (can't reach front-trimmed turns, keeps
truncated remnants, restores neither files nor working memory). Only used when
there is no checkpoint tree; the durable tree-rebuild path is always preferred.

* fix(worldline): derive tree working memory from the log, not live handler state

/continue resets agent.history (handler.history_info) to empty. _rw_commit
previously fed that live list as hist_info, so after a continue the per-turn WM
delta misaligned with the tree's log-derived WM and new turns' summaries were
dropped. commit now derives hist_info/key_info from the history it stores (the
full log) when not given, matching reconcile; _rw_commit stops passing the live
list. Tree WM is uniformly log-derived and survives the continue reset.

* feat(worldline): restore working memory on /continue (TUI-only, derived from the log)

continue_cmd clears handler.history_info on restore; the TUI's continue path now
derives history_info from the loaded log (same _derive_hist_info as the tree) and
writes it back to agent.history, so a continued session keeps its working memory,
consistent with the tree and live sessions. Scoped to tuiapp_v2 only — shared
continue_cmd is untouched, so telegram/discord/streamlit frontends are unaffected.

* refactor(continue): restore working memory on /continue via opt-in restore_wm

Move the WM restore from the TUI into continue_cmd as an opt-in. _load_history_into
derives history_info from the loaded log and writes it back to agent.history when
restore_wm=True; continue_inplace/continue_copy thread the flag and the worldline
TUI passes True. Default False keeps every other frontend (telegram/discord/
streamlit/shared chat) byte-for-byte unchanged. _derive_hist_info is self-contained
(no worldline dependency), same extraction口径 as the tree.

* perf(worldline): only re-parse the log in _rw_commit when front-trim is detected

_rw_commit re-parsed the whole log every segment to feed commit a full history;
for very long sessions (multi-MB logs) that adds a multi-second lag per turn. Now
it uses the fast in-memory backend.history by default and only falls back to
parsing the log when front-trim is detected — RewindStore.first_question() vs the
live history's first question (front-trim pops the first question, so they diverge).
Common case (no trim) pays nothing; correctness under trim is preserved.

* feat(worldline): conv/code bridge nodes + align _rw_commit to native log

- worldline: commit_bridge() + restore_plan() three-way (both/conv/code) with a new rw_tag field. conv bridges fork at parent(target); code bridges mount at parent(old_head) as a sibling of the current conversation node (same conversation, older code).

- tuiapp_v2: _rw_commit now reads the native log (parse_native_log) instead of the compressible live backend.history; stat-cached _rw_log_history; title from the real log delta; skip commit when there is no new complete pair. Cursor points at the bridge for conv/code; rw_tag rendered after the title.

- continue_cmd: add parse_native_log() public wrapper (complete Prompt->Response pairs only; [] for native-but-empty, None for non-native).

* fix(worldline): realpath 去重 key + 节点行数增删 + 剥离 project-mode

- key()/cwd 改用 realpath 解析 junction/symlink,同一物理文件只产生一个 tracked
  key(修 workspace 下 @提及绝对路径与相对写入产生双 key、回退误覆写当前内容)
- 新增 node_line_delta:按 node_diff 计每节点相对父节点的 +新增/-删除 行数,
  供 /rewind、worldline 显示代码变动量
- 重建历史时剥离 project-mode 注入块与自动注入标记(worldline._msg_user_text +
  continue_cmd._derive_hist_info),标题/提问只留用户原话

* feat(worldline/rewind): 面板与 rewind UI 精简重设计

worldline 面板:
- 右栏改用原生 OptionList(整项高亮/滑窗跟踪/点击映射,取代手写 ClickableList)
- 左右栏比例 3:2;详情面板精简(删掉与状态条/diff 重复的操作提示、时间、回退说明)
- 状态条重写为完整动宾短语,Enter 随聚焦切文案;右栏聚焦高亮改用更亮的 alt_bg
  (对齐左树,修此前聚焦态反而更淡的问题)

/rewind:
- 三列:用户 prompt · 上次时间 · 代码 +新增/-删除(绿/红,无改动显示「(无改动)」);
  倒序、聚焦底部、超长 prompt 省略号截断
- 延迟折叠(defer_collapse):选中先弹模式窗,确认才回退并清卡片;Esc 取消保留列表、
  焦点回到列表,不再留误导性「✓ 已选中」

其他:
- Ctrl+D 关会话时释放日志锁(abort + release_current),之后可原地 /continue

* fix(worldline): 回填输入框的 prefill 剥离 project-mode 注入

restore_plan 的 prefill/_prompt_of 走未清洗的 user_msg_text(树里的 user 消息取自
含注入的 native 日志),把 --- [PROJECT MODE:...] --- 一起塞进输入框。统一过
_strip_project_mode(幂等)。回归:temp/test_rewind_prefill_no_projectmode.py 9/9。

* refactor(tui): 删除被取代的旧 rewind 面板与死代码

- 删旧 /rewind 整簇:RewindScreen 类 + _on_rewind_pick + _rw_* 9 个 helper
  (已被内联 choice 卡 + RestoreModeScreen / RewindTreeScreen 取代,无 live 入口)
- 删未用 import next_same_depth/CheckpointTree、只写不读的 _diff_for/assistant_len
- 净 -276 行;import tuiapp_v2 通过、worldline 回归全绿

* fix(worldline): apply_code 回退失败不再静默,回传错误由 UI 提示

apply_code 直接写用户工作区文件,中途失败(权限/磁盘)会留下半回退状态。原先
restore_plan 吞成 changed=[],UI 显示「无变更」,用户毫不知情——全 PR 里失败半径
最大却唯一被静默的点。改为 _apply_code_safe 回传 (changed, code_error),
_rw_restore_node 据此追加「⚠️ 代码回退未完成…请检查」告警。
2026-07-07 08:36:28 +08:00
dd3xp 8325595ad7 merge main into RoundSquisheen 2026-07-06 11:14:32 -04:00
dd3xp c727ca34ca fix(desktop): refine chat ui and persistence 2026-07-06 10:53:40 -04:00
yiqi-017 a5c184c232 Merge branch 'yiqi_sessions_perf' into main
Fix desktop session-store scaling: store each session as its own
temp/desktop_sessions/<id>.json instead of one monolithic
desktop_sessions.json rewritten on every message. Write cost is now
O(one session) regardless of session count. Auto-migrates the legacy
file on first load; import reads both formats.
2026-07-06 14:35:26 +08:00
yiqi-017 bdd5309607 perf(desktop): store sessions one file each, not one monolithic JSON
Every message called _persist(), which rewrote the ENTIRE
desktop_sessions.json (all sessions, full messages + llm_history) under
the lock. Write cost was O(all sessions), so performance degraded badly
as sessions piled up.

Now each session is its own temp/desktop_sessions/<id>.json:
- _persist_session(s): atomic per-session write, O(one session)
- _delete_session_file(sid): remove on delete
- add_message / create / plan-bind / set_model / patch now write only
  the touched session; write cost no longer scales with session count
- _load_sessions reads the dir; one-time migration from the legacy
  monolithic file, which is then renamed to .json.migrated
- import_sessions reads both source formats (per-file dir + legacy),
  persists only newly added sessions
2026-07-06 14:05:31 +08:00
yiqi-017 157f4fec77 Merge branch 'yiqi_install' into main
Add "connect to a separate GenericAgent source" (thin-shell / design A):
a Settings option that points the packaged desktop app at a standalone
本体 checkout, so its bridge, agent code, memory and sessions all come
from that source. Invalid/missing override safely falls back to the
bundled runtime.
2026-07-06 02:54:17 +08:00
yiqi-017 300fe4ae34 feat(desktop): connect to a separate GA source (thin-shell / design A)
Adds a "GA source directory" setting so the packaged desktop app can run
against a standalone GenericAgent checkout instead of its own bundled
runtime/app — memory, sessions, model_responses and the agent code all
come from that 本体, live-shared with other frontends.

- lib.rs: ga_source_override settings key honored in get_or_discover_config
  BEFORE the bundle default; validated (agentmain.py + desktop_bridge.py),
  invalid/missing override falls back to the bundle (本体-moved safety net)
- set_ga_source / clear_ga_source / get_ga_source commands: write setting,
  stop current bridge, respawn from resolved config, reload webview
- startup uses the override-aware config for takeover + spawn
- ACL grants for the three new commands
- Settings > Features UI: pick source dir, show current, clear; zh/en i18n
2026-07-06 02:20:48 +08:00
yiqi-017 44f3706ddc Merge branch 'yiqi_memory' into main
Add import-memory feature to the desktop app: import memory/,
model_responses/ and desktop_sessions.json from an existing GenericAgent
install so past memory and sessions carry over to the standalone desktop.
2026-07-06 01:36:15 +08:00
yiqi-017 4798e72f3f fix(desktop): render sidebar after importing sessions
loadSessions() only refreshes the data model; the sidebar DOM is drawn by
renderSessionList(). Imported sessions therefore only appeared after the
next render (e.g. sending a message). Call renderSessionList() right after.
2026-07-06 01:13:29 +08:00
yiqi-017 aff6560440 feat(desktop): merge desktop_sessions.json on memory import
Import now also merges the source's temp/desktop_sessions.json into the
current session list (dedup by id), updating both memory and the on-disk
file so past desktop chats reappear in the sidebar immediately.

- manager.import_sessions(): id-dedup merge, in-memory + persist
- import handler returns sessionsAdded/sessionsSkipped
- frontend shows session count in toast and reloads the sidebar
2026-07-06 00:48:15 +08:00
yiqi-017 ec44d69bfe feat(desktop): clarify import-memory targets the GA root dir
- button label now says "select GenericAgent root"
- pick_directory accepts a title; native dialog shows the hint
- browser-fallback prompt clarifies root dir vs memory folder
2026-07-05 23:46:19 +08:00
yiqi-017 4cda8cadb7 fix(desktop): allow pick_directory command in ACL
The import-memory button failed with "Command pick_directory not allowed
by ACL" because Tauri v2 requires custom commands to be granted in the
capability. Add allow-pick-directory permission and grant it.
2026-07-05 22:55:10 +08:00
yiqi-017 74275f8980 feat(desktop): add import-memory feature in settings
Lets users import memory/ and temp/model_responses/ from an existing
GenericAgent install into the desktop app's ga_root, so past sessions
and memory are not lost when running the standalone desktop bundle.

- bridge: POST /memory/import copies memory (backup-then-overwrite) and
  model_responses (fill-missing), returns counts + backup dir
- tauri: pick_directory command (rfd native folder picker)
- frontend: "Import memory" button in Settings > Features + zh/en i18n
2026-07-05 22:28:17 +08:00
dd3xp 4d4c220152 Clarify desktop plan collapse labels 2026-07-05 05:43:37 -04:00
dd3xp 158aeabfa4 Align desktop plan mode activation with TUI 2026-07-05 05:14:52 -04:00
dd3xp 54e8d46603 Fix desktop session rename editing 2026-07-04 22:35:22 -04:00
Liang Jiaqing 91b5a14312 simplify mykey_template: remove non-native & antigravity configs, merge GLM/Kimi/MiniMax into vendor tables 2026-07-02 20:26:27 +08:00
dd3xp d205cd023e merge: bring test desktop packaging and model fixes into main 2026-07-02 18:40:02 +08:00
Liang Jiaqing 94d1e2e907 Add background ljqCtrl tool and GUI SOP guardrails 2026-06-30 18:33:52 +08:00
Liang Jiaqing b636a8df61 Refine UltraPlan orchestration workflow 2026-06-30 17:22:16 +08:00
Kailigithub 85bae5454f fix(llmcore): suppress intermediate error yield during retry and handle ChunkedEncodingError
When the LLM stream encounters a transient network error (ConnectionError,
Timeout, SSLError, ProxyError), the retry path yielded the error string
back to the caller on every attempt. This caused the UI to display a wall
of '!!!Error: ProxyError!!!Error: ConnectionError!!!Error: SSLError'
strings during a network blip, even when the retry ultimately succeeded.

Match the existing HTTP retry path (which sleeps without yielding) by
removing the intermediate yield so the caller only sees the final error
if retries are exhausted. Retry attempts remain visible via the existing
'[LLM Retry] ...' stdout log.

Also extend the exception tuple to include ChunkedEncodingError. Without
it, a truncated chunked response falls through to the bare 'except
Exception' branch and aborts the stream with no retry, even though the
transport-level error is transient and recoverable.

Closes #571
2026-06-29 03:06:54 +08:00
Liang Jiaqing 7ed13c009d fix(ga): turn_end summary fallback prefers cleaned response body (_c) over args dict 2026-06-28 22:24:52 +08:00
Liang Jiaqing 6c775def61 fix httpapp output auth and update ultraplan docs 2026-06-28 19:17:02 +08:00
Liang Jiaqing 1e4ca151a7 feat: support --history arg and in-memory intervene/keyinfo injection; add export_history; fix GenericAgent typo 2026-06-27 17:10:33 +08:00
Liang Jiaqing 84d5bf9291 Update loop controller and service discovery 2026-06-27 14:57:10 +08:00
yanghang 60dcf52e86 ci(desktop): bump upload-artifact v5 -> v7 (node24)
upload-artifact@v5 still targets node20; v6+ moved to node24. v7 is the
latest. This clears the last remaining Node.js 20 deprecation warning.
2026-06-26 20:39:43 +08:00
yanghang dc71a110ee ci(desktop): bump checkout/setup-node/upload-artifact to v5
Clears the Node.js 20 deprecation warnings on the desktop packaging
workflow. No download-artifact in use, so upload-artifact v5 has no
version-mismatch counterpart; release path uses gh CLI.
2026-06-26 20:34:34 +08:00
yanghang c471036839 refactor(desktop): move desktop_release/ → frontends/desktop/packaging/
Co-locate desktop packaging scripts with the Tauri app, declutter repo
root. Drop legacy manual-install flow (install.bat/start_windows.bat/
README_WINDOWS.md) and unused apps/ placeholder tree. Update CI workflow
paths and TODO references accordingly.
2026-06-26 20:12:46 +08:00
Liang Jiaqing 03fe8a618c fix: limit parallel max_workers to 3 2026-06-26 19:02:03 +08:00
Liang Jiaqing f573b8f397 add ga_httpapp, update ga_ultraplan, whitelist ultraplan_sop 2026-06-26 18:01:00 +08:00
yanghang c0e90263c4 fix(desktop): conductor reloads mykey per-task even with no bound model
_apply_desktop_model is called before every conductor task to make the agent
reflect the current desktop config. But the mykey reload only happened as a
side effect of next_llm(), which was gated on a bound model index (no != None).
On a fresh install nothing is selected (conductor.llmNo and ui.llmNo both null),
so no == None, next_llm was never called, and a conductor that started on the
empty template never picked up imported keys — the next message crashed on the
stale empty mixin ('dict' object has no attribute 'backend').

Add the no-bound-model branch: call agent.load_llm_sessions() (mtime-guarded,
rebuilds only when mykey actually changed) so a live conductor reflects imported
keys on its next task without any restart or task interruption.
2026-06-26 17:24:14 +08:00
yanghang 1e6f370cfd fix(desktop): restart conductor/scheduler only when actually broken after mykey import
conductor and scheduler are separate subprocesses that read mykey once at
startup. After a mykey rewrite (import keys / edit channel config), a healthy
running conductor already hot-reloads mykey on its next task via its own mtime
check, so it needs no restart — restarting it would only interrupt an in-flight
task.

So restart an extra only when it is genuinely broken: the process exited
unexpectedly (covers scheduler dying on a bad config), or the process is alive
but its "Exception in thread conductor-agent" crash signature is in the captured
log (uvicorn still up but the agent thread is dead and can no longer process
tasks). A fresh log buffer per start means the signature only reflects the
current process. Bridge-only; conductor core and agentmain untouched.
2026-06-26 16:18:21 +08:00
Liang Jiaqing 5de55ea872 feat(ultraplan): add phase/parallel/pipeline orchestrator with phase-tree HTML monitor
- assets/ga_ultraplan.py: 3 primitives (phase/parallel/pipeline), file-first
  message passing, runtime f-string prompt fill, subagent via subprocess,
  nested phase tree + random-port auto-popup HTML panel (1h idle self-destruct)
- agentmain.py: --nolog flag
- llmcore.py: honor log suppression
2026-06-26 15:16:11 +08:00