langchain-agentx-cli 0.2.2__tar.gz → 0.3.1__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.
Files changed (142) hide show
  1. {langchain_agentx_cli-0.2.2 → langchain_agentx_cli-0.3.1}/PKG-INFO +2 -2
  2. {langchain_agentx_cli-0.2.2 → langchain_agentx_cli-0.3.1}/langchain_agentx_cli/__init__.py +1 -1
  3. {langchain_agentx_cli-0.2.2 → langchain_agentx_cli-0.3.1}/langchain_agentx_cli/app.py +18 -1
  4. {langchain_agentx_cli-0.2.2 → langchain_agentx_cli-0.3.1}/langchain_agentx_cli/bridge/session_bridge.py +177 -15
  5. {langchain_agentx_cli-0.2.2 → langchain_agentx_cli-0.3.1}/langchain_agentx_cli/cli.py +21 -4
  6. langchain_agentx_cli-0.3.1/langchain_agentx_cli/commands/builtin/compact.py +74 -0
  7. {langchain_agentx_cli-0.2.2 → langchain_agentx_cli-0.3.1}/langchain_agentx_cli/session_factory.py +32 -10
  8. {langchain_agentx_cli-0.2.2 → langchain_agentx_cli-0.3.1}/langchain_agentx_cli/state/task_store.py +63 -1
  9. {langchain_agentx_cli-0.2.2 → langchain_agentx_cli-0.3.1}/langchain_agentx_cli/tui/permissions/__init__.py +1 -3
  10. {langchain_agentx_cli-0.2.2 → langchain_agentx_cli-0.3.1}/langchain_agentx_cli/tui/permissions/presenters/base.py +2 -1
  11. {langchain_agentx_cli-0.2.2 → langchain_agentx_cli-0.3.1}/langchain_agentx_cli/tui/permissions/presenters/bash.py +35 -2
  12. {langchain_agentx_cli-0.2.2 → langchain_agentx_cli-0.3.1}/langchain_agentx_cli/widgets/message_events.py +122 -4
  13. {langchain_agentx_cli-0.2.2 → langchain_agentx_cli-0.3.1}/langchain_agentx_cli/widgets/message_list.py +257 -11
  14. {langchain_agentx_cli-0.2.2 → langchain_agentx_cli-0.3.1}/langchain_agentx_cli/widgets/messages/__init__.py +12 -0
  15. langchain_agentx_cli-0.3.1/langchain_agentx_cli/widgets/messages/hook_message.py +72 -0
  16. langchain_agentx_cli-0.3.1/langchain_agentx_cli/widgets/messages/stop_hook_summary.py +70 -0
  17. {langchain_agentx_cli-0.2.2 → langchain_agentx_cli-0.3.1}/langchain_agentx_cli/widgets/permission_inline.py +25 -27
  18. {langchain_agentx_cli-0.2.2 → langchain_agentx_cli-0.3.1}/langchain_agentx_cli/widgets/permission_keybindings.py +6 -16
  19. {langchain_agentx_cli-0.2.2 → langchain_agentx_cli-0.3.1}/langchain_agentx_cli/widgets/tools/__init__.py +15 -8
  20. {langchain_agentx_cli-0.2.2 → langchain_agentx_cli-0.3.1}/langchain_agentx_cli/widgets/tools/agent/widget.py +34 -1
  21. {langchain_agentx_cli-0.2.2 → langchain_agentx_cli-0.3.1}/langchain_agentx_cli/widgets/tools/ask_user_question/widget.py +34 -2
  22. {langchain_agentx_cli-0.2.2 → langchain_agentx_cli-0.3.1}/langchain_agentx_cli/widgets/tools/base.py +97 -15
  23. {langchain_agentx_cli-0.2.2 → langchain_agentx_cli-0.3.1}/langchain_agentx_cli/widgets/tools/bash/widget.py +41 -5
  24. {langchain_agentx_cli-0.2.2 → langchain_agentx_cli-0.3.1}/langchain_agentx_cli/widgets/tools/batch_edit/widget.py +30 -15
  25. {langchain_agentx_cli-0.2.2 → langchain_agentx_cli-0.3.1}/langchain_agentx_cli/widgets/tools/edit/widget.py +10 -5
  26. {langchain_agentx_cli-0.2.2 → langchain_agentx_cli-0.3.1}/langchain_agentx_cli/widgets/tools/glob/widget.py +10 -5
  27. {langchain_agentx_cli-0.2.2 → langchain_agentx_cli-0.3.1}/langchain_agentx_cli/widgets/tools/grep/widget.py +10 -5
  28. {langchain_agentx_cli-0.2.2 → langchain_agentx_cli-0.3.1}/langchain_agentx_cli/widgets/tools/helpers.py +56 -3
  29. {langchain_agentx_cli-0.2.2 → langchain_agentx_cli-0.3.1}/langchain_agentx_cli/widgets/tools/read/widget.py +46 -6
  30. {langchain_agentx_cli-0.2.2 → langchain_agentx_cli-0.3.1}/langchain_agentx_cli/widgets/tools/skill/widget.py +13 -6
  31. langchain_agentx_cli-0.3.1/langchain_agentx_cli/widgets/tools/user_message/widget.py +83 -0
  32. {langchain_agentx_cli-0.2.2 → langchain_agentx_cli-0.3.1}/langchain_agentx_cli/widgets/tools/webfetch/widget.py +20 -5
  33. {langchain_agentx_cli-0.2.2 → langchain_agentx_cli-0.3.1}/langchain_agentx_cli/widgets/tools/websearch/widget.py +15 -5
  34. {langchain_agentx_cli-0.2.2 → langchain_agentx_cli-0.3.1}/langchain_agentx_cli/widgets/tools/write/widget.py +13 -6
  35. {langchain_agentx_cli-0.2.2 → langchain_agentx_cli-0.3.1}/langchain_agentx_cli.egg-info/PKG-INFO +2 -2
  36. {langchain_agentx_cli-0.2.2 → langchain_agentx_cli-0.3.1}/langchain_agentx_cli.egg-info/SOURCES.txt +2 -1
  37. {langchain_agentx_cli-0.2.2 → langchain_agentx_cli-0.3.1}/langchain_agentx_cli.egg-info/requires.txt +1 -1
  38. {langchain_agentx_cli-0.2.2 → langchain_agentx_cli-0.3.1}/pyproject.toml +2 -2
  39. langchain_agentx_cli-0.2.2/langchain_agentx_cli/commands/builtin/compact.py +0 -44
  40. langchain_agentx_cli-0.2.2/langchain_agentx_cli/tui/permissions/inject.py +0 -57
  41. langchain_agentx_cli-0.2.2/langchain_agentx_cli/widgets/tools/user_message/widget.py +0 -88
  42. {langchain_agentx_cli-0.2.2 → langchain_agentx_cli-0.3.1}/LICENSE +0 -0
  43. {langchain_agentx_cli-0.2.2 → langchain_agentx_cli-0.3.1}/README.md +0 -0
  44. {langchain_agentx_cli-0.2.2 → langchain_agentx_cli-0.3.1}/langchain_agentx_cli/__main__.py +0 -0
  45. {langchain_agentx_cli-0.2.2 → langchain_agentx_cli-0.3.1}/langchain_agentx_cli/bootstrap.py +0 -0
  46. {langchain_agentx_cli-0.2.2 → langchain_agentx_cli-0.3.1}/langchain_agentx_cli/bridge/__init__.py +0 -0
  47. {langchain_agentx_cli-0.2.2 → langchain_agentx_cli-0.3.1}/langchain_agentx_cli/commands/__init__.py +0 -0
  48. {langchain_agentx_cli-0.2.2 → langchain_agentx_cli-0.3.1}/langchain_agentx_cli/commands/builtin/__init__.py +0 -0
  49. {langchain_agentx_cli-0.2.2 → langchain_agentx_cli-0.3.1}/langchain_agentx_cli/commands/builtin/clear.py +0 -0
  50. {langchain_agentx_cli-0.2.2 → langchain_agentx_cli-0.3.1}/langchain_agentx_cli/commands/builtin/help.py +0 -0
  51. {langchain_agentx_cli-0.2.2 → langchain_agentx_cli-0.3.1}/langchain_agentx_cli/commands/builtin/model.py +0 -0
  52. {langchain_agentx_cli-0.2.2 → langchain_agentx_cli-0.3.1}/langchain_agentx_cli/commands/builtin/quit.py +0 -0
  53. {langchain_agentx_cli-0.2.2 → langchain_agentx_cli-0.3.1}/langchain_agentx_cli/commands/builtin/theme.py +0 -0
  54. {langchain_agentx_cli-0.2.2 → langchain_agentx_cli-0.3.1}/langchain_agentx_cli/commands/parser.py +0 -0
  55. {langchain_agentx_cli-0.2.2 → langchain_agentx_cli-0.3.1}/langchain_agentx_cli/commands/providers/__init__.py +0 -0
  56. {langchain_agentx_cli-0.2.2 → langchain_agentx_cli-0.3.1}/langchain_agentx_cli/commands/providers/sdk_commands.py +0 -0
  57. {langchain_agentx_cli-0.2.2 → langchain_agentx_cli-0.3.1}/langchain_agentx_cli/commands/registry.py +0 -0
  58. {langchain_agentx_cli-0.2.2 → langchain_agentx_cli-0.3.1}/langchain_agentx_cli/completion/__init__.py +0 -0
  59. {langchain_agentx_cli-0.2.2 → langchain_agentx_cli-0.3.1}/langchain_agentx_cli/completion/base.py +0 -0
  60. {langchain_agentx_cli-0.2.2 → langchain_agentx_cli-0.3.1}/langchain_agentx_cli/completion/command_source.py +0 -0
  61. {langchain_agentx_cli-0.2.2 → langchain_agentx_cli-0.3.1}/langchain_agentx_cli/completion/history_source.py +0 -0
  62. {langchain_agentx_cli-0.2.2 → langchain_agentx_cli-0.3.1}/langchain_agentx_cli/config.py +0 -0
  63. {langchain_agentx_cli-0.2.2 → langchain_agentx_cli-0.3.1}/langchain_agentx_cli/history/__init__.py +0 -0
  64. {langchain_agentx_cli-0.2.2 → langchain_agentx_cli-0.3.1}/langchain_agentx_cli/history/store.py +0 -0
  65. {langchain_agentx_cli-0.2.2 → langchain_agentx_cli-0.3.1}/langchain_agentx_cli/keybindings/__init__.py +0 -0
  66. {langchain_agentx_cli-0.2.2 → langchain_agentx_cli-0.3.1}/langchain_agentx_cli/keybindings/bindings.py +0 -0
  67. {langchain_agentx_cli-0.2.2 → langchain_agentx_cli-0.3.1}/langchain_agentx_cli/llm_config.py +0 -0
  68. {langchain_agentx_cli-0.2.2 → langchain_agentx_cli-0.3.1}/langchain_agentx_cli/observation/__init__.py +0 -0
  69. {langchain_agentx_cli-0.2.2 → langchain_agentx_cli-0.3.1}/langchain_agentx_cli/observation/config.py +0 -0
  70. {langchain_agentx_cli-0.2.2 → langchain_agentx_cli-0.3.1}/langchain_agentx_cli/observation/observer.py +0 -0
  71. {langchain_agentx_cli-0.2.2 → langchain_agentx_cli-0.3.1}/langchain_agentx_cli/permissions/__init__.py +0 -0
  72. {langchain_agentx_cli-0.2.2 → langchain_agentx_cli-0.3.1}/langchain_agentx_cli/permissions/factory.py +0 -0
  73. {langchain_agentx_cli-0.2.2 → langchain_agentx_cli-0.3.1}/langchain_agentx_cli/permissions/policy.py +0 -0
  74. {langchain_agentx_cli-0.2.2 → langchain_agentx_cli-0.3.1}/langchain_agentx_cli/prompts/__init__.py +0 -0
  75. {langchain_agentx_cli-0.2.2 → langchain_agentx_cli-0.3.1}/langchain_agentx_cli/prompts/assembler.py +0 -0
  76. {langchain_agentx_cli-0.2.2 → langchain_agentx_cli-0.3.1}/langchain_agentx_cli/prompts/sections.py +0 -0
  77. {langchain_agentx_cli-0.2.2 → langchain_agentx_cli-0.3.1}/langchain_agentx_cli/prompts/system_prompt.py +0 -0
  78. {langchain_agentx_cli-0.2.2 → langchain_agentx_cli-0.3.1}/langchain_agentx_cli/screens/__init__.py +0 -0
  79. {langchain_agentx_cli-0.2.2 → langchain_agentx_cli-0.3.1}/langchain_agentx_cli/screens/repl.py +0 -0
  80. {langchain_agentx_cli-0.2.2 → langchain_agentx_cli-0.3.1}/langchain_agentx_cli/session_options.py +0 -0
  81. {langchain_agentx_cli-0.2.2 → langchain_agentx_cli-0.3.1}/langchain_agentx_cli/state/__init__.py +0 -0
  82. {langchain_agentx_cli-0.2.2 → langchain_agentx_cli-0.3.1}/langchain_agentx_cli/theme/__init__.py +0 -0
  83. {langchain_agentx_cli-0.2.2 → langchain_agentx_cli-0.3.1}/langchain_agentx_cli/theme/colors.py +0 -0
  84. {langchain_agentx_cli-0.2.2 → langchain_agentx_cli-0.3.1}/langchain_agentx_cli/theme/detection.py +0 -0
  85. {langchain_agentx_cli-0.2.2 → langchain_agentx_cli-0.3.1}/langchain_agentx_cli/theme/manager.py +0 -0
  86. {langchain_agentx_cli-0.2.2 → langchain_agentx_cli-0.3.1}/langchain_agentx_cli/theme/settings.py +0 -0
  87. {langchain_agentx_cli-0.2.2 → langchain_agentx_cli-0.3.1}/langchain_agentx_cli/theme/system_theme.py +0 -0
  88. {langchain_agentx_cli-0.2.2 → langchain_agentx_cli-0.3.1}/langchain_agentx_cli/theme/themes.py +0 -0
  89. {langchain_agentx_cli-0.2.2 → langchain_agentx_cli-0.3.1}/langchain_agentx_cli/theme/watcher.py +0 -0
  90. {langchain_agentx_cli-0.2.2 → langchain_agentx_cli-0.3.1}/langchain_agentx_cli/tools/__init__.py +0 -0
  91. {langchain_agentx_cli-0.2.2 → langchain_agentx_cli-0.3.1}/langchain_agentx_cli/tools/registry.py +0 -0
  92. {langchain_agentx_cli-0.2.2 → langchain_agentx_cli-0.3.1}/langchain_agentx_cli/tui/__init__.py +0 -0
  93. {langchain_agentx_cli-0.2.2 → langchain_agentx_cli-0.3.1}/langchain_agentx_cli/tui/clipboard.py +0 -0
  94. {langchain_agentx_cli-0.2.2 → langchain_agentx_cli-0.3.1}/langchain_agentx_cli/tui/message_selection.py +0 -0
  95. {langchain_agentx_cli-0.2.2 → langchain_agentx_cli-0.3.1}/langchain_agentx_cli/tui/permissions/cache.py +0 -0
  96. {langchain_agentx_cli-0.2.2 → langchain_agentx_cli-0.3.1}/langchain_agentx_cli/tui/permissions/component_manager.py +0 -0
  97. {langchain_agentx_cli-0.2.2 → langchain_agentx_cli-0.3.1}/langchain_agentx_cli/tui/permissions/config.py +0 -0
  98. {langchain_agentx_cli-0.2.2 → langchain_agentx_cli-0.3.1}/langchain_agentx_cli/tui/permissions/consumer.py +0 -0
  99. {langchain_agentx_cli-0.2.2 → langchain_agentx_cli-0.3.1}/langchain_agentx_cli/tui/permissions/dialog.py +0 -0
  100. {langchain_agentx_cli-0.2.2 → langchain_agentx_cli-0.3.1}/langchain_agentx_cli/tui/permissions/models.py +0 -0
  101. {langchain_agentx_cli-0.2.2 → langchain_agentx_cli-0.3.1}/langchain_agentx_cli/tui/permissions/presenters/__init__.py +0 -0
  102. {langchain_agentx_cli-0.2.2 → langchain_agentx_cli-0.3.1}/langchain_agentx_cli/tui/permissions/presenters/fallback.py +0 -0
  103. {langchain_agentx_cli-0.2.2 → langchain_agentx_cli-0.3.1}/langchain_agentx_cli/tui/permissions/presenters/file.py +0 -0
  104. {langchain_agentx_cli-0.2.2 → langchain_agentx_cli-0.3.1}/langchain_agentx_cli/tui/permissions/queue.py +0 -0
  105. {langchain_agentx_cli-0.2.2 → langchain_agentx_cli-0.3.1}/langchain_agentx_cli/tui/safe_screen.py +0 -0
  106. {langchain_agentx_cli-0.2.2 → langchain_agentx_cli-0.3.1}/langchain_agentx_cli/welcome.py +0 -0
  107. {langchain_agentx_cli-0.2.2 → langchain_agentx_cli-0.3.1}/langchain_agentx_cli/widgets/__init__.py +0 -0
  108. {langchain_agentx_cli-0.2.2 → langchain_agentx_cli-0.3.1}/langchain_agentx_cli/widgets/compact_progress.py +0 -0
  109. {langchain_agentx_cli-0.2.2 → langchain_agentx_cli-0.3.1}/langchain_agentx_cli/widgets/completion_overlay.py +0 -0
  110. {langchain_agentx_cli-0.2.2 → langchain_agentx_cli-0.3.1}/langchain_agentx_cli/widgets/input_area.py +0 -0
  111. {langchain_agentx_cli-0.2.2 → langchain_agentx_cli-0.3.1}/langchain_agentx_cli/widgets/messages/assistant_message.py +0 -0
  112. {langchain_agentx_cli-0.2.2 → langchain_agentx_cli-0.3.1}/langchain_agentx_cli/widgets/messages/error_message.py +0 -0
  113. {langchain_agentx_cli-0.2.2 → langchain_agentx_cli-0.3.1}/langchain_agentx_cli/widgets/messages/rendering.py +0 -0
  114. {langchain_agentx_cli-0.2.2 → langchain_agentx_cli-0.3.1}/langchain_agentx_cli/widgets/messages/thinking_message.py +0 -0
  115. {langchain_agentx_cli-0.2.2 → langchain_agentx_cli-0.3.1}/langchain_agentx_cli/widgets/pending_permission.py +0 -0
  116. {langchain_agentx_cli-0.2.2 → langchain_agentx_cli-0.3.1}/langchain_agentx_cli/widgets/spinner.py +0 -0
  117. {langchain_agentx_cli-0.2.2 → langchain_agentx_cli-0.3.1}/langchain_agentx_cli/widgets/task_panel.py +0 -0
  118. {langchain_agentx_cli-0.2.2 → langchain_agentx_cli-0.3.1}/langchain_agentx_cli/widgets/tools/agent/__init__.py +0 -0
  119. {langchain_agentx_cli-0.2.2 → langchain_agentx_cli-0.3.1}/langchain_agentx_cli/widgets/tools/ask_user_question/__init__.py +0 -0
  120. {langchain_agentx_cli-0.2.2 → langchain_agentx_cli-0.3.1}/langchain_agentx_cli/widgets/tools/bash/__init__.py +0 -0
  121. {langchain_agentx_cli-0.2.2 → langchain_agentx_cli-0.3.1}/langchain_agentx_cli/widgets/tools/batch_edit/__init__.py +0 -0
  122. {langchain_agentx_cli-0.2.2 → langchain_agentx_cli-0.3.1}/langchain_agentx_cli/widgets/tools/edit/__init__.py +0 -0
  123. {langchain_agentx_cli-0.2.2 → langchain_agentx_cli-0.3.1}/langchain_agentx_cli/widgets/tools/glob/__init__.py +0 -0
  124. {langchain_agentx_cli-0.2.2 → langchain_agentx_cli-0.3.1}/langchain_agentx_cli/widgets/tools/grep/__init__.py +0 -0
  125. {langchain_agentx_cli-0.2.2 → langchain_agentx_cli-0.3.1}/langchain_agentx_cli/widgets/tools/read/__init__.py +0 -0
  126. {langchain_agentx_cli-0.2.2 → langchain_agentx_cli-0.3.1}/langchain_agentx_cli/widgets/tools/skill/__init__.py +0 -0
  127. {langchain_agentx_cli-0.2.2 → langchain_agentx_cli-0.3.1}/langchain_agentx_cli/widgets/tools/user_message/__init__.py +0 -0
  128. {langchain_agentx_cli-0.2.2 → langchain_agentx_cli-0.3.1}/langchain_agentx_cli/widgets/tools/webfetch/__init__.py +0 -0
  129. {langchain_agentx_cli-0.2.2 → langchain_agentx_cli-0.3.1}/langchain_agentx_cli/widgets/tools/websearch/__init__.py +0 -0
  130. {langchain_agentx_cli-0.2.2 → langchain_agentx_cli-0.3.1}/langchain_agentx_cli/widgets/tools/write/__init__.py +0 -0
  131. {langchain_agentx_cli-0.2.2 → langchain_agentx_cli-0.3.1}/langchain_agentx_cli.egg-info/dependency_links.txt +0 -0
  132. {langchain_agentx_cli-0.2.2 → langchain_agentx_cli-0.3.1}/langchain_agentx_cli.egg-info/entry_points.txt +0 -0
  133. {langchain_agentx_cli-0.2.2 → langchain_agentx_cli-0.3.1}/langchain_agentx_cli.egg-info/not-zip-safe +0 -0
  134. {langchain_agentx_cli-0.2.2 → langchain_agentx_cli-0.3.1}/langchain_agentx_cli.egg-info/top_level.txt +0 -0
  135. {langchain_agentx_cli-0.2.2 → langchain_agentx_cli-0.3.1}/setup.cfg +0 -0
  136. {langchain_agentx_cli-0.2.2 → langchain_agentx_cli-0.3.1}/tests/test_app_interrupt.py +0 -0
  137. {langchain_agentx_cli-0.2.2 → langchain_agentx_cli-0.3.1}/tests/test_llm_config_chain.py +0 -0
  138. {langchain_agentx_cli-0.2.2 → langchain_agentx_cli-0.3.1}/tests/test_repl_commands.py +0 -0
  139. {langchain_agentx_cli-0.2.2 → langchain_agentx_cli-0.3.1}/tests/test_repl_submit_flow.py +0 -0
  140. {langchain_agentx_cli-0.2.2 → langchain_agentx_cli-0.3.1}/tests/test_repl_ui.py +0 -0
  141. {langchain_agentx_cli-0.2.2 → langchain_agentx_cli-0.3.1}/tests/test_smoke.py +0 -0
  142. {langchain_agentx_cli-0.2.2 → langchain_agentx_cli-0.3.1}/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.2
