jarvis-ai-assistant 0.3.30__py3-none-any.whl → 0.7.6__py3-none-any.whl
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.
- jarvis/__init__.py +1 -1
- jarvis/jarvis_agent/__init__.py +458 -152
- jarvis/jarvis_agent/agent_manager.py +17 -13
- jarvis/jarvis_agent/builtin_input_handler.py +2 -6
- jarvis/jarvis_agent/config_editor.py +2 -7
- jarvis/jarvis_agent/event_bus.py +82 -12
- jarvis/jarvis_agent/file_context_handler.py +329 -0
- jarvis/jarvis_agent/file_methodology_manager.py +3 -4
- jarvis/jarvis_agent/jarvis.py +628 -55
- jarvis/jarvis_agent/language_extractors/__init__.py +57 -0
- jarvis/jarvis_agent/language_extractors/c_extractor.py +21 -0
- jarvis/jarvis_agent/language_extractors/cpp_extractor.py +21 -0
- jarvis/jarvis_agent/language_extractors/go_extractor.py +21 -0
- jarvis/jarvis_agent/language_extractors/java_extractor.py +84 -0
- jarvis/jarvis_agent/language_extractors/javascript_extractor.py +79 -0
- jarvis/jarvis_agent/language_extractors/python_extractor.py +21 -0
- jarvis/jarvis_agent/language_extractors/rust_extractor.py +21 -0
- jarvis/jarvis_agent/language_extractors/typescript_extractor.py +84 -0
- jarvis/jarvis_agent/language_support_info.py +486 -0
- jarvis/jarvis_agent/main.py +34 -10
- jarvis/jarvis_agent/memory_manager.py +7 -16
- jarvis/jarvis_agent/methodology_share_manager.py +10 -16
- jarvis/jarvis_agent/prompt_manager.py +1 -1
- jarvis/jarvis_agent/prompts.py +193 -171
- jarvis/jarvis_agent/protocols.py +8 -12
- jarvis/jarvis_agent/run_loop.py +105 -9
- jarvis/jarvis_agent/session_manager.py +2 -3
- jarvis/jarvis_agent/share_manager.py +20 -22
- jarvis/jarvis_agent/shell_input_handler.py +1 -2
- jarvis/jarvis_agent/stdio_redirect.py +295 -0
- jarvis/jarvis_agent/task_analyzer.py +31 -6
- jarvis/jarvis_agent/task_manager.py +11 -27
- jarvis/jarvis_agent/tool_executor.py +2 -3
- jarvis/jarvis_agent/tool_share_manager.py +12 -24
- jarvis/jarvis_agent/utils.py +5 -1
- jarvis/jarvis_agent/web_bridge.py +189 -0
- jarvis/jarvis_agent/web_output_sink.py +53 -0
- jarvis/jarvis_agent/web_server.py +786 -0
- jarvis/jarvis_c2rust/__init__.py +26 -0
- jarvis/jarvis_c2rust/cli.py +575 -0
- jarvis/jarvis_c2rust/collector.py +250 -0
- jarvis/jarvis_c2rust/constants.py +26 -0
- jarvis/jarvis_c2rust/library_replacer.py +1254 -0
- jarvis/jarvis_c2rust/llm_module_agent.py +1272 -0
- jarvis/jarvis_c2rust/loaders.py +207 -0
- jarvis/jarvis_c2rust/models.py +28 -0
- jarvis/jarvis_c2rust/optimizer.py +2157 -0
- jarvis/jarvis_c2rust/scanner.py +1681 -0
- jarvis/jarvis_c2rust/transpiler.py +2983 -0
- jarvis/jarvis_c2rust/utils.py +385 -0
- jarvis/jarvis_code_agent/build_validation_config.py +132 -0
- jarvis/jarvis_code_agent/code_agent.py +1371 -220
- jarvis/jarvis_code_agent/code_analyzer/__init__.py +65 -0
- jarvis/jarvis_code_agent/code_analyzer/base_language.py +74 -0
- jarvis/jarvis_code_agent/code_analyzer/build_validator/__init__.py +44 -0
- jarvis/jarvis_code_agent/code_analyzer/build_validator/base.py +106 -0
- jarvis/jarvis_code_agent/code_analyzer/build_validator/cmake.py +74 -0
- jarvis/jarvis_code_agent/code_analyzer/build_validator/detector.py +125 -0
- jarvis/jarvis_code_agent/code_analyzer/build_validator/fallback.py +72 -0
- jarvis/jarvis_code_agent/code_analyzer/build_validator/go.py +70 -0
- jarvis/jarvis_code_agent/code_analyzer/build_validator/java_gradle.py +53 -0
- jarvis/jarvis_code_agent/code_analyzer/build_validator/java_maven.py +47 -0
- jarvis/jarvis_code_agent/code_analyzer/build_validator/makefile.py +61 -0
- jarvis/jarvis_code_agent/code_analyzer/build_validator/nodejs.py +110 -0
- jarvis/jarvis_code_agent/code_analyzer/build_validator/python.py +154 -0
- jarvis/jarvis_code_agent/code_analyzer/build_validator/rust.py +110 -0
- jarvis/jarvis_code_agent/code_analyzer/build_validator/validator.py +153 -0
- jarvis/jarvis_code_agent/code_analyzer/build_validator.py +43 -0
- jarvis/jarvis_code_agent/code_analyzer/context_manager.py +648 -0
- jarvis/jarvis_code_agent/code_analyzer/context_recommender.py +18 -0
- jarvis/jarvis_code_agent/code_analyzer/dependency_analyzer.py +132 -0
- jarvis/jarvis_code_agent/code_analyzer/file_ignore.py +330 -0
- jarvis/jarvis_code_agent/code_analyzer/impact_analyzer.py +781 -0
- jarvis/jarvis_code_agent/code_analyzer/language_registry.py +185 -0
- jarvis/jarvis_code_agent/code_analyzer/language_support.py +110 -0
- jarvis/jarvis_code_agent/code_analyzer/languages/__init__.py +49 -0
- jarvis/jarvis_code_agent/code_analyzer/languages/c_cpp_language.py +299 -0
- jarvis/jarvis_code_agent/code_analyzer/languages/go_language.py +215 -0
- jarvis/jarvis_code_agent/code_analyzer/languages/java_language.py +212 -0
- jarvis/jarvis_code_agent/code_analyzer/languages/javascript_language.py +254 -0
- jarvis/jarvis_code_agent/code_analyzer/languages/python_language.py +269 -0
- jarvis/jarvis_code_agent/code_analyzer/languages/rust_language.py +281 -0
- jarvis/jarvis_code_agent/code_analyzer/languages/typescript_language.py +280 -0
- jarvis/jarvis_code_agent/code_analyzer/llm_context_recommender.py +605 -0
- jarvis/jarvis_code_agent/code_analyzer/structured_code.py +556 -0
- jarvis/jarvis_code_agent/code_analyzer/symbol_extractor.py +252 -0
- jarvis/jarvis_code_agent/code_analyzer/tree_sitter_extractor.py +58 -0
- jarvis/jarvis_code_agent/lint.py +501 -8
- jarvis/jarvis_code_agent/utils.py +141 -0
- jarvis/jarvis_code_analysis/code_review.py +493 -584
- jarvis/jarvis_data/config_schema.json +128 -12
- jarvis/jarvis_git_squash/main.py +4 -5
- jarvis/jarvis_git_utils/git_commiter.py +82 -75
- jarvis/jarvis_mcp/sse_mcp_client.py +22 -29
- jarvis/jarvis_mcp/stdio_mcp_client.py +12 -13
- jarvis/jarvis_mcp/streamable_mcp_client.py +15 -14
- jarvis/jarvis_memory_organizer/memory_organizer.py +55 -74
- jarvis/jarvis_methodology/main.py +32 -48
- jarvis/jarvis_multi_agent/__init__.py +287 -55
- jarvis/jarvis_multi_agent/main.py +36 -4
- jarvis/jarvis_platform/base.py +524 -202
- jarvis/jarvis_platform/human.py +7 -8
- jarvis/jarvis_platform/kimi.py +30 -36
- jarvis/jarvis_platform/openai.py +88 -25
- jarvis/jarvis_platform/registry.py +26 -10
- jarvis/jarvis_platform/tongyi.py +24 -25
- jarvis/jarvis_platform/yuanbao.py +32 -43
- jarvis/jarvis_platform_manager/main.py +66 -77
- jarvis/jarvis_platform_manager/service.py +8 -13
- jarvis/jarvis_rag/cli.py +53 -55
- jarvis/jarvis_rag/embedding_manager.py +13 -18
- jarvis/jarvis_rag/llm_interface.py +8 -9
- jarvis/jarvis_rag/query_rewriter.py +10 -21
- jarvis/jarvis_rag/rag_pipeline.py +24 -27
- jarvis/jarvis_rag/reranker.py +4 -5
- jarvis/jarvis_rag/retriever.py +28 -30
- jarvis/jarvis_sec/__init__.py +305 -0
- jarvis/jarvis_sec/agents.py +143 -0
- jarvis/jarvis_sec/analysis.py +276 -0
- jarvis/jarvis_sec/checkers/__init__.py +32 -0
- jarvis/jarvis_sec/checkers/c_checker.py +2680 -0
- jarvis/jarvis_sec/checkers/rust_checker.py +1108 -0
- jarvis/jarvis_sec/cli.py +139 -0
- jarvis/jarvis_sec/clustering.py +1439 -0
- jarvis/jarvis_sec/file_manager.py +427 -0
- jarvis/jarvis_sec/parsers.py +73 -0
- jarvis/jarvis_sec/prompts.py +268 -0
- jarvis/jarvis_sec/report.py +336 -0
- jarvis/jarvis_sec/review.py +453 -0
- jarvis/jarvis_sec/status.py +264 -0
- jarvis/jarvis_sec/types.py +20 -0
- jarvis/jarvis_sec/utils.py +499 -0
- jarvis/jarvis_sec/verification.py +848 -0
- jarvis/jarvis_sec/workflow.py +226 -0
- jarvis/jarvis_smart_shell/main.py +38 -87
- jarvis/jarvis_stats/cli.py +2 -2
- jarvis/jarvis_stats/stats.py +8 -8
- jarvis/jarvis_stats/storage.py +15 -21
- jarvis/jarvis_stats/visualizer.py +1 -1
- jarvis/jarvis_tools/clear_memory.py +3 -20
- jarvis/jarvis_tools/cli/main.py +21 -23
- jarvis/jarvis_tools/edit_file.py +1019 -132
- jarvis/jarvis_tools/execute_script.py +83 -25
- jarvis/jarvis_tools/file_analyzer.py +6 -9
- jarvis/jarvis_tools/generate_new_tool.py +14 -21
- jarvis/jarvis_tools/lsp_client.py +1552 -0
- jarvis/jarvis_tools/methodology.py +2 -3
- jarvis/jarvis_tools/read_code.py +1736 -35
- jarvis/jarvis_tools/read_symbols.py +140 -0
- jarvis/jarvis_tools/read_webpage.py +12 -13
- jarvis/jarvis_tools/registry.py +427 -200
- jarvis/jarvis_tools/retrieve_memory.py +20 -19
- jarvis/jarvis_tools/rewrite_file.py +72 -158
- jarvis/jarvis_tools/save_memory.py +3 -15
- jarvis/jarvis_tools/search_web.py +18 -18
- jarvis/jarvis_tools/sub_agent.py +36 -43
- jarvis/jarvis_tools/sub_code_agent.py +25 -26
- jarvis/jarvis_tools/virtual_tty.py +55 -33
- jarvis/jarvis_utils/clipboard.py +7 -10
- jarvis/jarvis_utils/config.py +232 -45
- jarvis/jarvis_utils/embedding.py +8 -5
- jarvis/jarvis_utils/fzf.py +8 -8
- jarvis/jarvis_utils/git_utils.py +225 -36
- jarvis/jarvis_utils/globals.py +3 -3
- jarvis/jarvis_utils/http.py +1 -1
- jarvis/jarvis_utils/input.py +99 -48
- jarvis/jarvis_utils/jsonnet_compat.py +465 -0
- jarvis/jarvis_utils/methodology.py +52 -48
- jarvis/jarvis_utils/utils.py +819 -491
- jarvis_ai_assistant-0.7.6.dist-info/METADATA +600 -0
- jarvis_ai_assistant-0.7.6.dist-info/RECORD +218 -0
- {jarvis_ai_assistant-0.3.30.dist-info → jarvis_ai_assistant-0.7.6.dist-info}/entry_points.txt +4 -0
- jarvis/jarvis_agent/config.py +0 -92
- jarvis/jarvis_agent/edit_file_handler.py +0 -296
- jarvis/jarvis_platform/ai8.py +0 -332
- jarvis/jarvis_tools/ask_user.py +0 -54
- jarvis_ai_assistant-0.3.30.dist-info/METADATA +0 -381
- jarvis_ai_assistant-0.3.30.dist-info/RECORD +0 -137
- {jarvis_ai_assistant-0.3.30.dist-info → jarvis_ai_assistant-0.7.6.dist-info}/WHEEL +0 -0
- {jarvis_ai_assistant-0.3.30.dist-info → jarvis_ai_assistant-0.7.6.dist-info}/licenses/LICENSE +0 -0
- {jarvis_ai_assistant-0.3.30.dist-info → jarvis_ai_assistant-0.7.6.dist-info}/top_level.txt +0 -0
jarvis/jarvis_utils/input.py
CHANGED
|
@@ -13,7 +13,6 @@ import sys
|
|
|
13
13
|
import base64
|
|
14
14
|
from typing import Iterable, List, Optional
|
|
15
15
|
import wcwidth
|
|
16
|
-
|
|
17
16
|
from colorama import Fore
|
|
18
17
|
from colorama import Style as ColoramaStyle
|
|
19
18
|
from fuzzywuzzy import process
|
|
@@ -35,11 +34,9 @@ from prompt_toolkit.layout.containers import Window
|
|
|
35
34
|
from prompt_toolkit.layout.controls import FormattedTextControl
|
|
36
35
|
from prompt_toolkit.layout.layout import Layout
|
|
37
36
|
from prompt_toolkit.styles import Style as PromptStyle
|
|
38
|
-
|
|
39
37
|
from jarvis.jarvis_utils.clipboard import copy_to_clipboard
|
|
40
38
|
from jarvis.jarvis_utils.config import get_data_dir, get_replace_map
|
|
41
39
|
from jarvis.jarvis_utils.globals import get_message_history
|
|
42
|
-
from jarvis.jarvis_utils.output import OutputType, PrettyOutput
|
|
43
40
|
from jarvis.jarvis_utils.tag import ot
|
|
44
41
|
|
|
45
42
|
# Sentinel value to indicate that Ctrl+O was pressed
|
|
@@ -54,9 +51,8 @@ FZF_REQUEST_ALL_SENTINEL_PREFIX = "__FZF_REQUEST_ALL__::"
|
|
|
54
51
|
# Persistent hint marker for multiline input (shown only once across runs)
|
|
55
52
|
_MULTILINE_HINT_MARK_FILE = os.path.join(get_data_dir(), "multiline_enter_hint_shown")
|
|
56
53
|
|
|
57
|
-
|
|
58
54
|
def _display_width(s: str) -> int:
|
|
59
|
-
"""
|
|
55
|
+
"""计算字符串在终端中的可打印宽度(处理宽字符)。"""
|
|
60
56
|
try:
|
|
61
57
|
w = 0
|
|
62
58
|
for ch in s:
|
|
@@ -69,11 +65,10 @@ def _display_width(s: str) -> int:
|
|
|
69
65
|
except Exception:
|
|
70
66
|
return len(s)
|
|
71
67
|
|
|
72
|
-
|
|
73
68
|
def _calc_prompt_rows(prev_text: str) -> int:
|
|
74
69
|
"""
|
|
75
|
-
|
|
76
|
-
|
|
70
|
+
估算上一个提示占用了多少终端行数。
|
|
71
|
+
考虑提示前缀和跨终端列的软换行。
|
|
77
72
|
"""
|
|
78
73
|
try:
|
|
79
74
|
cols = os.get_terminal_size().columns
|
|
@@ -102,17 +97,15 @@ def _calc_prompt_rows(prev_text: str) -> int:
|
|
|
102
97
|
total_rows += rows
|
|
103
98
|
return max(1, total_rows)
|
|
104
99
|
|
|
105
|
-
|
|
106
100
|
def _multiline_hint_already_shown() -> bool:
|
|
107
|
-
"""
|
|
101
|
+
"""检查是否已显示过多行输入提示(持久化存储)。"""
|
|
108
102
|
try:
|
|
109
103
|
return os.path.exists(_MULTILINE_HINT_MARK_FILE)
|
|
110
104
|
except Exception:
|
|
111
105
|
return False
|
|
112
106
|
|
|
113
|
-
|
|
114
107
|
def _mark_multiline_hint_shown() -> None:
|
|
115
|
-
"""
|
|
108
|
+
"""持久化存储多行输入提示已显示的状态。"""
|
|
116
109
|
try:
|
|
117
110
|
os.makedirs(os.path.dirname(_MULTILINE_HINT_MARK_FILE), exist_ok=True)
|
|
118
111
|
with open(_MULTILINE_HINT_MARK_FILE, "w", encoding="utf-8") as f:
|
|
@@ -121,7 +114,6 @@ def _mark_multiline_hint_shown() -> None:
|
|
|
121
114
|
# Non-critical persistence failure; ignore to avoid breaking input flow
|
|
122
115
|
pass
|
|
123
116
|
|
|
124
|
-
|
|
125
117
|
def get_single_line_input(tip: str, default: str = "") -> str:
|
|
126
118
|
"""
|
|
127
119
|
获取支持历史记录的单行输入。
|
|
@@ -133,7 +125,6 @@ def get_single_line_input(tip: str, default: str = "") -> str:
|
|
|
133
125
|
prompt = FormattedText([("class:prompt", f"👤 > {tip}")])
|
|
134
126
|
return session.prompt(prompt, default=default, style=style)
|
|
135
127
|
|
|
136
|
-
|
|
137
128
|
def get_choice(tip: str, choices: List[str]) -> str:
|
|
138
129
|
"""
|
|
139
130
|
提供一个可滚动的选择列表供用户选择。
|
|
@@ -229,7 +220,6 @@ def get_choice(tip: str, choices: List[str]) -> str:
|
|
|
229
220
|
except (KeyboardInterrupt, EOFError):
|
|
230
221
|
return ""
|
|
231
222
|
|
|
232
|
-
|
|
233
223
|
class FileCompleter(Completer):
|
|
234
224
|
"""
|
|
235
225
|
带有模糊匹配的文件路径自定义补全器。
|
|
@@ -363,25 +353,63 @@ class FileCompleter(Completer):
|
|
|
363
353
|
return tag
|
|
364
354
|
|
|
365
355
|
|
|
356
|
+
# ---------------------
|
|
357
|
+
# 公共判定辅助函数(按当前Agent优先)
|
|
358
|
+
# ---------------------
|
|
359
|
+
def _get_current_agent_for_input():
|
|
360
|
+
try:
|
|
361
|
+
import jarvis.jarvis_utils.globals as g
|
|
362
|
+
current_name = getattr(g, "current_agent_name", "")
|
|
363
|
+
if current_name:
|
|
364
|
+
return g.get_agent(current_name)
|
|
365
|
+
except Exception:
|
|
366
|
+
pass
|
|
367
|
+
return None
|
|
368
|
+
def _is_non_interactive_for_current_agent() -> bool:
|
|
369
|
+
try:
|
|
370
|
+
from jarvis.jarvis_utils.config import is_non_interactive
|
|
371
|
+
ag = _get_current_agent_for_input()
|
|
372
|
+
try:
|
|
373
|
+
return bool(getattr(ag, "non_interactive", False)) if ag else bool(is_non_interactive())
|
|
374
|
+
except Exception:
|
|
375
|
+
return bool(is_non_interactive())
|
|
376
|
+
except Exception:
|
|
377
|
+
return False
|
|
378
|
+
def _is_auto_complete_for_current_agent() -> bool:
|
|
379
|
+
try:
|
|
380
|
+
from jarvis.jarvis_utils.config import GLOBAL_CONFIG_DATA
|
|
381
|
+
ag = _get_current_agent_for_input()
|
|
382
|
+
if ag is not None and hasattr(ag, "auto_complete"):
|
|
383
|
+
try:
|
|
384
|
+
return bool(getattr(ag, "auto_complete", False))
|
|
385
|
+
except Exception:
|
|
386
|
+
pass
|
|
387
|
+
env_v = os.getenv("JARVIS_AUTO_COMPLETE")
|
|
388
|
+
if env_v is not None:
|
|
389
|
+
return str(env_v).strip().lower() in ("1", "true", "yes", "on")
|
|
390
|
+
return bool(GLOBAL_CONFIG_DATA.get("JARVIS_AUTO_COMPLETE", False))
|
|
391
|
+
except Exception:
|
|
392
|
+
return False
|
|
366
393
|
def user_confirm(tip: str, default: bool = True) -> bool:
|
|
367
|
-
"""
|
|
394
|
+
"""提示用户确认是/否问题(按当前Agent优先判断非交互)"""
|
|
368
395
|
try:
|
|
396
|
+
if _is_non_interactive_for_current_agent():
|
|
397
|
+
return default
|
|
369
398
|
suffix = "[Y/n]" if default else "[y/N]"
|
|
370
399
|
ret = get_single_line_input(f"{tip} {suffix}: ")
|
|
371
400
|
return default if ret == "" else ret.lower() == "y"
|
|
372
401
|
except KeyboardInterrupt:
|
|
373
402
|
return False
|
|
374
403
|
|
|
375
|
-
|
|
376
404
|
def _show_history_and_copy():
|
|
377
405
|
"""
|
|
378
|
-
|
|
379
|
-
|
|
406
|
+
显示消息历史记录并处理复制到剪贴板。
|
|
407
|
+
此函数使用标准I/O,可在提示会话之外安全调用。
|
|
380
408
|
"""
|
|
381
409
|
|
|
382
410
|
history = get_message_history()
|
|
383
411
|
if not history:
|
|
384
|
-
|
|
412
|
+
print("ℹ️ 没有可复制的消息")
|
|
385
413
|
return
|
|
386
414
|
|
|
387
415
|
# 为避免 PrettyOutput 在循环中为每行加框,先拼接后统一打印
|
|
@@ -393,8 +421,8 @@ def _show_history_and_copy():
|
|
|
393
421
|
(cleaned_msg[:70] + "...") if len(cleaned_msg) > 70 else cleaned_msg
|
|
394
422
|
)
|
|
395
423
|
lines.append(f" {i + 1}: {display_msg.strip()}")
|
|
396
|
-
|
|
397
|
-
|
|
424
|
+
lines.append("=" * 58 + "\n")
|
|
425
|
+
print("ℹ️ " + "\n".join(lines))
|
|
398
426
|
|
|
399
427
|
while True:
|
|
400
428
|
try:
|
|
@@ -403,11 +431,11 @@ def _show_history_and_copy():
|
|
|
403
431
|
|
|
404
432
|
if not choice_str: # User pressed Enter
|
|
405
433
|
if not history:
|
|
406
|
-
|
|
434
|
+
print("ℹ️ 没有历史记录可供选择。")
|
|
407
435
|
break
|
|
408
436
|
choice = len(history) - 1
|
|
409
437
|
elif choice_str.lower() == "c":
|
|
410
|
-
|
|
438
|
+
print("ℹ️ 已取消")
|
|
411
439
|
break
|
|
412
440
|
else:
|
|
413
441
|
choice = int(choice_str) - 1
|
|
@@ -415,19 +443,16 @@ def _show_history_and_copy():
|
|
|
415
443
|
if 0 <= choice < len(history):
|
|
416
444
|
selected_msg = history[choice]
|
|
417
445
|
copy_to_clipboard(selected_msg)
|
|
418
|
-
|
|
419
|
-
f"已复制消息: {selected_msg[:70]}...", OutputType.SUCCESS
|
|
420
|
-
)
|
|
446
|
+
print(f"✅ 已复制消息: {selected_msg[:70]}...")
|
|
421
447
|
break
|
|
422
448
|
else:
|
|
423
|
-
|
|
449
|
+
print("⚠️ 无效的序号,请重试。")
|
|
424
450
|
except ValueError:
|
|
425
|
-
|
|
451
|
+
print("⚠️ 无效的输入,请输入数字。")
|
|
426
452
|
except (KeyboardInterrupt, EOFError):
|
|
427
|
-
|
|
453
|
+
print("\nℹ️ 操作取消")
|
|
428
454
|
break
|
|
429
455
|
|
|
430
|
-
|
|
431
456
|
def _get_multiline_input_internal(
|
|
432
457
|
tip: str, preset: Optional[str] = None, preset_cursor: Optional[int] = None
|
|
433
458
|
) -> str:
|
|
@@ -447,10 +472,7 @@ def _get_multiline_input_internal(
|
|
|
447
472
|
first_enter_hint_shown = True
|
|
448
473
|
|
|
449
474
|
def _show_notice():
|
|
450
|
-
|
|
451
|
-
"提示:当前支持多行输入。输入完成请使用 Ctrl+J 确认;Enter 仅用于换行。",
|
|
452
|
-
OutputType.INFO,
|
|
453
|
-
)
|
|
475
|
+
print("ℹ️ 提示:当前支持多行输入。输入完成请使用 Ctrl+J 确认;Enter 仅用于换行。")
|
|
454
476
|
try:
|
|
455
477
|
input("按回车继续...")
|
|
456
478
|
except Exception:
|
|
@@ -482,7 +504,7 @@ def _get_multiline_input_internal(
|
|
|
482
504
|
"""Handle Ctrl+O by exiting the prompt and returning the sentinel value."""
|
|
483
505
|
event.app.exit(result=CTRL_O_SENTINEL)
|
|
484
506
|
|
|
485
|
-
@bindings.add("c-t", filter=has_focus(DEFAULT_BUFFER))
|
|
507
|
+
@bindings.add("c-t", filter=has_focus(DEFAULT_BUFFER), eager=True)
|
|
486
508
|
def _(event):
|
|
487
509
|
"""Return a shell command like '!bash' for upper input_handler to execute."""
|
|
488
510
|
|
|
@@ -650,7 +672,6 @@ def _get_multiline_input_internal(
|
|
|
650
672
|
except (KeyboardInterrupt, EOFError):
|
|
651
673
|
return ""
|
|
652
674
|
|
|
653
|
-
|
|
654
675
|
def get_multiline_input(tip: str, print_on_empty: bool = True) -> str:
|
|
655
676
|
"""
|
|
656
677
|
获取带有增强补全和确认功能的多行输入。
|
|
@@ -663,6 +684,40 @@ def get_multiline_input(tip: str, print_on_empty: bool = True) -> str:
|
|
|
663
684
|
preset: Optional[str] = None
|
|
664
685
|
preset_cursor: Optional[int] = None
|
|
665
686
|
while True:
|
|
687
|
+
# 基于“当前Agent”精确判断非交互与自动完成,避免多Agent相互干扰
|
|
688
|
+
if _is_non_interactive_for_current_agent():
|
|
689
|
+
# 在多Agent系统中,无论是否启用自动完成,均提示可用智能体并建议使用 SEND_MESSAGE 转移控制权
|
|
690
|
+
hint = ""
|
|
691
|
+
try:
|
|
692
|
+
ag = _get_current_agent_for_input()
|
|
693
|
+
ohs = getattr(ag, "output_handler", [])
|
|
694
|
+
available_agents: List[str] = []
|
|
695
|
+
for oh in (ohs or []):
|
|
696
|
+
cfgs = getattr(oh, "agents_config", None)
|
|
697
|
+
if isinstance(cfgs, list):
|
|
698
|
+
for c in cfgs:
|
|
699
|
+
try:
|
|
700
|
+
name = c.get("name")
|
|
701
|
+
except Exception:
|
|
702
|
+
name = None
|
|
703
|
+
if isinstance(name, str) and name.strip():
|
|
704
|
+
available_agents.append(name.strip())
|
|
705
|
+
if available_agents:
|
|
706
|
+
# 去重但保留顺序
|
|
707
|
+
seen = set()
|
|
708
|
+
ordered = []
|
|
709
|
+
for n in available_agents:
|
|
710
|
+
if n not in seen:
|
|
711
|
+
seen.add(n)
|
|
712
|
+
ordered.append(n)
|
|
713
|
+
hint = "\n当前可用智能体: " + ", ".join(ordered) + f"\n如需将任务交给其他智能体,请使用 {ot('SEND_MESSAGE')} 块。"
|
|
714
|
+
except Exception:
|
|
715
|
+
hint = ""
|
|
716
|
+
if _is_auto_complete_for_current_agent():
|
|
717
|
+
base_msg = "我无法与你交互,所有的事情你都自我决策,如果无法决策,就完成任务。输出" + ot("!!!COMPLETE!!!")
|
|
718
|
+
return base_msg + hint
|
|
719
|
+
else:
|
|
720
|
+
return "我无法与你交互,所有的事情你都自我决策" + hint
|
|
666
721
|
user_input = _get_multiline_input_internal(
|
|
667
722
|
tip, preset=preset, preset_cursor=preset_cursor
|
|
668
723
|
)
|
|
@@ -695,9 +750,7 @@ def get_multiline_input(tip: str, print_on_empty: bool = True) -> str:
|
|
|
695
750
|
import subprocess
|
|
696
751
|
|
|
697
752
|
if shutil.which("fzf") is None:
|
|
698
|
-
|
|
699
|
-
"未检测到 fzf,无法打开文件选择器。", OutputType.WARNING
|
|
700
|
-
)
|
|
753
|
+
print("⚠️ 未检测到 fzf,无法打开文件选择器。")
|
|
701
754
|
else:
|
|
702
755
|
files = []
|
|
703
756
|
try:
|
|
@@ -726,7 +779,7 @@ def get_multiline_input(tip: str, print_on_empty: bool = True) -> str:
|
|
|
726
779
|
break
|
|
727
780
|
|
|
728
781
|
if not files:
|
|
729
|
-
|
|
782
|
+
print("ℹ️ 未找到可选择的文件。")
|
|
730
783
|
else:
|
|
731
784
|
try:
|
|
732
785
|
specials = [
|
|
@@ -770,7 +823,7 @@ def get_multiline_input(tip: str, print_on_empty: bool = True) -> str:
|
|
|
770
823
|
if sel:
|
|
771
824
|
selected_path = sel
|
|
772
825
|
except Exception as e:
|
|
773
|
-
|
|
826
|
+
print(f"❌ FZF 执行失败: {e}")
|
|
774
827
|
|
|
775
828
|
# Compute new text based on selection (or keep original if none)
|
|
776
829
|
if selected_path:
|
|
@@ -828,9 +881,7 @@ def get_multiline_input(tip: str, print_on_empty: bool = True) -> str:
|
|
|
828
881
|
import subprocess
|
|
829
882
|
|
|
830
883
|
if shutil.which("fzf") is None:
|
|
831
|
-
|
|
832
|
-
"未检测到 fzf,无法打开文件选择器。", OutputType.WARNING
|
|
833
|
-
)
|
|
884
|
+
print("⚠️ 未检测到 fzf,无法打开文件选择器。")
|
|
834
885
|
else:
|
|
835
886
|
files = []
|
|
836
887
|
try:
|
|
@@ -851,7 +902,7 @@ def get_multiline_input(tip: str, print_on_empty: bool = True) -> str:
|
|
|
851
902
|
files = []
|
|
852
903
|
|
|
853
904
|
if not files:
|
|
854
|
-
|
|
905
|
+
print("ℹ️ 未找到可选择的文件。")
|
|
855
906
|
else:
|
|
856
907
|
try:
|
|
857
908
|
specials = [
|
|
@@ -895,7 +946,7 @@ def get_multiline_input(tip: str, print_on_empty: bool = True) -> str:
|
|
|
895
946
|
if sel:
|
|
896
947
|
selected_path = sel
|
|
897
948
|
except Exception as e:
|
|
898
|
-
|
|
949
|
+
print(f"❌ FZF 执行失败: {e}")
|
|
899
950
|
|
|
900
951
|
# Compute new text based on selection (or keep original if none)
|
|
901
952
|
if selected_path:
|
|
@@ -949,5 +1000,5 @@ def get_multiline_input(tip: str, print_on_empty: bool = True) -> str:
|
|
|
949
1000
|
continue
|
|
950
1001
|
else:
|
|
951
1002
|
if not user_input and print_on_empty:
|
|
952
|
-
|
|
1003
|
+
print("ℹ️ 输入已取消")
|
|
953
1004
|
return user_input
|