* docs: govern agent guidance size * refactor: split agent guidance by code scope * Clarify virtual path handling in AGENTS.md Updated the translation section to clarify the role of `LocalSandboxProvider` and the handling of virtual paths in the tool layer. --------- Co-authored-by: Willem Jiang <willem.jiang@gmail.com>
2.9 KiB
Terminal Workbench / TUI (packages/harness/deerflow/tui/)
A terminal-native UI over the embedded harness, exposed as the deerflow console script ([project.scripts] in packages/harness/pyproject.toml). It is a UI shell over DeerFlowClient and does not fork agent behavior. textual is an optional dependency (deerflow-harness[tui]; also in the backend dev group); the console script degrades to headless help when it is absent. Full guide: docs/TUI.md.
Module layout (all layers except app.py are pure / Textual-free and unit-tested directly):
cli.py—plan_launch()(pure launch-mode decision) + headless--print/--json+main()entry point. TTY → TUI, else headless help.--tui-transparent/DEER_FLOW_TUI_TRANSPARENTopt into terminal-default backgrounds without changing the solid-theme default. Uses an absolutefrom deerflow.tui.app import run_tuiso theapp.pymodule name doesn't triptest_harness_boundary.py(which records relative import module names verbatim).view_state.py—ViewState+reduce(state, action), the testable heart. Rows: user / assistant / tool / system. Title captured fromvaluesevents.runtime.py—translate(StreamEvent) -> [Action](pure) +stream_actions()which brackets a run withRunStarted/RunEndedand turns model errors into anAssistantErrorrow.message_format.py/command_registry.py/input_history.py/render.py/theme.py— pure helpers (tool summaries, slash registry +resolve(), ↑/↓ history, Rich renderers).app.py— TextualApp. RunsDeerFlowClient.stream()(sync) on a worker thread and marshals actions to the UI thread viacall_from_thread. Slash palette with/goalmanagement + model/thread modal pickers; routes idle display-only/clearthroughClearRowswithout replacing the active thread, and blocks state-resetting local commands like/newand/clearwith the standard "Still working" message during an active run; priority key bindings gated bycheck_actionso they never steal keys from overlays or the composer.session.py/persistence.py— builds the client + checkpointer and theThreadMetaWriter.
Web UI visibility: the Web UI lists threads from the threads_meta SQL table (user-scoped), not the checkpointer. persistence.py writes a threads_meta row under the default user ("default") into the same DB the Gateway reads — via the harness-only deerflow.persistence.engine.init_engine_from_config() — so TUI sessions appear in the Web UI sidebar without running the Gateway. Best-effort: a no-op on the memory backend. All DB work runs on one long-lived background event loop (a SQLAlchemy async engine is bound to its creating loop).
Tests: tests/test_tui_*.py — pure layers via plain pytest, the app/palette/overlays via Textual's pilot harness with a fake in-process session, and test_tui_persistence.py for the threads_meta round-trip.