jarvis-ai-assistant 0.7.0__py3-none-any.whl → 0.7.8__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 +243 -139
- jarvis/jarvis_agent/agent_manager.py +5 -10
- 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 +265 -15
- jarvis/jarvis_agent/file_methodology_manager.py +3 -4
- jarvis/jarvis_agent/jarvis.py +113 -98
- 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 +6 -12
- 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 +77 -14
- jarvis/jarvis_agent/session_manager.py +2 -3
- jarvis/jarvis_agent/share_manager.py +12 -21
- jarvis/jarvis_agent/shell_input_handler.py +1 -2
- jarvis/jarvis_agent/task_analyzer.py +26 -4
- 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/web_server.py +55 -20
- jarvis/jarvis_c2rust/__init__.py +5 -5
- jarvis/jarvis_c2rust/cli.py +461 -499
- jarvis/jarvis_c2rust/collector.py +45 -53
- jarvis/jarvis_c2rust/constants.py +26 -0
- jarvis/jarvis_c2rust/library_replacer.py +264 -132
- jarvis/jarvis_c2rust/llm_module_agent.py +162 -190
- jarvis/jarvis_c2rust/loaders.py +207 -0
- jarvis/jarvis_c2rust/models.py +28 -0
- jarvis/jarvis_c2rust/optimizer.py +1592 -395
- jarvis/jarvis_c2rust/transpiler.py +1722 -1064
- jarvis/jarvis_c2rust/utils.py +385 -0
- jarvis/jarvis_code_agent/build_validation_config.py +2 -3
- jarvis/jarvis_code_agent/code_agent.py +394 -320
- jarvis/jarvis_code_agent/code_analyzer/__init__.py +3 -0
- jarvis/jarvis_code_agent/code_analyzer/build_validator/base.py +4 -0
- jarvis/jarvis_code_agent/code_analyzer/build_validator/cmake.py +17 -2
- jarvis/jarvis_code_agent/code_analyzer/build_validator/fallback.py +3 -0
- jarvis/jarvis_code_agent/code_analyzer/build_validator/go.py +36 -4
- jarvis/jarvis_code_agent/code_analyzer/build_validator/java_gradle.py +9 -0
- jarvis/jarvis_code_agent/code_analyzer/build_validator/java_maven.py +9 -0
- jarvis/jarvis_code_agent/code_analyzer/build_validator/makefile.py +12 -1
- jarvis/jarvis_code_agent/code_analyzer/build_validator/nodejs.py +22 -5
- jarvis/jarvis_code_agent/code_analyzer/build_validator/python.py +57 -32
- jarvis/jarvis_code_agent/code_analyzer/build_validator/rust.py +62 -6
- jarvis/jarvis_code_agent/code_analyzer/build_validator/validator.py +8 -9
- jarvis/jarvis_code_agent/code_analyzer/context_manager.py +290 -5
- jarvis/jarvis_code_agent/code_analyzer/language_support.py +21 -0
- jarvis/jarvis_code_agent/code_analyzer/languages/__init__.py +21 -3
- jarvis/jarvis_code_agent/code_analyzer/languages/c_cpp_language.py +72 -4
- jarvis/jarvis_code_agent/code_analyzer/languages/go_language.py +35 -3
- 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 +52 -2
- jarvis/jarvis_code_agent/code_analyzer/languages/rust_language.py +73 -1
- jarvis/jarvis_code_agent/code_analyzer/languages/typescript_language.py +280 -0
- jarvis/jarvis_code_agent/code_analyzer/llm_context_recommender.py +306 -152
- jarvis/jarvis_code_agent/code_analyzer/structured_code.py +556 -0
- jarvis/jarvis_code_agent/code_analyzer/symbol_extractor.py +193 -18
- jarvis/jarvis_code_agent/code_analyzer/tree_sitter_extractor.py +18 -8
- jarvis/jarvis_code_agent/lint.py +258 -27
- jarvis/jarvis_code_agent/utils.py +0 -1
- jarvis/jarvis_code_analysis/code_review.py +19 -24
- jarvis/jarvis_data/config_schema.json +53 -26
- jarvis/jarvis_git_squash/main.py +4 -5
- jarvis/jarvis_git_utils/git_commiter.py +44 -49
- jarvis/jarvis_mcp/sse_mcp_client.py +20 -27
- jarvis/jarvis_mcp/stdio_mcp_client.py +11 -12
- 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 +79 -61
- jarvis/jarvis_multi_agent/main.py +3 -7
- jarvis/jarvis_platform/base.py +469 -199
- jarvis/jarvis_platform/human.py +7 -8
- jarvis/jarvis_platform/kimi.py +30 -36
- jarvis/jarvis_platform/openai.py +65 -27
- jarvis/jarvis_platform/registry.py +26 -10
- jarvis/jarvis_platform/tongyi.py +24 -25
- jarvis/jarvis_platform/yuanbao.py +31 -42
- jarvis/jarvis_platform_manager/main.py +66 -77
- jarvis/jarvis_platform_manager/service.py +8 -13
- jarvis/jarvis_rag/cli.py +49 -51
- 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 +220 -3520
- jarvis/jarvis_sec/agents.py +143 -0
- jarvis/jarvis_sec/analysis.py +276 -0
- jarvis/jarvis_sec/cli.py +29 -6
- 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 +83 -4
- jarvis/jarvis_sec/review.py +453 -0
- jarvis/jarvis_sec/utils.py +499 -0
- jarvis/jarvis_sec/verification.py +848 -0
- jarvis/jarvis_sec/workflow.py +7 -0
- jarvis/jarvis_smart_shell/main.py +38 -87
- jarvis/jarvis_stats/cli.py +1 -1
- jarvis/jarvis_stats/stats.py +7 -7
- jarvis/jarvis_stats/storage.py +15 -21
- jarvis/jarvis_tools/clear_memory.py +3 -20
- jarvis/jarvis_tools/cli/main.py +20 -23
- jarvis/jarvis_tools/edit_file.py +1066 -0
- jarvis/jarvis_tools/execute_script.py +42 -21
- jarvis/jarvis_tools/file_analyzer.py +6 -9
- jarvis/jarvis_tools/generate_new_tool.py +11 -20
- jarvis/jarvis_tools/lsp_client.py +1552 -0
- jarvis/jarvis_tools/methodology.py +2 -3
- jarvis/jarvis_tools/read_code.py +1525 -87
- jarvis/jarvis_tools/read_symbols.py +2 -3
- jarvis/jarvis_tools/read_webpage.py +7 -10
- jarvis/jarvis_tools/registry.py +370 -181
- jarvis/jarvis_tools/retrieve_memory.py +20 -19
- jarvis/jarvis_tools/rewrite_file.py +105 -0
- jarvis/jarvis_tools/save_memory.py +3 -15
- jarvis/jarvis_tools/search_web.py +3 -7
- jarvis/jarvis_tools/sub_agent.py +17 -6
- jarvis/jarvis_tools/sub_code_agent.py +14 -16
- jarvis/jarvis_tools/virtual_tty.py +54 -32
- jarvis/jarvis_utils/clipboard.py +7 -10
- jarvis/jarvis_utils/config.py +98 -63
- jarvis/jarvis_utils/embedding.py +5 -5
- jarvis/jarvis_utils/fzf.py +8 -8
- jarvis/jarvis_utils/git_utils.py +81 -67
- jarvis/jarvis_utils/input.py +24 -49
- jarvis/jarvis_utils/jsonnet_compat.py +465 -0
- jarvis/jarvis_utils/methodology.py +33 -35
- jarvis/jarvis_utils/utils.py +245 -202
- {jarvis_ai_assistant-0.7.0.dist-info → jarvis_ai_assistant-0.7.8.dist-info}/METADATA +205 -70
- jarvis_ai_assistant-0.7.8.dist-info/RECORD +218 -0
- jarvis/jarvis_agent/edit_file_handler.py +0 -584
- jarvis/jarvis_agent/rewrite_file_handler.py +0 -141
- jarvis/jarvis_agent/task_planner.py +0 -496
- jarvis/jarvis_platform/ai8.py +0 -332
- jarvis/jarvis_tools/ask_user.py +0 -54
- jarvis_ai_assistant-0.7.0.dist-info/RECORD +0 -192
- {jarvis_ai_assistant-0.7.0.dist-info → jarvis_ai_assistant-0.7.8.dist-info}/WHEEL +0 -0
- {jarvis_ai_assistant-0.7.0.dist-info → jarvis_ai_assistant-0.7.8.dist-info}/entry_points.txt +0 -0
- {jarvis_ai_assistant-0.7.0.dist-info → jarvis_ai_assistant-0.7.8.dist-info}/licenses/LICENSE +0 -0
- {jarvis_ai_assistant-0.7.0.dist-info → jarvis_ai_assistant-0.7.8.dist-info}/top_level.txt +0 -0
jarvis/jarvis_sec/workflow.py
CHANGED
|
@@ -187,6 +187,9 @@ def run_with_agent(
|
|
|
187
187
|
report_file: Optional[str] = None,
|
|
188
188
|
cluster_limit: int = 50,
|
|
189
189
|
exclude_dirs: Optional[List[str]] = None,
|
|
190
|
+
enable_verification: bool = True,
|
|
191
|
+
force_save_memory: bool = False,
|
|
192
|
+
output_file: Optional[str] = None,
|
|
190
193
|
) -> str:
|
|
191
194
|
"""
|
|
192
195
|
使用单Agent逐条子任务分析模式运行(与 jarvis.jarvis_sec.__init__ 中保持一致)。
|
|
@@ -199,6 +202,7 @@ def run_with_agent(
|
|
|
199
202
|
- report_file: JSONL 报告文件路径(可选,透传)
|
|
200
203
|
- cluster_limit: 聚类时每批次最多处理的告警数(默认 50),当单个文件告警过多时按批次进行聚类
|
|
201
204
|
- exclude_dirs: 要排除的目录列表(可选),默认已包含构建产物(build, out, target, dist, bin, obj)、依赖目录(third_party, vendor, deps, dependencies, libs, libraries, external, node_modules)、测试目录(test, tests, __tests__, spec, testsuite, testdata)、性能测试目录(benchmark, benchmarks, perf, performance, bench, benches, profiling, profiler)、示例目录(example, examples)、临时/缓存(tmp, temp, cache, .cache)、文档(docs, doc, documentation)、生成代码(generated, gen)和其他(mocks, fixtures, samples, sample, playground, sandbox)
|
|
205
|
+
- enable_verification: 是否启用二次验证(默认 True),关闭后分析Agent确认的问题将直接写入报告
|
|
202
206
|
"""
|
|
203
207
|
from jarvis.jarvis_sec import run_security_analysis # 延迟导入,避免循环
|
|
204
208
|
return run_security_analysis(
|
|
@@ -208,6 +212,9 @@ def run_with_agent(
|
|
|
208
212
|
report_file=report_file,
|
|
209
213
|
cluster_limit=cluster_limit,
|
|
210
214
|
exclude_dirs=exclude_dirs,
|
|
215
|
+
enable_verification=enable_verification,
|
|
216
|
+
force_save_memory=force_save_memory,
|
|
217
|
+
output_file=output_file,
|
|
211
218
|
)
|
|
212
219
|
|
|
213
220
|
|
|
@@ -9,7 +9,6 @@ from jarvis.jarvis_platform.registry import PlatformRegistry
|
|
|
9
9
|
from jarvis.jarvis_utils.config import get_shell_name, set_config
|
|
10
10
|
from jarvis.jarvis_utils.input import get_multiline_input
|
|
11
11
|
from jarvis.jarvis_utils.utils import init_env
|
|
12
|
-
from jarvis.jarvis_utils.output import OutputType, PrettyOutput
|
|
13
12
|
|
|
14
13
|
app = typer.Typer(
|
|
15
14
|
help="将自然语言要求转换为shell命令",
|
|
@@ -115,8 +114,8 @@ def install_jss_completion(
|
|
|
115
114
|
) -> None:
|
|
116
115
|
"""为指定的shell安装'命令未找到'处理器,实现自然语言命令建议"""
|
|
117
116
|
if shell not in ("fish", "bash", "zsh"):
|
|
118
|
-
|
|
119
|
-
f"错误: 不支持的shell类型: {shell}, 仅支持fish, bash, zsh"
|
|
117
|
+
print(
|
|
118
|
+
f"❌ 错误: 不支持的shell类型: {shell}, 仅支持fish, bash, zsh"
|
|
120
119
|
)
|
|
121
120
|
raise typer.Exit(code=1)
|
|
122
121
|
|
|
@@ -125,7 +124,7 @@ def install_jss_completion(
|
|
|
125
124
|
start_marker, end_marker = _get_markers()
|
|
126
125
|
|
|
127
126
|
if not os.path.exists(config_file):
|
|
128
|
-
|
|
127
|
+
print("ℹ️ 未找到 config.fish 文件,将创建新文件")
|
|
129
128
|
os.makedirs(os.path.dirname(config_file), exist_ok=True)
|
|
130
129
|
with open(config_file, "w") as f:
|
|
131
130
|
f.write("")
|
|
@@ -134,9 +133,8 @@ def install_jss_completion(
|
|
|
134
133
|
content = f.read()
|
|
135
134
|
|
|
136
135
|
if start_marker in content:
|
|
137
|
-
|
|
138
|
-
"JSS fish completion 已安装,请执行: source ~/.config/fish/config.fish"
|
|
139
|
-
OutputType.SUCCESS,
|
|
136
|
+
print(
|
|
137
|
+
"✅ JSS fish completion 已安装,请执行: source ~/.config/fish/config.fish"
|
|
140
138
|
)
|
|
141
139
|
return
|
|
142
140
|
|
|
@@ -157,16 +155,15 @@ end
|
|
|
157
155
|
{end_marker}
|
|
158
156
|
"""
|
|
159
157
|
)
|
|
160
|
-
|
|
161
|
-
"JSS fish completion 已安装,请执行: source ~/.config/fish/config.fish"
|
|
162
|
-
OutputType.SUCCESS,
|
|
158
|
+
print(
|
|
159
|
+
"✅ JSS fish completion 已安装,请执行: source ~/.config/fish/config.fish"
|
|
163
160
|
)
|
|
164
161
|
elif shell == "bash":
|
|
165
162
|
config_file = _get_bash_config_file()
|
|
166
163
|
start_marker, end_marker = _get_bash_markers()
|
|
167
164
|
|
|
168
165
|
if not os.path.exists(config_file):
|
|
169
|
-
|
|
166
|
+
print("ℹ️ 未找到 ~/.bashrc 文件,将创建新文件")
|
|
170
167
|
os.makedirs(os.path.dirname(config_file), exist_ok=True)
|
|
171
168
|
with open(config_file, "w") as f:
|
|
172
169
|
f.write("")
|
|
@@ -175,9 +172,8 @@ end
|
|
|
175
172
|
content = f.read()
|
|
176
173
|
|
|
177
174
|
if start_marker in content:
|
|
178
|
-
|
|
179
|
-
"JSS bash completion 已安装,请执行: source ~/.bashrc"
|
|
180
|
-
OutputType.SUCCESS,
|
|
175
|
+
print(
|
|
176
|
+
"✅ JSS bash completion 已安装,请执行: source ~/.bashrc"
|
|
181
177
|
)
|
|
182
178
|
return
|
|
183
179
|
else:
|
|
@@ -221,16 +217,15 @@ command_not_found_handle() {{
|
|
|
221
217
|
{end_marker}
|
|
222
218
|
"""
|
|
223
219
|
)
|
|
224
|
-
|
|
225
|
-
"JSS bash completion 已安装,请执行: source ~/.bashrc"
|
|
226
|
-
OutputType.SUCCESS,
|
|
220
|
+
print(
|
|
221
|
+
"✅ JSS bash completion 已安装,请执行: source ~/.bashrc"
|
|
227
222
|
)
|
|
228
223
|
elif shell == "zsh":
|
|
229
224
|
config_file = _get_zsh_config_file()
|
|
230
225
|
start_marker, end_marker = _get_zsh_markers()
|
|
231
226
|
|
|
232
227
|
if not os.path.exists(config_file):
|
|
233
|
-
|
|
228
|
+
print("ℹ️ 未找到 ~/.zshrc 文件,将创建新文件")
|
|
234
229
|
os.makedirs(os.path.dirname(config_file), exist_ok=True)
|
|
235
230
|
with open(config_file, "w") as f:
|
|
236
231
|
f.write("")
|
|
@@ -239,8 +234,8 @@ command_not_found_handle() {{
|
|
|
239
234
|
content = f.read()
|
|
240
235
|
|
|
241
236
|
if start_marker in content:
|
|
242
|
-
|
|
243
|
-
"JSS zsh completion 已安装,请执行: source ~/.zshrc"
|
|
237
|
+
print(
|
|
238
|
+
"✅ JSS zsh completion 已安装,请执行: source ~/.zshrc"
|
|
244
239
|
)
|
|
245
240
|
return
|
|
246
241
|
|
|
@@ -288,55 +283,11 @@ command_not_found_handler() {{
|
|
|
288
283
|
{end_marker}
|
|
289
284
|
"""
|
|
290
285
|
)
|
|
291
|
-
|
|
292
|
-
"JSS zsh completion 已安装,请执行: source ~/.zshrc"
|
|
286
|
+
print(
|
|
287
|
+
"✅ JSS zsh completion 已安装,请执行: source ~/.zshrc"
|
|
293
288
|
)
|
|
294
289
|
return
|
|
295
290
|
|
|
296
|
-
with open(config_file, "a") as f:
|
|
297
|
-
f.write(
|
|
298
|
-
f"""
|
|
299
|
-
{start_marker}
|
|
300
|
-
# Bash 'command not found' handler for JSS
|
|
301
|
-
# 行为:
|
|
302
|
-
# - 生成可编辑的建议命令,用户可直接编辑后回车执行
|
|
303
|
-
# - 非交互模式下仅打印建议
|
|
304
|
-
command_not_found_handle() {{
|
|
305
|
-
local cmd="$1"
|
|
306
|
-
shift || true
|
|
307
|
-
local text="$cmd $*"
|
|
308
|
-
|
|
309
|
-
# 与 fish 行为保持一致:对过短输入不处理
|
|
310
|
-
if [ ${{#text}} -lt 10 ]; then
|
|
311
|
-
return 127
|
|
312
|
-
fi
|
|
313
|
-
|
|
314
|
-
local suggestion edited
|
|
315
|
-
suggestion=$(jss request "$text")
|
|
316
|
-
if [ -n "$suggestion" ]; then
|
|
317
|
-
# 交互式:用 readline 预填命令,用户可直接回车执行或编辑
|
|
318
|
-
if [[ $- == *i* ]]; then
|
|
319
|
-
edited="$suggestion"
|
|
320
|
-
# -e 启用 readline;-i 预填默认值;无提示前缀,使体验更接近 fish 的“替换命令行”
|
|
321
|
-
read -e -i "$edited" edited
|
|
322
|
-
if [ -n "$edited" ]; then
|
|
323
|
-
eval "$edited"
|
|
324
|
-
return $?
|
|
325
|
-
fi
|
|
326
|
-
else
|
|
327
|
-
# 非交互:仅打印建议
|
|
328
|
-
printf '%s\n' "$suggestion"
|
|
329
|
-
fi
|
|
330
|
-
fi
|
|
331
|
-
return 127
|
|
332
|
-
}}
|
|
333
|
-
{end_marker}
|
|
334
|
-
"""
|
|
335
|
-
)
|
|
336
|
-
PrettyOutput.print(
|
|
337
|
-
"JSS bash completion 已安装,请执行: source ~/.bashrc", OutputType.SUCCESS
|
|
338
|
-
)
|
|
339
|
-
|
|
340
291
|
|
|
341
292
|
@app.command("uninstall")
|
|
342
293
|
def uninstall_jss_completion(
|
|
@@ -344,8 +295,8 @@ def uninstall_jss_completion(
|
|
|
344
295
|
) -> None:
|
|
345
296
|
"""卸载JSS shell'命令未找到'处理器"""
|
|
346
297
|
if shell not in ("fish", "bash", "zsh"):
|
|
347
|
-
|
|
348
|
-
f"错误: 不支持的shell类型: {shell}, 仅支持fish, bash, zsh"
|
|
298
|
+
print(
|
|
299
|
+
f"❌ 错误: 不支持的shell类型: {shell}, 仅支持fish, bash, zsh"
|
|
349
300
|
)
|
|
350
301
|
raise typer.Exit(code=1)
|
|
351
302
|
|
|
@@ -354,8 +305,8 @@ def uninstall_jss_completion(
|
|
|
354
305
|
start_marker, end_marker = _get_markers()
|
|
355
306
|
|
|
356
307
|
if not os.path.exists(config_file):
|
|
357
|
-
|
|
358
|
-
"未找到 JSS fish completion 配置,无需卸载"
|
|
308
|
+
print(
|
|
309
|
+
"ℹ️ 未找到 JSS fish completion 配置,无需卸载"
|
|
359
310
|
)
|
|
360
311
|
return
|
|
361
312
|
|
|
@@ -363,8 +314,8 @@ def uninstall_jss_completion(
|
|
|
363
314
|
content = f.read()
|
|
364
315
|
|
|
365
316
|
if start_marker not in content:
|
|
366
|
-
|
|
367
|
-
"未找到 JSS fish completion 配置,无需卸载"
|
|
317
|
+
print(
|
|
318
|
+
"ℹ️ 未找到 JSS fish completion 配置,无需卸载"
|
|
368
319
|
)
|
|
369
320
|
return
|
|
370
321
|
|
|
@@ -373,17 +324,16 @@ def uninstall_jss_completion(
|
|
|
373
324
|
with open(config_file, "w") as f:
|
|
374
325
|
f.write(new_content)
|
|
375
326
|
|
|
376
|
-
|
|
377
|
-
"JSS fish completion 已卸载,请执行: source ~/.config/fish/config.fish"
|
|
378
|
-
OutputType.SUCCESS,
|
|
327
|
+
print(
|
|
328
|
+
"✅ JSS fish completion 已卸载,请执行: source ~/.config/fish/config.fish"
|
|
379
329
|
)
|
|
380
330
|
elif shell == "bash":
|
|
381
331
|
config_file = _get_bash_config_file()
|
|
382
332
|
start_marker, end_marker = _get_bash_markers()
|
|
383
333
|
|
|
384
334
|
if not os.path.exists(config_file):
|
|
385
|
-
|
|
386
|
-
"未找到 JSS bash completion 配置,无需卸载"
|
|
335
|
+
print(
|
|
336
|
+
"ℹ️ 未找到 JSS bash completion 配置,无需卸载"
|
|
387
337
|
)
|
|
388
338
|
return
|
|
389
339
|
|
|
@@ -391,8 +341,8 @@ def uninstall_jss_completion(
|
|
|
391
341
|
content = f.read()
|
|
392
342
|
|
|
393
343
|
if start_marker not in content:
|
|
394
|
-
|
|
395
|
-
"未找到 JSS bash completion 配置,无需卸载"
|
|
344
|
+
print(
|
|
345
|
+
"ℹ️ 未找到 JSS bash completion 配置,无需卸载"
|
|
396
346
|
)
|
|
397
347
|
return
|
|
398
348
|
|
|
@@ -401,16 +351,16 @@ def uninstall_jss_completion(
|
|
|
401
351
|
with open(config_file, "w") as f:
|
|
402
352
|
f.write(new_content)
|
|
403
353
|
|
|
404
|
-
|
|
405
|
-
"JSS bash completion 已卸载,请执行: source ~/.bashrc"
|
|
354
|
+
print(
|
|
355
|
+
"✅ JSS bash completion 已卸载,请执行: source ~/.bashrc"
|
|
406
356
|
)
|
|
407
357
|
elif shell == "zsh":
|
|
408
358
|
config_file = _get_zsh_config_file()
|
|
409
359
|
start_marker, end_marker = _get_zsh_markers()
|
|
410
360
|
|
|
411
361
|
if not os.path.exists(config_file):
|
|
412
|
-
|
|
413
|
-
"未找到 JSS zsh completion 配置,无需卸载"
|
|
362
|
+
print(
|
|
363
|
+
"ℹ️ 未找到 JSS zsh completion 配置,无需卸载"
|
|
414
364
|
)
|
|
415
365
|
return
|
|
416
366
|
|
|
@@ -418,8 +368,8 @@ def uninstall_jss_completion(
|
|
|
418
368
|
content = f.read()
|
|
419
369
|
|
|
420
370
|
if start_marker not in content:
|
|
421
|
-
|
|
422
|
-
"未找到 JSS zsh completion 配置,无需卸载"
|
|
371
|
+
print(
|
|
372
|
+
"ℹ️ 未找到 JSS zsh completion 配置,无需卸载"
|
|
423
373
|
)
|
|
424
374
|
return
|
|
425
375
|
|
|
@@ -428,8 +378,8 @@ def uninstall_jss_completion(
|
|
|
428
378
|
with open(config_file, "w") as f:
|
|
429
379
|
f.write(new_content)
|
|
430
380
|
|
|
431
|
-
|
|
432
|
-
"JSS zsh completion 已卸载,请执行: source ~/.zshrc"
|
|
381
|
+
print(
|
|
382
|
+
"✅ JSS zsh completion 已卸载,请执行: source ~/.zshrc"
|
|
433
383
|
)
|
|
434
384
|
|
|
435
385
|
|
|
@@ -444,6 +394,7 @@ def process_request(request: str) -> Optional[str]:
|
|
|
444
394
|
"""
|
|
445
395
|
try:
|
|
446
396
|
# Get language model instance
|
|
397
|
+
# 使用normal平台,智能shell命令生成是一般任务
|
|
447
398
|
model = PlatformRegistry.get_global_platform_registry().get_normal_platform()
|
|
448
399
|
|
|
449
400
|
shell = get_shell_name()
|
jarvis/jarvis_stats/cli.py
CHANGED
jarvis/jarvis_stats/stats.py
CHANGED
|
@@ -9,7 +9,7 @@ from typing import Dict, List, Optional, Union, Any
|
|
|
9
9
|
|
|
10
10
|
from jarvis.jarvis_stats.storage import StatsStorage
|
|
11
11
|
from jarvis.jarvis_stats.visualizer import StatsVisualizer
|
|
12
|
-
from jarvis.jarvis_utils.output import OutputType, PrettyOutput
|
|
12
|
+
from jarvis.jarvis_utils.output import OutputType, PrettyOutput # 保留用于语法高亮
|
|
13
13
|
|
|
14
14
|
|
|
15
15
|
class StatsManager:
|
|
@@ -549,8 +549,8 @@ class StatsManager:
|
|
|
549
549
|
)
|
|
550
550
|
|
|
551
551
|
if not aggregated:
|
|
552
|
-
|
|
553
|
-
f"没有找到指标 '{metric_name}' 的数据"
|
|
552
|
+
print(
|
|
553
|
+
f"⚠️ 没有找到指标 '{metric_name}' 的数据"
|
|
554
554
|
)
|
|
555
555
|
return
|
|
556
556
|
|
|
@@ -585,7 +585,7 @@ class StatsManager:
|
|
|
585
585
|
show_values=True,
|
|
586
586
|
)
|
|
587
587
|
|
|
588
|
-
PrettyOutput.print(chart, OutputType.CODE, lang="text")
|
|
588
|
+
PrettyOutput.print(chart, OutputType.CODE, lang="text") # 保留用于语法高亮
|
|
589
589
|
|
|
590
590
|
# 显示时间范围
|
|
591
591
|
from rich.panel import Panel
|
|
@@ -681,8 +681,8 @@ class StatsManager:
|
|
|
681
681
|
)
|
|
682
682
|
|
|
683
683
|
if not aggregated:
|
|
684
|
-
|
|
685
|
-
f"没有找到指标 '{metric_name}' 的数据"
|
|
684
|
+
print(
|
|
685
|
+
f"⚠️ 没有找到指标 '{metric_name}' 的数据"
|
|
686
686
|
)
|
|
687
687
|
return
|
|
688
688
|
|
|
@@ -693,7 +693,7 @@ class StatsManager:
|
|
|
693
693
|
# 显示汇总
|
|
694
694
|
summary = visualizer.show_summary(aggregated, metric_name, unit, tags)
|
|
695
695
|
if summary: # 如果返回了内容才打印(兼容性)
|
|
696
|
-
|
|
696
|
+
print(f"ℹ️ {summary}")
|
|
697
697
|
|
|
698
698
|
# 显示时间范围
|
|
699
699
|
from rich.panel import Panel
|
jarvis/jarvis_stats/storage.py
CHANGED
|
@@ -71,7 +71,7 @@ class StatsStorage:
|
|
|
71
71
|
with open(filepath, "r", encoding="utf-8") as f:
|
|
72
72
|
data = json.load(f)
|
|
73
73
|
return data
|
|
74
|
-
except
|
|
74
|
+
except Exception:
|
|
75
75
|
if attempt < max_retries - 1:
|
|
76
76
|
time.sleep(0.1 * (attempt + 1)) # 递增延迟
|
|
77
77
|
continue
|
|
@@ -160,6 +160,9 @@ class StatsStorage:
|
|
|
160
160
|
|
|
161
161
|
# 更新元数据
|
|
162
162
|
meta = self._load_json(self.meta_file)
|
|
163
|
+
# 确保 meta 字典中有 "metrics" 键
|
|
164
|
+
if "metrics" not in meta:
|
|
165
|
+
meta["metrics"] = {}
|
|
163
166
|
if metric_name not in meta["metrics"]:
|
|
164
167
|
meta["metrics"][metric_name] = {
|
|
165
168
|
"unit": unit,
|
|
@@ -218,9 +221,9 @@ class StatsStorage:
|
|
|
218
221
|
new_total = current_total + float(value)
|
|
219
222
|
self._save_text_atomic(total_file, str(new_total))
|
|
220
223
|
else:
|
|
221
|
-
#
|
|
222
|
-
#
|
|
223
|
-
|
|
224
|
+
# 首次生成:直接写入当前值,避免扫描所有历史文件
|
|
225
|
+
# 如果后续需要精确总量,可以通过 get_metric_total 重新计算
|
|
226
|
+
self._save_text_atomic(total_file, str(float(value)))
|
|
224
227
|
except Exception:
|
|
225
228
|
# 静默失败,不影响主流程
|
|
226
229
|
pass
|
|
@@ -452,21 +455,11 @@ class StatsStorage:
|
|
|
452
455
|
|
|
453
456
|
def list_metrics(self) -> List[str]:
|
|
454
457
|
"""列出所有指标"""
|
|
455
|
-
#
|
|
458
|
+
# 从元数据文件获取指标(主要来源,避免扫描所有历史文件)
|
|
456
459
|
meta = self._load_json(self.meta_file)
|
|
457
460
|
metrics_from_meta = set(meta.get("metrics", {}).keys())
|
|
458
461
|
|
|
459
|
-
#
|
|
460
|
-
metrics_from_data: Set[str] = set()
|
|
461
|
-
for data_file in self.data_dir.glob("stats_*.json"):
|
|
462
|
-
try:
|
|
463
|
-
data = self._load_json(data_file)
|
|
464
|
-
metrics_from_data.update(data.keys())
|
|
465
|
-
except (json.JSONDecodeError, OSError):
|
|
466
|
-
# 忽略无法读取的文件
|
|
467
|
-
continue
|
|
468
|
-
|
|
469
|
-
# 扫描总量缓存目录中已有的指标文件
|
|
462
|
+
# 扫描总量缓存目录中已有的指标文件(快速)
|
|
470
463
|
metrics_from_totals: Set[str] = set()
|
|
471
464
|
try:
|
|
472
465
|
for f in self.totals_dir.glob("*"):
|
|
@@ -475,10 +468,9 @@ class StatsStorage:
|
|
|
475
468
|
except Exception:
|
|
476
469
|
pass
|
|
477
470
|
|
|
478
|
-
#
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
)
|
|
471
|
+
# 合并两个来源的指标并返回排序后的列表
|
|
472
|
+
# 注意:不再扫描所有历史数据文件,避免性能问题
|
|
473
|
+
all_metrics = metrics_from_meta.union(metrics_from_totals)
|
|
482
474
|
return sorted(list(all_metrics))
|
|
483
475
|
|
|
484
476
|
def aggregate_metrics(
|
|
@@ -560,7 +552,9 @@ class StatsStorage:
|
|
|
560
552
|
"""
|
|
561
553
|
# 检查指标是否存在
|
|
562
554
|
meta = self._load_json(self.meta_file)
|
|
563
|
-
if
|
|
555
|
+
if "metrics" not in meta:
|
|
556
|
+
meta["metrics"] = {}
|
|
557
|
+
if metric_name not in meta["metrics"]:
|
|
564
558
|
return False
|
|
565
559
|
|
|
566
560
|
# 从元数据中删除指标
|
|
@@ -4,7 +4,6 @@ from pathlib import Path
|
|
|
4
4
|
from typing import Any, Dict, List, Optional
|
|
5
5
|
|
|
6
6
|
from jarvis.jarvis_utils.config import get_data_dir
|
|
7
|
-
from jarvis.jarvis_utils.output import OutputType, PrettyOutput
|
|
8
7
|
from jarvis.jarvis_utils.globals import (
|
|
9
8
|
clear_short_term_memories,
|
|
10
9
|
short_term_memories,
|
|
@@ -15,21 +14,7 @@ class ClearMemoryTool:
|
|
|
15
14
|
"""清除记忆工具,用于批量清除指定的记忆"""
|
|
16
15
|
|
|
17
16
|
name = "clear_memory"
|
|
18
|
-
description = ""
|
|
19
|
-
|
|
20
|
-
支持的清除方式:
|
|
21
|
-
1. 按记忆类型清除所有记忆
|
|
22
|
-
2. 按标签清除特定记忆
|
|
23
|
-
3. 按记忆ID清除单个记忆
|
|
24
|
-
|
|
25
|
-
支持的记忆类型:
|
|
26
|
-
- project_long_term: 项目长期记忆
|
|
27
|
-
- global_long_term: 全局长期记忆
|
|
28
|
-
- short_term: 短期记忆
|
|
29
|
-
- all: 所有类型的记忆
|
|
30
|
-
|
|
31
|
-
注意:清除操作不可恢复,请谨慎使用
|
|
32
|
-
"""
|
|
17
|
+
description = "批量清除指定的记忆。支持按类型、标签或ID清除。记忆类型:project_long_term/global_long_term/short_term/all。注意:清除操作不可恢复。"
|
|
33
18
|
|
|
34
19
|
parameters = {
|
|
35
20
|
"type": "object",
|
|
@@ -160,9 +145,7 @@ class ClearMemoryTool:
|
|
|
160
145
|
removed_count += 1
|
|
161
146
|
|
|
162
147
|
except Exception as e:
|
|
163
|
-
|
|
164
|
-
f"处理记忆文件 {memory_file} 时出错: {str(e)}", OutputType.WARNING
|
|
165
|
-
)
|
|
148
|
+
print(f"⚠️ 处理记忆文件 {memory_file} 时出错: {str(e)}")
|
|
166
149
|
|
|
167
150
|
# 如果目录为空,可以删除目录
|
|
168
151
|
if not any(memory_dir.iterdir()) and memory_dir != self.project_memory_dir:
|
|
@@ -235,5 +218,5 @@ class ClearMemoryTool:
|
|
|
235
218
|
|
|
236
219
|
except Exception as e:
|
|
237
220
|
error_msg = f"清除记忆失败: {str(e)}"
|
|
238
|
-
|
|
221
|
+
print(f"❌ {error_msg}")
|
|
239
222
|
return {"success": False, "stdout": "", "stderr": error_msg}
|
jarvis/jarvis_tools/cli/main.py
CHANGED
|
@@ -38,7 +38,7 @@ def list_tools(
|
|
|
38
38
|
lang="json",
|
|
39
39
|
)
|
|
40
40
|
else:
|
|
41
|
-
|
|
41
|
+
print("📋 可用工具列表")
|
|
42
42
|
# 为避免 PrettyOutput 对每行加框造成信息稀疏,先拼接字符串再统一打印
|
|
43
43
|
lines = []
|
|
44
44
|
import json as _json # local import to ensure available
|
|
@@ -54,7 +54,7 @@ def list_tools(
|
|
|
54
54
|
except Exception:
|
|
55
55
|
lines.append(str(tool.get("parameters")))
|
|
56
56
|
lines.append("```")
|
|
57
|
-
PrettyOutput.print("\n".join(lines), OutputType.
|
|
57
|
+
PrettyOutput.print("\n".join(lines), OutputType.CODE, lang="markdown")
|
|
58
58
|
|
|
59
59
|
|
|
60
60
|
@app.command("stat")
|
|
@@ -90,7 +90,7 @@ def stat_tools(
|
|
|
90
90
|
)
|
|
91
91
|
else:
|
|
92
92
|
time_desc = f"最近{last_days}天" if last_days else "所有历史"
|
|
93
|
-
|
|
93
|
+
print(f"📊 工具调用统计 ({time_desc})")
|
|
94
94
|
if table_data:
|
|
95
95
|
PrettyOutput.print(
|
|
96
96
|
tabulate(
|
|
@@ -99,15 +99,12 @@ def stat_tools(
|
|
|
99
99
|
OutputType.CODE,
|
|
100
100
|
lang="text",
|
|
101
101
|
)
|
|
102
|
-
|
|
103
|
-
f"\n总计: {len(table_data)} 个工具被使用,共 {sum(x[1] for x in table_data)} 次调用",
|
|
104
|
-
OutputType.INFO,
|
|
105
|
-
)
|
|
102
|
+
print(f"ℹ️ 总计: {len(table_data)} 个工具被使用,共 {sum(x[1] for x in table_data)} 次调用")
|
|
106
103
|
else:
|
|
107
|
-
|
|
104
|
+
print("ℹ️ 暂无工具调用记录")
|
|
108
105
|
else:
|
|
109
106
|
# 使用 stats 系统的高级功能
|
|
110
|
-
|
|
107
|
+
print("📊 工具组统计")
|
|
111
108
|
# 显示所有标记为 tool 组的指标
|
|
112
109
|
metrics = StatsManager.list_metrics()
|
|
113
110
|
tool_metrics = []
|
|
@@ -166,7 +163,7 @@ def stat_tools(
|
|
|
166
163
|
tags={"group": "tool"},
|
|
167
164
|
)
|
|
168
165
|
else:
|
|
169
|
-
|
|
166
|
+
print("ℹ️ 暂无工具调用记录")
|
|
170
167
|
|
|
171
168
|
|
|
172
169
|
@app.command("call")
|
|
@@ -182,24 +179,24 @@ def call_tool(
|
|
|
182
179
|
tool_obj = registry.get_tool(tool_name)
|
|
183
180
|
|
|
184
181
|
if not tool_obj:
|
|
185
|
-
|
|
182
|
+
print(f"❌ 错误: 工具 '{tool_name}' 不存在")
|
|
186
183
|
available_tools = ", ".join([t["name"] for t in registry.get_all_tools()])
|
|
187
|
-
|
|
184
|
+
print(f"ℹ️ 可用工具: {available_tools}")
|
|
188
185
|
raise typer.Exit(code=1)
|
|
189
186
|
|
|
190
187
|
tool_args = {}
|
|
191
188
|
if args:
|
|
192
189
|
try:
|
|
193
190
|
tool_args = json.loads(args)
|
|
194
|
-
except
|
|
195
|
-
|
|
191
|
+
except Exception:
|
|
192
|
+
print("❌ 错误: 参数必须是有效的JSON格式")
|
|
196
193
|
raise typer.Exit(code=1)
|
|
197
194
|
elif args_file:
|
|
198
195
|
try:
|
|
199
196
|
with open(args_file, "r", encoding="utf-8") as f:
|
|
200
197
|
tool_args = json.load(f)
|
|
201
|
-
except (
|
|
202
|
-
|
|
198
|
+
except (Exception, FileNotFoundError) as e:
|
|
199
|
+
print(f"❌ 错误: 无法从文件加载参数: {str(e)}")
|
|
203
200
|
raise typer.Exit(code=1)
|
|
204
201
|
|
|
205
202
|
required_params = tool_obj.parameters.get("required", [])
|
|
@@ -217,23 +214,23 @@ def call_tool(
|
|
|
217
214
|
param_info = params.get(param_name, {})
|
|
218
215
|
desc = param_info.get("description", "无描述")
|
|
219
216
|
lines.append(f" - {param_name}: {desc}")
|
|
220
|
-
|
|
217
|
+
print("❌ " + "\n❌ ".join(lines))
|
|
221
218
|
raise typer.Exit(code=1)
|
|
222
219
|
|
|
223
220
|
result = registry.execute_tool(tool_name, tool_args)
|
|
224
221
|
|
|
225
222
|
if result["success"]:
|
|
226
|
-
|
|
223
|
+
print(f"✅ 工具 {tool_name} 执行成功")
|
|
227
224
|
else:
|
|
228
|
-
|
|
225
|
+
print(f"❌ 工具 {tool_name} 执行失败")
|
|
229
226
|
|
|
230
227
|
if result.get("stdout"):
|
|
231
|
-
|
|
228
|
+
print("\n📤 输出:")
|
|
232
229
|
PrettyOutput.print(result["stdout"], OutputType.CODE, lang="text")
|
|
233
230
|
|
|
234
231
|
if result.get("stderr"):
|
|
235
|
-
|
|
236
|
-
PrettyOutput.print(result["stderr"], OutputType.
|
|
232
|
+
print("\n❌ 错误:")
|
|
233
|
+
PrettyOutput.print(result["stderr"], OutputType.CODE, lang="text")
|
|
237
234
|
|
|
238
235
|
if not result["success"]:
|
|
239
236
|
raise typer.Exit(code=1)
|
|
@@ -241,7 +238,7 @@ def call_tool(
|
|
|
241
238
|
|
|
242
239
|
def cli():
|
|
243
240
|
"""Typer application entry point"""
|
|
244
|
-
init_env(
|
|
241
|
+
init_env()
|
|
245
242
|
app()
|
|
246
243
|
|
|
247
244
|
|