3
+ Version: 0.3.1
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.7
25
+ Requires-Dist: langchain-agentx-python<0.6.0,>=0.4.5
26
26
  Requires-Dist: click>=8.1
27
27
  Requires-Dist: textual>=0.79.0
28
28
  Provides-Extra: dev
@@ -1,3 +1,3 @@
1
1
  """langchain_agentx_cli:依托 langchain_agentx_python SDK 的终端 CLI/TUI(CC Ink 迁移)。"""
2
2
 
3
- __version__ = "0.2.2"
3
+ __version__ = "0.3.1"
@@ -10,6 +10,7 @@ app.py — Textual ReplApp 容器。
10
10
 
11
11
  from __future__ import annotations
12
12
 
13
+ import asyncio
13
14
  from pathlib import Path
14
15
  from typing import TYPE_CHECKING
15
16
 
@@ -36,6 +37,10 @@ from langchain_agentx_cli.widgets.messages import UserMessage
36
37
 
37
38
  if TYPE_CHECKING:
38
39
  from langchain_agentx import AgentSession
40
+ from langchain_agentx.tool_runtime.resolvers import (
41
+ AgentSessionPermissionResolver,
42
+ PermissionRequest,
43
+ )
39
44
 
40
45
  _CANCEL_HINT = "已取消当前生成。再次按 Ctrl+C 退出。"
