jarvis-ai-assistant 0.7.16__py3-none-any.whl → 1.0.2__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 +567 -222
- jarvis/jarvis_agent/agent_manager.py +19 -12
- jarvis/jarvis_agent/builtin_input_handler.py +79 -11
- jarvis/jarvis_agent/config_editor.py +7 -2
- jarvis/jarvis_agent/event_bus.py +24 -13
- jarvis/jarvis_agent/events.py +19 -1
- jarvis/jarvis_agent/file_context_handler.py +67 -64
- jarvis/jarvis_agent/file_methodology_manager.py +38 -24
- jarvis/jarvis_agent/jarvis.py +186 -114
- jarvis/jarvis_agent/language_extractors/__init__.py +8 -1
- jarvis/jarvis_agent/language_extractors/c_extractor.py +7 -4
- jarvis/jarvis_agent/language_extractors/cpp_extractor.py +9 -4
- jarvis/jarvis_agent/language_extractors/go_extractor.py +7 -4
- jarvis/jarvis_agent/language_extractors/java_extractor.py +27 -20
- jarvis/jarvis_agent/language_extractors/javascript_extractor.py +22 -17
- jarvis/jarvis_agent/language_extractors/python_extractor.py +7 -4
- jarvis/jarvis_agent/language_extractors/rust_extractor.py +7 -4
- jarvis/jarvis_agent/language_extractors/typescript_extractor.py +22 -17
- jarvis/jarvis_agent/language_support_info.py +250 -219
- jarvis/jarvis_agent/main.py +19 -23
- jarvis/jarvis_agent/memory_manager.py +9 -6
- jarvis/jarvis_agent/methodology_share_manager.py +21 -15
- jarvis/jarvis_agent/output_handler.py +4 -2
- jarvis/jarvis_agent/prompt_builder.py +7 -6
- jarvis/jarvis_agent/prompt_manager.py +113 -8
- jarvis/jarvis_agent/prompts.py +317 -85
- jarvis/jarvis_agent/protocols.py +5 -2
- jarvis/jarvis_agent/run_loop.py +192 -32
- jarvis/jarvis_agent/session_manager.py +7 -3
- jarvis/jarvis_agent/share_manager.py +23 -13
- jarvis/jarvis_agent/shell_input_handler.py +12 -8
- jarvis/jarvis_agent/stdio_redirect.py +25 -26
- jarvis/jarvis_agent/task_analyzer.py +29 -23
- jarvis/jarvis_agent/task_list.py +869 -0
- jarvis/jarvis_agent/task_manager.py +26 -23
- jarvis/jarvis_agent/tool_executor.py +6 -5
- jarvis/jarvis_agent/tool_share_manager.py +24 -14
- jarvis/jarvis_agent/user_interaction.py +3 -3
- jarvis/jarvis_agent/utils.py +9 -1
- jarvis/jarvis_agent/web_bridge.py +37 -17
- jarvis/jarvis_agent/web_output_sink.py +5 -2
- jarvis/jarvis_agent/web_server.py +165 -36
- jarvis/jarvis_c2rust/__init__.py +1 -1
- jarvis/jarvis_c2rust/cli.py +260 -141
- jarvis/jarvis_c2rust/collector.py +37 -18
- jarvis/jarvis_c2rust/constants.py +60 -0
- jarvis/jarvis_c2rust/library_replacer.py +242 -1010
- jarvis/jarvis_c2rust/library_replacer_checkpoint.py +133 -0
- jarvis/jarvis_c2rust/library_replacer_llm.py +287 -0
- jarvis/jarvis_c2rust/library_replacer_loader.py +191 -0
- jarvis/jarvis_c2rust/library_replacer_output.py +134 -0
- jarvis/jarvis_c2rust/library_replacer_prompts.py +124 -0
- jarvis/jarvis_c2rust/library_replacer_utils.py +188 -0
- jarvis/jarvis_c2rust/llm_module_agent.py +98 -1044
- jarvis/jarvis_c2rust/llm_module_agent_apply.py +170 -0
- jarvis/jarvis_c2rust/llm_module_agent_executor.py +288 -0
- jarvis/jarvis_c2rust/llm_module_agent_loader.py +170 -0
- jarvis/jarvis_c2rust/llm_module_agent_prompts.py +268 -0
- jarvis/jarvis_c2rust/llm_module_agent_types.py +57 -0
- jarvis/jarvis_c2rust/llm_module_agent_utils.py +150 -0
- jarvis/jarvis_c2rust/llm_module_agent_validator.py +119 -0
- jarvis/jarvis_c2rust/loaders.py +28 -10
- jarvis/jarvis_c2rust/models.py +5 -2
- jarvis/jarvis_c2rust/optimizer.py +192 -1974
- jarvis/jarvis_c2rust/optimizer_build_fix.py +286 -0
- jarvis/jarvis_c2rust/optimizer_clippy.py +766 -0
- jarvis/jarvis_c2rust/optimizer_config.py +49 -0
- jarvis/jarvis_c2rust/optimizer_docs.py +183 -0
- jarvis/jarvis_c2rust/optimizer_options.py +48 -0
- jarvis/jarvis_c2rust/optimizer_progress.py +469 -0
- jarvis/jarvis_c2rust/optimizer_report.py +52 -0
- jarvis/jarvis_c2rust/optimizer_unsafe.py +309 -0
- jarvis/jarvis_c2rust/optimizer_utils.py +469 -0
- jarvis/jarvis_c2rust/optimizer_visibility.py +185 -0
- jarvis/jarvis_c2rust/scanner.py +229 -166
- jarvis/jarvis_c2rust/transpiler.py +531 -2732
- jarvis/jarvis_c2rust/transpiler_agents.py +503 -0
- jarvis/jarvis_c2rust/transpiler_build.py +1294 -0
- jarvis/jarvis_c2rust/transpiler_codegen.py +204 -0
- jarvis/jarvis_c2rust/transpiler_compile.py +146 -0
- jarvis/jarvis_c2rust/transpiler_config.py +178 -0
- jarvis/jarvis_c2rust/transpiler_context.py +122 -0
- jarvis/jarvis_c2rust/transpiler_executor.py +516 -0
- jarvis/jarvis_c2rust/transpiler_generation.py +278 -0
- jarvis/jarvis_c2rust/transpiler_git.py +163 -0
- jarvis/jarvis_c2rust/transpiler_mod_utils.py +225 -0
- jarvis/jarvis_c2rust/transpiler_modules.py +336 -0
- jarvis/jarvis_c2rust/transpiler_planning.py +394 -0
- jarvis/jarvis_c2rust/transpiler_review.py +1196 -0
- jarvis/jarvis_c2rust/transpiler_symbols.py +176 -0
- jarvis/jarvis_c2rust/utils.py +269 -79
- jarvis/jarvis_code_agent/after_change.py +233 -0
- jarvis/jarvis_code_agent/build_validation_config.py +37 -30
- jarvis/jarvis_code_agent/builtin_rules.py +68 -0
- jarvis/jarvis_code_agent/code_agent.py +976 -1517
- jarvis/jarvis_code_agent/code_agent_build.py +227 -0
- jarvis/jarvis_code_agent/code_agent_diff.py +246 -0
- jarvis/jarvis_code_agent/code_agent_git.py +525 -0
- jarvis/jarvis_code_agent/code_agent_impact.py +177 -0
- jarvis/jarvis_code_agent/code_agent_lint.py +283 -0
- jarvis/jarvis_code_agent/code_agent_llm.py +159 -0
- jarvis/jarvis_code_agent/code_agent_postprocess.py +105 -0
- jarvis/jarvis_code_agent/code_agent_prompts.py +46 -0
- jarvis/jarvis_code_agent/code_agent_rules.py +305 -0
- jarvis/jarvis_code_agent/code_analyzer/__init__.py +52 -48
- jarvis/jarvis_code_agent/code_analyzer/base_language.py +12 -10
- jarvis/jarvis_code_agent/code_analyzer/build_validator/__init__.py +12 -11
- jarvis/jarvis_code_agent/code_analyzer/build_validator/base.py +16 -12
- jarvis/jarvis_code_agent/code_analyzer/build_validator/cmake.py +26 -17
- jarvis/jarvis_code_agent/code_analyzer/build_validator/detector.py +558 -104
- jarvis/jarvis_code_agent/code_analyzer/build_validator/fallback.py +27 -16
- jarvis/jarvis_code_agent/code_analyzer/build_validator/go.py +22 -18
- jarvis/jarvis_code_agent/code_analyzer/build_validator/java_gradle.py +21 -16
- jarvis/jarvis_code_agent/code_analyzer/build_validator/java_maven.py +20 -16
- jarvis/jarvis_code_agent/code_analyzer/build_validator/makefile.py +27 -16
- jarvis/jarvis_code_agent/code_analyzer/build_validator/nodejs.py +47 -23
- jarvis/jarvis_code_agent/code_analyzer/build_validator/python.py +71 -37
- jarvis/jarvis_code_agent/code_analyzer/build_validator/rust.py +162 -35
- jarvis/jarvis_code_agent/code_analyzer/build_validator/validator.py +111 -57
- jarvis/jarvis_code_agent/code_analyzer/build_validator.py +18 -12
- jarvis/jarvis_code_agent/code_analyzer/context_manager.py +185 -183
- jarvis/jarvis_code_agent/code_analyzer/context_recommender.py +2 -1
- jarvis/jarvis_code_agent/code_analyzer/dependency_analyzer.py +24 -15
- jarvis/jarvis_code_agent/code_analyzer/file_ignore.py +227 -141
- jarvis/jarvis_code_agent/code_analyzer/impact_analyzer.py +321 -247
- jarvis/jarvis_code_agent/code_analyzer/language_registry.py +37 -29
- jarvis/jarvis_code_agent/code_analyzer/language_support.py +21 -13
- jarvis/jarvis_code_agent/code_analyzer/languages/__init__.py +15 -9
- jarvis/jarvis_code_agent/code_analyzer/languages/c_cpp_language.py +75 -45
- jarvis/jarvis_code_agent/code_analyzer/languages/go_language.py +87 -52
- jarvis/jarvis_code_agent/code_analyzer/languages/java_language.py +84 -51
- jarvis/jarvis_code_agent/code_analyzer/languages/javascript_language.py +94 -64
- jarvis/jarvis_code_agent/code_analyzer/languages/python_language.py +109 -71
- jarvis/jarvis_code_agent/code_analyzer/languages/rust_language.py +97 -63
- jarvis/jarvis_code_agent/code_analyzer/languages/typescript_language.py +103 -69
- jarvis/jarvis_code_agent/code_analyzer/llm_context_recommender.py +271 -268
- jarvis/jarvis_code_agent/code_analyzer/symbol_extractor.py +76 -64
- jarvis/jarvis_code_agent/code_analyzer/tree_sitter_extractor.py +92 -19
- jarvis/jarvis_code_agent/diff_visualizer.py +998 -0
- jarvis/jarvis_code_agent/lint.py +223 -524
- jarvis/jarvis_code_agent/rule_share_manager.py +158 -0
- jarvis/jarvis_code_agent/rules/clean_code.md +144 -0
- jarvis/jarvis_code_agent/rules/code_review.md +115 -0
- jarvis/jarvis_code_agent/rules/documentation.md +165 -0
- jarvis/jarvis_code_agent/rules/generate_rules.md +52 -0
- jarvis/jarvis_code_agent/rules/performance.md +158 -0
- jarvis/jarvis_code_agent/rules/refactoring.md +139 -0
- jarvis/jarvis_code_agent/rules/security.md +160 -0
- jarvis/jarvis_code_agent/rules/tdd.md +78 -0
- jarvis/jarvis_code_agent/test_rules/cpp_test.md +118 -0
- jarvis/jarvis_code_agent/test_rules/go_test.md +98 -0
- jarvis/jarvis_code_agent/test_rules/java_test.md +99 -0
- jarvis/jarvis_code_agent/test_rules/javascript_test.md +113 -0
- jarvis/jarvis_code_agent/test_rules/php_test.md +117 -0
- jarvis/jarvis_code_agent/test_rules/python_test.md +91 -0
- jarvis/jarvis_code_agent/test_rules/ruby_test.md +102 -0
- jarvis/jarvis_code_agent/test_rules/rust_test.md +86 -0
- jarvis/jarvis_code_agent/utils.py +36 -26
- jarvis/jarvis_code_analysis/checklists/loader.py +21 -21
- jarvis/jarvis_code_analysis/code_review.py +64 -33
- jarvis/jarvis_data/config_schema.json +285 -192
- jarvis/jarvis_git_squash/main.py +8 -6
- jarvis/jarvis_git_utils/git_commiter.py +53 -76
- jarvis/jarvis_mcp/__init__.py +5 -2
- jarvis/jarvis_mcp/sse_mcp_client.py +40 -30
- jarvis/jarvis_mcp/stdio_mcp_client.py +27 -19
- jarvis/jarvis_mcp/streamable_mcp_client.py +35 -26
- jarvis/jarvis_memory_organizer/memory_organizer.py +78 -55
- jarvis/jarvis_methodology/main.py +48 -39
- jarvis/jarvis_multi_agent/__init__.py +56 -23
- jarvis/jarvis_multi_agent/main.py +15 -18
- jarvis/jarvis_platform/base.py +179 -111
- jarvis/jarvis_platform/human.py +27 -16
- jarvis/jarvis_platform/kimi.py +52 -45
- jarvis/jarvis_platform/openai.py +101 -40
- jarvis/jarvis_platform/registry.py +51 -33
- jarvis/jarvis_platform/tongyi.py +68 -38
- jarvis/jarvis_platform/yuanbao.py +59 -43
- jarvis/jarvis_platform_manager/main.py +68 -76
- jarvis/jarvis_platform_manager/service.py +24 -14
- jarvis/jarvis_rag/README_CONFIG.md +314 -0
- jarvis/jarvis_rag/README_DYNAMIC_LOADING.md +311 -0
- jarvis/jarvis_rag/README_ONLINE_MODELS.md +230 -0
- jarvis/jarvis_rag/__init__.py +57 -4
- jarvis/jarvis_rag/cache.py +3 -1
- jarvis/jarvis_rag/cli.py +48 -68
- jarvis/jarvis_rag/embedding_interface.py +39 -0
- jarvis/jarvis_rag/embedding_manager.py +7 -230
- jarvis/jarvis_rag/embeddings/__init__.py +41 -0
- jarvis/jarvis_rag/embeddings/base.py +114 -0
- jarvis/jarvis_rag/embeddings/cohere.py +66 -0
- jarvis/jarvis_rag/embeddings/edgefn.py +117 -0
- jarvis/jarvis_rag/embeddings/local.py +260 -0
- jarvis/jarvis_rag/embeddings/openai.py +62 -0
- jarvis/jarvis_rag/embeddings/registry.py +293 -0
- jarvis/jarvis_rag/llm_interface.py +8 -6
- jarvis/jarvis_rag/query_rewriter.py +8 -9
- jarvis/jarvis_rag/rag_pipeline.py +61 -52
- jarvis/jarvis_rag/reranker.py +7 -75
- jarvis/jarvis_rag/reranker_interface.py +32 -0
- jarvis/jarvis_rag/rerankers/__init__.py +41 -0
- jarvis/jarvis_rag/rerankers/base.py +109 -0
- jarvis/jarvis_rag/rerankers/cohere.py +67 -0
- jarvis/jarvis_rag/rerankers/edgefn.py +140 -0
- jarvis/jarvis_rag/rerankers/jina.py +79 -0
- jarvis/jarvis_rag/rerankers/local.py +89 -0
- jarvis/jarvis_rag/rerankers/registry.py +293 -0
- jarvis/jarvis_rag/retriever.py +58 -43
- jarvis/jarvis_sec/__init__.py +66 -141
- jarvis/jarvis_sec/agents.py +21 -17
- jarvis/jarvis_sec/analysis.py +80 -33
- jarvis/jarvis_sec/checkers/__init__.py +7 -13
- jarvis/jarvis_sec/checkers/c_checker.py +356 -164
- jarvis/jarvis_sec/checkers/rust_checker.py +47 -29
- jarvis/jarvis_sec/cli.py +43 -21
- jarvis/jarvis_sec/clustering.py +430 -272
- jarvis/jarvis_sec/file_manager.py +99 -55
- jarvis/jarvis_sec/parsers.py +9 -6
- jarvis/jarvis_sec/prompts.py +4 -3
- jarvis/jarvis_sec/report.py +44 -22
- jarvis/jarvis_sec/review.py +180 -107
- jarvis/jarvis_sec/status.py +50 -41
- jarvis/jarvis_sec/types.py +3 -0
- jarvis/jarvis_sec/utils.py +160 -83
- jarvis/jarvis_sec/verification.py +411 -181
- jarvis/jarvis_sec/workflow.py +132 -21
- jarvis/jarvis_smart_shell/main.py +28 -41
- jarvis/jarvis_stats/cli.py +14 -12
- jarvis/jarvis_stats/stats.py +28 -19
- jarvis/jarvis_stats/storage.py +14 -8
- jarvis/jarvis_stats/visualizer.py +12 -7
- jarvis/jarvis_tools/base.py +5 -2
- jarvis/jarvis_tools/clear_memory.py +13 -9
- jarvis/jarvis_tools/cli/main.py +23 -18
- jarvis/jarvis_tools/edit_file.py +572 -873
- jarvis/jarvis_tools/execute_script.py +10 -7
- jarvis/jarvis_tools/file_analyzer.py +7 -8
- jarvis/jarvis_tools/meta_agent.py +287 -0
- jarvis/jarvis_tools/methodology.py +5 -3
- jarvis/jarvis_tools/read_code.py +305 -1438
- jarvis/jarvis_tools/read_symbols.py +50 -17
- jarvis/jarvis_tools/read_webpage.py +19 -18
- jarvis/jarvis_tools/registry.py +435 -156
- jarvis/jarvis_tools/retrieve_memory.py +16 -11
- jarvis/jarvis_tools/save_memory.py +8 -6
- jarvis/jarvis_tools/search_web.py +31 -31
- jarvis/jarvis_tools/sub_agent.py +32 -28
- jarvis/jarvis_tools/sub_code_agent.py +44 -60
- jarvis/jarvis_tools/task_list_manager.py +1811 -0
- jarvis/jarvis_tools/virtual_tty.py +29 -19
- jarvis/jarvis_utils/__init__.py +4 -0
- jarvis/jarvis_utils/builtin_replace_map.py +2 -1
- jarvis/jarvis_utils/clipboard.py +9 -8
- jarvis/jarvis_utils/collections.py +331 -0
- jarvis/jarvis_utils/config.py +699 -194
- jarvis/jarvis_utils/dialogue_recorder.py +294 -0
- jarvis/jarvis_utils/embedding.py +6 -3
- jarvis/jarvis_utils/file_processors.py +7 -1
- jarvis/jarvis_utils/fzf.py +9 -3
- jarvis/jarvis_utils/git_utils.py +71 -42
- jarvis/jarvis_utils/globals.py +116 -32
- jarvis/jarvis_utils/http.py +6 -2
- jarvis/jarvis_utils/input.py +318 -83
- jarvis/jarvis_utils/jsonnet_compat.py +119 -104
- jarvis/jarvis_utils/methodology.py +37 -28
- jarvis/jarvis_utils/output.py +201 -44
- jarvis/jarvis_utils/utils.py +986 -628
- {jarvis_ai_assistant-0.7.16.dist-info → jarvis_ai_assistant-1.0.2.dist-info}/METADATA +49 -33
- jarvis_ai_assistant-1.0.2.dist-info/RECORD +304 -0
- jarvis/jarvis_code_agent/code_analyzer/structured_code.py +0 -556
- jarvis/jarvis_tools/generate_new_tool.py +0 -205
- jarvis/jarvis_tools/lsp_client.py +0 -1552
- jarvis/jarvis_tools/rewrite_file.py +0 -105
- jarvis_ai_assistant-0.7.16.dist-info/RECORD +0 -218
- {jarvis_ai_assistant-0.7.16.dist-info → jarvis_ai_assistant-1.0.2.dist-info}/WHEEL +0 -0
- {jarvis_ai_assistant-0.7.16.dist-info → jarvis_ai_assistant-1.0.2.dist-info}/entry_points.txt +0 -0
- {jarvis_ai_assistant-0.7.16.dist-info → jarvis_ai_assistant-1.0.2.dist-info}/licenses/LICENSE +0 -0
- {jarvis_ai_assistant-0.7.16.dist-info → jarvis_ai_assistant-1.0.2.dist-info}/top_level.txt +0 -0
|
@@ -2,7 +2,11 @@
|
|
|
2
2
|
import os
|
|
3
3
|
import sys
|
|
4
4
|
import time
|
|
5
|
-
from typing import
|
|
5
|
+
from typing import TYPE_CHECKING
|
|
6
|
+
from typing import Any
|
|
7
|
+
from typing import Dict
|
|
8
|
+
|
|
9
|
+
from jarvis.jarvis_utils.output import PrettyOutput
|
|
6
10
|
|
|
7
11
|
# 为了类型检查,总是导入这些模块
|
|
8
12
|
if TYPE_CHECKING:
|
|
@@ -112,7 +116,7 @@ class VirtualTTYTool:
|
|
|
112
116
|
try:
|
|
113
117
|
if action == "launch":
|
|
114
118
|
if args.get("keys", "") != "":
|
|
115
|
-
|
|
119
|
+
PrettyOutput.auto_print("❌ 启动虚拟终端时,不能同时指定 keys 参数")
|
|
116
120
|
return {
|
|
117
121
|
"success": False,
|
|
118
122
|
"stdout": "",
|
|
@@ -121,7 +125,7 @@ class VirtualTTYTool:
|
|
|
121
125
|
|
|
122
126
|
result = self._launch_tty(agent, tty_id)
|
|
123
127
|
if not result["success"]:
|
|
124
|
-
|
|
128
|
+
PrettyOutput.auto_print(f"❌ 启动虚拟终端 [{tty_id}] 失败")
|
|
125
129
|
return result
|
|
126
130
|
elif action == "send_keys":
|
|
127
131
|
keys = args.get("keys", "").strip()
|
|
@@ -130,32 +134,29 @@ class VirtualTTYTool:
|
|
|
130
134
|
|
|
131
135
|
result = self._input_command(agent, tty_id, keys, timeout, add_enter)
|
|
132
136
|
if not result["success"]:
|
|
133
|
-
|
|
137
|
+
PrettyOutput.auto_print(f"❌ 发送按键序列到终端 [{tty_id}] 失败")
|
|
134
138
|
return result
|
|
135
139
|
elif action == "output":
|
|
136
140
|
timeout = args.get("timeout", 5.0) # 默认5秒超时
|
|
137
141
|
|
|
138
142
|
result = self._get_output(agent, tty_id, timeout)
|
|
139
143
|
if not result["success"]:
|
|
140
|
-
|
|
144
|
+
PrettyOutput.auto_print(f"❌ 获取终端 [{tty_id}] 输出失败")
|
|
141
145
|
return result
|
|
142
146
|
elif action == "close":
|
|
143
|
-
|
|
144
147
|
result = self._close_tty(agent, tty_id)
|
|
145
148
|
if not result["success"]:
|
|
146
|
-
|
|
149
|
+
PrettyOutput.auto_print(f"❌ 关闭虚拟终端 [{tty_id}] 失败")
|
|
147
150
|
return result
|
|
148
151
|
elif action == "get_screen":
|
|
149
|
-
|
|
150
152
|
result = self._get_screen(agent, tty_id)
|
|
151
153
|
if not result["success"]:
|
|
152
|
-
|
|
154
|
+
PrettyOutput.auto_print(f"❌ 获取终端 [{tty_id}] 屏幕内容失败")
|
|
153
155
|
return result
|
|
154
156
|
elif action == "list":
|
|
155
|
-
|
|
156
157
|
result = self._list_ttys(agent)
|
|
157
158
|
if not result["success"]:
|
|
158
|
-
|
|
159
|
+
PrettyOutput.auto_print("❌ 获取虚拟终端列表失败")
|
|
159
160
|
return result
|
|
160
161
|
return {"success": False, "stdout": "", "stderr": "不支持的操作"}
|
|
161
162
|
|
|
@@ -181,8 +182,8 @@ class VirtualTTYTool:
|
|
|
181
182
|
self._close_tty(agent, tty_id)
|
|
182
183
|
|
|
183
184
|
# 在Unix平台上导入需要的模块
|
|
184
|
-
import pty as _pty # pylint: disable=import-outside-toplevel
|
|
185
185
|
import fcntl as _fcntl # pylint: disable=import-outside-toplevel
|
|
186
|
+
import pty as _pty # pylint: disable=import-outside-toplevel
|
|
186
187
|
import select as _select # pylint: disable=import-outside-toplevel
|
|
187
188
|
|
|
188
189
|
# 创建伪终端
|
|
@@ -216,7 +217,9 @@ class VirtualTTYTool:
|
|
|
216
217
|
continue
|
|
217
218
|
|
|
218
219
|
if output:
|
|
219
|
-
|
|
220
|
+
PrettyOutput.auto_print(
|
|
221
|
+
f"📥 启动终端时的初始输出 [{tty_id}]:\n{output}"
|
|
222
|
+
)
|
|
220
223
|
return {"success": True, "stdout": output, "stderr": ""}
|
|
221
224
|
|
|
222
225
|
except Exception as e:
|
|
@@ -234,9 +237,9 @@ class VirtualTTYTool:
|
|
|
234
237
|
self._close_tty(agent, tty_id)
|
|
235
238
|
|
|
236
239
|
# 在Windows平台上导入需要的模块
|
|
240
|
+
import queue as _queue # pylint: disable=import-outside-toplevel
|
|
237
241
|
import subprocess as _subprocess # pylint: disable=import-outside-toplevel
|
|
238
242
|
import threading as _threading # pylint: disable=import-outside-toplevel
|
|
239
|
-
import queue as _queue # pylint: disable=import-outside-toplevel
|
|
240
243
|
|
|
241
244
|
# 创建子进程
|
|
242
245
|
process = _subprocess.Popen(
|
|
@@ -283,7 +286,9 @@ class VirtualTTYTool:
|
|
|
283
286
|
continue
|
|
284
287
|
|
|
285
288
|
if output:
|
|
286
|
-
|
|
289
|
+
PrettyOutput.auto_print(
|
|
290
|
+
f"📥 启动终端时的初始输出 [{tty_id}]:\n{output}"
|
|
291
|
+
)
|
|
287
292
|
return {"success": True, "stdout": output, "stderr": ""}
|
|
288
293
|
|
|
289
294
|
except Exception as e:
|
|
@@ -361,7 +366,9 @@ class VirtualTTYTool:
|
|
|
361
366
|
except BlockingIOError:
|
|
362
367
|
continue
|
|
363
368
|
if output:
|
|
364
|
-
|
|
369
|
+
PrettyOutput.auto_print(
|
|
370
|
+
f"📥 命令执行后的输出内容 [{tty_id}]:\n{output}"
|
|
371
|
+
)
|
|
365
372
|
return {"success": True, "stdout": output, "stderr": ""}
|
|
366
373
|
|
|
367
374
|
except Exception as e:
|
|
@@ -411,7 +418,9 @@ class VirtualTTYTool:
|
|
|
411
418
|
continue
|
|
412
419
|
|
|
413
420
|
if output:
|
|
414
|
-
|
|
421
|
+
PrettyOutput.auto_print(
|
|
422
|
+
f"📥 命令执行后的输出内容 [{tty_id}]:\n{output}"
|
|
423
|
+
)
|
|
415
424
|
return {"success": True, "stdout": output, "stderr": ""}
|
|
416
425
|
|
|
417
426
|
except Exception as e:
|
|
@@ -465,7 +474,7 @@ class VirtualTTYTool:
|
|
|
465
474
|
except BlockingIOError:
|
|
466
475
|
break
|
|
467
476
|
if output:
|
|
468
|
-
|
|
477
|
+
PrettyOutput.auto_print(f"📥 获取到的输出内容 [{tty_id}]:\n{output}")
|
|
469
478
|
return {"success": True, "stdout": output, "stderr": ""}
|
|
470
479
|
|
|
471
480
|
except Exception as e:
|
|
@@ -498,7 +507,7 @@ class VirtualTTYTool:
|
|
|
498
507
|
continue
|
|
499
508
|
|
|
500
509
|
if output:
|
|
501
|
-
|
|
510
|
+
PrettyOutput.auto_print(f"📥 获取到的输出内容 [{tty_id}]:\n{output}")
|
|
502
511
|
return {"success": True, "stdout": output, "stderr": ""}
|
|
503
512
|
|
|
504
513
|
except Exception as e:
|
|
@@ -568,6 +577,7 @@ class VirtualTTYTool:
|
|
|
568
577
|
# 终止进程
|
|
569
578
|
try:
|
|
570
579
|
import subprocess as _subprocess # pylint: disable=import-outside-toplevel
|
|
580
|
+
|
|
571
581
|
process.terminate()
|
|
572
582
|
process.wait(timeout=2)
|
|
573
583
|
except _subprocess.TimeoutExpired:
|
jarvis/jarvis_utils/__init__.py
CHANGED
|
@@ -5,6 +5,7 @@ Jarvis工具模块
|
|
|
5
5
|
包含多种辅助函数、配置管理和常见操作。
|
|
6
6
|
该模块组织为以下几个子模块:
|
|
7
7
|
- config: 配置管理
|
|
8
|
+
- dialogue_recorder: 对话记录器
|
|
8
9
|
- embedding: 文本嵌入工具
|
|
9
10
|
- git_utils: Git仓库操作
|
|
10
11
|
- input: 用户输入处理
|
|
@@ -12,6 +13,7 @@ Jarvis工具模块
|
|
|
12
13
|
- output: 输出格式化
|
|
13
14
|
- utils: 通用工具
|
|
14
15
|
"""
|
|
16
|
+
|
|
15
17
|
import os
|
|
16
18
|
|
|
17
19
|
import colorama
|
|
@@ -19,6 +21,8 @@ from rich.traceback import install as install_rich_traceback
|
|
|
19
21
|
|
|
20
22
|
# 从新模块重新导出
|
|
21
23
|
# 这些导入是项目功能所必需的,可能会被动态使用
|
|
24
|
+
from .dialogue_recorder import DialogueRecorder as DialogueRecorder
|
|
25
|
+
|
|
22
26
|
# 初始化colorama以支持跨平台的彩色文本
|
|
23
27
|
colorama.init()
|
|
24
28
|
# 禁用tokenizers并行以避免多进程问题
|
jarvis/jarvis_utils/clipboard.py
CHANGED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
import platform
|
|
3
3
|
import subprocess
|
|
4
4
|
|
|
5
|
+
from jarvis.jarvis_utils.output import PrettyOutput
|
|
5
6
|
|
|
6
7
|
|
|
7
8
|
def copy_to_clipboard(text: str) -> None:
|
|
@@ -10,9 +11,9 @@ def copy_to_clipboard(text: str) -> None:
|
|
|
10
11
|
参数:
|
|
11
12
|
text: 要复制的文本
|
|
12
13
|
"""
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
14
|
+
PrettyOutput.auto_print("ℹ️ --- 剪贴板内容开始 ---")
|
|
15
|
+
PrettyOutput.auto_print(text)
|
|
16
|
+
PrettyOutput.auto_print("ℹ️ --- 剪贴板内容结束 ---")
|
|
16
17
|
|
|
17
18
|
system = platform.system()
|
|
18
19
|
|
|
@@ -32,7 +33,7 @@ def copy_to_clipboard(text: str) -> None:
|
|
|
32
33
|
process.stdin.close()
|
|
33
34
|
return
|
|
34
35
|
except Exception as e:
|
|
35
|
-
|
|
36
|
+
PrettyOutput.auto_print(f"⚠️ 使用Windows clip命令时出错: {e}")
|
|
36
37
|
|
|
37
38
|
# macOS系统
|
|
38
39
|
elif system == "Darwin":
|
|
@@ -48,7 +49,7 @@ def copy_to_clipboard(text: str) -> None:
|
|
|
48
49
|
process.stdin.close()
|
|
49
50
|
return
|
|
50
51
|
except Exception as e:
|
|
51
|
-
|
|
52
|
+
PrettyOutput.auto_print(f"⚠️ 使用macOS pbcopy命令时出错: {e}")
|
|
52
53
|
|
|
53
54
|
# Linux系统
|
|
54
55
|
else:
|
|
@@ -67,7 +68,7 @@ def copy_to_clipboard(text: str) -> None:
|
|
|
67
68
|
except FileNotFoundError:
|
|
68
69
|
pass # xsel 未安装,继续尝试下一个
|
|
69
70
|
except Exception as e:
|
|
70
|
-
|
|
71
|
+
PrettyOutput.auto_print(f"⚠️ 使用xsel时出错: {e}")
|
|
71
72
|
|
|
72
73
|
# 尝试使用 xclip
|
|
73
74
|
try:
|
|
@@ -82,6 +83,6 @@ def copy_to_clipboard(text: str) -> None:
|
|
|
82
83
|
process.stdin.close()
|
|
83
84
|
return
|
|
84
85
|
except FileNotFoundError:
|
|
85
|
-
|
|
86
|
+
PrettyOutput.auto_print("⚠️ xsel 和 xclip 均未安装, 无法复制到剪贴板")
|
|
86
87
|
except Exception as e:
|
|
87
|
-
|
|
88
|
+
PrettyOutput.auto_print(f"⚠️ 使用xclip时出错: {e}")
|
|
@@ -0,0 +1,331 @@
|
|
|
1
|
+
"""
|
|
2
|
+
大小写不敏感的字典和其他集合工具类。
|
|
3
|
+
|
|
4
|
+
这个模块提供了大小写不敏感的字典实现,用于处理配置键的访问,
|
|
5
|
+
确保无论在何种大小写形式下都能正确访问相同的键值。
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
from typing import Any
|
|
9
|
+
from typing import Dict
|
|
10
|
+
from typing import Iterator
|
|
11
|
+
from typing import Mapping
|
|
12
|
+
from typing import Optional
|
|
13
|
+
from typing import Tuple
|
|
14
|
+
from typing import Union
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
class CaseInsensitiveDict(Mapping[str, Any]):
|
|
18
|
+
"""
|
|
19
|
+
大小写不敏感的字典类。
|
|
20
|
+
|
|
21
|
+
这个字典类允许使用任意大小写形式的键来访问相同的值。
|
|
22
|
+
内部使用小写形式存储键,但保留了原始的键名用于迭代和显示。
|
|
23
|
+
|
|
24
|
+
示例:
|
|
25
|
+
>>> d = CaseInsensitiveDict({'Content-Type': 'text/plain'})
|
|
26
|
+
>>> d['content-type']
|
|
27
|
+
'text/plain'
|
|
28
|
+
>>> d['CONTENT-TYPE']
|
|
29
|
+
'text/plain'
|
|
30
|
+
>>> d['Content-Type']
|
|
31
|
+
'text/plain'
|
|
32
|
+
>>> list(d.keys())
|
|
33
|
+
['Content-Type']
|
|
34
|
+
"""
|
|
35
|
+
|
|
36
|
+
def __init__(
|
|
37
|
+
self, data: Optional[Union[Dict[str, Any], "CaseInsensitiveDict"]] = None
|
|
38
|
+
) -> None:
|
|
39
|
+
"""
|
|
40
|
+
初始化CaseInsensitiveDict。
|
|
41
|
+
|
|
42
|
+
Args:
|
|
43
|
+
data: 可选的初始数据,可以是字典或另一个CaseInsensitiveDict
|
|
44
|
+
"""
|
|
45
|
+
self._data: Dict[str, Any] = {}
|
|
46
|
+
self._case_map: Dict[str, str] = {} # 小写键 -> 原始键的映射
|
|
47
|
+
|
|
48
|
+
if data is not None:
|
|
49
|
+
if isinstance(data, CaseInsensitiveDict):
|
|
50
|
+
# 从另一个CaseInsensitiveDict复制
|
|
51
|
+
self._data = data._data.copy()
|
|
52
|
+
self._case_map = data._case_map.copy()
|
|
53
|
+
elif hasattr(data, "items"):
|
|
54
|
+
# 从普通字典或其他映射类型初始化
|
|
55
|
+
for key, value in data.items():
|
|
56
|
+
self[key] = value
|
|
57
|
+
|
|
58
|
+
def __getitem__(self, key: str) -> Any:
|
|
59
|
+
"""
|
|
60
|
+
通过键获取值,大小写不敏感。
|
|
61
|
+
|
|
62
|
+
Args:
|
|
63
|
+
key: 要查找的键
|
|
64
|
+
|
|
65
|
+
Returns:
|
|
66
|
+
对应的值
|
|
67
|
+
|
|
68
|
+
Raises:
|
|
69
|
+
KeyError: 如果键不存在
|
|
70
|
+
"""
|
|
71
|
+
if not isinstance(key, str):
|
|
72
|
+
raise TypeError(f"键必须是字符串类型,得到 {type(key).__name__}")
|
|
73
|
+
|
|
74
|
+
lower_key = key.lower()
|
|
75
|
+
if lower_key not in self._case_map:
|
|
76
|
+
raise KeyError(key)
|
|
77
|
+
|
|
78
|
+
return self._data[lower_key]
|
|
79
|
+
|
|
80
|
+
def __setitem__(self, key: str, value: Any) -> None:
|
|
81
|
+
"""
|
|
82
|
+
设置键值对,大小写不敏感。
|
|
83
|
+
|
|
84
|
+
Args:
|
|
85
|
+
key: 要设置的键
|
|
86
|
+
value: 要设置的值
|
|
87
|
+
"""
|
|
88
|
+
if not isinstance(key, str):
|
|
89
|
+
raise TypeError(f"键必须是字符串类型,得到 {type(key).__name__}")
|
|
90
|
+
|
|
91
|
+
lower_key = key.lower()
|
|
92
|
+
# 如果键已存在,保持原有的原始键名;否则使用新的键名
|
|
93
|
+
if lower_key not in self._case_map:
|
|
94
|
+
self._case_map[lower_key] = key # 保留原始键名
|
|
95
|
+
self._data[lower_key] = value
|
|
96
|
+
|
|
97
|
+
def __delitem__(self, key: str) -> None:
|
|
98
|
+
"""
|
|
99
|
+
删除键值对,大小写不敏感。
|
|
100
|
+
|
|
101
|
+
Args:
|
|
102
|
+
key: 要删除的键
|
|
103
|
+
|
|
104
|
+
Raises:
|
|
105
|
+
KeyError: 如果键不存在
|
|
106
|
+
"""
|
|
107
|
+
if not isinstance(key, str):
|
|
108
|
+
raise TypeError(f"键必须是字符串类型,得到 {type(key).__name__}")
|
|
109
|
+
|
|
110
|
+
lower_key = key.lower()
|
|
111
|
+
if lower_key not in self._case_map:
|
|
112
|
+
raise KeyError(key)
|
|
113
|
+
|
|
114
|
+
del self._case_map[lower_key]
|
|
115
|
+
del self._data[lower_key]
|
|
116
|
+
|
|
117
|
+
def __contains__(self, key: object) -> bool:
|
|
118
|
+
"""
|
|
119
|
+
检查键是否存在,大小写不敏感。
|
|
120
|
+
|
|
121
|
+
Args:
|
|
122
|
+
key: 要检查的键
|
|
123
|
+
|
|
124
|
+
Returns:
|
|
125
|
+
如果键存在返回True,否则返回False
|
|
126
|
+
"""
|
|
127
|
+
if not isinstance(key, str):
|
|
128
|
+
return False
|
|
129
|
+
return key.lower() in self._case_map
|
|
130
|
+
|
|
131
|
+
def __iter__(self) -> Iterator[str]:
|
|
132
|
+
"""
|
|
133
|
+
返回键的迭代器,保持原始大小写。
|
|
134
|
+
|
|
135
|
+
Returns:
|
|
136
|
+
键的迭代器
|
|
137
|
+
"""
|
|
138
|
+
return iter(self._case_map.values())
|
|
139
|
+
|
|
140
|
+
def __len__(self) -> int:
|
|
141
|
+
"""
|
|
142
|
+
返回字典中的键值对数量。
|
|
143
|
+
|
|
144
|
+
Returns:
|
|
145
|
+
键值对的数量
|
|
146
|
+
"""
|
|
147
|
+
return len(self._data)
|
|
148
|
+
|
|
149
|
+
def __repr__(self) -> str:
|
|
150
|
+
"""
|
|
151
|
+
返回字典的字符串表示。
|
|
152
|
+
|
|
153
|
+
Returns:
|
|
154
|
+
字符串表示
|
|
155
|
+
"""
|
|
156
|
+
items = []
|
|
157
|
+
for original_key in self._case_map.values():
|
|
158
|
+
value = self._data[original_key.lower()]
|
|
159
|
+
items.append(f"{original_key!r}: {value!r}")
|
|
160
|
+
return f"CaseInsensitiveDict({{{', '.join(items)}}})"
|
|
161
|
+
|
|
162
|
+
def __eq__(self, other: object) -> bool:
|
|
163
|
+
"""
|
|
164
|
+
比较两个字典是否相等。
|
|
165
|
+
|
|
166
|
+
Args:
|
|
167
|
+
other: 要比较的对象
|
|
168
|
+
|
|
169
|
+
Returns:
|
|
170
|
+
如果相等返回True,否则返回False
|
|
171
|
+
"""
|
|
172
|
+
if not isinstance(other, CaseInsensitiveDict):
|
|
173
|
+
return NotImplemented
|
|
174
|
+
return self._data == other._data
|
|
175
|
+
|
|
176
|
+
def copy(self) -> "CaseInsensitiveDict":
|
|
177
|
+
"""
|
|
178
|
+
创建字典的浅拷贝。
|
|
179
|
+
|
|
180
|
+
Returns:
|
|
181
|
+
新的CaseInsensitiveDict实例
|
|
182
|
+
"""
|
|
183
|
+
return CaseInsensitiveDict(self)
|
|
184
|
+
|
|
185
|
+
def get(self, key: str, default: Any = None) -> Any:
|
|
186
|
+
"""
|
|
187
|
+
获取键对应的值,如果键不存在返回默认值。
|
|
188
|
+
|
|
189
|
+
Args:
|
|
190
|
+
key: 要查找的键
|
|
191
|
+
default: 如果键不存在时返回的默认值
|
|
192
|
+
|
|
193
|
+
Returns:
|
|
194
|
+
键对应的值或默认值
|
|
195
|
+
"""
|
|
196
|
+
try:
|
|
197
|
+
return self[key]
|
|
198
|
+
except KeyError:
|
|
199
|
+
return default
|
|
200
|
+
|
|
201
|
+
def keys(self):
|
|
202
|
+
"""
|
|
203
|
+
返回所有键的视图,保持原始大小写。
|
|
204
|
+
|
|
205
|
+
Returns:
|
|
206
|
+
键的视图对象
|
|
207
|
+
"""
|
|
208
|
+
from collections.abc import KeysView
|
|
209
|
+
|
|
210
|
+
return KeysView(self)
|
|
211
|
+
|
|
212
|
+
def values(self):
|
|
213
|
+
"""
|
|
214
|
+
返回所有值的视图。
|
|
215
|
+
|
|
216
|
+
Returns:
|
|
217
|
+
值的视图对象
|
|
218
|
+
"""
|
|
219
|
+
from collections.abc import ValuesView
|
|
220
|
+
|
|
221
|
+
return ValuesView(self)
|
|
222
|
+
|
|
223
|
+
def items(self):
|
|
224
|
+
"""
|
|
225
|
+
返回所有键值对的视图,键保持原始大小写。
|
|
226
|
+
|
|
227
|
+
Returns:
|
|
228
|
+
键值对的视图对象
|
|
229
|
+
"""
|
|
230
|
+
from collections.abc import ItemsView
|
|
231
|
+
|
|
232
|
+
return ItemsView(self)
|
|
233
|
+
|
|
234
|
+
def pop(self, key: str, *args: Any) -> Any:
|
|
235
|
+
"""
|
|
236
|
+
移除并返回指定键的值。
|
|
237
|
+
|
|
238
|
+
Args:
|
|
239
|
+
key: 要移除的键
|
|
240
|
+
*args: 如果键不存在时的默认值(可选)
|
|
241
|
+
|
|
242
|
+
Returns:
|
|
243
|
+
键对应的值
|
|
244
|
+
|
|
245
|
+
Raises:
|
|
246
|
+
KeyError: 如果键不存在且没有提供默认值
|
|
247
|
+
"""
|
|
248
|
+
if not isinstance(key, str):
|
|
249
|
+
raise TypeError(f"键必须是字符串类型,得到 {type(key).__name__}")
|
|
250
|
+
|
|
251
|
+
lower_key = key.lower()
|
|
252
|
+
if lower_key not in self._case_map:
|
|
253
|
+
if args:
|
|
254
|
+
return args[0]
|
|
255
|
+
raise KeyError(key)
|
|
256
|
+
|
|
257
|
+
self._case_map.pop(lower_key)
|
|
258
|
+
value = self._data.pop(lower_key)
|
|
259
|
+
return value
|
|
260
|
+
|
|
261
|
+
def popitem(self) -> Tuple[str, Any]:
|
|
262
|
+
"""
|
|
263
|
+
移除并返回最后一个键值对。
|
|
264
|
+
|
|
265
|
+
Returns:
|
|
266
|
+
键值对
|
|
267
|
+
|
|
268
|
+
Raises:
|
|
269
|
+
KeyError: 如果字典为空
|
|
270
|
+
"""
|
|
271
|
+
if not self._data:
|
|
272
|
+
raise KeyError("字典为空")
|
|
273
|
+
|
|
274
|
+
lower_key, value = self._data.popitem()
|
|
275
|
+
original_key = self._case_map.pop(lower_key)
|
|
276
|
+
return original_key, value
|
|
277
|
+
|
|
278
|
+
def setdefault(self, key: str, default: Any = None) -> Any:
|
|
279
|
+
"""
|
|
280
|
+
如果键存在返回对应的值,否则设置键的值为默认值并返回默认值。
|
|
281
|
+
|
|
282
|
+
Args:
|
|
283
|
+
key: 要查找的键
|
|
284
|
+
default: 默认值
|
|
285
|
+
|
|
286
|
+
Returns:
|
|
287
|
+
键对应的值或默认值
|
|
288
|
+
"""
|
|
289
|
+
try:
|
|
290
|
+
return self[key]
|
|
291
|
+
except KeyError:
|
|
292
|
+
self[key] = default
|
|
293
|
+
return default
|
|
294
|
+
|
|
295
|
+
def update(self, *args: Any, **kwargs: Any) -> None:
|
|
296
|
+
"""
|
|
297
|
+
更新字典。
|
|
298
|
+
|
|
299
|
+
Args:
|
|
300
|
+
*args: 可以是另一个字典或键值对的可迭代对象
|
|
301
|
+
**kwargs: 关键字参数形式的键值对(下划线会被转换为连字符)
|
|
302
|
+
"""
|
|
303
|
+
if args:
|
|
304
|
+
other = args[0]
|
|
305
|
+
if hasattr(other, "items"):
|
|
306
|
+
for key, value in other.items():
|
|
307
|
+
self[key] = value
|
|
308
|
+
else:
|
|
309
|
+
for key, value in other:
|
|
310
|
+
self[key] = value
|
|
311
|
+
|
|
312
|
+
for key, value in kwargs.items():
|
|
313
|
+
# 将关键字参数中的下划线转换为连字符(用于HTTP头部等场景)
|
|
314
|
+
normalized_key = key.replace("_", "-")
|
|
315
|
+
self[normalized_key] = value
|
|
316
|
+
|
|
317
|
+
def clear(self) -> None:
|
|
318
|
+
"""
|
|
319
|
+
清空字典。
|
|
320
|
+
"""
|
|
321
|
+
self._data.clear()
|
|
322
|
+
self._case_map.clear()
|
|
323
|
+
|
|
324
|
+
def lower_keys(self) -> Iterator[str]:
|
|
325
|
+
"""
|
|
326
|
+
返回所有键的小写形式的迭代器。
|
|
327
|
+
|
|
328
|
+
Returns:
|
|
329
|
+
小写键的迭代器
|
|
330
|
+
"""
|
|
331
|
+
return iter(self._case_map.keys())
|