langchain-agentx-cli 0.5.2__tar.gz → 0.5.3__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.5.2 → langchain-agentx-cli-0.5.3}/PKG-INFO +1 -1
- {langchain-agentx-cli-0.5.2 → langchain-agentx-cli-0.5.3}/langchain_agentx_cli/__init__.py +1 -1
- {langchain-agentx-cli-0.5.2 → langchain-agentx-cli-0.5.3}/langchain_agentx_cli/widgets/message_list.py +4 -3
- {langchain-agentx-cli-0.5.2 → langchain-agentx-cli-0.5.3}/langchain_agentx_cli/widgets/messages/__init__.py +4 -0
- langchain-agentx-cli-0.5.3/langchain_agentx_cli/widgets/messages/streaming_assistant_message.py +323 -0
- {langchain-agentx-cli-0.5.2 → langchain-agentx-cli-0.5.3}/langchain_agentx_cli.egg-info/PKG-INFO +1 -1
- {langchain-agentx-cli-0.5.2 → langchain-agentx-cli-0.5.3}/langchain_agentx_cli.egg-info/SOURCES.txt +1 -0
- {langchain-agentx-cli-0.5.2 → langchain-agentx-cli-0.5.3}/langchain_agentx_cli.egg-info/requires.txt +1 -1
- {langchain-agentx-cli-0.5.2 → langchain-agentx-cli-0.5.3}/pyproject.toml +2 -2
- {langchain-agentx-cli-0.5.2 → langchain-agentx-cli-0.5.3}/LICENSE +0 -0
- {langchain-agentx-cli-0.5.2 → langchain-agentx-cli-0.5.3}/README.md +0 -0
- {langchain-agentx-cli-0.5.2 → langchain-agentx-cli-0.5.3}/langchain_agentx_cli/__main__.py +0 -0
- {langchain-agentx-cli-0.5.2 → langchain-agentx-cli-0.5.3}/langchain_agentx_cli/app.py +0 -0
- {langchain-agentx-cli-0.5.2 → langchain-agentx-cli-0.5.3}/langchain_agentx_cli/auto_mode_config.py +0 -0
- {langchain-agentx-cli-0.5.2 → langchain-agentx-cli-0.5.3}/langchain_agentx_cli/bootstrap.py +0 -0
- {langchain-agentx-cli-0.5.2 → langchain-agentx-cli-0.5.3}/langchain_agentx_cli/bridge/__init__.py +0 -0
- {langchain-agentx-cli-0.5.2 → langchain-agentx-cli-0.5.3}/langchain_agentx_cli/bridge/auto_mode_config_apply.py +0 -0
- {langchain-agentx-cli-0.5.2 → langchain-agentx-cli-0.5.3}/langchain_agentx_cli/bridge/auto_mode_messages.py +0 -0
- {langchain-agentx-cli-0.5.2 → langchain-agentx-cli-0.5.3}/langchain_agentx_cli/bridge/auto_mode_sink.py +0 -0
- {langchain-agentx-cli-0.5.2 → langchain-agentx-cli-0.5.3}/langchain_agentx_cli/bridge/auto_mode_status.py +0 -0
- {langchain-agentx-cli-0.5.2 → langchain-agentx-cli-0.5.3}/langchain_agentx_cli/bridge/boundary_inspector.py +0 -0
- {langchain-agentx-cli-0.5.2 → langchain-agentx-cli-0.5.3}/langchain_agentx_cli/bridge/cli_l3_user_ui_queue.py +0 -0
- {langchain-agentx-cli-0.5.2 → langchain-agentx-cli-0.5.3}/langchain_agentx_cli/bridge/deny_override.py +0 -0
- {langchain-agentx-cli-0.5.2 → langchain-agentx-cli-0.5.3}/langchain_agentx_cli/bridge/hook_constants.py +0 -0
- {langchain-agentx-cli-0.5.2 → langchain-agentx-cli-0.5.3}/langchain_agentx_cli/bridge/hook_payload.py +0 -0
- {langchain-agentx-cli-0.5.2 → langchain-agentx-cli-0.5.3}/langchain_agentx_cli/bridge/permission_mode_apply.py +0 -0
- {langchain-agentx-cli-0.5.2 → langchain-agentx-cli-0.5.3}/langchain_agentx_cli/bridge/permission_response_builder.py +0 -0
- {langchain-agentx-cli-0.5.2 → langchain-agentx-cli-0.5.3}/langchain_agentx_cli/bridge/permission_user_ui.py +0 -0
- {langchain-agentx-cli-0.5.2 → langchain-agentx-cli-0.5.3}/langchain_agentx_cli/bridge/session_bridge.py +0 -0
- {langchain-agentx-cli-0.5.2 → langchain-agentx-cli-0.5.3}/langchain_agentx_cli/cli.py +0 -0
- {langchain-agentx-cli-0.5.2 → langchain-agentx-cli-0.5.3}/langchain_agentx_cli/commands/__init__.py +0 -0
- {langchain-agentx-cli-0.5.2 → langchain-agentx-cli-0.5.3}/langchain_agentx_cli/commands/builtin/__init__.py +0 -0
- {langchain-agentx-cli-0.5.2 → langchain-agentx-cli-0.5.3}/langchain_agentx_cli/commands/builtin/auto_mode.py +0 -0
- {langchain-agentx-cli-0.5.2 → langchain-agentx-cli-0.5.3}/langchain_agentx_cli/commands/builtin/clear.py +0 -0
- {langchain-agentx-cli-0.5.2 → langchain-agentx-cli-0.5.3}/langchain_agentx_cli/commands/builtin/compact.py +0 -0
- {langchain-agentx-cli-0.5.2 → langchain-agentx-cli-0.5.3}/langchain_agentx_cli/commands/builtin/doctor.py +0 -0
- {langchain-agentx-cli-0.5.2 → langchain-agentx-cli-0.5.3}/langchain_agentx_cli/commands/builtin/grant.py +0 -0
- {langchain-agentx-cli-0.5.2 → langchain-agentx-cli-0.5.3}/langchain_agentx_cli/commands/builtin/grants.py +0 -0
- {langchain-agentx-cli-0.5.2 → langchain-agentx-cli-0.5.3}/langchain_agentx_cli/commands/builtin/help.py +0 -0
- {langchain-agentx-cli-0.5.2 → langchain-agentx-cli-0.5.3}/langchain_agentx_cli/commands/builtin/model.py +0 -0
- {langchain-agentx-cli-0.5.2 → langchain-agentx-cli-0.5.3}/langchain_agentx_cli/commands/builtin/permissions.py +0 -0
- {langchain-agentx-cli-0.5.2 → langchain-agentx-cli-0.5.3}/langchain_agentx_cli/commands/builtin/quit.py +0 -0
- {langchain-agentx-cli-0.5.2 → langchain-agentx-cli-0.5.3}/langchain_agentx_cli/commands/builtin/revoke.py +0 -0
- {langchain-agentx-cli-0.5.2 → langchain-agentx-cli-0.5.3}/langchain_agentx_cli/commands/builtin/roots.py +0 -0
- {langchain-agentx-cli-0.5.2 → langchain-agentx-cli-0.5.3}/langchain_agentx_cli/commands/builtin/theme.py +0 -0
- {langchain-agentx-cli-0.5.2 → langchain-agentx-cli-0.5.3}/langchain_agentx_cli/commands/parser.py +0 -0
- {langchain-agentx-cli-0.5.2 → langchain-agentx-cli-0.5.3}/langchain_agentx_cli/commands/providers/__init__.py +0 -0
- {langchain-agentx-cli-0.5.2 → langchain-agentx-cli-0.5.3}/langchain_agentx_cli/commands/providers/sdk_commands.py +0 -0
- {langchain-agentx-cli-0.5.2 → langchain-agentx-cli-0.5.3}/langchain_agentx_cli/commands/registry.py +0 -0
- {langchain-agentx-cli-0.5.2 → langchain-agentx-cli-0.5.3}/langchain_agentx_cli/completion/__init__.py +0 -0
- {langchain-agentx-cli-0.5.2 → langchain-agentx-cli-0.5.3}/langchain_agentx_cli/completion/base.py +0 -0
- {langchain-agentx-cli-0.5.2 → langchain-agentx-cli-0.5.3}/langchain_agentx_cli/completion/command_source.py +0 -0
- {langchain-agentx-cli-0.5.2 → langchain-agentx-cli-0.5.3}/langchain_agentx_cli/completion/history_source.py +0 -0
- {langchain-agentx-cli-0.5.2 → langchain-agentx-cli-0.5.3}/langchain_agentx_cli/config.py +0 -0
- {langchain-agentx-cli-0.5.2 → langchain-agentx-cli-0.5.3}/langchain_agentx_cli/health_report.py +0 -0
- {langchain-agentx-cli-0.5.2 → langchain-agentx-cli-0.5.3}/langchain_agentx_cli/history/__init__.py +0 -0
- {langchain-agentx-cli-0.5.2 → langchain-agentx-cli-0.5.3}/langchain_agentx_cli/history/store.py +0 -0
- {langchain-agentx-cli-0.5.2 → langchain-agentx-cli-0.5.3}/langchain_agentx_cli/keybindings/__init__.py +0 -0
- {langchain-agentx-cli-0.5.2 → langchain-agentx-cli-0.5.3}/langchain_agentx_cli/keybindings/bindings.py +0 -0
- {langchain-agentx-cli-0.5.2 → langchain-agentx-cli-0.5.3}/langchain_agentx_cli/launch_config_validator.py +0 -0
- {langchain-agentx-cli-0.5.2 → langchain-agentx-cli-0.5.3}/langchain_agentx_cli/llm_config.py +0 -0
- {langchain-agentx-cli-0.5.2 → langchain-agentx-cli-0.5.3}/langchain_agentx_cli/observation/__init__.py +0 -0
- {langchain-agentx-cli-0.5.2 → langchain-agentx-cli-0.5.3}/langchain_agentx_cli/observation/audit_subscriber.py +0 -0
- {langchain-agentx-cli-0.5.2 → langchain-agentx-cli-0.5.3}/langchain_agentx_cli/observation/config.py +0 -0
- {langchain-agentx-cli-0.5.2 → langchain-agentx-cli-0.5.3}/langchain_agentx_cli/observation/failure_counts.py +0 -0
- {langchain-agentx-cli-0.5.2 → langchain-agentx-cli-0.5.3}/langchain_agentx_cli/observation/failure_observation.py +0 -0
- {langchain-agentx-cli-0.5.2 → langchain-agentx-cli-0.5.3}/langchain_agentx_cli/observation/log_rotator.py +0 -0
- {langchain-agentx-cli-0.5.2 → langchain-agentx-cli-0.5.3}/langchain_agentx_cli/observation/observer.py +0 -0
- {langchain-agentx-cli-0.5.2 → langchain-agentx-cli-0.5.3}/langchain_agentx_cli/observation/session_context.py +0 -0
- {langchain-agentx-cli-0.5.2 → langchain-agentx-cli-0.5.3}/langchain_agentx_cli/permissions/__init__.py +0 -0
- {langchain-agentx-cli-0.5.2 → langchain-agentx-cli-0.5.3}/langchain_agentx_cli/permissions/factory.py +0 -0
- {langchain-agentx-cli-0.5.2 → langchain-agentx-cli-0.5.3}/langchain_agentx_cli/permissions/mode.py +0 -0
- {langchain-agentx-cli-0.5.2 → langchain-agentx-cli-0.5.3}/langchain_agentx_cli/permissions/policy.py +0 -0
- {langchain-agentx-cli-0.5.2 → langchain-agentx-cli-0.5.3}/langchain_agentx_cli/permissions/session_mode.py +0 -0
- {langchain-agentx-cli-0.5.2 → langchain-agentx-cli-0.5.3}/langchain_agentx_cli/prompts/__init__.py +0 -0
- {langchain-agentx-cli-0.5.2 → langchain-agentx-cli-0.5.3}/langchain_agentx_cli/prompts/assembler.py +0 -0
- {langchain-agentx-cli-0.5.2 → langchain-agentx-cli-0.5.3}/langchain_agentx_cli/prompts/sections.py +0 -0
- {langchain-agentx-cli-0.5.2 → langchain-agentx-cli-0.5.3}/langchain_agentx_cli/prompts/system_prompt.py +0 -0
- {langchain-agentx-cli-0.5.2 → langchain-agentx-cli-0.5.3}/langchain_agentx_cli/screens/__init__.py +0 -0
- {langchain-agentx-cli-0.5.2 → langchain-agentx-cli-0.5.3}/langchain_agentx_cli/screens/repl.py +0 -0
- {langchain-agentx-cli-0.5.2 → langchain-agentx-cli-0.5.3}/langchain_agentx_cli/session_factory.py +0 -0
- {langchain-agentx-cli-0.5.2 → langchain-agentx-cli-0.5.3}/langchain_agentx_cli/session_headless.py +0 -0
- {langchain-agentx-cli-0.5.2 → langchain-agentx-cli-0.5.3}/langchain_agentx_cli/session_options.py +0 -0
- {langchain-agentx-cli-0.5.2 → langchain-agentx-cli-0.5.3}/langchain_agentx_cli/state/__init__.py +0 -0
- {langchain-agentx-cli-0.5.2 → langchain-agentx-cli-0.5.3}/langchain_agentx_cli/state/task_store.py +0 -0
- {langchain-agentx-cli-0.5.2 → langchain-agentx-cli-0.5.3}/langchain_agentx_cli/theme/__init__.py +0 -0
- {langchain-agentx-cli-0.5.2 → langchain-agentx-cli-0.5.3}/langchain_agentx_cli/theme/colors.py +0 -0
- {langchain-agentx-cli-0.5.2 → langchain-agentx-cli-0.5.3}/langchain_agentx_cli/theme/detection.py +0 -0
- {langchain-agentx-cli-0.5.2 → langchain-agentx-cli-0.5.3}/langchain_agentx_cli/theme/manager.py +0 -0
- {langchain-agentx-cli-0.5.2 → langchain-agentx-cli-0.5.3}/langchain_agentx_cli/theme/settings.py +0 -0
- {langchain-agentx-cli-0.5.2 → langchain-agentx-cli-0.5.3}/langchain_agentx_cli/theme/system_theme.py +0 -0
- {langchain-agentx-cli-0.5.2 → langchain-agentx-cli-0.5.3}/langchain_agentx_cli/theme/themes.py +0 -0
- {langchain-agentx-cli-0.5.2 → langchain-agentx-cli-0.5.3}/langchain_agentx_cli/theme/watcher.py +0 -0
- {langchain-agentx-cli-0.5.2 → langchain-agentx-cli-0.5.3}/langchain_agentx_cli/tools/__init__.py +0 -0
- {langchain-agentx-cli-0.5.2 → langchain-agentx-cli-0.5.3}/langchain_agentx_cli/tools/registry.py +0 -0
- {langchain-agentx-cli-0.5.2 → langchain-agentx-cli-0.5.3}/langchain_agentx_cli/tui/__init__.py +0 -0
- {langchain-agentx-cli-0.5.2 → langchain-agentx-cli-0.5.3}/langchain_agentx_cli/tui/bootstrap.py +0 -0
- {langchain-agentx-cli-0.5.2 → langchain-agentx-cli-0.5.3}/langchain_agentx_cli/tui/clipboard.py +0 -0
- {langchain-agentx-cli-0.5.2 → langchain-agentx-cli-0.5.3}/langchain_agentx_cli/tui/memory_paths.py +0 -0
- {langchain-agentx-cli-0.5.2 → langchain-agentx-cli-0.5.3}/langchain_agentx_cli/tui/message_selection.py +0 -0
- {langchain-agentx-cli-0.5.2 → langchain-agentx-cli-0.5.3}/langchain_agentx_cli/tui/permissions/__init__.py +0 -0
- {langchain-agentx-cli-0.5.2 → langchain-agentx-cli-0.5.3}/langchain_agentx_cli/tui/permissions/cache.py +0 -0
- {langchain-agentx-cli-0.5.2 → langchain-agentx-cli-0.5.3}/langchain_agentx_cli/tui/permissions/component_manager.py +0 -0
- {langchain-agentx-cli-0.5.2 → langchain-agentx-cli-0.5.3}/langchain_agentx_cli/tui/permissions/config.py +0 -0
- {langchain-agentx-cli-0.5.2 → langchain-agentx-cli-0.5.3}/langchain_agentx_cli/tui/permissions/consumer.py +0 -0
- {langchain-agentx-cli-0.5.2 → langchain-agentx-cli-0.5.3}/langchain_agentx_cli/tui/permissions/dialog.py +0 -0
- {langchain-agentx-cli-0.5.2 → langchain-agentx-cli-0.5.3}/langchain_agentx_cli/tui/permissions/models.py +0 -0
- {langchain-agentx-cli-0.5.2 → langchain-agentx-cli-0.5.3}/langchain_agentx_cli/tui/permissions/persistent_rules.py +0 -0
- {langchain-agentx-cli-0.5.2 → langchain-agentx-cli-0.5.3}/langchain_agentx_cli/tui/permissions/presenters/__init__.py +0 -0
- {langchain-agentx-cli-0.5.2 → langchain-agentx-cli-0.5.3}/langchain_agentx_cli/tui/permissions/presenters/base.py +0 -0
- {langchain-agentx-cli-0.5.2 → langchain-agentx-cli-0.5.3}/langchain_agentx_cli/tui/permissions/presenters/bash.py +0 -0
- {langchain-agentx-cli-0.5.2 → langchain-agentx-cli-0.5.3}/langchain_agentx_cli/tui/permissions/presenters/fallback.py +0 -0
- {langchain-agentx-cli-0.5.2 → langchain-agentx-cli-0.5.3}/langchain_agentx_cli/tui/permissions/presenters/file.py +0 -0
- {langchain-agentx-cli-0.5.2 → langchain-agentx-cli-0.5.3}/langchain_agentx_cli/tui/permissions/queue.py +0 -0
- {langchain-agentx-cli-0.5.2 → langchain-agentx-cli-0.5.3}/langchain_agentx_cli/tui/permissions/requests/__init__.py +0 -0
- {langchain-agentx-cli-0.5.2 → langchain-agentx-cli-0.5.3}/langchain_agentx_cli/tui/permissions/requests/auto_mode_deny.py +0 -0
- {langchain-agentx-cli-0.5.2 → langchain-agentx-cli-0.5.3}/langchain_agentx_cli/tui/permissions/requests/base.py +0 -0
- {langchain-agentx-cli-0.5.2 → langchain-agentx-cli-0.5.3}/langchain_agentx_cli/tui/permissions/requests/boundary/__init__.py +0 -0
- {langchain-agentx-cli-0.5.2 → langchain-agentx-cli-0.5.3}/langchain_agentx_cli/tui/permissions/requests/boundary/extract.py +0 -0
- {langchain-agentx-cli-0.5.2 → langchain-agentx-cli-0.5.3}/langchain_agentx_cli/tui/permissions/requests/boundary/request.py +0 -0
- {langchain-agentx-cli-0.5.2 → langchain-agentx-cli-0.5.3}/langchain_agentx_cli/tui/permissions/requests/fallback/__init__.py +0 -0
- {langchain-agentx-cli-0.5.2 → langchain-agentx-cli-0.5.3}/langchain_agentx_cli/tui/permissions/requests/fallback/request.py +0 -0
- {langchain-agentx-cli-0.5.2 → langchain-agentx-cli-0.5.3}/langchain_agentx_cli/tui/permissions/requests/file/__init__.py +0 -0
- {langchain-agentx-cli-0.5.2 → langchain-agentx-cli-0.5.3}/langchain_agentx_cli/tui/permissions/requests/file/_base.py +0 -0
- {langchain-agentx-cli-0.5.2 → langchain-agentx-cli-0.5.3}/langchain_agentx_cli/tui/permissions/requests/file/diff.py +0 -0
- {langchain-agentx-cli-0.5.2 → langchain-agentx-cli-0.5.3}/langchain_agentx_cli/tui/permissions/requests/file/edit/__init__.py +0 -0
- {langchain-agentx-cli-0.5.2 → langchain-agentx-cli-0.5.3}/langchain_agentx_cli/tui/permissions/requests/file/edit/request.py +0 -0
- {langchain-agentx-cli-0.5.2 → langchain-agentx-cli-0.5.3}/langchain_agentx_cli/tui/permissions/requests/file/filesystem/__init__.py +0 -0
- {langchain-agentx-cli-0.5.2 → langchain-agentx-cli-0.5.3}/langchain_agentx_cli/tui/permissions/requests/file/filesystem/request.py +0 -0
- {langchain-agentx-cli-0.5.2 → langchain-agentx-cli-0.5.3}/langchain_agentx_cli/tui/permissions/requests/file/paths.py +0 -0
- {langchain-agentx-cli-0.5.2 → langchain-agentx-cli-0.5.3}/langchain_agentx_cli/tui/permissions/requests/file/write/__init__.py +0 -0
- {langchain-agentx-cli-0.5.2 → langchain-agentx-cli-0.5.3}/langchain_agentx_cli/tui/permissions/requests/file/write/request.py +0 -0
- {langchain-agentx-cli-0.5.2 → langchain-agentx-cli-0.5.3}/langchain_agentx_cli/tui/permissions/requests/plan_mode/__init__.py +0 -0
- {langchain-agentx-cli-0.5.2 → langchain-agentx-cli-0.5.3}/langchain_agentx_cli/tui/permissions/requests/plan_mode/request.py +0 -0
- {langchain-agentx-cli-0.5.2 → langchain-agentx-cli-0.5.3}/langchain_agentx_cli/tui/permissions/requests/shell/__init__.py +0 -0
- {langchain-agentx-cli-0.5.2 → langchain-agentx-cli-0.5.3}/langchain_agentx_cli/tui/permissions/requests/shell/bash/__init__.py +0 -0
- {langchain-agentx-cli-0.5.2 → langchain-agentx-cli-0.5.3}/langchain_agentx_cli/tui/permissions/requests/shell/bash/request.py +0 -0
- {langchain-agentx-cli-0.5.2 → langchain-agentx-cli-0.5.3}/langchain_agentx_cli/tui/permissions/requests/shell/extract.py +0 -0
- {langchain-agentx-cli-0.5.2 → langchain-agentx-cli-0.5.3}/langchain_agentx_cli/tui/permissions/requests/shell/helpers.py +0 -0
- {langchain-agentx-cli-0.5.2 → langchain-agentx-cli-0.5.3}/langchain_agentx_cli/tui/permissions/requests/skill/__init__.py +0 -0
- {langchain-agentx-cli-0.5.2 → langchain-agentx-cli-0.5.3}/langchain_agentx_cli/tui/permissions/requests/skill/request.py +0 -0
- {langchain-agentx-cli-0.5.2 → langchain-agentx-cli-0.5.3}/langchain_agentx_cli/tui/permissions/requests/webfetch/__init__.py +0 -0
- {langchain-agentx-cli-0.5.2 → langchain-agentx-cli-0.5.3}/langchain_agentx_cli/tui/permissions/requests/webfetch/request.py +0 -0
- {langchain-agentx-cli-0.5.2 → langchain-agentx-cli-0.5.3}/langchain_agentx_cli/tui/permissions/router.py +0 -0
- {langchain-agentx-cli-0.5.2 → langchain-agentx-cli-0.5.3}/langchain_agentx_cli/tui/safe_screen.py +0 -0
- {langchain-agentx-cli-0.5.2 → langchain-agentx-cli-0.5.3}/langchain_agentx_cli/tui/widgets/health_view.py +0 -0
- {langchain-agentx-cli-0.5.2 → langchain-agentx-cli-0.5.3}/langchain_agentx_cli/tui/workspace_trust.py +0 -0
- {langchain-agentx-cli-0.5.2 → langchain-agentx-cli-0.5.3}/langchain_agentx_cli/welcome.py +0 -0
- {langchain-agentx-cli-0.5.2 → langchain-agentx-cli-0.5.3}/langchain_agentx_cli/widgets/__init__.py +0 -0
- {langchain-agentx-cli-0.5.2 → langchain-agentx-cli-0.5.3}/langchain_agentx_cli/widgets/compact_progress.py +0 -0
- {langchain-agentx-cli-0.5.2 → langchain-agentx-cli-0.5.3}/langchain_agentx_cli/widgets/completion_overlay.py +0 -0
- {langchain-agentx-cli-0.5.2 → langchain-agentx-cli-0.5.3}/langchain_agentx_cli/widgets/footer.py +0 -0
- {langchain-agentx-cli-0.5.2 → langchain-agentx-cli-0.5.3}/langchain_agentx_cli/widgets/input_area.py +0 -0
- {langchain-agentx-cli-0.5.2 → langchain-agentx-cli-0.5.3}/langchain_agentx_cli/widgets/message_events.py +0 -0
- {langchain-agentx-cli-0.5.2 → langchain-agentx-cli-0.5.3}/langchain_agentx_cli/widgets/messages/assistant_message.py +0 -0
- {langchain-agentx-cli-0.5.2 → langchain-agentx-cli-0.5.3}/langchain_agentx_cli/widgets/messages/auto_mode_chip.py +0 -0
- {langchain-agentx-cli-0.5.2 → langchain-agentx-cli-0.5.3}/langchain_agentx_cli/widgets/messages/error_message.py +0 -0
- {langchain-agentx-cli-0.5.2 → langchain-agentx-cli-0.5.3}/langchain_agentx_cli/widgets/messages/hook_message.py +0 -0
- {langchain-agentx-cli-0.5.2 → langchain-agentx-cli-0.5.3}/langchain_agentx_cli/widgets/messages/rendering.py +0 -0
- {langchain-agentx-cli-0.5.2 → langchain-agentx-cli-0.5.3}/langchain_agentx_cli/widgets/messages/stop_hook_summary.py +0 -0
- {langchain-agentx-cli-0.5.2 → langchain-agentx-cli-0.5.3}/langchain_agentx_cli/widgets/messages/thinking_message.py +0 -0
- {langchain-agentx-cli-0.5.2 → langchain-agentx-cli-0.5.3}/langchain_agentx_cli/widgets/messages/tool_result.py +0 -0
- {langchain-agentx-cli-0.5.2 → langchain-agentx-cli-0.5.3}/langchain_agentx_cli/widgets/pending_permission.py +0 -0
- {langchain-agentx-cli-0.5.2 → langchain-agentx-cli-0.5.3}/langchain_agentx_cli/widgets/permission_inline.py +0 -0
- {langchain-agentx-cli-0.5.2 → langchain-agentx-cli-0.5.3}/langchain_agentx_cli/widgets/permission_keybindings.py +0 -0
- {langchain-agentx-cli-0.5.2 → langchain-agentx-cli-0.5.3}/langchain_agentx_cli/widgets/presentation/__init__.py +0 -0
- {langchain-agentx-cli-0.5.2 → langchain-agentx-cli-0.5.3}/langchain_agentx_cli/widgets/presentation/expand_hint.py +0 -0
- {langchain-agentx-cli-0.5.2 → langchain-agentx-cli-0.5.3}/langchain_agentx_cli/widgets/presentation/full_output.py +0 -0
- {langchain-agentx-cli-0.5.2 → langchain-agentx-cli-0.5.3}/langchain_agentx_cli/widgets/presentation/message_layout.py +0 -0
- {langchain-agentx-cli-0.5.2 → langchain-agentx-cli-0.5.3}/langchain_agentx_cli/widgets/presentation/shell_output.py +0 -0
- {langchain-agentx-cli-0.5.2 → langchain-agentx-cli-0.5.3}/langchain_agentx_cli/widgets/presentation/view_mode.py +0 -0
- {langchain-agentx-cli-0.5.2 → langchain-agentx-cli-0.5.3}/langchain_agentx_cli/widgets/spinner.py +0 -0
- {langchain-agentx-cli-0.5.2 → langchain-agentx-cli-0.5.3}/langchain_agentx_cli/widgets/status_bar.py +0 -0
- {langchain-agentx-cli-0.5.2 → langchain-agentx-cli-0.5.3}/langchain_agentx_cli/widgets/task_panel.py +0 -0
- {langchain-agentx-cli-0.5.2 → langchain-agentx-cli-0.5.3}/langchain_agentx_cli/widgets/tool_result/__init__.py +0 -0
- {langchain-agentx-cli-0.5.2 → langchain-agentx-cli-0.5.3}/langchain_agentx_cli/widgets/tool_result/base.py +0 -0
- {langchain-agentx-cli-0.5.2 → langchain-agentx-cli-0.5.3}/langchain_agentx_cli/widgets/tool_result/blocked_view.py +0 -0
- {langchain-agentx-cli-0.5.2 → langchain-agentx-cli-0.5.3}/langchain_agentx_cli/widgets/tool_result/error_view.py +0 -0
- {langchain-agentx-cli-0.5.2 → langchain-agentx-cli-0.5.3}/langchain_agentx_cli/widgets/tool_result/success_view.py +0 -0
- {langchain-agentx-cli-0.5.2 → langchain-agentx-cli-0.5.3}/langchain_agentx_cli/widgets/tools/__init__.py +0 -0
- {langchain-agentx-cli-0.5.2 → langchain-agentx-cli-0.5.3}/langchain_agentx_cli/widgets/tools/agent/__init__.py +0 -0
- {langchain-agentx-cli-0.5.2 → langchain-agentx-cli-0.5.3}/langchain_agentx_cli/widgets/tools/agent/widget.py +0 -0
- {langchain-agentx-cli-0.5.2 → langchain-agentx-cli-0.5.3}/langchain_agentx_cli/widgets/tools/ask_user_question/__init__.py +0 -0
- {langchain-agentx-cli-0.5.2 → langchain-agentx-cli-0.5.3}/langchain_agentx_cli/widgets/tools/ask_user_question/widget.py +0 -0
- {langchain-agentx-cli-0.5.2 → langchain-agentx-cli-0.5.3}/langchain_agentx_cli/widgets/tools/base.py +0 -0
- {langchain-agentx-cli-0.5.2 → langchain-agentx-cli-0.5.3}/langchain_agentx_cli/widgets/tools/bash/__init__.py +0 -0
- {langchain-agentx-cli-0.5.2 → langchain-agentx-cli-0.5.3}/langchain_agentx_cli/widgets/tools/bash/widget.py +0 -0
- {langchain-agentx-cli-0.5.2 → langchain-agentx-cli-0.5.3}/langchain_agentx_cli/widgets/tools/batch_edit/__init__.py +0 -0
- {langchain-agentx-cli-0.5.2 → langchain-agentx-cli-0.5.3}/langchain_agentx_cli/widgets/tools/batch_edit/widget.py +0 -0
- {langchain-agentx-cli-0.5.2 → langchain-agentx-cli-0.5.3}/langchain_agentx_cli/widgets/tools/edit/__init__.py +0 -0
- {langchain-agentx-cli-0.5.2 → langchain-agentx-cli-0.5.3}/langchain_agentx_cli/widgets/tools/edit/widget.py +0 -0
- {langchain-agentx-cli-0.5.2 → langchain-agentx-cli-0.5.3}/langchain_agentx_cli/widgets/tools/glob/__init__.py +0 -0
- {langchain-agentx-cli-0.5.2 → langchain-agentx-cli-0.5.3}/langchain_agentx_cli/widgets/tools/glob/widget.py +0 -0
- {langchain-agentx-cli-0.5.2 → langchain-agentx-cli-0.5.3}/langchain_agentx_cli/widgets/tools/grep/__init__.py +0 -0
- {langchain-agentx-cli-0.5.2 → langchain-agentx-cli-0.5.3}/langchain_agentx_cli/widgets/tools/grep/widget.py +0 -0
- {langchain-agentx-cli-0.5.2 → langchain-agentx-cli-0.5.3}/langchain_agentx_cli/widgets/tools/helpers.py +0 -0
- {langchain-agentx-cli-0.5.2 → langchain-agentx-cli-0.5.3}/langchain_agentx_cli/widgets/tools/read/__init__.py +0 -0
- {langchain-agentx-cli-0.5.2 → langchain-agentx-cli-0.5.3}/langchain_agentx_cli/widgets/tools/read/widget.py +0 -0
- {langchain-agentx-cli-0.5.2 → langchain-agentx-cli-0.5.3}/langchain_agentx_cli/widgets/tools/skill/__init__.py +0 -0
- {langchain-agentx-cli-0.5.2 → langchain-agentx-cli-0.5.3}/langchain_agentx_cli/widgets/tools/skill/widget.py +0 -0
- {langchain-agentx-cli-0.5.2 → langchain-agentx-cli-0.5.3}/langchain_agentx_cli/widgets/tools/user_message/__init__.py +0 -0
- {langchain-agentx-cli-0.5.2 → langchain-agentx-cli-0.5.3}/langchain_agentx_cli/widgets/tools/user_message/widget.py +0 -0
- {langchain-agentx-cli-0.5.2 → langchain-agentx-cli-0.5.3}/langchain_agentx_cli/widgets/tools/webfetch/__init__.py +0 -0
- {langchain-agentx-cli-0.5.2 → langchain-agentx-cli-0.5.3}/langchain_agentx_cli/widgets/tools/webfetch/widget.py +0 -0
- {langchain-agentx-cli-0.5.2 → langchain-agentx-cli-0.5.3}/langchain_agentx_cli/widgets/tools/websearch/__init__.py +0 -0
- {langchain-agentx-cli-0.5.2 → langchain-agentx-cli-0.5.3}/langchain_agentx_cli/widgets/tools/websearch/widget.py +0 -0
- {langchain-agentx-cli-0.5.2 → langchain-agentx-cli-0.5.3}/langchain_agentx_cli/widgets/tools/write/__init__.py +0 -0
- {langchain-agentx-cli-0.5.2 → langchain-agentx-cli-0.5.3}/langchain_agentx_cli/widgets/tools/write/widget.py +0 -0
- {langchain-agentx-cli-0.5.2 → langchain-agentx-cli-0.5.3}/langchain_agentx_cli.egg-info/dependency_links.txt +0 -0
- {langchain-agentx-cli-0.5.2 → langchain-agentx-cli-0.5.3}/langchain_agentx_cli.egg-info/entry_points.txt +0 -0
- {langchain-agentx-cli-0.5.2 → langchain-agentx-cli-0.5.3}/langchain_agentx_cli.egg-info/not-zip-safe +0 -0
- {langchain-agentx-cli-0.5.2 → langchain-agentx-cli-0.5.3}/langchain_agentx_cli.egg-info/top_level.txt +0 -0
- {langchain-agentx-cli-0.5.2 → langchain-agentx-cli-0.5.3}/setup.cfg +0 -0
|
@@ -35,6 +35,7 @@ from langchain_agentx_cli.widgets.messages import (
|
|
|
35
35
|
HookMessageWidget,
|
|
36
36
|
HookProgressed,
|
|
37
37
|
HookStarted,
|
|
38
|
+
StreamingAssistantMessage,
|
|
38
39
|
TaskProgress,
|
|
39
40
|
TaskStarted,
|
|
40
41
|
ThinkingContentDelta,
|
|
@@ -221,7 +222,7 @@ class MessageListWidget(ScrollableContainer):
|
|
|
221
222
|
|
|
222
223
|
def __init__(self, *args, **kwargs) -> None:
|
|
223
224
|
super().__init__(*args, **kwargs)
|
|
224
|
-
self._active_assistant: AssistantMessageWidget | None = None
|
|
225
|
+
self._active_assistant: StreamingAssistantMessage | AssistantMessageWidget | None = None
|
|
225
226
|
self._welcome_shown = False
|
|
226
227
|
self._pending_permission: InlinePermissionWidget | None = None
|
|
227
228
|
self._turn_spinner: SpinnerWidget | None = None
|
|
@@ -695,7 +696,7 @@ class MessageListWidget(ScrollableContainer):
|
|
|
695
696
|
|
|
696
697
|
if not chunk.delta and self._active_assistant is None:
|
|
697
698
|
info("[ML] creating new assistant widget (empty delta)")
|
|
698
|
-
line =
|
|
699
|
+
line = StreamingAssistantMessage(streaming=True)
|
|
699
700
|
self._mount_keeping_spinner_below(line)
|
|
700
701
|
self._active_assistant = line
|
|
701
702
|
self._scroll_to_end(force=True)
|
|
@@ -704,7 +705,7 @@ class MessageListWidget(ScrollableContainer):
|
|
|
704
705
|
if chunk.delta:
|
|
705
706
|
if self._active_assistant is None:
|
|
706
707
|
info("[ML] creating new assistant widget (first delta)")
|
|
707
|
-
line =
|
|
708
|
+
line = StreamingAssistantMessage(streaming=True)
|
|
708
709
|
self._mount_keeping_spinner_below(line)
|
|
709
710
|
self._active_assistant = line
|
|
710
711
|
self._scroll_to_end(force=True)
|
|
@@ -38,6 +38,9 @@ from langchain_agentx_cli.widgets.message_events import (
|
|
|
38
38
|
)
|
|
39
39
|
from langchain_agentx_cli.widgets.messages.assistant_message import AssistantMessageWidget
|
|
40
40
|
from langchain_agentx_cli.widgets.messages.error_message import ErrorMessageWidget
|
|
41
|
+
from langchain_agentx_cli.widgets.messages.streaming_assistant_message import (
|
|
42
|
+
StreamingAssistantMessage,
|
|
43
|
+
)
|
|
41
44
|
from langchain_agentx_cli.widgets.messages.hook_message import HookMessageWidget
|
|
42
45
|
from langchain_agentx_cli.widgets.messages.stop_hook_summary import StopHookSummaryWidget
|
|
43
46
|
from langchain_agentx_cli.widgets.messages.thinking_message import ThinkingMessageWidget
|
|
@@ -63,6 +66,7 @@ __all__ = [
|
|
|
63
66
|
"PermissionPendingShown",
|
|
64
67
|
"SpinnerCompletion",
|
|
65
68
|
"StopHookSummaryWidget",
|
|
69
|
+
"StreamingAssistantMessage",
|
|
66
70
|
"TaskProgress",
|
|
67
71
|
"TaskStarted",
|
|
68
72
|
"ThinkingContentDelta",
|
langchain-agentx-cli-0.5.3/langchain_agentx_cli/widgets/messages/streaming_assistant_message.py
ADDED
|
@@ -0,0 +1,323 @@
|
|
|
1
|
+
"""
|
|
2
|
+
widgets/messages/streaming_assistant_message.py — 双 Widget 流式渲染组件。
|
|
3
|
+
|
|
4
|
+
职责:
|
|
5
|
+
对齐 CC StreamingMarkdown:stable 用 Static(不解析),unstable 用 Markdown(流式)。
|
|
6
|
+
边界单调前进,stable 只增不减,避免重新解析已完成内容。
|
|
7
|
+
|
|
8
|
+
链路位置:
|
|
9
|
+
MessageListWidget.handle_assistant_chunk → StreamingAssistantMessage。
|
|
10
|
+
|
|
11
|
+
架构对比:
|
|
12
|
+
旧版(AssistantMessageWidget):单一 Markdown Widget,每次都重新解析整个内容
|
|
13
|
+
新版(本组件):双 Widget,stable 部分 Static 不触发 Markdown 解析
|
|
14
|
+
|
|
15
|
+
性能优化:
|
|
16
|
+
stable 长文本不再触发 Markdown.lexer(),O(1) vs O(n)
|
|
17
|
+
unstable 部分仍是 Markdown 解析,但长度受限(当前段落)
|
|
18
|
+
"""
|
|
19
|
+
|
|
20
|
+
from __future__ import annotations
|
|
21
|
+
|
|
22
|
+
from datetime import datetime
|
|
23
|
+
from typing import TYPE_CHECKING
|
|
24
|
+
|
|
25
|
+
import time
|
|
26
|
+
|
|
27
|
+
from textual.containers import Vertical
|
|
28
|
+
from textual.widgets import Markdown, Static
|
|
29
|
+
|
|
30
|
+
from langchain_agentx_cli.observation import info
|
|
31
|
+
from langchain_agentx_cli.widgets.messages.rendering import (
|
|
32
|
+
MAX_COLLAPSE_LINES,
|
|
33
|
+
STREAM_RENDER_INTERVAL_S,
|
|
34
|
+
STREAM_RENDER_MIN_CHARS,
|
|
35
|
+
escape_markdown_unsafe,
|
|
36
|
+
preprocess_assistant_markdown,
|
|
37
|
+
truncate_lines,
|
|
38
|
+
)
|
|
39
|
+
|
|
40
|
+
if TYPE_CHECKING:
|
|
41
|
+
from langchain_agentx_cli.app import ReplApp
|
|
42
|
+
|
|
43
|
+
_PARAGRAPH_SEPARATOR = "\n\n"
|
|
44
|
+
_METADATA_SEPARATOR = " · "
|
|
45
|
+
_BLACK_CIRCLE = "●"
|
|
46
|
+
_PLAIN_TEXT_SCAN_CHARS = 500
|
|
47
|
+
_MARKDOWN_PATTERN = __import__("re").compile(
|
|
48
|
+
r"(?m)^#{1,6}\s|" # 标题
|
|
49
|
+
r"`|" # 行内代码
|
|
50
|
+
r"\*\*|" # 粗体
|
|
51
|
+
r"\*|" # 斜体
|
|
52
|
+
r"\[.*?\]\(|" # 链接
|
|
53
|
+
r"^\s*[-*+]\s|" # 无序列表
|
|
54
|
+
r"^\s*\d+\.\s|" # 有序列表
|
|
55
|
+
r"^\s*>\s|" # 引用
|
|
56
|
+
r"\|" # 表格
|
|
57
|
+
)
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
def _looks_like_plain_text(text: str) -> bool:
|
|
61
|
+
"""快速检测文本是否为纯文本。"""
|
|
62
|
+
if not text:
|
|
63
|
+
return True
|
|
64
|
+
scan = text[:_PLAIN_TEXT_SCAN_CHARS]
|
|
65
|
+
return not bool(_MARKDOWN_PATTERN.search(scan))
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
def _format_timestamp() -> str:
|
|
69
|
+
"""格式化时间戳(HH:MM 格式)。"""
|
|
70
|
+
return datetime.now().strftime("%H:%M")
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
def _format_metadata(model: str | None, tokens: int | None = None) -> str:
|
|
74
|
+
"""格式化元数据行。"""
|
|
75
|
+
parts: list[str] = []
|
|
76
|
+
if model:
|
|
77
|
+
parts.append(model)
|
|
78
|
+
if tokens is not None and tokens > 0:
|
|
79
|
+
parts.append(f"{tokens} tokens")
|
|
80
|
+
parts.append(_format_timestamp())
|
|
81
|
+
return _METADATA_SEPARATOR.join(parts)
|
|
82
|
+
|
|
83
|
+
|
|
84
|
+
def _render_text_fast(text: str) -> str:
|
|
85
|
+
"""快速渲染文本:纯文本跳过 Markdown 解析。"""
|
|
86
|
+
if not text:
|
|
87
|
+
return ""
|
|
88
|
+
if _looks_like_plain_text(text):
|
|
89
|
+
return escape_markdown_unsafe(text)
|
|
90
|
+
return preprocess_assistant_markdown(text)
|
|
91
|
+
|
|
92
|
+
|
|
93
|
+
def _with_dot_prefix(content: str) -> str:
|
|
94
|
+
"""添加 BLACK_CIRCLE 前缀。"""
|
|
95
|
+
if not content:
|
|
96
|
+
return f"{_BLACK_CIRCLE} "
|
|
97
|
+
return f"{_BLACK_CIRCLE} {content}"
|
|
98
|
+
|
|
99
|
+
|
|
100
|
+
class StreamingAssistantMessage(Vertical):
|
|
101
|
+
"""双 Widget 流式助手消息(对齐 CC StreamingMarkdown)。
|
|
102
|
+
|
|
103
|
+
架构:
|
|
104
|
+
- _stable_widget: Static,已完成的段落,不再触发 Markdown 解析
|
|
105
|
+
- _unstable_widget: Markdown,当前增长中的段落,流式更新
|
|
106
|
+
|
|
107
|
+
边界前进:
|
|
108
|
+
- stable 只增不减(单调)
|
|
109
|
+
- 段落边界(\n\n)触发内容从 unstable 移动到 stable
|
|
110
|
+
"""
|
|
111
|
+
|
|
112
|
+
DEFAULT_CSS = """
|
|
113
|
+
StreamingAssistantMessage {
|
|
114
|
+
width: 100%;
|
|
115
|
+
height: auto;
|
|
116
|
+
margin: 1 0;
|
|
117
|
+
padding: 0 1;
|
|
118
|
+
background: $surface;
|
|
119
|
+
}
|
|
120
|
+
StreamingAssistantMessage.-streaming {
|
|
121
|
+
border-left: solid $accent;
|
|
122
|
+
}
|
|
123
|
+
StreamingAssistantMessage .stable-content {
|
|
124
|
+
width: 100%;
|
|
125
|
+
height: auto;
|
|
126
|
+
}
|
|
127
|
+
StreamingAssistantMessage .unstable-content {
|
|
128
|
+
width: 100%;
|
|
129
|
+
height: auto;
|
|
130
|
+
}
|
|
131
|
+
StreamingAssistantMessage .message-metadata {
|
|
132
|
+
text-align: right;
|
|
133
|
+
color: $text-muted;
|
|
134
|
+
text-style: dim;
|
|
135
|
+
margin: 1 0 0 0;
|
|
136
|
+
padding: 0 1;
|
|
137
|
+
}
|
|
138
|
+
"""
|
|
139
|
+
|
|
140
|
+
def __init__(self, content: str = "", *, streaming: bool = True) -> None:
|
|
141
|
+
classes = "message-assistant"
|
|
142
|
+
if streaming:
|
|
143
|
+
classes += " -streaming"
|
|
144
|
+
super().__init__(classes=classes)
|
|
145
|
+
|
|
146
|
+
# 内部状态
|
|
147
|
+
self._streaming = streaming
|
|
148
|
+
self._stable_text: str = "" # 已完成的段落(原始文本)
|
|
149
|
+
self._stable_rendered_blocks: list[str] = [] # 已渲染的段落块(增量追加)
|
|
150
|
+
self._last_stable_rendered: str = "" # 上次渲染的 stable(避免无谓更新)
|
|
151
|
+
self._unstable_buffer: str = "" # 当前增长中的段落
|
|
152
|
+
self._chars_since_render: int = 0
|
|
153
|
+
self._last_render_at: float = 0.0
|
|
154
|
+
|
|
155
|
+
# 子 Widget(延迟挂载,在首次 _ensure_widgets 时挂载)
|
|
156
|
+
self._stable_widget: Static | None = None
|
|
157
|
+
self._unstable_widget: Markdown | None = None
|
|
158
|
+
self._widgets_mounted: bool = False
|
|
159
|
+
|
|
160
|
+
# 初始内容
|
|
161
|
+
if content:
|
|
162
|
+
self._unstable_buffer = content
|
|
163
|
+
|
|
164
|
+
# 初始渲染(延迟到首次 update_content 或 finalize)
|
|
165
|
+
self._initial_content = content
|
|
166
|
+
|
|
167
|
+
@property
|
|
168
|
+
def text(self) -> str:
|
|
169
|
+
"""获取完整文本(stable + unstable)。"""
|
|
170
|
+
return self._stable_text + self._unstable_buffer
|
|
171
|
+
|
|
172
|
+
def _ensure_widgets(self) -> None:
|
|
173
|
+
"""确保子 Widget 已挂载(延迟挂载以支持测试环境)。"""
|
|
174
|
+
if self._widgets_mounted:
|
|
175
|
+
return
|
|
176
|
+
|
|
177
|
+
# 创建子 Widget
|
|
178
|
+
self._stable_widget = Static("", classes="stable-content")
|
|
179
|
+
self._unstable_widget = Markdown("", classes="unstable-content")
|
|
180
|
+
|
|
181
|
+
# 尝试挂载(如果没有 app,跳过挂载但保持内部状态)
|
|
182
|
+
try:
|
|
183
|
+
self.mount(self._stable_widget)
|
|
184
|
+
self.mount(self._unstable_widget)
|
|
185
|
+
self._widgets_mounted = True
|
|
186
|
+
|
|
187
|
+
# 初始渲染
|
|
188
|
+
if self._initial_content:
|
|
189
|
+
self._update_unstable_widget()
|
|
190
|
+
else:
|
|
191
|
+
self._unstable_widget.update(_with_dot_prefix(""))
|
|
192
|
+
except Exception:
|
|
193
|
+
# 无 app 环境(测试),跳过挂载
|
|
194
|
+
pass
|
|
195
|
+
|
|
196
|
+
def update_content(self, delta: str) -> None:
|
|
197
|
+
"""接收流式 delta,更新 unstable,检测段落边界。"""
|
|
198
|
+
# 确保子 Widget 已挂载
|
|
199
|
+
self._ensure_widgets()
|
|
200
|
+
|
|
201
|
+
if delta:
|
|
202
|
+
self._unstable_buffer += delta
|
|
203
|
+
self._chars_since_render += len(delta)
|
|
204
|
+
# 检查是否有段落边界(\n\n),有则移入 stable
|
|
205
|
+
self._try_flush_unstable_to_stable()
|
|
206
|
+
|
|
207
|
+
if self._should_render_now():
|
|
208
|
+
self._flush_render()
|
|
209
|
+
|
|
210
|
+
def _try_flush_unstable_to_stable(self) -> None:
|
|
211
|
+
"""检测段落边界,将已完成段落移入 stable(对齐 CC 边界单调前进)。"""
|
|
212
|
+
# 查找最后一个完整的段落边界(保留最后一个可能不完整的段落)
|
|
213
|
+
last_separator_idx = self._unstable_buffer.rfind(_PARAGRAPH_SEPARATOR)
|
|
214
|
+
if last_separator_idx == -1:
|
|
215
|
+
return
|
|
216
|
+
|
|
217
|
+
# 将边界之前的内容移入 stable
|
|
218
|
+
to_stable = self._unstable_buffer[: last_separator_idx + 2] # +2 保留 \n\n
|
|
219
|
+
self._unstable_buffer = self._unstable_buffer[last_separator_idx + 2 :]
|
|
220
|
+
|
|
221
|
+
# 更新 stable 文本
|
|
222
|
+
self._stable_text += to_stable
|
|
223
|
+
|
|
224
|
+
# 增量渲染:只渲染新增的 to_stable,避免重新处理整个 stable
|
|
225
|
+
newly_rendered = _render_text_fast(to_stable)
|
|
226
|
+
self._stable_rendered_blocks.append(newly_rendered)
|
|
227
|
+
|
|
228
|
+
# 拼接所有已渲染的块(用于 widget 更新)
|
|
229
|
+
stable_rendered = "\n\n".join(self._stable_rendered_blocks)
|
|
230
|
+
|
|
231
|
+
# 只在内容变化时更新(避免无谓重绘)
|
|
232
|
+
if stable_rendered != self._last_stable_rendered:
|
|
233
|
+
if self._stable_widget is not None:
|
|
234
|
+
self._stable_widget.update(_with_dot_prefix(stable_rendered))
|
|
235
|
+
self._last_stable_rendered = stable_rendered
|
|
236
|
+
|
|
237
|
+
info(
|
|
238
|
+
"[SAM] boundary advanced stable_len=%d unstable_len=%d blocks=%d",
|
|
239
|
+
len(self._stable_text),
|
|
240
|
+
len(self._unstable_buffer),
|
|
241
|
+
len(self._stable_rendered_blocks),
|
|
242
|
+
)
|
|
243
|
+
|
|
244
|
+
def _should_render_now(self) -> bool:
|
|
245
|
+
"""判断是否应该现在渲染(节流)。"""
|
|
246
|
+
if not self._streaming:
|
|
247
|
+
return True
|
|
248
|
+
if self._chars_since_render >= STREAM_RENDER_MIN_CHARS:
|
|
249
|
+
return True
|
|
250
|
+
if self._last_render_at == 0.0:
|
|
251
|
+
return True
|
|
252
|
+
return (time.monotonic() - self._last_render_at) >= STREAM_RENDER_INTERVAL_S
|
|
253
|
+
|
|
254
|
+
def _flush_render(self) -> None:
|
|
255
|
+
"""更新 unstable widget 的显示。"""
|
|
256
|
+
self._update_unstable_widget()
|
|
257
|
+
self._chars_since_render = 0
|
|
258
|
+
self._last_render_at = time.monotonic()
|
|
259
|
+
|
|
260
|
+
def _update_unstable_widget(self) -> str:
|
|
261
|
+
"""更新 unstable widget(Markdown 解析)。"""
|
|
262
|
+
# unstable 始终需要 Markdown 解析(因为可能在增长中)
|
|
263
|
+
unstable_rendered = _render_text_fast(self._unstable_buffer)
|
|
264
|
+
content = _with_dot_prefix(unstable_rendered) if unstable_rendered else _with_dot_prefix("")
|
|
265
|
+
if self._unstable_widget is not None:
|
|
266
|
+
self._unstable_widget.update(content)
|
|
267
|
+
return content
|
|
268
|
+
|
|
269
|
+
def finalize(
|
|
270
|
+
self,
|
|
271
|
+
*,
|
|
272
|
+
model: str | None = None,
|
|
273
|
+
tokens: int | None = None,
|
|
274
|
+
) -> None:
|
|
275
|
+
"""完成流式渲染,添加元数据行。"""
|
|
276
|
+
info(
|
|
277
|
+
"[SAM] finalize model=%s stable_len=%d unstable_len=%d",
|
|
278
|
+
model,
|
|
279
|
+
len(self._stable_text),
|
|
280
|
+
len(self._unstable_buffer),
|
|
281
|
+
)
|
|
282
|
+
|
|
283
|
+
self._streaming = False
|
|
284
|
+
self.remove_class("-streaming")
|
|
285
|
+
|
|
286
|
+
# 将剩余 unstable 全部移入 stable
|
|
287
|
+
if self._unstable_buffer:
|
|
288
|
+
self._stable_text += self._unstable_buffer
|
|
289
|
+
# 增量渲染:把剩余部分也加入 blocks
|
|
290
|
+
newly_rendered = _render_text_fast(self._unstable_buffer)
|
|
291
|
+
if newly_rendered:
|
|
292
|
+
self._stable_rendered_blocks.append(newly_rendered)
|
|
293
|
+
self._unstable_buffer = ""
|
|
294
|
+
|
|
295
|
+
# 截断超长内容
|
|
296
|
+
body = self._stable_text
|
|
297
|
+
truncated, was_truncated = truncate_lines(body, MAX_COLLAPSE_LINES)
|
|
298
|
+
if was_truncated:
|
|
299
|
+
truncated += f"\n\n… 输出超过 {MAX_COLLAPSE_LINES} 行,已截断"
|
|
300
|
+
self._stable_text = truncated
|
|
301
|
+
# 截断后需要重新构建 blocks(简单方式:重新渲染整个截断后的内容)
|
|
302
|
+
self._stable_rendered_blocks = [_render_text_fast(truncated)]
|
|
303
|
+
|
|
304
|
+
# 最终渲染(使用已渲染的块)
|
|
305
|
+
final_rendered = "\n\n".join(self._stable_rendered_blocks)
|
|
306
|
+
final_content = _with_dot_prefix(final_rendered) if final_rendered else _with_dot_prefix("")
|
|
307
|
+
|
|
308
|
+
# 追加元数据行
|
|
309
|
+
metadata = _format_metadata(model, tokens)
|
|
310
|
+
final_content += f"\n\n<div class='message-metadata'>{metadata}</div>"
|
|
311
|
+
|
|
312
|
+
# 移除 unstable widget(全部移入 stable)
|
|
313
|
+
if self._stable_widget is not None:
|
|
314
|
+
self._stable_widget.update(final_content)
|
|
315
|
+
if self._unstable_widget is not None and self._unstable_widget.is_attached:
|
|
316
|
+
self._unstable_widget.remove()
|
|
317
|
+
|
|
318
|
+
info("[SAM] finalized content_len=%d", len(final_content))
|
|
319
|
+
|
|
320
|
+
def set_verbose(self, value: bool) -> None:
|
|
321
|
+
"""设置 verbose 模式(占位,未来可能用于控制显示细节)。"""
|
|
322
|
+
# 对齐现有 API,当前暂无实现
|
|
323
|
+
pass
|
{langchain-agentx-cli-0.5.2 → langchain-agentx-cli-0.5.3}/langchain_agentx_cli.egg-info/SOURCES.txt
RENAMED
|
@@ -166,6 +166,7 @@ langchain_agentx_cli/widgets/messages/error_message.py
|
|
|
166
166
|
langchain_agentx_cli/widgets/messages/hook_message.py
|
|
167
167
|
langchain_agentx_cli/widgets/messages/rendering.py
|
|
168
168
|
langchain_agentx_cli/widgets/messages/stop_hook_summary.py
|
|
169
|
+
langchain_agentx_cli/widgets/messages/streaming_assistant_message.py
|
|
169
170
|
langchain_agentx_cli/widgets/messages/thinking_message.py
|
|
170
171
|
langchain_agentx_cli/widgets/messages/tool_result.py
|
|
171
172
|
langchain_agentx_cli/widgets/presentation/__init__.py
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "langchain-agentx-cli"
|
|
7
|
-
version = "0.5.
|
|
7
|
+
version = "0.5.3"
|
|
8
8
|
description = "Terminal CLI/TUI for AgentX: migrate Claude Code Ink UI, backed by langchain-agentx-python SDK."
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
requires-python = ">=3.11"
|
|
@@ -26,7 +26,7 @@ classifiers = [
|
|
|
26
26
|
"Topic :: Software Development",
|
|
27
27
|
]
|
|
28
28
|
dependencies = [
|
|
29
|
-
"langchain-agentx-python>=0.8.
|
|
29
|
+
"langchain-agentx-python>=0.8.4,<0.9.0",
|
|
30
30
|
"click>=8.1",
|
|
31
31
|
"textual>=0.79.0",
|
|
32
32
|
]
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{langchain-agentx-cli-0.5.2 → langchain-agentx-cli-0.5.3}/langchain_agentx_cli/auto_mode_config.py
RENAMED
|
File without changes
|
|
File without changes
|
{langchain-agentx-cli-0.5.2 → langchain-agentx-cli-0.5.3}/langchain_agentx_cli/bridge/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{langchain-agentx-cli-0.5.2 → langchain-agentx-cli-0.5.3}/langchain_agentx_cli/commands/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{langchain-agentx-cli-0.5.2 → langchain-agentx-cli-0.5.3}/langchain_agentx_cli/commands/parser.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{langchain-agentx-cli-0.5.2 → langchain-agentx-cli-0.5.3}/langchain_agentx_cli/commands/registry.py
RENAMED
|
File without changes
|
|
File without changes
|
{langchain-agentx-cli-0.5.2 → langchain-agentx-cli-0.5.3}/langchain_agentx_cli/completion/base.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{langchain-agentx-cli-0.5.2 → langchain-agentx-cli-0.5.3}/langchain_agentx_cli/health_report.py
RENAMED
|
File without changes
|
{langchain-agentx-cli-0.5.2 → langchain-agentx-cli-0.5.3}/langchain_agentx_cli/history/__init__.py
RENAMED
|
File without changes
|
{langchain-agentx-cli-0.5.2 → langchain-agentx-cli-0.5.3}/langchain_agentx_cli/history/store.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{langchain-agentx-cli-0.5.2 → langchain-agentx-cli-0.5.3}/langchain_agentx_cli/llm_config.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{langchain-agentx-cli-0.5.2 → langchain-agentx-cli-0.5.3}/langchain_agentx_cli/observation/config.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{langchain-agentx-cli-0.5.2 → langchain-agentx-cli-0.5.3}/langchain_agentx_cli/permissions/mode.py
RENAMED
|
File without changes
|
{langchain-agentx-cli-0.5.2 → langchain-agentx-cli-0.5.3}/langchain_agentx_cli/permissions/policy.py
RENAMED
|
File without changes
|
|
File without changes
|
{langchain-agentx-cli-0.5.2 → langchain-agentx-cli-0.5.3}/langchain_agentx_cli/prompts/__init__.py
RENAMED
|
File without changes
|
{langchain-agentx-cli-0.5.2 → langchain-agentx-cli-0.5.3}/langchain_agentx_cli/prompts/assembler.py
RENAMED
|
File without changes
|
{langchain-agentx-cli-0.5.2 → langchain-agentx-cli-0.5.3}/langchain_agentx_cli/prompts/sections.py
RENAMED
|
File without changes
|
|
File without changes
|
{langchain-agentx-cli-0.5.2 → langchain-agentx-cli-0.5.3}/langchain_agentx_cli/screens/__init__.py
RENAMED
|
File without changes
|
{langchain-agentx-cli-0.5.2 → langchain-agentx-cli-0.5.3}/langchain_agentx_cli/screens/repl.py
RENAMED
|
File without changes
|
{langchain-agentx-cli-0.5.2 → langchain-agentx-cli-0.5.3}/langchain_agentx_cli/session_factory.py
RENAMED
|
File without changes
|
{langchain-agentx-cli-0.5.2 → langchain-agentx-cli-0.5.3}/langchain_agentx_cli/session_headless.py
RENAMED
|
File without changes
|
{langchain-agentx-cli-0.5.2 → langchain-agentx-cli-0.5.3}/langchain_agentx_cli/session_options.py
RENAMED
|
File without changes
|
{langchain-agentx-cli-0.5.2 → langchain-agentx-cli-0.5.3}/langchain_agentx_cli/state/__init__.py
RENAMED
|
File without changes
|
{langchain-agentx-cli-0.5.2 → langchain-agentx-cli-0.5.3}/langchain_agentx_cli/state/task_store.py
RENAMED
|
File without changes
|
{langchain-agentx-cli-0.5.2 → langchain-agentx-cli-0.5.3}/langchain_agentx_cli/theme/__init__.py
RENAMED
|
File without changes
|
{langchain-agentx-cli-0.5.2 → langchain-agentx-cli-0.5.3}/langchain_agentx_cli/theme/colors.py
RENAMED
|
File without changes
|
{langchain-agentx-cli-0.5.2 → langchain-agentx-cli-0.5.3}/langchain_agentx_cli/theme/detection.py
RENAMED
|
File without changes
|
{langchain-agentx-cli-0.5.2 → langchain-agentx-cli-0.5.3}/langchain_agentx_cli/theme/manager.py
RENAMED
|
File without changes
|