fix(tui_v3): deps, CPR warning, free-text ask_user, and NameError fixes#661
Open
dracpet wants to merge 789 commits into
Open
fix(tui_v3): deps, CPR warning, free-text ask_user, and NameError fixes#661dracpet wants to merge 789 commits into
dracpet wants to merge 789 commits into
Conversation
…done_prompt shutdown mechanism
…sdefine#398) When setup window starts the bridge, the main window was already created with URL http://127.0.0.1:14168/ but failed to load (bridge not running yet). After bridge becomes ready, we now navigate the main window to reload the bridge URL before showing it, preventing the white screen issue.
…lsdefine#342) (lsdefine#414) When a single LLM provider goes down mid-task (auth, network, quota, etc.), the conductor falls completely silent: MixinSession yields errors as text chunks (not Python exceptions), so the existing try/except guard in conductor_loop never triggers, and the conductor's only way to talk to the user (LLM-decided POST /chat tool call) is dead. Add a tiny watchdog: monitor_conductor_queue now returns the conductor agent's final done text, and conductor_loop scans the tail-1000-char window for "!!!Error:" — the prefix llmcore uses for unrecoverable errors. Tail window (not whole text) avoids false positives from earlier turns; using a character window (not last-line) matches ga.do_no_tool's content[-100:] style and tolerates the decoration (fence + "[Info] Final response to user.") that do_no_tool appends after the error chunk when its own short window check misses. When detected, push the matched error line as a system chat message so the user knows what happened. A dedup check prevents repeated warnings if multiple events fail in succession. +16 -4 lines. Only frontends/conductor.py touched. No agent_loop / llmcore changes; other frontends unaffected.
Co-authored-by: GA Agent <ga-agent@users.noreply.github.com>
Eight independent fixes accumulated since the last batch, all landing in tuiapp_v2.py: 1. Code-block selection offset: _align_md_renders's is_centered heuristic tripped on any code line indented >=4 spaces (Python's default), stripping the indent from the source string so the visible selection and the copied text disagreed. Add wide_lead >= 2*nt0_lead guard — only Rich's H1 centering (wide_lead ~ width/2) crosses it, code lines never do. 2. Blockquote-continuation selection offset: Rich re-emits `▌ ` on every wrapped visual line of a quote, but the wide-render carries the marker only once. Strip the marker as a decoration prefix (counts as indent, not content) and switch the wrap-accumulator to account for the per-break eaten space — both pre-existing code-block wraps and blockquotes now map correctly. 3. Streaming ANSI garbage: while a turn is streaming, the tail text segment was rendered with `Text(content, style=C_FG)` instead of `Text.from_ansi`. SGR codes from the model/tool output would render as literal `[31m` glyphs and only resolve after `m.done` flipped or a resize forced a remount via the Markdown path. Switch the two streaming fast paths to Text.from_ansi — O(n) scan, no Markdown parse, colors honored live. 4. continue picker LIMIT removed: tuiapp's own `LIMIT = 20` truncated the /continue picker even though list_sessions() always builds the full list. Show everything; header now reads "选择要恢复的会话 (N 条)". 5. Long-paste rescue + user echo elision: Windows Terminal yanks window focus when its >=5KiB paste-warning dialog pops, leaving focused=None after the user confirms; Textual then routes the Paste event to the App bubble instead of InputArea, and the paste appears to do nothing. Add a GenericAgentTUI._on_paste forwarder that refocuses #input and replays the event into InputArea._on_paste. Separately, on submit, elide user-side display of very long pastes (head 10 / tail 5 / `⋯ 省略 N 行 ⋯`); the agent still receives the full content via expand_placeholders. 6. mykey.py hot reload: load_llm_sessions() already had mtime-gated reload plumbing, but it only ran on Agent.__init__ / next_llm / list_llms — so editing mykey.py mid-session required restart. Two triggers added: on_input_area_submitted now calls load_llm_sessions() before sending (cheap mtime check; rebuilds on change), and a new /reload-keys command forces a sweep across every session (resetting llmcore._mykey_mtime per-iteration so the cache doesn't short-circuit later sessions). 7. Resize / sidebar toggle no longer jumps to bottom: _remount_current_session used to unconditionally scroll_end after rebuilding. Capture scroll_y + "was at bottom?" first; stick to bottom only if the user was already there, otherwise restore the prior scroll_y so resizes don't yank the user away from what they were reading. 8. Markdown table cells wrap instead of ellipsizing: Rich's Markdown TableElement passes no `overflow` to Table.add_column, so the default "ellipsis" hides long cell content with `…` on narrow widths. Patch TableElement.__rich_console__ on import to pass overflow="fold".
…auth-396-416 fix: 微信 /stop 中止检测 + AuthExpired 处理 + 配置向导改进
…nline-selection [codex] feat(tg): add inline selection menus
Replace _history_lines (pre-rendered) with _blocks (source + kind) so _repaint_screen can re-render every chip, banner, user panel at the current width. \x1b[3J wipes scrollback on resize/Ctrl+L so the entire conversation reflows, not just the visible viewport. SIGWINCH delivery via self-pipe + select() — PEP 475 auto-retry on os.read makes signal-driven InterruptedError unreliable under iTerm split panes, so a dedicated pipe wakes the loop deterministically. Streaming tracks a single _streaming_block whose source grows monotonically through safe-position commits; mid-stream resize re-renders both the committed source and the volatile live_tail. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
macOS Terminal.app quantises truecolor to its nearest 256 slot (so #5e6ad2 lavender lands on slot 62 #5f5fd7, visibly more blue) and renders \x1b[2m as a heavy multiply instead of a gentle blend, producing the "blue border + heavy shadow" against iTerm's identical code. Branch on TERM_PROGRAM: iTerm keeps its truecolor accent and \x1b[2m dim; Apple_Terminal switches to pinned 256-slot accent (105) and an explicit mid-gray (244) for dim. Box border (146) was already 256-slot so it carries unchanged. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
…rface-v2 feat: 更新飞书接口
feat(tui): scrollback-first TUI rewrite (tui_sb)
* 加入高危命令黑名单 Add high-risk command blacklist * GenericAgent Agent System Design Overview * Subagent 集群监控,Subagents Monitor * remove desing overview html * skill_learn_from_cases — 案例驱动技能学习 CLI 工具 * skill_learn_from_cases — 案例驱动技能学习 CLI 工具 v001 * skill_learn_from_cases — 案例驱动技能学习 CLI 工具 v002 * skill_learn_from_cases — 案例驱动技能学习 CLI 工具 v003 * skill_learn_from_cases — 案例驱动技能学习 CLI 工具 v005 * skill_learn_from_cases 案例驱动技能学习 CLI 工具 v006 * skill_learn_from_cases 案例驱动技能学习 CLI 工具 v007 * skill\_learn\_from\_cases 案例驱动技能学习 CLI 工具 v008 * skill_learn_from_cases 案例驱动技能学习 CLI 工具 v009 * skill_learn_from_cases v010 * skill_learn_from_cases v 011 * earn_skill_from_cases v000 * fix:[开始空闲自主行动]按钮点击无反应 * 修复点击[开始空闲自主行动]按钮,无反应问题 * clean fork 0515 * clean051502 * 自主行动相关按钮修复 * learn_skill_from_cases v000 * cleaned again --------- Co-authored-by: benechen <13817895035@126.com>
原链接 installation.zh.md 路径不正确,已更正为 docs/installation.md
docs: 修复安装文档中的链接路径
…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
…; add export_history; fix GenericAgent typo
…le 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 lsdefine#571
…ge GLM/Kimi/MiniMax into vendor tables
context_chars_used doesn't exist in cost_tracker → AttributeError silently caught → always falls back to 'n/a'. Also cap*3 double- multiplies since context_window_chars already returns ctx_win*3. Co-Authored-By: GenericAgent <bot@gaagent.ai>
…play context_window_chars() was returning context_win * 3 (the internal trim trigger) instead of the actual model context window. This made /cost and /status show 3M instead of 1M for deepseek/mimo. Also: - Update _cost_str docstring in tui_v3.py - Set deepseek default_context_win to 1M in llmcore.py - Add context_win/max_tokens for deepseek (384k) and mimo (128k) in configure_mykey.py template The trim trigger *3 in llmcore.py:99 (trim_messages_history) remains unchanged — it's the internal buffer before trimming kicks in. Co-Authored-By: GenericAgent <bot@gaagent.ai>
These packages are required by tui_v3.py at startup but were listed only under optional [ui] extras. Users running (the recommended install path) would hit ImportError for rich, then for prompt_toolkit, before the TUI could start. Co-Authored-By: GenericAgent <bot@gaagent.ai>
tui_v3.py redirects sys.stdout to a log file before creating the prompt_toolkit Application. The stdout redirect disrupts prompt_toolkit's CPR (cursor position report) probe — the DSR escape sequence is written to the terminal fd, but the response either fails to arrive or is not dispatched correctly, causing a 2-second timeout and a loud warning. Disable CPR probing unconditionally. GA's scrollback-first layout uses dont_extend_height=True, no floats, and no mouse support — none of the prompt_toolkit features that consume CPR data are active. Co-Authored-By: GenericAgent <bot@gaagent.ai>
- Promote rich>=15.0.0 and prompt-toolkit>=3.0.52 as direct deps - Expand CPR disable comment with terminal compatibility details - Add uv.lock Co-Authored-By: GenericAgent <bot@gaagent.ai>
The previous fix (807ab60) disabled CPR probing entirely to silence a startup warning, but this also breaks _min_available_height tracking in prompt_toolkit's renderer — which is needed for dynamic-height regions like the ask_user picker card. Instead, keep CPR probing enabled (so height tracking works) and just override cpr_not_supported_callback to silence the warning on terminals that don't support cursor position requests. Co-Authored-By: GenericAgent <bot@gaagent.ai>
With CPR probing restored (4e0f985), the free-text ask_card no longer freezes the terminal. Remove the guard that skipped the ask_card when no candidates were supplied, so that free-text ask_user prompts now get a proper interactive input card instead of falling through to the normal input box. Co-Authored-By: GenericAgent <bot@gaagent.ai>
Commit 59370f5 removed the no-candidates guard in _extract_ask_user, allowing free-text ask_user events to reach _ask_card. But _ask_card defined 'multi' inside the 'if ae.candidates:' block while referencing it outside — causing NameError when candidates were empty. Move the multi assignment before the candidates block so it is always in scope. Free-text ask_user (no candidates) now correctly renders the inline input box inside the ask card. Co-Authored-By: GenericAgent <bot@gaagent.ai>
uv.lock was accidentally included; upstream does not track it. Add to .gitignore to prevent future inclusion. Co-Authored-By: GenericAgent <bot@gaagent.ai>
The Application's cpr_not_supported_callback override was not enough — prompt-toolkit's Renderer captures its own copy during __init__ and calls that one when CPR times out. The warning wrote directly to the real terminal fd (via self.output.write()), causing a brief flash before the TUI overwrote it on the next frame. Silence both callbacks (app + renderer) to fully suppress the flash. Co-Authored-By: GenericAgent <bot@gaagent.ai>
…ersion The rotating banner tip told the user to put [multi-select] in an ask_user prompt — something only the agent writes. Replaced both en/zh with user-facing instructions on how to use the multi-choice picker (Space to toggle, Enter to confirm). Co-Authored-By: GenericAgent <bot@gaagent.ai>
…d + /worldline) (lsdefine#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 据此追加「⚠️ 代码回退未完成…请检查」告警。
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>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Changes (stacked on upstream/main)
1. Deps & CPR warning (
f656038,807ab60,6e06490)richandprompt-toolkitto direct dependencies (fixes freshuv sync)cpr_not_supported_callbackinstead of disabling CPR entirely2. Evolved CPR approach (
4e0f985)3. Free-text ask_user support (
59370f5,856226a)ask_usercalls without candidates to render a free-text input cardmultivariable was defined insideif ae.candidates:block but referenced outside — causing crash on any free-text ask_user4. Other fixes
/statuscontext no longer shows "n/a" (7f50db5,4de1941)Closes #659. Co-Authored-By: GenericAgent bot@gaagent.ai