fix(tui v2): normalize first printable-key insert path in InputArea#587
Open
rodboev wants to merge 695 commits into
Open
fix(tui v2): normalize first printable-key insert path in InputArea#587rodboev wants to merge 695 commits into
rodboev wants to merge 695 commits into
Conversation
) * feat: add setup.py -- interactive initialization wizard * fix: address PR lsdefine#295 review — rename to configure.py, improve all feedback - Rename setup.py → configure.py to avoid pip/setuptools conflict - Fix lark exception: catch generic Exception instead of non-existent AppAccessDeniedError/AppExpiredError - Add proxy support to probe_models via HTTPS_PROXY/HTTP_PROXY env vars - Implement masked_input() with real-time API key masking - Add pip install hints for messaging platform dependencies - Add 2 new providers: CRS Gemini Ultra (Antigravity), Kimi/Moonshot OAI - Restructure main menu: LLM only / platform only / or both with cascade prompts - Add Python 3.14 compatibility warning and reconfiguration detection - Fix welcome_message: WeCom only, correct variable name - Show GETTING_STARTED example commands after configuration - Add advanced LLM options: proxy, context_win, stream, user_agent --------- Co-authored-by: guowenjiao54 <guowenjiao54@users.noreply.github.com>
… fix missing summary prompt wording
…sdefine#307) When the model only outputs tool calls with no meaningful text, combined_content may contain only whitespace text blocks (e.g. '\n'). Strict API proxies reject this with HTTP 400 'empty content' error. Filter out such blocks before sending to the API.
…ar Caches on Windows (lsdefine#309)
Co-authored-by: Kailigithub <Kailigithub@users.noreply.github.com>
Mirrors Claude Code's /btw: ask the agent a quick question without interrupting the in-flight main task. - frontends/btw_cmd.py: snapshot backend.history under lock + deepcopy → background-thread backend.raw_ask single-turn answer; never writes backend.history; never touches task_queue. Reuses backend.raw_ask + make_messages, no new LLM instance. - frontends/chatapp_common.py: register /btw in HELP_COMMANDS; handle /btw in AgentChatMixin (sync via asyncio.to_thread); install() at module bottom so the slash hook is wired for any frontend that imports chatapp_common. - frontends/stapp.py: persist display_queue + partial_response in st.session_state so the streaming bubble survives Streamlit reruns; new render_main_stream() helper covers both new tasks and resume; /btw branch uses plain st.rerun() (preserves dq) so the main task's remaining output renders in a follow-up bubble; non-/btw prompts explicitly call agent.abort() to keep the original "submit cancels" UX. Strip <summary> meta tags from text segments and drop dangling "LLM Running (Turn N) ..." markers in resumed partials to clean up the rendered chat. Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…es to non-native paths
Keep Telegram streaming overflow messages tied to the primary live message, reuse them across edits, and delete stale overflow replies when streamed content shrinks.
新增 command/ 包和 ga.cmd/ga 入口脚本,用户可通过 `ga <command>` 启动各前端。
PPT/Word copies include both image/png and text/plain items. Only intercept paste when no text item is present (pure screenshot/image).
新版 TUI 与 tuiapp.py 并存,共享 GenericAgent 调度/队列/线程协议, 重做视觉与交互: - 多行 InputArea:≤3 行自适应、>3 行三行滑动窗口、粘贴占位符 - 命令面板(OptionList + 模糊匹配 + Tab 补全) - /llm、command 选择走 ChoiceList,选完区域收缩 - Markdown HardBreak 渲染 + ANSI 缓存 - 响应式布局(窄屏隐藏侧栏 / 宽屏按比例放大) - selection-aware 自动滚动(选文本时不抢滚动) - 新增 /btw、/continue、/export、/restore 不改 cli / hub / README / tuiapp.py 入口。
* fix(tui): drain exit-boundary intervened replay * refine(tui): soften intervened message prompt
Update WeChat group QR code (group 19 → group 20)
…search nav (lsdefine#554) * fix(tui): stop CRLF stdout rendering as blank lines (v2) Windows child stdout is `\r\n`; the streaming path fed it straight to `Text.from_ansi`, which treats `\r` as a carriage return and erases each line's text, so a `[Stdout]` block rendered as a run of blank lines until the turn finished (the done-state Markdown render strips `\r`). Normalise `\r\n` -> `\n` before `from_ansi`; lone `\r` is kept so progress-bar overwrites still work. * fix(tui): stop leaking empty per-session task_dir signal folders Both v2 and v3 eagerly `os.makedirs` the per-session `_intervene` / `_keyinfo` signal dir, but the only writer (`_intervene`) already creates it lazily — so every session that never used intervene left a stale empty `temp/_tui_v2_<pid>_<id>` / `temp/_tui_v3_<pid>` behind (85+ accumulated). `consume_file` tolerates a missing dir, so the eager create is redundant. - Set only the task_dir *path*; let the writer create it on first inject. - Remove empty dirs on session close (v2 `_cmd_close`), on graceful exit (v2 `on_unmount`, v3 `_cleanup`), and sweep stale ones left by crashes at startup (v2 `on_mount`, v3 `main`). `os.rmdir` only removes empty dirs, so a still-pending `_intervene` is never clobbered. * fix(tui): repair /continue search box cursor & up-nav loop (v2) The SearchablePicker swallowed Right while the search Input had focus (always treating it as "select"), so the caret could never move right in the query. And Up could leave the list but never return: from the search box Down entered the list, yet Up at the top row was stuck. - Right commits the highlight only when the caret is already at end of the query; otherwise it moves the caret within the search text. - Up on the first list row returns focus to the search box (scoped to /continue — no-op for ChoiceLists outside a SearchablePicker), clearing the highlight so the next Down re-enters at the first row, not the second. - Up from the search box wraps around to the bottom of the list.
fix: add plugins/__init__.py for proper package recognition
…证后增补验收线/锁边界质疑目标/遗留项如实入报告; TMWebDriver: 修mark_disconnected重复打印
/continue list previews showed JSON debris (e.g. `{`, `" } ]} === Response ===`)
for some sessions. Two causes in _preview_from_file:
1. Models sometimes emit an unclosed <summary>, so the non-greedy DOTALL regex
pairs it with a far-away </summary> and captures === block headers / JSON
across rounds. Now only the latest <summary> is used, and it is rejected if
it looks like such a cross-segment capture (contains `=== `/`"role"` or
>200 chars) — falling through instead of digging for older summaries.
2. The fallback scanned for the first non-=== line, returning JSON structure
lines. It now uses the last real user prompt via a new _last_user(), which
scans Prompt blocks directly (so response-less/aborted sessions still
preview) and reuses _user_text() to skip tool_result continuations and all
_INJECT_MARKERS (WORKING MEMORY / SYSTEM TIPS / DANGER ...).
Scanned 261 local logs: garbage previews 26 -> 0.
…ew-garbage fix(continue): robust session preview for malformed logs
…loop, log name collision fix, checklist poll hard cap
- conductor_im_plugins: 新增 lark.py(飞书收消息插件,无状态轮询)、email.py、_TEMPLATE.py - wechat.py/config.local.json 经gitignore排除(含个人会话ID) - conductor.html/py: UI重构(grid/可折叠卡片/console/approvals)、action与pool化重构 - stapp.py: 移除_js_scroll_fix - ljqCtrl_sop: 补充Click点歪诊断/DPI坐标陷阱/文本输入经验
Rename tracked email.py/lark.py to _email_example.py/_lark_example.py so the poller (which skips _-prefixed files) no longer polls them on a fresh clone. Activate by copying to email.py/lark.py (now gitignored). Also nudge manager to reuse existing subagents on IM signals.
…ar (lsdefine#572) - _term_write(): route OSC/control sequences through Textual's driver writer queue instead of direct sys.__stdout__. A title/OSC write landing mid-frame during streaming used to split Textual's own escape sequences, rendering as flashing ANSI garbage; serializing on the same writer queue lands it cleanly. - sidebar: wrap the session list in a VerticalScroll (#sidebar-scroll) so it scrolls when overflowing (scrollbar-gutter reserved to avoid row reflow); inner #sidebar Static keeps padding so the click hit-test math is unchanged. Keyboard session-switch scrolls the active session into view.
…e#581) Ctrl+C / selection copy fell back to Textual's OSC 52 escape on Windows/Linux. Some terminals (notably VSCode's integrated terminal) decode the OSC 52 base64 payload as latin-1 instead of UTF-8, so non-ASCII copied text lands in the clipboard as mojibake (e.g. 需要 -> éè¦). Classic Windows conhost ignores OSC 52 clipboard writes entirely, so copy was a silent no-op there (incl. Windows Server). Prefer the OS-native clipboard (_copy_to_clipboard: win32 CF_UNICODETEXT / pbcopy / wl-copy / xclip), which writes real Unicode and bypasses the terminal. Keep OSC 52 only as a fallback, and force it under SSH (SSH_CONNECTION / SSH_TTY) where the native call would write the remote host's clipboard instead of the user's local one.
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.
Summary
frontends/tuiapp_v2.pywithout touching other files.InputArea._on_key()goes through the same insertion path used by paste/newline via_insert_via_keyboard(), including a Windows-safe fallback.Root cause
InputArea._on_key(), printable keys relied onsuper()._on_key(event).event.is_printablecan be true whileevent.characteris missing, which can cause the baseTextAreainsertion path to not apply that first key reliably.Fix
frontends/tuiapp_v2.py:2334insideInputArea._on_key():super()path.event.characterfirst and falls back toevent.keywhencharacterisNoneandkeyis a single character._insert_via_keyboard()._history_indeximmediately for in-line editing (same intent as existing history-reset behavior).Verification
python -m py_compile frontends/tuiapp_v2.pypython -c "import ast; ast.parse(open('frontends/tuiapp_v2.py', encoding='utf-8').read())"python frontends/tuiapp_v2.py— run attempt blocked by existing runtime config issue in this environment:ZeroDivisionError: integer modulo by zeroinagentmain.py:84(load_llm_sessions()with empty LLM config list).Upstream
Closes #498.
Reported by @luodh0157.