41
46
  _EXIT_HINT = "再次按 Ctrl+C 退出。"
@@ -64,11 +69,15 @@ class ReplApp(App[None]):
64
69
  self,
65
70
  launch_config: ReplLaunchConfig,
66
71
  session: AgentSession | None = None,
72
+ permission_queue: asyncio.Queue[PermissionRequest] | None = None,
73
+ permission_resolver: AgentSessionPermissionResolver | None = None,
67
74
  debug: bool = False,
68
75
  ) -> None:
69
76
  super().__init__()
70
77
  self._launch_config = launch_config
71
78
  self._session = session
79
+ self._permission_queue = permission_queue
80
+ self._permission_resolver = permission_resolver
72
81
  self._bridge: SessionBridge | None = None
73
82
  self._exit_armed = False
74
83
  self.command_registry = CommandRegistry()
@@ -109,7 +118,15 @@ class ReplApp(App[None]):
109
118
  self.theme_manager = ThemeManager(self)
110
119
  self.theme_manager.setup(initial=initial_setting)
111
120
  if self._session is not None:
112
- self._bridge = SessionBridge(self, self._session)
121
+ # 方案 A: 传入预先创建的 permission_queue 和 permission_resolver
122
+ if self._permission_queue is None or self._permission_resolver is None:
123
+ raise RuntimeError("permission_queue 和 permission_resolver 必须由 open_agent_session 提供")
124
+ self._bridge = SessionBridge(
125
+ self,
126
+ self._session,
127
+ permission_queue=self._permission_queue,
128
+ permission_resolver=self._permission_resolver,
129
+ )
113
130
  register_sdk_commands(self.command_registry, self._session)
