langchain-agentx-cli 0.2.1__tar.gz → 0.2.2__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {langchain_agentx_cli-0.2.1 → langchain_agentx_cli-0.2.2}/PKG-INFO +2 -2
- {langchain_agentx_cli-0.2.1 → langchain_agentx_cli-0.2.2}/langchain_agentx_cli/__init__.py +1 -1
- {langchain_agentx_cli-0.2.1 → langchain_agentx_cli-0.2.2}/langchain_agentx_cli/app.py +30 -0
- {langchain_agentx_cli-0.2.1 → langchain_agentx_cli-0.2.2}/langchain_agentx_cli/bridge/session_bridge.py +36 -6
- {langchain_agentx_cli-0.2.1 → langchain_agentx_cli-0.2.2}/langchain_agentx_cli/cli.py +15 -3
- langchain_agentx_cli-0.2.2/langchain_agentx_cli/observation/__init__.py +44 -0
- langchain_agentx_cli-0.2.2/langchain_agentx_cli/observation/config.py +35 -0
- langchain_agentx_cli-0.2.2/langchain_agentx_cli/observation/observer.py +173 -0
- {langchain_agentx_cli-0.2.1 → langchain_agentx_cli-0.2.2}/langchain_agentx_cli/screens/repl.py +0 -3
- {langchain_agentx_cli-0.2.1 → langchain_agentx_cli-0.2.2}/langchain_agentx_cli/tui/permissions/consumer.py +4 -2
- {langchain_agentx_cli-0.2.1 → langchain_agentx_cli-0.2.2}/langchain_agentx_cli/widgets/message_list.py +116 -43
- {langchain_agentx_cli-0.2.1 → langchain_agentx_cli-0.2.2}/langchain_agentx_cli/widgets/messages/assistant_message.py +16 -0
- {langchain_agentx_cli-0.2.1 → langchain_agentx_cli-0.2.2}/langchain_agentx_cli.egg-info/PKG-INFO +2 -2
- {langchain_agentx_cli-0.2.1 → langchain_agentx_cli-0.2.2}/langchain_agentx_cli.egg-info/SOURCES.txt +4 -0
- {langchain_agentx_cli-0.2.1 → langchain_agentx_cli-0.2.2}/langchain_agentx_cli.egg-info/requires.txt +1 -1
- {langchain_agentx_cli-0.2.1 → langchain_agentx_cli-0.2.2}/pyproject.toml +2 -2
- langchain_agentx_cli-0.2.2/tests/test_llm_config_chain.py +182 -0
- {langchain_agentx_cli-0.2.1 → langchain_agentx_cli-0.2.2}/LICENSE +0 -0
- {langchain_agentx_cli-0.2.1 → langchain_agentx_cli-0.2.2}/README.md +0 -0
- {langchain_agentx_cli-0.2.1 → langchain_agentx_cli-0.2.2}/langchain_agentx_cli/__main__.py +0 -0
- {langchain_agentx_cli-0.2.1 → langchain_agentx_cli-0.2.2}/langchain_agentx_cli/bootstrap.py +0 -0
- {langchain_agentx_cli-0.2.1 → langchain_agentx_cli-0.2.2}/langchain_agentx_cli/bridge/__init__.py +0 -0
- {langchain_agentx_cli-0.2.1 → langchain_agentx_cli-0.2.2}/langchain_agentx_cli/commands/__init__.py +0 -0
- {langchain_agentx_cli-0.2.1 → langchain_agentx_cli-0.2.2}/langchain_agentx_cli/commands/builtin/__init__.py +0 -0
- {langchain_agentx_cli-0.2.1 → langchain_agentx_cli-0.2.2}/langchain_agentx_cli/commands/builtin/clear.py +0 -0
- {langchain_agentx_cli-0.2.1 → langchain_agentx_cli-0.2.2}/langchain_agentx_cli/commands/builtin/compact.py +0 -0
- {langchain_agentx_cli-0.2.1 → langchain_agentx_cli-0.2.2}/langchain_agentx_cli/commands/builtin/help.py +0 -0
- {langchain_agentx_cli-0.2.1 → langchain_agentx_cli-0.2.2}/langchain_agentx_cli/commands/builtin/model.py +0 -0
- {langchain_agentx_cli-0.2.1 → langchain_agentx_cli-0.2.2}/langchain_agentx_cli/commands/builtin/quit.py +0 -0
- {langchain_agentx_cli-0.2.1 → langchain_agentx_cli-0.2.2}/langchain_agentx_cli/commands/builtin/theme.py +0 -0
- {langchain_agentx_cli-0.2.1 → langchain_agentx_cli-0.2.2}/langchain_agentx_cli/commands/parser.py +0 -0
- {langchain_agentx_cli-0.2.1 → langchain_agentx_cli-0.2.2}/langchain_agentx_cli/commands/providers/__init__.py +0 -0
- {langchain_agentx_cli-0.2.1 → langchain_agentx_cli-0.2.2}/langchain_agentx_cli/commands/providers/sdk_commands.py +0 -0
- {langchain_agentx_cli-0.2.1 → langchain_agentx_cli-0.2.2}/langchain_agentx_cli/commands/registry.py +0 -0
- {langchain_agentx_cli-0.2.1 → langchain_agentx_cli-0.2.2}/langchain_agentx_cli/completion/__init__.py +0 -0
- {langchain_agentx_cli-0.2.1 → langchain_agentx_cli-0.2.2}/langchain_agentx_cli/completion/base.py +0 -0
- {langchain_agentx_cli-0.2.1 → langchain_agentx_cli-0.2.2}/langchain_agentx_cli/completion/command_source.py +0 -0
- {langchain_agentx_cli-0.2.1 → langchain_agentx_cli-0.2.2}/langchain_agentx_cli/completion/history_source.py +0 -0
- {langchain_agentx_cli-0.2.1 → langchain_agentx_cli-0.2.2}/langchain_agentx_cli/config.py +0 -0
- {langchain_agentx_cli-0.2.1 → langchain_agentx_cli-0.2.2}/langchain_agentx_cli/history/__init__.py +0 -0
- {langchain_agentx_cli-0.2.1 → langchain_agentx_cli-0.2.2}/langchain_agentx_cli/history/store.py +0 -0
- {langchain_agentx_cli-0.2.1 → langchain_agentx_cli-0.2.2}/langchain_agentx_cli/keybindings/__init__.py +0 -0
- {langchain_agentx_cli-0.2.1 → langchain_agentx_cli-0.2.2}/langchain_agentx_cli/keybindings/bindings.py +0 -0
- {langchain_agentx_cli-0.2.1 → langchain_agentx_cli-0.2.2}/langchain_agentx_cli/llm_config.py +0 -0
- {langchain_agentx_cli-0.2.1 → langchain_agentx_cli-0.2.2}/langchain_agentx_cli/permissions/__init__.py +0 -0
- {langchain_agentx_cli-0.2.1 → langchain_agentx_cli-0.2.2}/langchain_agentx_cli/permissions/factory.py +0 -0
- {langchain_agentx_cli-0.2.1 → langchain_agentx_cli-0.2.2}/langchain_agentx_cli/permissions/policy.py +0 -0
- {langchain_agentx_cli-0.2.1 → langchain_agentx_cli-0.2.2}/langchain_agentx_cli/prompts/__init__.py +0 -0
- {langchain_agentx_cli-0.2.1 → langchain_agentx_cli-0.2.2}/langchain_agentx_cli/prompts/assembler.py +0 -0
- {langchain_agentx_cli-0.2.1 → langchain_agentx_cli-0.2.2}/langchain_agentx_cli/prompts/sections.py +0 -0
- {langchain_agentx_cli-0.2.1 → langchain_agentx_cli-0.2.2}/langchain_agentx_cli/prompts/system_prompt.py +0 -0
- {langchain_agentx_cli-0.2.1 → langchain_agentx_cli-0.2.2}/langchain_agentx_cli/screens/__init__.py +0 -0
- {langchain_agentx_cli-0.2.1 → langchain_agentx_cli-0.2.2}/langchain_agentx_cli/session_factory.py +0 -0
- {langchain_agentx_cli-0.2.1 → langchain_agentx_cli-0.2.2}/langchain_agentx_cli/session_options.py +0 -0
- {langchain_agentx_cli-0.2.1 → langchain_agentx_cli-0.2.2}/langchain_agentx_cli/state/__init__.py +0 -0
- {langchain_agentx_cli-0.2.1 → langchain_agentx_cli-0.2.2}/langchain_agentx_cli/state/task_store.py +0 -0
- {langchain_agentx_cli-0.2.1 → langchain_agentx_cli-0.2.2}/langchain_agentx_cli/theme/__init__.py +0 -0
- {langchain_agentx_cli-0.2.1 → langchain_agentx_cli-0.2.2}/langchain_agentx_cli/theme/colors.py +0 -0
- {langchain_agentx_cli-0.2.1 → langchain_agentx_cli-0.2.2}/langchain_agentx_cli/theme/detection.py +0 -0
- {langchain_agentx_cli-0.2.1 → langchain_agentx_cli-0.2.2}/langchain_agentx_cli/theme/manager.py +0 -0
- {langchain_agentx_cli-0.2.1 → langchain_agentx_cli-0.2.2}/langchain_agentx_cli/theme/settings.py +0 -0
- {langchain_agentx_cli-0.2.1 → langchain_agentx_cli-0.2.2}/langchain_agentx_cli/theme/system_theme.py +0 -0
- {langchain_agentx_cli-0.2.1 → langchain_agentx_cli-0.2.2}/langchain_agentx_cli/theme/themes.py +0 -0
- {langchain_agentx_cli-0.2.1 → langchain_agentx_cli-0.2.2}/langchain_agentx_cli/theme/watcher.py +0 -0
- {langchain_agentx_cli-0.2.1 → langchain_agentx_cli-0.2.2}/langchain_agentx_cli/tools/__init__.py +0 -0
- {langchain_agentx_cli-0.2.1 → langchain_agentx_cli-0.2.2}/langchain_agentx_cli/tools/registry.py +0 -0
- {langchain_agentx_cli-0.2.1 → langchain_agentx_cli-0.2.2}/langchain_agentx_cli/tui/__init__.py +0 -0
- {langchain_agentx_cli-0.2.1 → langchain_agentx_cli-0.2.2}/langchain_agentx_cli/tui/clipboard.py +0 -0
- {langchain_agentx_cli-0.2.1 → langchain_agentx_cli-0.2.2}/langchain_agentx_cli/tui/message_selection.py +0 -0
- {langchain_agentx_cli-0.2.1 → langchain_agentx_cli-0.2.2}/langchain_agentx_cli/tui/permissions/__init__.py +0 -0
- {langchain_agentx_cli-0.2.1 → langchain_agentx_cli-0.2.2}/langchain_agentx_cli/tui/permissions/cache.py +0 -0
- {langchain_agentx_cli-0.2.1 → langchain_agentx_cli-0.2.2}/langchain_agentx_cli/tui/permissions/component_manager.py +0 -0
- {langchain_agentx_cli-0.2.1 → langchain_agentx_cli-0.2.2}/langchain_agentx_cli/tui/permissions/config.py +0 -0
- {langchain_agentx_cli-0.2.1 → langchain_agentx_cli-0.2.2}/langchain_agentx_cli/tui/permissions/dialog.py +0 -0
- {langchain_agentx_cli-0.2.1 → langchain_agentx_cli-0.2.2}/langchain_agentx_cli/tui/permissions/inject.py +0 -0
- {langchain_agentx_cli-0.2.1 → langchain_agentx_cli-0.2.2}/langchain_agentx_cli/tui/permissions/models.py +0 -0
- {langchain_agentx_cli-0.2.1 → langchain_agentx_cli-0.2.2}/langchain_agentx_cli/tui/permissions/presenters/__init__.py +0 -0
- {langchain_agentx_cli-0.2.1 → langchain_agentx_cli-0.2.2}/langchain_agentx_cli/tui/permissions/presenters/base.py +0 -0
- {langchain_agentx_cli-0.2.1 → langchain_agentx_cli-0.2.2}/langchain_agentx_cli/tui/permissions/presenters/bash.py +0 -0
- {langchain_agentx_cli-0.2.1 → langchain_agentx_cli-0.2.2}/langchain_agentx_cli/tui/permissions/presenters/fallback.py +0 -0
- {langchain_agentx_cli-0.2.1 → langchain_agentx_cli-0.2.2}/langchain_agentx_cli/tui/permissions/presenters/file.py +0 -0
- {langchain_agentx_cli-0.2.1 → langchain_agentx_cli-0.2.2}/langchain_agentx_cli/tui/permissions/queue.py +0 -0
- {langchain_agentx_cli-0.2.1 → langchain_agentx_cli-0.2.2}/langchain_agentx_cli/tui/safe_screen.py +0 -0
- {langchain_agentx_cli-0.2.1 → langchain_agentx_cli-0.2.2}/langchain_agentx_cli/welcome.py +0 -0
- {langchain_agentx_cli-0.2.1 → langchain_agentx_cli-0.2.2}/langchain_agentx_cli/widgets/__init__.py +0 -0
- {langchain_agentx_cli-0.2.1 → langchain_agentx_cli-0.2.2}/langchain_agentx_cli/widgets/compact_progress.py +0 -0
- {langchain_agentx_cli-0.2.1 → langchain_agentx_cli-0.2.2}/langchain_agentx_cli/widgets/completion_overlay.py +0 -0
- {langchain_agentx_cli-0.2.1 → langchain_agentx_cli-0.2.2}/langchain_agentx_cli/widgets/input_area.py +0 -0
- {langchain_agentx_cli-0.2.1 → langchain_agentx_cli-0.2.2}/langchain_agentx_cli/widgets/message_events.py +0 -0
- {langchain_agentx_cli-0.2.1 → langchain_agentx_cli-0.2.2}/langchain_agentx_cli/widgets/messages/__init__.py +0 -0
- {langchain_agentx_cli-0.2.1 → langchain_agentx_cli-0.2.2}/langchain_agentx_cli/widgets/messages/error_message.py +0 -0
- {langchain_agentx_cli-0.2.1 → langchain_agentx_cli-0.2.2}/langchain_agentx_cli/widgets/messages/rendering.py +0 -0
- {langchain_agentx_cli-0.2.1 → langchain_agentx_cli-0.2.2}/langchain_agentx_cli/widgets/messages/thinking_message.py +0 -0
- {langchain_agentx_cli-0.2.1 → langchain_agentx_cli-0.2.2}/langchain_agentx_cli/widgets/pending_permission.py +0 -0
- {langchain_agentx_cli-0.2.1 → langchain_agentx_cli-0.2.2}/langchain_agentx_cli/widgets/permission_inline.py +0 -0
- {langchain_agentx_cli-0.2.1 → langchain_agentx_cli-0.2.2}/langchain_agentx_cli/widgets/permission_keybindings.py +0 -0
- {langchain_agentx_cli-0.2.1 → langchain_agentx_cli-0.2.2}/langchain_agentx_cli/widgets/spinner.py +0 -0
- {langchain_agentx_cli-0.2.1 → langchain_agentx_cli-0.2.2}/langchain_agentx_cli/widgets/task_panel.py +0 -0
- {langchain_agentx_cli-0.2.1 → langchain_agentx_cli-0.2.2}/langchain_agentx_cli/widgets/tools/__init__.py +0 -0
- {langchain_agentx_cli-0.2.1 → langchain_agentx_cli-0.2.2}/langchain_agentx_cli/widgets/tools/agent/__init__.py +0 -0
- {langchain_agentx_cli-0.2.1 → langchain_agentx_cli-0.2.2}/langchain_agentx_cli/widgets/tools/agent/widget.py +0 -0
- {langchain_agentx_cli-0.2.1 → langchain_agentx_cli-0.2.2}/langchain_agentx_cli/widgets/tools/ask_user_question/__init__.py +0 -0
- {langchain_agentx_cli-0.2.1 → langchain_agentx_cli-0.2.2}/langchain_agentx_cli/widgets/tools/ask_user_question/widget.py +0 -0
- {langchain_agentx_cli-0.2.1 → langchain_agentx_cli-0.2.2}/langchain_agentx_cli/widgets/tools/base.py +0 -0
- {langchain_agentx_cli-0.2.1 → langchain_agentx_cli-0.2.2}/langchain_agentx_cli/widgets/tools/bash/__init__.py +0 -0
- {langchain_agentx_cli-0.2.1 → langchain_agentx_cli-0.2.2}/langchain_agentx_cli/widgets/tools/bash/widget.py +0 -0
- {langchain_agentx_cli-0.2.1 → langchain_agentx_cli-0.2.2}/langchain_agentx_cli/widgets/tools/batch_edit/__init__.py +0 -0
- {langchain_agentx_cli-0.2.1 → langchain_agentx_cli-0.2.2}/langchain_agentx_cli/widgets/tools/batch_edit/widget.py +0 -0
- {langchain_agentx_cli-0.2.1 → langchain_agentx_cli-0.2.2}/langchain_agentx_cli/widgets/tools/edit/__init__.py +0 -0
- {langchain_agentx_cli-0.2.1 → langchain_agentx_cli-0.2.2}/langchain_agentx_cli/widgets/tools/edit/widget.py +0 -0
- {langchain_agentx_cli-0.2.1 → langchain_agentx_cli-0.2.2}/langchain_agentx_cli/widgets/tools/glob/__init__.py +0 -0
- {langchain_agentx_cli-0.2.1 → langchain_agentx_cli-0.2.2}/langchain_agentx_cli/widgets/tools/glob/widget.py +0 -0
- {langchain_agentx_cli-0.2.1 → langchain_agentx_cli-0.2.2}/langchain_agentx_cli/widgets/tools/grep/__init__.py +0 -0
- {langchain_agentx_cli-0.2.1 → langchain_agentx_cli-0.2.2}/langchain_agentx_cli/widgets/tools/grep/widget.py +0 -0
- {langchain_agentx_cli-0.2.1 → langchain_agentx_cli-0.2.2}/langchain_agentx_cli/widgets/tools/helpers.py +0 -0
- {langchain_agentx_cli-0.2.1 → langchain_agentx_cli-0.2.2}/langchain_agentx_cli/widgets/tools/read/__init__.py +0 -0
- {langchain_agentx_cli-0.2.1 → langchain_agentx_cli-0.2.2}/langchain_agentx_cli/widgets/tools/read/widget.py +0 -0
- {langchain_agentx_cli-0.2.1 → langchain_agentx_cli-0.2.2}/langchain_agentx_cli/widgets/tools/skill/__init__.py +0 -0
- {langchain_agentx_cli-0.2.1 → langchain_agentx_cli-0.2.2}/langchain_agentx_cli/widgets/tools/skill/widget.py +0 -0
- {langchain_agentx_cli-0.2.1 → langchain_agentx_cli-0.2.2}/langchain_agentx_cli/widgets/tools/user_message/__init__.py +0 -0
- {langchain_agentx_cli-0.2.1 → langchain_agentx_cli-0.2.2}/langchain_agentx_cli/widgets/tools/user_message/widget.py +0 -0
- {langchain_agentx_cli-0.2.1 → langchain_agentx_cli-0.2.2}/langchain_agentx_cli/widgets/tools/webfetch/__init__.py +0 -0
- {langchain_agentx_cli-0.2.1 → langchain_agentx_cli-0.2.2}/langchain_agentx_cli/widgets/tools/webfetch/widget.py +0 -0
- {langchain_agentx_cli-0.2.1 → langchain_agentx_cli-0.2.2}/langchain_agentx_cli/widgets/tools/websearch/__init__.py +0 -0
- {langchain_agentx_cli-0.2.1 → langchain_agentx_cli-0.2.2}/langchain_agentx_cli/widgets/tools/websearch/widget.py +0 -0
- {langchain_agentx_cli-0.2.1 → langchain_agentx_cli-0.2.2}/langchain_agentx_cli/widgets/tools/write/__init__.py +0 -0
- {langchain_agentx_cli-0.2.1 → langchain_agentx_cli-0.2.2}/langchain_agentx_cli/widgets/tools/write/widget.py +0 -0
- {langchain_agentx_cli-0.2.1 → langchain_agentx_cli-0.2.2}/langchain_agentx_cli.egg-info/dependency_links.txt +0 -0
- {langchain_agentx_cli-0.2.1 → langchain_agentx_cli-0.2.2}/langchain_agentx_cli.egg-info/entry_points.txt +0 -0
- {langchain_agentx_cli-0.2.1 → langchain_agentx_cli-0.2.2}/langchain_agentx_cli.egg-info/not-zip-safe +0 -0
- {langchain_agentx_cli-0.2.1 → langchain_agentx_cli-0.2.2}/langchain_agentx_cli.egg-info/top_level.txt +0 -0
- {langchain_agentx_cli-0.2.1 → langchain_agentx_cli-0.2.2}/setup.cfg +0 -0
- {langchain_agentx_cli-0.2.1 → langchain_agentx_cli-0.2.2}/tests/test_app_interrupt.py +0 -0
- {langchain_agentx_cli-0.2.1 → langchain_agentx_cli-0.2.2}/tests/test_repl_commands.py +0 -0
- {langchain_agentx_cli-0.2.1 → langchain_agentx_cli-0.2.2}/tests/test_repl_submit_flow.py +0 -0
- {langchain_agentx_cli-0.2.1 → langchain_agentx_cli-0.2.2}/tests/test_repl_ui.py +0 -0
- {langchain_agentx_cli-0.2.1 → langchain_agentx_cli-0.2.2}/tests/test_smoke.py +0 -0
- {langchain_agentx_cli-0.2.1 → langchain_agentx_cli-0.2.2}/tests/test_welcome.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: langchain-agentx-cli
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.2
|
|
4
4
|
Summary: Terminal CLI/TUI for AgentX: migrate Claude Code Ink UI, backed by langchain-agentx-python SDK.
|
|
5
5
|
Author: GoodMood2008
|
|
6
6
|
License: Apache-2.0
|
|
@@ -22,7 +22,7 @@ Classifier: Topic :: Software Development
|
|
|
22
22
|
Requires-Python: >=3.11
|
|
23
23
|
Description-Content-Type: text/markdown
|
|
24
24
|
License-File: LICENSE
|
|
25
|
-
Requires-Dist: langchain-agentx-python<0.4.0,>=0.3.
|
|
25
|
+
Requires-Dist: langchain-agentx-python<0.4.0,>=0.3.7
|
|
26
26
|
Requires-Dist: click>=8.1
|
|
27
27
|
Requires-Dist: textual>=0.79.0
|
|
28
28
|
Provides-Extra: dev
|
|
@@ -10,6 +10,7 @@ app.py — Textual ReplApp 容器。
|
|
|
10
10
|
|
|
11
11
|
from __future__ import annotations
|
|
12
12
|
|
|
13
|
+
from pathlib import Path
|
|
13
14
|
from typing import TYPE_CHECKING
|
|
14
15
|
|
|
15
16
|
from textual import on
|
|
@@ -55,12 +56,15 @@ class ReplApp(App[None]):
|
|
|
55
56
|
show=False,
|
|
56
57
|
priority=True,
|
|
57
58
|
),
|
|
59
|
+
# 对齐 CC: Ctrl+O 切换 Transcript 模式
|
|
60
|
+
Binding("ctrl+o", "toggle_transcript", "Transcript", show=False, priority=True),
|
|
58
61
|
]
|
|
59
62
|
|
|
60
63
|
def __init__(
|
|
61
64
|
self,
|
|
62
65
|
launch_config: ReplLaunchConfig,
|
|
63
66
|
session: AgentSession | None = None,
|
|
67
|
+
debug: bool = False,
|
|
64
68
|
) -> None:
|
|
65
69
|
super().__init__()
|
|
66
70
|
self._launch_config = launch_config
|
|
@@ -74,6 +78,7 @@ class ReplApp(App[None]):
|
|
|
74
78
|
self._screen_messenger = ReplScreenMessenger(self)
|
|
75
79
|
# Phase 3: 加载用户偏好(供 MessageListWidget 和工具 Widget 使用)
|
|
76
80
|
self.preferences: AppUserPreferences = AppPreferencesStore().load()
|
|
81
|
+
self._debug = debug
|
|
77
82
|
|
|
78
83
|
@property
|
|
79
84
|
def screen_messenger(self) -> ReplScreenMessenger:
|
|
@@ -92,6 +97,13 @@ class ReplApp(App[None]):
|
|
|
92
97
|
return self._bridge
|
|
93
98
|
|
|
94
99
|
def on_mount(self) -> None:
|
|
100
|
+
# DEBUG: 启用观测日志
|
|
101
|
+
if self._debug:
|
|
102
|
+
from langchain_agentx_cli.observation import observer
|
|
103
|
+
|
|
104
|
+
observer.enable(self.workspace_root)
|
|
105
|
+
observer.info("[APP] ReplApp mounted, workspace=%s", self.workspace_root)
|
|
106
|
+
|
|
95
107
|
prefs = AppPreferencesStore().load()
|
|
96
108
|
initial_setting = self._launch_config.theme or prefs.theme
|
|
97
109
|
self.theme_manager = ThemeManager(self)
|
|
@@ -149,3 +161,21 @@ class ReplApp(App[None]):
|
|
|
149
161
|
if self._bridge is not None:
|
|
150
162
|
self._bridge.cancel_stream()
|
|
151
163
|
self.exit(0)
|
|
164
|
+
|
|
165
|
+
def action_toggle_transcript(self) -> None:
|
|
166
|
+
"""切换 Transcript 模式(对齐 CC Ctrl+O)。"""
|
|
167
|
+
screen = self.screen
|
|
168
|
+
if isinstance(screen, ReplScreen):
|
|
169
|
+
message_list = screen._message_list()
|
|
170
|
+
if message_list is not None:
|
|
171
|
+
from langchain_agentx_cli.observation import info
|
|
172
|
+
old_mode = message_list.display_mode
|
|
173
|
+
message_list.toggle_transcript_mode()
|
|
174
|
+
new_mode = message_list.display_mode
|
|
175
|
+
info("[APP] transcript toggled: %s → %s", old_mode, new_mode)
|
|
176
|
+
|
|
177
|
+
# 显示通知
|
|
178
|
+
if new_mode.value == "transcript":
|
|
179
|
+
self.notify("Transcript 模式已启用(显示所有内容)", severity="information", timeout=3)
|
|
180
|
+
else:
|
|
181
|
+
self.notify("已返回 Normal 模式", severity="information", timeout=2)
|
|
@@ -18,12 +18,14 @@ from __future__ import annotations
|
|
|
18
18
|
|
|
19
19
|
import asyncio
|
|
20
20
|
from collections.abc import Callable
|
|
21
|
+
from dataclasses import dataclass, field
|
|
21
22
|
from typing import TYPE_CHECKING, Any
|
|
22
23
|
|
|
23
24
|
from langchain_agentx.tool_runtime.resolvers import (
|
|
24
25
|
AgentSessionPermissionResolver,
|
|
25
26
|
PermissionRequest,
|
|
26
27
|
)
|
|
28
|
+
from langchain_agentx_cli.observation import debug, info
|
|
27
29
|
from langchain_agentx_cli.tui.permissions import (
|
|
28
30
|
PermissionQueueConsumer,
|
|
29
31
|
SessionPermissionCache,
|
|
@@ -70,6 +72,16 @@ MVP_ADAPTER_CONFIG: dict[str, bool] = {
|
|
|
70
72
|
_LLM_FAILED_PREFIX = "[LLM request failed]"
|
|
71
73
|
|
|
72
74
|
|
|
75
|
+
@dataclass
|
|
76
|
+
class _TurnSegmentState:
|
|
77
|
+
"""一个 compaction 段内的流式状态;在 turn 开始和 COMPACT_END 时整体重置。"""
|
|
78
|
+
|
|
79
|
+
streamed_text: bool = False
|
|
80
|
+
|
|
81
|
+
def reset(self) -> None:
|
|
82
|
+
self.streamed_text = False
|
|
83
|
+
|
|
84
|
+
|
|
73
85
|
class SessionBridge:
|
|
74
86
|
"""TUI 与 SDK 之间的桥接层(消费 LangchainAgentEvent)。"""
|
|
75
87
|
|
|
@@ -79,7 +91,7 @@ class SessionBridge:
|
|
|
79
91
|
self._session = session
|
|
80
92
|
self._adapter = LangGraphToLangchainAgentEventAdapter(config=dict(MVP_ADAPTER_CONFIG))
|
|
81
93
|
self._current_worker: Any = None
|
|
82
|
-
self.
|
|
94
|
+
self._seg = _TurnSegmentState()
|
|
83
95
|
# 对齐 CC: 集中式权限队列状态管理
|
|
84
96
|
self._permission_queue: asyncio.Queue[PermissionRequest] = asyncio.Queue()
|
|
85
97
|
self._permission_cache = SessionPermissionCache()
|
|
@@ -111,12 +123,15 @@ class SessionBridge:
|
|
|
111
123
|
|
|
112
124
|
async def _stream_turn(self, user_input: str) -> None:
|
|
113
125
|
self._adapter._reset_state()
|
|
114
|
-
self.
|
|
126
|
+
self._seg.reset()
|
|
115
127
|
raw_events = self._session.stream_loop_events(user_input)
|
|
116
128
|
try:
|
|
117
129
|
async for event in self._adapter.adapt(raw_events):
|
|
118
130
|
self._dispatch_event(event)
|
|
131
|
+
except (KeyboardInterrupt, SystemExit):
|
|
132
|
+
raise
|
|
119
133
|
except Exception as exc:
|
|
134
|
+
debug("stream_turn error", exc_info=True)
|
|
120
135
|
self._post_ui(ErrorMessageOccurred(error=str(exc)))
|
|
121
136
|
finally:
|
|
122
137
|
self._post_ui(TurnInProgress(in_progress=False))
|
|
@@ -124,6 +139,12 @@ class SessionBridge:
|
|
|
124
139
|
|
|
125
140
|
def _dispatch_event(self, event: LangchainAgentEvent) -> None:
|
|
126
141
|
data = event.data or {}
|
|
142
|
+
# DEBUG: 追踪所有事件
|
|
143
|
+
info(
|
|
144
|
+
"[BRIDGE] event=%s data_keys=%s",
|
|
145
|
+
event.event_type,
|
|
146
|
+
list(data.keys()) if data else [],
|
|
147
|
+
)
|
|
127
148
|
match event.event_type:
|
|
128
149
|
case LangchainAgentEventType.TEXT_START:
|
|
129
150
|
self._post_ui(
|
|
@@ -131,8 +152,9 @@ class SessionBridge:
|
|
|
131
152
|
)
|
|
132
153
|
case LangchainAgentEventType.TEXT_DELTA:
|
|
133
154
|
delta = str(data.get("text", ""))
|
|
155
|
+
info("[BRIDGE] TEXT_DELTA len=%d first50=%r", len(delta), delta[:50])
|
|
134
156
|
if delta:
|
|
135
|
-
self.
|
|
157
|
+
self._seg.streamed_text = True
|
|
136
158
|
self._post_ui(
|
|
137
159
|
AssistantMessageChunk(
|
|
138
160
|
delta=delta,
|
|
@@ -140,6 +162,7 @@ class SessionBridge:
|
|
|
140
162
|
)
|
|
141
163
|
)
|
|
142
164
|
case LangchainAgentEventType.TEXT_END:
|
|
165
|
+
info("[BRIDGE] TEXT_END — finalizing assistant")
|
|
143
166
|
self._post_ui(
|
|
144
167
|
AssistantMessageChunk(delta="", is_complete=True)
|
|
145
168
|
)
|
|
@@ -191,9 +214,16 @@ class SessionBridge:
|
|
|
191
214
|
self._emit_finish_answer(str(data.get("answer", "")))
|
|
192
215
|
self._post_ui(TurnInProgress(in_progress=False))
|
|
193
216
|
case LangchainAgentEventType.COMPACT_END:
|
|
194
|
-
self.
|
|
217
|
+
self._seg.reset()
|
|
218
|
+
compact_type = data.get("compact_type", "autocompact") # 向后兼容
|
|
219
|
+
tokens_freed = data.get("tokens_freed") or 0
|
|
220
|
+
info("[BRIDGE] COMPACT_END type=%s tokens=%s", compact_type, tokens_freed)
|
|
221
|
+
# 只显示 autocompact(LLM 摘要),忽略 microcompact(工具清理)
|
|
222
|
+
if compact_type == "autocompact":
|
|
223
|
+
self._post_ui(ContextCompactedMessage())
|
|
195
224
|
case LangchainAgentEventType.COMPACT_START:
|
|
196
|
-
|
|
225
|
+
info("[BRIDGE] COMPACT_START — compacting...")
|
|
226
|
+
pass
|
|
197
227
|
case _:
|
|
198
228
|
pass
|
|
199
229
|
|
|
@@ -205,7 +235,7 @@ class SessionBridge:
|
|
|
205
235
|
if text.startswith(_LLM_FAILED_PREFIX):
|
|
206
236
|
self._post_ui(ErrorMessageOccurred(error=text))
|
|
207
237
|
return
|
|
208
|
-
if not self.
|
|
238
|
+
if not self._seg.streamed_text:
|
|
209
239
|
self._post_ui(
|
|
210
240
|
AssistantMessageChunk(delta=text, is_complete=True)
|
|
211
241
|
)
|
|
@@ -50,6 +50,7 @@ class CliEntry:
|
|
|
50
50
|
show_config: bool,
|
|
51
51
|
enable_git_snapshot: bool | None,
|
|
52
52
|
skip_permissions: bool = False,
|
|
53
|
+
debug: bool = False,
|
|
53
54
|
) -> int:
|
|
54
55
|
# Mode 到 agent_home 的映射(优先级高于 --agent-home)
|
|
55
56
|
if mode:
|
|
@@ -88,7 +89,7 @@ class CliEntry:
|
|
|
88
89
|
return 2
|
|
89
90
|
|
|
90
91
|
try:
|
|
91
|
-
return self._run_tui(launch_config, session)
|
|
92
|
+
return self._run_tui(launch_config, session, debug=debug)
|
|
92
93
|
finally:
|
|
93
94
|
asyncio.run(close_agent_session(session))
|
|
94
95
|
|
|
@@ -138,8 +139,10 @@ class CliEntry:
|
|
|
138
139
|
}
|
|
139
140
|
return mode_map.get(mode.lower(), ".langchain_agentx")
|
|
140
141
|
|
|
141
|
-
def _run_tui(
|
|
142
|
-
|
|
142
|
+
def _run_tui(
|
|
143
|
+
self, launch_config: ReplLaunchConfig, session, debug: bool = False # noqa: ANN001
|
|
144
|
+
) -> int:
|
|
145
|
+
app = ReplApp(launch_config=launch_config, session=session, debug=debug)
|
|
143
146
|
app.run()
|
|
144
147
|
return 0
|
|
145
148
|
|
|
@@ -203,6 +206,13 @@ _CONFIG_PATH = user_config_path()
|
|
|
203
206
|
default=False,
|
|
204
207
|
help="跳过工具权限确认(对齐 CC --dangerously-skip-permissions)",
|
|
205
208
|
)
|
|
209
|
+
@click.option(
|
|
210
|
+
"--debug",
|
|
211
|
+
"-d",
|
|
212
|
+
is_flag=True,
|
|
213
|
+
default=False,
|
|
214
|
+
help="启用观察日志(写入 workspace/log/agentx-{pid}.log)",
|
|
215
|
+
)
|
|
206
216
|
def main(
|
|
207
217
|
workspace_root: Path | None,
|
|
208
218
|
mode: str | None,
|
|
@@ -212,6 +222,7 @@ def main(
|
|
|
212
222
|
show_config: bool,
|
|
213
223
|
enable_git_snapshot: bool | None,
|
|
214
224
|
skip_permissions: bool,
|
|
225
|
+
debug: bool,
|
|
215
226
|
) -> None:
|
|
216
227
|
"""langchain-agentx 终端 REPL(MVP)。"""
|
|
217
228
|
code = CliEntry().run(
|
|
@@ -223,5 +234,6 @@ def main(
|
|
|
223
234
|
show_config=show_config,
|
|
224
235
|
enable_git_snapshot=enable_git_snapshot,
|
|
225
236
|
skip_permissions=skip_permissions,
|
|
237
|
+
debug=debug,
|
|
226
238
|
)
|
|
227
239
|
raise SystemExit(code)
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
"""
|
|
2
|
+
observation — 统一日志观测模块。
|
|
3
|
+
|
|
4
|
+
提供启用/禁用控制的日志接口,默认禁用(零开销)。
|
|
5
|
+
|
|
6
|
+
使用方式:
|
|
7
|
+
from langchain_agentx_cli.observation import observer, info
|
|
8
|
+
|
|
9
|
+
# 模块直接调用
|
|
10
|
+
info("[MODULE] some_event value=%s", value)
|
|
11
|
+
|
|
12
|
+
# 或使用 observer 实例
|
|
13
|
+
observer.info("[MODULE] some_event value=%s", value)
|
|
14
|
+
"""
|
|
15
|
+
|
|
16
|
+
from langchain_agentx_cli.observation.observer import (
|
|
17
|
+
Observer,
|
|
18
|
+
critical,
|
|
19
|
+
debug,
|
|
20
|
+
disable,
|
|
21
|
+
enable,
|
|
22
|
+
error,
|
|
23
|
+
get_observer,
|
|
24
|
+
info,
|
|
25
|
+
is_enabled,
|
|
26
|
+
warning,
|
|
27
|
+
)
|
|
28
|
+
|
|
29
|
+
# 全局 observer 实例(常用别名)
|
|
30
|
+
observer = get_observer()
|
|
31
|
+
|
|
32
|
+
__all__ = [
|
|
33
|
+
"Observer",
|
|
34
|
+
"observer",
|
|
35
|
+
"get_observer",
|
|
36
|
+
"enable",
|
|
37
|
+
"disable",
|
|
38
|
+
"is_enabled",
|
|
39
|
+
"debug",
|
|
40
|
+
"info",
|
|
41
|
+
"warning",
|
|
42
|
+
"error",
|
|
43
|
+
"critical",
|
|
44
|
+
]
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
"""
|
|
2
|
+
observation/config.py — 日志配置常量。
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
from __future__ import annotations
|
|
6
|
+
|
|
7
|
+
import os
|
|
8
|
+
from pathlib import Path
|
|
9
|
+
|
|
10
|
+
# 日志文件名模板
|
|
11
|
+
LOG_FILENAME_TEMPLATE = "agentx-{pid}.log"
|
|
12
|
+
|
|
13
|
+
# 默认日志格式
|
|
14
|
+
LOG_FORMAT = "%(asctime)s %(name)s %(levelname)s %(message)s"
|
|
15
|
+
LOG_DATE_FORMAT = "%Y-%m-%d %H:%M:%S"
|
|
16
|
+
|
|
17
|
+
# 默认日志级别
|
|
18
|
+
DEFAULT_LOG_LEVEL = "INFO"
|
|
19
|
+
|
|
20
|
+
# 日志目录名(相对 workspace root)
|
|
21
|
+
LOG_DIR_NAME = "log"
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
def get_log_dir(workspace_root: Path | None) -> Path:
|
|
25
|
+
"""获取日志目录路径。"""
|
|
26
|
+
if workspace_root:
|
|
27
|
+
return workspace_root / LOG_DIR_NAME
|
|
28
|
+
# 回退到临时目录(无 workspace 时)
|
|
29
|
+
return Path(os.getenv("TMPDIR", "/tmp")) / "agentx-logs"
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
def get_log_path(workspace_root: Path | None) -> Path:
|
|
33
|
+
"""获取日志文件完整路径。"""
|
|
34
|
+
log_dir = get_log_dir(workspace_root)
|
|
35
|
+
return log_dir / LOG_FILENAME_TEMPLATE.format(pid=os.getpid())
|
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
"""
|
|
2
|
+
observation/observer.py — 观测器(单例)。
|
|
3
|
+
|
|
4
|
+
提供统一的日志接口,支持启用/禁用切换。禁用时所有操作为 no-op。
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from __future__ import annotations
|
|
8
|
+
|
|
9
|
+
import logging
|
|
10
|
+
from pathlib import Path
|
|
11
|
+
from typing import Final
|
|
12
|
+
|
|
13
|
+
from langchain_agentx_cli.observation.config import (
|
|
14
|
+
DEFAULT_LOG_LEVEL,
|
|
15
|
+
LOG_DATE_FORMAT,
|
|
16
|
+
LOG_FORMAT,
|
|
17
|
+
get_log_path,
|
|
18
|
+
)
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
class _NullHandler(logging.Handler):
|
|
22
|
+
"""零开销的空 Handler,用于禁用状态。"""
|
|
23
|
+
|
|
24
|
+
def emit(self, record: logging.LogRecord) -> None:
|
|
25
|
+
pass
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
class Observer:
|
|
29
|
+
"""
|
|
30
|
+
观测器:统一的日志入口。
|
|
31
|
+
|
|
32
|
+
单例模式,通过 get_instance() 获取实例。
|
|
33
|
+
|
|
34
|
+
禁用状态:所有 log 方法为 no-op(零开销)。
|
|
35
|
+
启用状态:日志写入 workspace/log/agentx-{pid}.log
|
|
36
|
+
"""
|
|
37
|
+
|
|
38
|
+
_instance: Final[Observer] = None # type: ignore[assignment]
|
|
39
|
+
|
|
40
|
+
def __new__(cls) -> "Observer":
|
|
41
|
+
if cls._instance is None:
|
|
42
|
+
cls._instance = super().__new__(cls)
|
|
43
|
+
cls._instance._initialized = False
|
|
44
|
+
return cls._instance
|
|
45
|
+
|
|
46
|
+
def __init__(self) -> None:
|
|
47
|
+
if self._initialized:
|
|
48
|
+
return
|
|
49
|
+
self._initialized = True
|
|
50
|
+
|
|
51
|
+
self._enabled: bool = False
|
|
52
|
+
self._logger: logging.Logger | None = None
|
|
53
|
+
self._null_handler = _NullHandler()
|
|
54
|
+
|
|
55
|
+
def enable(self, workspace_root: Path, level: str = DEFAULT_LOG_LEVEL) -> None:
|
|
56
|
+
"""
|
|
57
|
+
启用观测日志。
|
|
58
|
+
|
|
59
|
+
Args:
|
|
60
|
+
workspace_root: 工作区根目录,日志写入 workspace_root/log/
|
|
61
|
+
level: 日志级别(DEBUG/INFO/WARNING/ERROR/CRITICAL)
|
|
62
|
+
"""
|
|
63
|
+
if self._enabled:
|
|
64
|
+
return
|
|
65
|
+
|
|
66
|
+
log_path = get_log_path(workspace_root)
|
|
67
|
+
log_path.parent.mkdir(parents=True, exist_ok=True)
|
|
68
|
+
|
|
69
|
+
self._logger = logging.getLogger("agentx")
|
|
70
|
+
self._logger.setLevel(getattr(logging, level.upper(), logging.INFO))
|
|
71
|
+
self._logger.handlers.clear()
|
|
72
|
+
|
|
73
|
+
handler = logging.FileHandler(log_path, encoding="utf-8")
|
|
74
|
+
handler.setFormatter(logging.Formatter(LOG_FORMAT, LOG_DATE_FORMAT))
|
|
75
|
+
self._logger.addHandler(handler)
|
|
76
|
+
|
|
77
|
+
self._enabled = True
|
|
78
|
+
self.info("[OBSERVER] enabled log_file=%s", log_path)
|
|
79
|
+
|
|
80
|
+
def disable(self) -> None:
|
|
81
|
+
"""关闭观测日志,后续调用变为 no-op。"""
|
|
82
|
+
if not self._enabled:
|
|
83
|
+
return
|
|
84
|
+
|
|
85
|
+
self.info("[OBSERVER] disabling")
|
|
86
|
+
self._enabled = False
|
|
87
|
+
|
|
88
|
+
if self._logger:
|
|
89
|
+
for handler in self._logger.handlers[:]:
|
|
90
|
+
handler.close()
|
|
91
|
+
self._logger.removeHandler(handler)
|
|
92
|
+
self._logger = None
|
|
93
|
+
|
|
94
|
+
@property
|
|
95
|
+
def is_enabled(self) -> bool:
|
|
96
|
+
"""是否已启用。"""
|
|
97
|
+
return self._enabled
|
|
98
|
+
|
|
99
|
+
def _log(self, level: int, msg: str, *args, **kwargs) -> None:
|
|
100
|
+
"""内部日志方法。"""
|
|
101
|
+
if not self._enabled or self._logger is None:
|
|
102
|
+
return
|
|
103
|
+
self._logger.log(level, msg, *args, **kwargs)
|
|
104
|
+
|
|
105
|
+
def debug(self, msg: str, *args, **kwargs) -> None:
|
|
106
|
+
"""记录 DEBUG 级别日志。"""
|
|
107
|
+
self._log(logging.DEBUG, msg, *args, **kwargs)
|
|
108
|
+
|
|
109
|
+
def info(self, msg: str, *args, **kwargs) -> None:
|
|
110
|
+
"""记录 INFO 级别日志。"""
|
|
111
|
+
self._log(logging.INFO, msg, *args, **kwargs)
|
|
112
|
+
|
|
113
|
+
def warning(self, msg: str, *args, **kwargs) -> None:
|
|
114
|
+
"""记录 WARNING 级别日志。"""
|
|
115
|
+
self._log(logging.WARNING, msg, *args, **kwargs)
|
|
116
|
+
|
|
117
|
+
def error(self, msg: str, *args, **kwargs) -> None:
|
|
118
|
+
"""记录 ERROR 级别日志。"""
|
|
119
|
+
self._log(logging.ERROR, msg, *args, **kwargs)
|
|
120
|
+
|
|
121
|
+
def critical(self, msg: str, *args, **kwargs) -> None:
|
|
122
|
+
"""记录 CRITICAL 级别日志。"""
|
|
123
|
+
self._log(logging.CRITICAL, msg, *args, **kwargs)
|
|
124
|
+
|
|
125
|
+
|
|
126
|
+
# 全局单例实例
|
|
127
|
+
_observer: Observer = Observer()
|
|
128
|
+
|
|
129
|
+
|
|
130
|
+
def get_observer() -> Observer:
|
|
131
|
+
"""获取观测器单例实例。"""
|
|
132
|
+
return _observer
|
|
133
|
+
|
|
134
|
+
|
|
135
|
+
# 模块级便捷函数,直接调用单例方法
|
|
136
|
+
def enable(workspace_root: Path, level: str = DEFAULT_LOG_LEVEL) -> None:
|
|
137
|
+
"""启用观测日志。"""
|
|
138
|
+
_observer.enable(workspace_root, level)
|
|
139
|
+
|
|
140
|
+
|
|
141
|
+
def disable() -> None:
|
|
142
|
+
"""关闭观测日志。"""
|
|
143
|
+
_observer.disable()
|
|
144
|
+
|
|
145
|
+
|
|
146
|
+
def is_enabled() -> bool:
|
|
147
|
+
"""是否已启用。"""
|
|
148
|
+
return _observer.is_enabled
|
|
149
|
+
|
|
150
|
+
|
|
151
|
+
def debug(msg: str, *args, **kwargs) -> None:
|
|
152
|
+
"""记录 DEBUG 级别日志。"""
|
|
153
|
+
_observer.debug(msg, *args, **kwargs)
|
|
154
|
+
|
|
155
|
+
|
|
156
|
+
def info(msg: str, *args, **kwargs) -> None:
|
|
157
|
+
"""记录 INFO 级别日志。"""
|
|
158
|
+
_observer.info(msg, *args, **kwargs)
|
|
159
|
+
|
|
160
|
+
|
|
161
|
+
def warning(msg: str, *args, **kwargs) -> None:
|
|
162
|
+
"""记录 WARNING 级别日志。"""
|
|
163
|
+
_observer.warning(msg, *args, **kwargs)
|
|
164
|
+
|
|
165
|
+
|
|
166
|
+
def error(msg: str, *args, **kwargs) -> None:
|
|
167
|
+
"""记录 ERROR 级别日志。"""
|
|
168
|
+
_observer.error(msg, *args, **kwargs)
|
|
169
|
+
|
|
170
|
+
|
|
171
|
+
def critical(msg: str, *args, **kwargs) -> None:
|
|
172
|
+
"""记录 CRITICAL 级别日志。"""
|
|
173
|
+
_observer.critical(msg, *args, **kwargs)
|
{langchain_agentx_cli-0.2.1 → langchain_agentx_cli-0.2.2}/langchain_agentx_cli/screens/repl.py
RENAMED
|
@@ -88,9 +88,6 @@ class ReplScreen(Screen):
|
|
|
88
88
|
self._message_list().show_welcome(launch_config)
|
|
89
89
|
# Phase 3: 传递用户偏好配置给 MessageListWidget
|
|
90
90
|
if hasattr(app, "preferences"):
|
|
91
|
-
self._message_list().set_show_suppressed_text(
|
|
92
|
-
app.preferences.show_suppressed_text
|
|
93
|
-
)
|
|
94
91
|
# 对齐 CC:传递 verbose 模式(控制 thinking 内容显示)
|
|
95
92
|
self._message_list().set_verbose(app.preferences.verbose)
|
|
96
93
|
input_area = self.query_one("#input-area", InputAreaWidget)
|
|
@@ -23,7 +23,7 @@ from langchain_agentx.tool_runtime.resolvers import PermissionRequest
|
|
|
23
23
|
from langchain_agentx_cli.tui.permissions.cache import SessionPermissionCache
|
|
24
24
|
from langchain_agentx_cli.tui.permissions.models import PermissionDecision
|
|
25
25
|
from langchain_agentx_cli.tui.permissions.presenters import permission_presenter_for_tool
|
|
26
|
-
from langchain_agentx_cli.tui.permissions.queue import ConfirmQueue
|
|
26
|
+
from langchain_agentx_cli.tui.permissions.queue import ConfirmQueue, QueuedPermission
|
|
27
27
|
|
|
28
28
|
if TYPE_CHECKING:
|
|
29
29
|
from langchain_agentx_cli.app import ReplApp
|
|
@@ -38,6 +38,7 @@ class PermissionDecisionPort(Protocol):
|
|
|
38
38
|
self,
|
|
39
39
|
request: PermissionRequest,
|
|
40
40
|
cache: SessionPermissionCache,
|
|
41
|
+
queued: QueuedPermission | None = None,
|
|
41
42
|
) -> PermissionDecision:
|
|
42
43
|
"""返回用户对本次权限请求的决策。"""
|
|
43
44
|
|
|
@@ -49,8 +50,9 @@ class NoDialogPermissionDecisionPort:
|
|
|
49
50
|
self,
|
|
50
51
|
request: PermissionRequest,
|
|
51
52
|
cache: SessionPermissionCache,
|
|
53
|
+
queued: QueuedPermission | None = None,
|
|
52
54
|
) -> PermissionDecision:
|
|
53
|
-
del request, cache
|
|
55
|
+
del request, cache, queued
|
|
54
56
|
logger.debug("permission request denied (no dialog)")
|
|
55
57
|
return PermissionDecision.DENY
|
|
56
58
|
|