114
131
  self._bridge.permission_consumer.start()
115
132
  self.push_screen(ReplScreen())
@@ -29,7 +29,6 @@ from langchain_agentx_cli.observation import debug, info
29
29
  from langchain_agentx_cli.tui.permissions import (
30
30
  PermissionQueueConsumer,
31
31
  SessionPermissionCache,
32
- inject_permission_resolver,
33
32
  )
34
33
  from langchain_agentx_cli.tui.permissions.config import DEFAULT_PERMISSION_TIMEOUT_SECONDS
35
34
  from langchain_agentx_cli.tui.permissions.dialog import DialogPermissionDecisionPort
@@ -46,6 +45,10 @@ from langchain_agentx_cli.widgets.messages import (
46
45
  ContextCompactedMessage,
47
46
  ContextCompactingMessage,
48
47
  ErrorMessageOccurred,
48
+ HookFinished,
49
+ HookStarted,
50
+ TaskProgress,
51
+ TaskStarted,
49
52
  ThinkingContentDelta,
50
53
  ThinkingEnded,
51
54
  ThinkingStarted,
@@ -63,9 +66,9 @@ if TYPE_CHECKING:
63
66
  MVP_ADAPTER_CONFIG: dict[str, bool] = {
64
67
  "enable_reasoning_events": True,
65
68
  "enable_step_events": False,
66
- "enable_hook_events": False,
69
+ "enable_hook_events": True, # 启用 Hook 事件
67
70
  "enable_compact_events": True,
68
- "enable_subagent_events": False,
71
+ "enable_subagent_events": True, # Phase 3: 启用子 agent 事件
69
72
  "synthesize_tool_call": True,
70
73
  }
71
74
 
@@ -85,22 +88,26 @@ class _TurnSegmentState:
85
88
  class SessionBridge:
86
89
  """TUI 与 SDK 之间的桥接层(消费 LangchainAgentEvent)。"""
87
90
 
88
- def __init__(self, app: ReplApp, session: AgentSession) -> None:
91
+ def __init__(
92
+ self,
93
+ app: ReplApp,
94
+ session: AgentSession,
95
+ *,
96
+ permission_queue: asyncio.Queue[PermissionRequest],
97
+ permission_resolver: AgentSessionPermissionResolver,
98
+ ) -> None:
89
99
  self._app = app
90
100
  self._screen_messenger = app.screen_messenger
91
101
  self._session = session
92
102
  self._adapter = LangGraphToLangchainAgentEventAdapter(config=dict(MVP_ADAPTER_CONFIG))
93
103
  self._current_worker: Any = None
94
104
  self._seg = _TurnSegmentState()
95
- # 对齐 CC: 集中式权限队列状态管理
96
- self._permission_queue: asyncio.Queue[PermissionRequest] = asyncio.Queue()
105
+ # 方案 A: 接收预先创建的 queue 和 resolver(由 open_agent_session 传入)
106
+ self._permission_queue = permission_queue
97
107
  self._permission_cache = SessionPermissionCache()
98
108
  self._confirm_queue = ConfirmQueue(max_size=10) # 对齐 CC confirmQueue
99
- self._permission_resolver = AgentSessionPermissionResolver(
100
- request_queue=self._permission_queue,
101
- timeout=DEFAULT_PERMISSION_TIMEOUT_SECONDS,
102
- )
103
- inject_permission_resolver(session, self._permission_resolver)
109
+ self._permission_resolver = permission_resolver
110
+ # 不再需要 inject_permission_resolver,SDK 在编译时已使用传入的 resolver
104
111
  self._permission_consumer = PermissionQueueConsumer(
105
112
  queue=self._permission_queue,
106
113
  cache=self._permission_cache,
@@ -112,6 +119,27 @@ class SessionBridge:
112
119
  def _post_ui(self, message: object) -> None:
113
120
  self._screen_messenger.post(message)
114
121
 
122
+ @staticmethod
123
+ def _build_fallback_text(data: dict[str, Any]) -> str:
124
+ """为未升级的 widget 提供兜底渲染文本:summary + payload。
125
+
126
+ 与 SDK envelope_to_tool_output 的语义一致(summary\\npayload),
127
+ 让仍按 event.output 字符串渲染的 widget 不需要改动即可工作。
128
+ """
129
+ summary = str(data.get("summary", ""))
130
+ payload = data.get("payload")
131
+ if payload is None or payload == "":
132
+ return summary
133
+ if isinstance(payload, str):
134
+ payload_str = payload
135
+ else:
136
+ import json
137
+ try:
138
+ payload_str = json.dumps(payload, ensure_ascii=False)
139
+ except (TypeError, ValueError):
140
+ payload_str = str(payload)
141
+ return f"{summary}\n{payload_str}" if summary else payload_str
142
+
115
143
  def submit_input(self, text: str) -> None:
116
144
  self._post_ui(UserMessage(content=text))
117
145
  self._post_ui(TurnInProgress(in_progress=True))
@@ -168,30 +196,56 @@ class SessionBridge:
168
196
  )
169
197
  case LangchainAgentEventType.TOOL_INPUT:
170
198
  tool_input = data.get("input")
199
+ tool_name = str(data.get("tool_name", ""))
171
200
  if not isinstance(tool_input, dict):
172
201
  tool_input = data.get("params") if isinstance(data.get("params"), dict) else {}
202
+ info("[BRIDGE] TOOL_INPUT tool_name=%s", tool_name)
173
203
  self._post_ui(
174
204
  ToolUseStarted(
175
- tool_name=str(data.get("tool_name", "")),
205
+ tool_name=tool_name,
176
206
  tool_input=tool_input,
177
207
  )
178
208
  )
179
209
  case LangchainAgentEventType.TOOL_CALL:
210
+ tool_name = str(data.get("tool_name", ""))
211
+ info("[BRIDGE] TOOL_CALL tool_name=%s", tool_name)
180
212
  pass
181
213
  case LangchainAgentEventType.TOOL_RESULT:
214
+ tool_name = str(data.get("tool_name", ""))
215
+ fallback_output = self._build_fallback_text(data)
216
+ info(
217
+ "[BRIDGE] TOOL_RESULT tool_name=%s summary_len=%d payload_type=%s has_display=%s",
218
+ tool_name,
219
+ len(str(data.get("summary", ""))),
220
+ type(data.get("payload")).__name__,
221
+ bool(data.get("display")),
222
+ )
182
223
  self._post_ui(
183
224
  ToolUseCompleted(
184
- tool_name=str(data.get("tool_name", "")),
185
- output=str(data.get("output", "")),
225
+ tool_name=tool_name,
226
+ output=fallback_output,
227
+ summary=str(data.get("summary", "")),
228
+ payload=data.get("payload"),
229
+ status=str(data.get("status", "ok")),
230
+ meta=data.get("meta") if isinstance(data.get("meta"), dict) else None,
231
+ display=data.get("display") if isinstance(data.get("display"), dict) else None,
232
+ truncated=bool(data.get("truncated", False)),
233
+ overflow_file=data.get("overflow_file"),
186
234
  )
187
235
  )
188
236
  case LangchainAgentEventType.TOOL_ERROR:
237
+ tool_name = str(data.get("tool_name", ""))
189
238
  error_text = str(data.get("error", ""))
190
239
  self._post_ui(
191
240
  ToolUseCompleted(
192
- tool_name=str(data.get("tool_name", "")),
241
+ tool_name=tool_name,
193
242
  output=f"Error: {error_text}",
194
243
  error=error_text or None,
244
+ summary=str(data.get("summary", "")),
245
+ payload=data.get("payload"),
246
+ status=str(data.get("status", "error")),
247
+ meta=data.get("meta") if isinstance(data.get("meta"), dict) else None,
248
+ display=data.get("display") if isinstance(data.get("display"), dict) else None,
195
249
  )
196
250
  )
197
251
  case LangchainAgentEventType.ERROR:
@@ -224,6 +278,114 @@ class SessionBridge:
224
278
  case LangchainAgentEventType.COMPACT_START:
225
279
  info("[BRIDGE] COMPACT_START — compacting...")
226
280
  pass
281
+ # Phase 3: 子 agent 工具事件(通过 adispatch_custom_event 冒泡)
282
+ case LangchainAgentEventType.SUBAGENT_TOOL_CALL:
283
+ tool_name = str(data.get("tool_name", ""))
284
+ tool_input = data.get("tool_input")
285
+ parent_tool_use_id = data.get("parent_tool_use_id")
286
+ info(
287
+ "[BRIDGE] SUBAGENT_TOOL_CALL tool=%s parent=%s",
288
+ tool_name,
289
+ parent_tool_use_id,
290
+ )
291
+ self._post_ui(
292
+ ToolUseStarted(
293
+ tool_name=tool_name,
294
+ tool_input=tool_input if isinstance(tool_input, dict) else {},
295
+ parent_tool_use_id=parent_tool_use_id,
296
+ )
297
+ )
298
+ case LangchainAgentEventType.SUBAGENT_TOOL_RESULT:
299
+ tool_name = str(data.get("tool_name", ""))
300
+ parent_tool_use_id = data.get("parent_tool_use_id")
301
+ fallback_output = self._build_fallback_text(data)
302
+ info(
303
+ "[BRIDGE] SUBAGENT_TOOL_RESULT tool=%s parent=%s summary_len=%d",
304
+ tool_name,
305
+ parent_tool_use_id,
306
+ len(str(data.get("summary", ""))),
307
+ )
308
+ self._post_ui(
309
+ ToolUseCompleted(
310
+ tool_name=tool_name,
311
+ output=fallback_output,
312
+ summary=str(data.get("summary", "")),
313
+ payload=data.get("payload"),
314
+ status=str(data.get("status", "ok")),
315
+ meta=data.get("meta") if isinstance(data.get("meta"), dict) else None,
316
+ display=data.get("display") if isinstance(data.get("display"), dict) else None,
317
+ truncated=bool(data.get("truncated", False)),
318
+ overflow_file=data.get("overflow_file"),
319
+ parent_tool_use_id=parent_tool_use_id,
320
+ )
321
+ )
322
+ case LangchainAgentEventType.HOOK_STARTED:
323
+ hook_event = str(data.get("hook_event", ""))
324
+ hook_name = str(data.get("hook_name", ""))
325
+ info("[BRIDGE] HOOK_STARTED event=%s name=%s", hook_event, hook_name)
326
+ self._post_ui(
327
+ HookStarted(
328
+ hook_event=hook_event,
329
+ hook_name=hook_name,
330
+ )
331
+ )
332
+ case LangchainAgentEventType.HOOK_FINISHED:
333
+ hook_event = str(data.get("hook_event", ""))
334
+ hook_name = str(data.get("hook_name", ""))
335
+ outcome = str(data.get("outcome", ""))
336
+ info(
337
+ "[BRIDGE] HOOK_FINISHED event=%s name=%s outcome=%s stdout_len=%d stderr_len=%d",
338
+ hook_event,
339
+ hook_name,
340
+ outcome,
341
+ len(str(data.get("combined_stdout", ""))),
342
+ len(str(data.get("combined_stderr", ""))),
343
+ )
344
+ self._post_ui(
345
+ HookFinished(
346
+ hook_event=hook_event,
347
+ hook_name=hook_name,
348
+ outcome=outcome,
349
+ stdout=data.get("combined_stdout"),
350
+ stderr=data.get("combined_stderr"),
351
+ exit_codes=data.get("exit_codes"),
352
+ combined_stdout=data.get("combined_stdout"),
353
+ combined_stderr=data.get("combined_stderr"),
354
+ )
355
+ )
356
+ case LangchainAgentEventType.TASK_STARTED:
357
+ task_id = str(data.get("task_id", ""))
358
+ task_type = str(data.get("task_type", ""))
359
+ description = str(data.get("description", ""))
360
+ tool_use_id = data.get("tool_use_id")
361
+ info("[BRIDGE] TASK_STARTED id=%s type=%s", task_id, task_type)
362
+ self._post_ui(
363
+ TaskStarted(
364
+ task_id=task_id,
365
+ task_type=task_type,
366
+ description=description,
367
+ tool_use_id=tool_use_id,
368
+ prompt=data.get("prompt"),
369
+ workflow_name=data.get("workflow_name"),
370
+ )
371
+ )
372
+ case LangchainAgentEventType.TASK_PROGRESS:
373
+ task_id = str(data.get("task_id", ""))
374
+ description = str(data.get("description", ""))
375
+ usage = data.get("usage")
376
+ last_tool_name = data.get("last_tool_name")
377
+ summary = data.get("summary")
378
+ info("[BRIDGE] TASK_PROGRESS id=%s summary=%s", task_id, summary)
379
+ self._post_ui(
380
+ TaskProgress(
381
+ task_id=task_id,
382
+ description=description,
383
+ usage=usage if isinstance(usage, dict) else None,
384
+ last_tool_name=last_tool_name,
385
+ summary=summary,
386
+ tool_use_id=data.get("tool_use_id"),
387
+ )
388
+ )
227
389
  case _:
228
390
  pass
229
391
 
@@ -76,7 +76,7 @@ class CliEntry:
76
76
  return 0
77
77
 
78
78
  try:
79
- session = asyncio.run(
79
+ session, permission_queue, permission_resolver = asyncio.run(
80
80
  open_agent_session(
81
81
  launch_config,
82
82
  cli_provider=provider,
@@ -89,7 +89,13 @@ class CliEntry:
89
89
  return 2
90
90
 
91
91
  try:
92
- return self._run_tui(launch_config, session, debug=debug)
92
+ return self._run_tui(
93
+ launch_config,
94
+ session,
95
+ permission_queue=permission_queue,
96
+ permission_resolver=permission_resolver,
97
+ debug=debug,
98
+ )
93
99
  finally:
94
100
  asyncio.run(close_agent_session(session))
95
101
 
@@ -140,9 +146,20 @@ class CliEntry:
140
146
  return mode_map.get(mode.lower(), ".langchain_agentx")
141
147
 
142
148
  def _run_tui(
143
- self, launch_config: ReplLaunchConfig, session, debug: bool = False # noqa: ANN001
149
+ self,
150
+ launch_config: ReplLaunchConfig,
151
+ session, # noqa: ANN001
152
+ permission_queue, # noqa: ANN001
153
+ permission_resolver, # noqa: ANN001
154
+ debug: bool = False,
144
155
  ) -> int:
145
- app = ReplApp(launch_config=launch_config, session=session, debug=debug)
156
+ app = ReplApp(
157
+ launch_config=launch_config,
158
+ session=session,
159
+ permission_queue=permission_queue,
160
+ permission_resolver=permission_resolver,
161
+ debug=debug,
162
+ )
146
163
  app.run()
147
164
  return 0
148
165
 
@@ -0,0 +1,74 @@
1
+ """builtin/compact.py — /compact 命令(调用 SDK compact_context)。"""
2
+
3
+ from __future__ import annotations
4
+
5
+ from langchain_agentx_cli.commands.registry import Command, CommandContext
6
+ from langchain_agentx_cli.widgets.message_events import (
7
+ CompactFinished,
8
+ CompactProgressUpdate,
9
+ CompactStarted,
10
+ )
11
+
12
+ _SESSION_REQUIRED = "错误:会话未建立,无法压缩上下文"
13
+
14
+
15
+ async def handle_compact(ctx: CommandContext) -> str:
16
+ if ctx.bridge is None or not ctx.bridge.is_session_ready():
17
+ return _SESSION_REQUIRED
18
+
19
+ # 对齐 CC:支持可选的自定义总结指令参数
20
+ custom_instructions = ctx.args.strip() if ctx.args else None
21
+
22
+ # 通知 TUI 开始 compact(mount 进度条 widget)
23
+ ctx.app.post_message(CompactStarted())
24
+
25
+ def on_progress(p) -> None: # noqa: ANN001
26
+ """SDK 回调:向 TUI 发送进度更新。"""
27
+ ctx.app.post_message(
28
+ CompactProgressUpdate(percent=p.percent, detail=p.detail)
29
+ )
30
+
31
+ # 如果有自定义指令,设置到 CompactionSettings
32
+ if custom_instructions:
33
+ from langchain_agentx.loop.context.settings import (
34
+ CompactionSettings,
35
+ set_active_compaction_settings,
36
+ get_active_compaction_settings,
37
+ )
38
+ current = get_active_compaction_settings()
39
+ # 创建新的 settings,只替换 compact_custom_instructions
40
+ updated = CompactionSettings(
41
+ **{**current.__dict__, 'compact_custom_instructions': custom_instructions}
42
+ )
43
+ set_active_compaction_settings(updated)
44
+
45
+ try:
46
+ before, after = await ctx.bridge.session.compact_context(
47
+ progress_callback=on_progress
48
+ )
49
+ finally:
50
+ # 恢复原始设置(即使出错也要恢复)
51
+ if custom_instructions:
52
+ from langchain_agentx.loop.context.settings import set_active_compaction_settings, get_active_compaction_settings
53
+ current = get_active_compaction_settings()
54
+ updated = CompactionSettings(
55
+ **{**current.__dict__, 'compact_custom_instructions': None}
56
+ )
57
+ set_active_compaction_settings(updated)
58
+
59
+ # 通知 TUI 结束(移除进度条,显示结果)
60
+ ctx.app.post_message(CompactFinished(before=before, after=after))
61
+
62
+ pct = int(round(after / before * 100)) if before > 0 else 0
63
+ result = f"[信息] 已压缩:{before} tokens → {after} tokens ({pct}%)"
64
+ if custom_instructions:
65
+ result += f"\n[使用自定义指令: {custom_instructions}]"
66
+ return result
67
+
68
+
69
+ def make_compact_command() -> Command:
70
+ return Command(
71
+ name="compact",
72
+ description="压缩当前会话上下文。可选: /compact [自定义总结指令]",
73
+ handler=handle_compact,
74
+ )
@@ -13,6 +13,7 @@ session_factory.py — AgentSession 创建与生命周期。
13
13
 
14
14
  from __future__ import annotations
15
15
 
16
+ import asyncio
16
17
  from typing import TYPE_CHECKING
17
18
 
18
19
  from langchain_agentx_cli.bootstrap import CliEnvironmentError
@@ -27,6 +28,10 @@ if TYPE_CHECKING:
27
28
  from langchain_core.language_models.chat_models import BaseChatModel
28
29
 
29
30
  from langchain_agentx import AgentSession
31
+ from langchain_agentx.tool_runtime.resolvers import (
32
+ AgentSessionPermissionResolver,
33
+ PermissionRequest,
34
+ )
30
35
 
31
36
  from langchain_agentx_cli.config import ReplLaunchConfig
32
37
 
@@ -64,9 +69,15 @@ async def open_agent_session(
64
69
  cli_model: str | None = None,
65
70
  enable_git_snapshot: bool | None = None,
66
71
  include_default_session_context: bool = True,
67
- ) -> AgentSession:
68
- """创建并进入 AgentSession(构建 graph、SESSION_START hook)。"""
72
+ ) -> tuple[AgentSession, asyncio.Queue[PermissionRequest], AgentSessionPermissionResolver]:
73
+ """创建并进入 AgentSession(构建 graph、SESSION_START hook)。
74
+
75
+ 返回: (session, permission_queue, permission_resolver)
76
+ permission_queue 和 permission_resolver 由调用方传递给 SessionBridge。
77
+ """
69
78
  from langchain_agentx import create_agent_session
79
+ from langchain_agentx.tool_runtime.resolvers import AgentSessionPermissionResolver
80
+ from langchain_agentx_cli.tui.permissions.config import DEFAULT_PERMISSION_TIMEOUT_SECONDS
70
81
 
71
82
  cfg = resolve_llm_config(cli_provider=cli_provider, cli_model=cli_model)
72
83
  llm = build_chat_model(cfg)
@@ -82,18 +93,29 @@ async def open_agent_session(
82
93
  skip_permissions=launch_config.skip_permissions,
83
94
  )
84
95
 
96
+ # 方案 A: 在 session 创建前创建 permission_resolver,通过 loop_kwargs 传入
97
+ permission_queue: asyncio.Queue[PermissionRequest] = asyncio.Queue()
98
+ permission_resolver = AgentSessionPermissionResolver(
99
+ request_queue=permission_queue,
100
+ timeout=DEFAULT_PERMISSION_TIMEOUT_SECONDS,
101
+ )
102
+
103
+ loop_kwargs = build_session_loop_kwargs(
104
+ workspace_root=launch_config.workspace_root,
105
+ model=cfg.model,
106
+ provider=cfg.provider,
107
+ enable_git_snapshot=enable_git_snapshot,
108
+ include_default_session_context=include_default_session_context,
109
+ )
110
+ # 注入 permission_resolver 到 loop_kwargs
111
+ loop_kwargs["permission_resolver"] = permission_resolver
112
+
85
113
  session = create_agent_session(
86
114
  llm,
87
115
  workspace_root=launch_config.workspace_root,
88
116
  agent_home=launch_config.agent_home,
89
117
  loader=loader,
90
- **build_session_loop_kwargs(
91
- workspace_root=launch_config.workspace_root,
92
- model=cfg.model,
93
- provider=cfg.provider,
94
- enable_git_snapshot=enable_git_snapshot,
95
- include_default_session_context=include_default_session_context,
96
- ),
118
+ **loop_kwargs,
97
119
  )
98
120
  try:
99
121
  await session.__aenter__()
@@ -103,7 +125,7 @@ async def open_agent_session(
103
125
  raise CliEnvironmentError(
104
126
  f"无法创建 AgentSession(provider={cfg.provider!r}, model={cfg.model!r}):{exc}"
105
127
  ) from exc
106
- return session
128
+ return session, permission_queue, permission_resolver
107
129
 
108
130
 
109
131
  async def close_agent_session(session: AgentSession) -> None:
@@ -19,7 +19,7 @@ from __future__ import annotations
19
19
  import time
20
20
  from dataclasses import dataclass, field
21
21
  from enum import Enum
22
- from typing import Callable
22
+ from typing import Any, Callable
23
23
 
24
24
 
25
25
  class TaskStatus(Enum):
@@ -165,6 +165,68 @@ class TaskStore:
165
165
  del self._tasks[task_id]
166
166
  self._notify()
167
167
 
168
+ def update_from_tool_result(
169
+ self,
170
+ tool_name: str,
171
+ tool_input: dict,
172
+ *,
173
+ display: dict[str, Any] | None = None,
174
+ output: str = "",
175
+ ) -> None:
176
+ """从 TOOL_RESULT 的 display 字段同步 Task 状态(D09 + SDK 双流)。"""
177
+ d = display or {}
178
+ now = time.time()
179
+
180
+ if tool_name == "TaskCreate":
181
+ if not d.get("success"):
182
+ return
183
+ task_id = str(d.get("task_id") or "").strip()
184
+ if not task_id:
185
+ return
186
+ subject = str(d.get("subject") or tool_input.get("subject", ""))
187
+ description = str(tool_input.get("description", ""))
188
+ if task_id in self._tasks:
189
+ self._tasks[task_id].subject = subject or self._tasks[task_id].subject
190
+ else:
191
+ self._tasks[task_id] = TaskEntry(
192
+ id=task_id,
193
+ subject=subject,
194
+ description=description,
195
+ status=TaskStatus.PENDING.value,
196
+ active_form=tool_input.get("activeForm"),
197
+ metadata=tool_input.get("metadata"),
198
+ )
199
+ self._notify()
200
+ return
201
+
202
+ if tool_name == "TaskUpdate":
203
+ task_id = str(d.get("task_id") or tool_input.get("taskId", "")).strip()
204
+ if not task_id or task_id not in self._tasks:
205
+ return
206
+ entry = self._tasks[task_id]
207
+ new_status = d.get("new_status")
208
+ if new_status:
209
+ if (
210
+ new_status == TaskStatus.COMPLETED.value
211
+ and entry.status != new_status
212
+ ):
213
+ entry.completed_at = now
214
+ entry.status = str(new_status)
215
+ self._notify()
216
+ return
217
+
218
+ if tool_name == "TaskGet" and d.get("found") and d.get("task_id"):
219
+ task_id = str(d["task_id"])
220
+ if task_id in self._tasks and d.get("status"):
221
+ self._tasks[task_id].status = str(d["status"])
222
+ self._notify()
223
+ return
224
+
225
+ if tool_name == "TaskList":
226
+ # 列表工具不改变单条 Task;TaskPanel 仍由 started 事件驱动
227
+ _ = output
228
+ return
229
+
168
230
  def get_sorted_tasks(self) -> list[TaskEntry]:
169
231
  """获取排序后的 Task 列表(对齐 CC 优先级)。
170
232
 
@@ -6,7 +6,7 @@ tui/permissions — 权限确认子系统(Queue + Future)。
6
6
  集成 ConfirmQueue 状态管理(对齐 CC)。
7
7
 
8
8
  链路位置:
9
- SessionBridge 创建 Queue/Resolver → PermissionQueueConsumer → SDK Future。
9
+ open_agent_session 创建 Queue/Resolver → SessionBridge → PermissionQueueConsumer → SDK Future。
10
10
  """
11
11
 
12
12
  from langchain_agentx_cli.tui.permissions.cache import SessionPermissionCache
@@ -19,7 +19,6 @@ from langchain_agentx_cli.tui.permissions.consumer import (
19
19
  from langchain_agentx_cli.tui.permissions.dialog import (
20
20
  DialogPermissionDecisionPort,
21
21
  )
22
- from langchain_agentx_cli.tui.permissions.inject import inject_permission_resolver
23
22
  from langchain_agentx_cli.tui.permissions.models import PermissionDecision
24
23
  from langchain_agentx_cli.tui.permissions.presenters import (
25
24
  PermissionPresentation,
@@ -38,6 +37,5 @@ __all__ = [
38
37
  "PermissionQueueConsumer",
39
38
  "QueuedPermission",
40
39
  "SessionPermissionCache",
41
- "inject_permission_resolver",
42
40
  "permission_presenter_for_tool",
43
41
  ]
@@ -65,4 +65,5 @@ class PermissionPresenter:
65
65
  return None
66
66
 
67
67
  def _default_prompt(self) -> str:
68
- return "Do you want to proceed?"
68
+ # 对齐 CC:默认 prompt 为空,由 InlinePermissionWidget 添加 "Do you want to proceed?"
69
+ return ""