jarvis-ai-assistant 0.3.24__tar.gz → 0.3.26__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.
- {jarvis_ai_assistant-0.3.24/src/jarvis_ai_assistant.egg-info → jarvis_ai_assistant-0.3.26}/PKG-INFO +1 -1
- {jarvis_ai_assistant-0.3.24 → jarvis_ai_assistant-0.3.26}/pyproject.toml +1 -1
- {jarvis_ai_assistant-0.3.24 → jarvis_ai_assistant-0.3.26}/setup.py +1 -1
- {jarvis_ai_assistant-0.3.24 → jarvis_ai_assistant-0.3.26}/src/jarvis/__init__.py +1 -1
- {jarvis_ai_assistant-0.3.24 → jarvis_ai_assistant-0.3.26}/src/jarvis/jarvis_agent/__init__.py +4 -0
- {jarvis_ai_assistant-0.3.24 → jarvis_ai_assistant-0.3.26}/src/jarvis/jarvis_agent/jarvis.py +17 -17
- {jarvis_ai_assistant-0.3.24 → jarvis_ai_assistant-0.3.26}/src/jarvis/jarvis_data/config_schema.json +7 -0
- {jarvis_ai_assistant-0.3.24 → jarvis_ai_assistant-0.3.26}/src/jarvis/jarvis_git_utils/git_commiter.py +4 -3
- {jarvis_ai_assistant-0.3.24 → jarvis_ai_assistant-0.3.26}/src/jarvis/jarvis_platform/base.py +49 -17
- {jarvis_ai_assistant-0.3.24 → jarvis_ai_assistant-0.3.26}/src/jarvis/jarvis_rag/cli.py +12 -9
- jarvis_ai_assistant-0.3.26/src/jarvis/jarvis_rag/embedding_manager.py +239 -0
- {jarvis_ai_assistant-0.3.24 → jarvis_ai_assistant-0.3.26}/src/jarvis/jarvis_rag/rag_pipeline.py +21 -4
- {jarvis_ai_assistant-0.3.24 → jarvis_ai_assistant-0.3.26}/src/jarvis/jarvis_rag/reranker.py +24 -2
- {jarvis_ai_assistant-0.3.24 → jarvis_ai_assistant-0.3.26}/src/jarvis/jarvis_smart_shell/main.py +1 -10
- {jarvis_ai_assistant-0.3.24 → jarvis_ai_assistant-0.3.26}/src/jarvis/jarvis_tools/edit_file.py +6 -6
- {jarvis_ai_assistant-0.3.24 → jarvis_ai_assistant-0.3.26}/src/jarvis/jarvis_tools/execute_script.py +1 -2
- {jarvis_ai_assistant-0.3.24 → jarvis_ai_assistant-0.3.26}/src/jarvis/jarvis_tools/sub_agent.py +4 -7
- {jarvis_ai_assistant-0.3.24 → jarvis_ai_assistant-0.3.26}/src/jarvis/jarvis_tools/sub_code_agent.py +4 -1
- {jarvis_ai_assistant-0.3.24 → jarvis_ai_assistant-0.3.26}/src/jarvis/jarvis_utils/config.py +10 -0
- {jarvis_ai_assistant-0.3.24 → jarvis_ai_assistant-0.3.26}/src/jarvis/jarvis_utils/git_utils.py +3 -8
- {jarvis_ai_assistant-0.3.24 → jarvis_ai_assistant-0.3.26}/src/jarvis/jarvis_utils/input.py +2 -2
- {jarvis_ai_assistant-0.3.24 → jarvis_ai_assistant-0.3.26}/src/jarvis/jarvis_utils/utils.py +51 -19
- {jarvis_ai_assistant-0.3.24 → jarvis_ai_assistant-0.3.26/src/jarvis_ai_assistant.egg-info}/PKG-INFO +1 -1
- jarvis_ai_assistant-0.3.24/src/jarvis/jarvis_rag/embedding_manager.py +0 -119
- {jarvis_ai_assistant-0.3.24 → jarvis_ai_assistant-0.3.26}/LICENSE +0 -0
- {jarvis_ai_assistant-0.3.24 → jarvis_ai_assistant-0.3.26}/MANIFEST.in +0 -0
- {jarvis_ai_assistant-0.3.24 → jarvis_ai_assistant-0.3.26}/README.md +0 -0
- {jarvis_ai_assistant-0.3.24 → jarvis_ai_assistant-0.3.26}/setup.cfg +0 -0
- {jarvis_ai_assistant-0.3.24 → jarvis_ai_assistant-0.3.26}/src/jarvis/jarvis_agent/agent_manager.py +0 -0
- {jarvis_ai_assistant-0.3.24 → jarvis_ai_assistant-0.3.26}/src/jarvis/jarvis_agent/builtin_input_handler.py +0 -0
- {jarvis_ai_assistant-0.3.24 → jarvis_ai_assistant-0.3.26}/src/jarvis/jarvis_agent/config_editor.py +0 -0
- {jarvis_ai_assistant-0.3.24 → jarvis_ai_assistant-0.3.26}/src/jarvis/jarvis_agent/edit_file_handler.py +0 -0
- {jarvis_ai_assistant-0.3.24 → jarvis_ai_assistant-0.3.26}/src/jarvis/jarvis_agent/file_methodology_manager.py +0 -0
- {jarvis_ai_assistant-0.3.24 → jarvis_ai_assistant-0.3.26}/src/jarvis/jarvis_agent/main.py +0 -0
- {jarvis_ai_assistant-0.3.24 → jarvis_ai_assistant-0.3.26}/src/jarvis/jarvis_agent/memory_manager.py +0 -0
- {jarvis_ai_assistant-0.3.24 → jarvis_ai_assistant-0.3.26}/src/jarvis/jarvis_agent/methodology_share_manager.py +0 -0
- {jarvis_ai_assistant-0.3.24 → jarvis_ai_assistant-0.3.26}/src/jarvis/jarvis_agent/output_handler.py +0 -0
- {jarvis_ai_assistant-0.3.24 → jarvis_ai_assistant-0.3.26}/src/jarvis/jarvis_agent/prompt_builder.py +0 -0
- {jarvis_ai_assistant-0.3.24 → jarvis_ai_assistant-0.3.26}/src/jarvis/jarvis_agent/prompts.py +0 -0
- {jarvis_ai_assistant-0.3.24 → jarvis_ai_assistant-0.3.26}/src/jarvis/jarvis_agent/protocols.py +0 -0
- {jarvis_ai_assistant-0.3.24 → jarvis_ai_assistant-0.3.26}/src/jarvis/jarvis_agent/session_manager.py +0 -0
- {jarvis_ai_assistant-0.3.24 → jarvis_ai_assistant-0.3.26}/src/jarvis/jarvis_agent/share_manager.py +0 -0
- {jarvis_ai_assistant-0.3.24 → jarvis_ai_assistant-0.3.26}/src/jarvis/jarvis_agent/shell_input_handler.py +0 -0
- {jarvis_ai_assistant-0.3.24 → jarvis_ai_assistant-0.3.26}/src/jarvis/jarvis_agent/task_analyzer.py +0 -0
- {jarvis_ai_assistant-0.3.24 → jarvis_ai_assistant-0.3.26}/src/jarvis/jarvis_agent/task_manager.py +0 -0
- {jarvis_ai_assistant-0.3.24 → jarvis_ai_assistant-0.3.26}/src/jarvis/jarvis_agent/tool_executor.py +0 -0
- {jarvis_ai_assistant-0.3.24 → jarvis_ai_assistant-0.3.26}/src/jarvis/jarvis_agent/tool_share_manager.py +0 -0
- {jarvis_ai_assistant-0.3.24 → jarvis_ai_assistant-0.3.26}/src/jarvis/jarvis_code_agent/__init__.py +0 -0
- {jarvis_ai_assistant-0.3.24 → jarvis_ai_assistant-0.3.26}/src/jarvis/jarvis_code_agent/code_agent.py +0 -0
- {jarvis_ai_assistant-0.3.24 → jarvis_ai_assistant-0.3.26}/src/jarvis/jarvis_code_agent/lint.py +0 -0
- {jarvis_ai_assistant-0.3.24 → jarvis_ai_assistant-0.3.26}/src/jarvis/jarvis_code_analysis/checklists/__init__.py +0 -0
- {jarvis_ai_assistant-0.3.24 → jarvis_ai_assistant-0.3.26}/src/jarvis/jarvis_code_analysis/checklists/c_cpp.py +0 -0
- {jarvis_ai_assistant-0.3.24 → jarvis_ai_assistant-0.3.26}/src/jarvis/jarvis_code_analysis/checklists/csharp.py +0 -0
- {jarvis_ai_assistant-0.3.24 → jarvis_ai_assistant-0.3.26}/src/jarvis/jarvis_code_analysis/checklists/data_format.py +0 -0
- {jarvis_ai_assistant-0.3.24 → jarvis_ai_assistant-0.3.26}/src/jarvis/jarvis_code_analysis/checklists/devops.py +0 -0
- {jarvis_ai_assistant-0.3.24 → jarvis_ai_assistant-0.3.26}/src/jarvis/jarvis_code_analysis/checklists/docs.py +0 -0
- {jarvis_ai_assistant-0.3.24 → jarvis_ai_assistant-0.3.26}/src/jarvis/jarvis_code_analysis/checklists/go.py +0 -0
- {jarvis_ai_assistant-0.3.24 → jarvis_ai_assistant-0.3.26}/src/jarvis/jarvis_code_analysis/checklists/infrastructure.py +0 -0
- {jarvis_ai_assistant-0.3.24 → jarvis_ai_assistant-0.3.26}/src/jarvis/jarvis_code_analysis/checklists/java.py +0 -0
- {jarvis_ai_assistant-0.3.24 → jarvis_ai_assistant-0.3.26}/src/jarvis/jarvis_code_analysis/checklists/javascript.py +0 -0
- {jarvis_ai_assistant-0.3.24 → jarvis_ai_assistant-0.3.26}/src/jarvis/jarvis_code_analysis/checklists/kotlin.py +0 -0
- {jarvis_ai_assistant-0.3.24 → jarvis_ai_assistant-0.3.26}/src/jarvis/jarvis_code_analysis/checklists/loader.py +0 -0
- {jarvis_ai_assistant-0.3.24 → jarvis_ai_assistant-0.3.26}/src/jarvis/jarvis_code_analysis/checklists/php.py +0 -0
- {jarvis_ai_assistant-0.3.24 → jarvis_ai_assistant-0.3.26}/src/jarvis/jarvis_code_analysis/checklists/python.py +0 -0
- {jarvis_ai_assistant-0.3.24 → jarvis_ai_assistant-0.3.26}/src/jarvis/jarvis_code_analysis/checklists/ruby.py +0 -0
- {jarvis_ai_assistant-0.3.24 → jarvis_ai_assistant-0.3.26}/src/jarvis/jarvis_code_analysis/checklists/rust.py +0 -0
- {jarvis_ai_assistant-0.3.24 → jarvis_ai_assistant-0.3.26}/src/jarvis/jarvis_code_analysis/checklists/shell.py +0 -0
- {jarvis_ai_assistant-0.3.24 → jarvis_ai_assistant-0.3.26}/src/jarvis/jarvis_code_analysis/checklists/sql.py +0 -0
- {jarvis_ai_assistant-0.3.24 → jarvis_ai_assistant-0.3.26}/src/jarvis/jarvis_code_analysis/checklists/swift.py +0 -0
- {jarvis_ai_assistant-0.3.24 → jarvis_ai_assistant-0.3.26}/src/jarvis/jarvis_code_analysis/checklists/web.py +0 -0
- {jarvis_ai_assistant-0.3.24 → jarvis_ai_assistant-0.3.26}/src/jarvis/jarvis_code_analysis/code_review.py +0 -0
- {jarvis_ai_assistant-0.3.24 → jarvis_ai_assistant-0.3.26}/src/jarvis/jarvis_data/tiktoken/9b5ad71b2ce5302211f9c61530b329a4922fc6a4 +0 -0
- {jarvis_ai_assistant-0.3.24 → jarvis_ai_assistant-0.3.26}/src/jarvis/jarvis_git_squash/__init__.py +0 -0
- {jarvis_ai_assistant-0.3.24 → jarvis_ai_assistant-0.3.26}/src/jarvis/jarvis_git_squash/main.py +0 -0
- {jarvis_ai_assistant-0.3.24 → jarvis_ai_assistant-0.3.26}/src/jarvis/jarvis_mcp/__init__.py +0 -0
- {jarvis_ai_assistant-0.3.24 → jarvis_ai_assistant-0.3.26}/src/jarvis/jarvis_mcp/sse_mcp_client.py +0 -0
- {jarvis_ai_assistant-0.3.24 → jarvis_ai_assistant-0.3.26}/src/jarvis/jarvis_mcp/stdio_mcp_client.py +0 -0
- {jarvis_ai_assistant-0.3.24 → jarvis_ai_assistant-0.3.26}/src/jarvis/jarvis_mcp/streamable_mcp_client.py +0 -0
- {jarvis_ai_assistant-0.3.24 → jarvis_ai_assistant-0.3.26}/src/jarvis/jarvis_memory_organizer/__init__.py +0 -0
- {jarvis_ai_assistant-0.3.24 → jarvis_ai_assistant-0.3.26}/src/jarvis/jarvis_memory_organizer/memory_organizer.py +0 -0
- {jarvis_ai_assistant-0.3.24 → jarvis_ai_assistant-0.3.26}/src/jarvis/jarvis_methodology/main.py +0 -0
- {jarvis_ai_assistant-0.3.24 → jarvis_ai_assistant-0.3.26}/src/jarvis/jarvis_multi_agent/__init__.py +0 -0
- {jarvis_ai_assistant-0.3.24 → jarvis_ai_assistant-0.3.26}/src/jarvis/jarvis_multi_agent/main.py +0 -0
- {jarvis_ai_assistant-0.3.24 → jarvis_ai_assistant-0.3.26}/src/jarvis/jarvis_platform/__init__.py +0 -0
- {jarvis_ai_assistant-0.3.24 → jarvis_ai_assistant-0.3.26}/src/jarvis/jarvis_platform/ai8.py +0 -0
- {jarvis_ai_assistant-0.3.24 → jarvis_ai_assistant-0.3.26}/src/jarvis/jarvis_platform/human.py +0 -0
- {jarvis_ai_assistant-0.3.24 → jarvis_ai_assistant-0.3.26}/src/jarvis/jarvis_platform/kimi.py +0 -0
- {jarvis_ai_assistant-0.3.24 → jarvis_ai_assistant-0.3.26}/src/jarvis/jarvis_platform/openai.py +0 -0
- {jarvis_ai_assistant-0.3.24 → jarvis_ai_assistant-0.3.26}/src/jarvis/jarvis_platform/registry.py +0 -0
- {jarvis_ai_assistant-0.3.24 → jarvis_ai_assistant-0.3.26}/src/jarvis/jarvis_platform/tongyi.py +0 -0
- {jarvis_ai_assistant-0.3.24 → jarvis_ai_assistant-0.3.26}/src/jarvis/jarvis_platform/yuanbao.py +0 -0
- {jarvis_ai_assistant-0.3.24 → jarvis_ai_assistant-0.3.26}/src/jarvis/jarvis_platform_manager/__init__.py +0 -0
- {jarvis_ai_assistant-0.3.24 → jarvis_ai_assistant-0.3.26}/src/jarvis/jarvis_platform_manager/main.py +0 -0
- {jarvis_ai_assistant-0.3.24 → jarvis_ai_assistant-0.3.26}/src/jarvis/jarvis_platform_manager/service.py +0 -0
- {jarvis_ai_assistant-0.3.24 → jarvis_ai_assistant-0.3.26}/src/jarvis/jarvis_rag/__init__.py +0 -0
- {jarvis_ai_assistant-0.3.24 → jarvis_ai_assistant-0.3.26}/src/jarvis/jarvis_rag/cache.py +0 -0
- {jarvis_ai_assistant-0.3.24 → jarvis_ai_assistant-0.3.26}/src/jarvis/jarvis_rag/llm_interface.py +0 -0
- {jarvis_ai_assistant-0.3.24 → jarvis_ai_assistant-0.3.26}/src/jarvis/jarvis_rag/query_rewriter.py +0 -0
- {jarvis_ai_assistant-0.3.24 → jarvis_ai_assistant-0.3.26}/src/jarvis/jarvis_rag/retriever.py +0 -0
- {jarvis_ai_assistant-0.3.24 → jarvis_ai_assistant-0.3.26}/src/jarvis/jarvis_smart_shell/__init__.py +0 -0
- {jarvis_ai_assistant-0.3.24 → jarvis_ai_assistant-0.3.26}/src/jarvis/jarvis_stats/__init__.py +0 -0
- {jarvis_ai_assistant-0.3.24 → jarvis_ai_assistant-0.3.26}/src/jarvis/jarvis_stats/cli.py +0 -0
- {jarvis_ai_assistant-0.3.24 → jarvis_ai_assistant-0.3.26}/src/jarvis/jarvis_stats/stats.py +0 -0
- {jarvis_ai_assistant-0.3.24 → jarvis_ai_assistant-0.3.26}/src/jarvis/jarvis_stats/storage.py +0 -0
- {jarvis_ai_assistant-0.3.24 → jarvis_ai_assistant-0.3.26}/src/jarvis/jarvis_stats/visualizer.py +0 -0
- {jarvis_ai_assistant-0.3.24 → jarvis_ai_assistant-0.3.26}/src/jarvis/jarvis_tools/__init__.py +0 -0
- {jarvis_ai_assistant-0.3.24 → jarvis_ai_assistant-0.3.26}/src/jarvis/jarvis_tools/ask_user.py +0 -0
- {jarvis_ai_assistant-0.3.24 → jarvis_ai_assistant-0.3.26}/src/jarvis/jarvis_tools/base.py +0 -0
- {jarvis_ai_assistant-0.3.24 → jarvis_ai_assistant-0.3.26}/src/jarvis/jarvis_tools/clear_memory.py +0 -0
- {jarvis_ai_assistant-0.3.24 → jarvis_ai_assistant-0.3.26}/src/jarvis/jarvis_tools/cli/__init__.py +0 -0
- {jarvis_ai_assistant-0.3.24 → jarvis_ai_assistant-0.3.26}/src/jarvis/jarvis_tools/cli/main.py +0 -0
- {jarvis_ai_assistant-0.3.24 → jarvis_ai_assistant-0.3.26}/src/jarvis/jarvis_tools/file_analyzer.py +0 -0
- {jarvis_ai_assistant-0.3.24 → jarvis_ai_assistant-0.3.26}/src/jarvis/jarvis_tools/generate_new_tool.py +0 -0
- {jarvis_ai_assistant-0.3.24 → jarvis_ai_assistant-0.3.26}/src/jarvis/jarvis_tools/methodology.py +0 -0
- {jarvis_ai_assistant-0.3.24 → jarvis_ai_assistant-0.3.26}/src/jarvis/jarvis_tools/read_code.py +0 -0
- {jarvis_ai_assistant-0.3.24 → jarvis_ai_assistant-0.3.26}/src/jarvis/jarvis_tools/read_webpage.py +0 -0
- {jarvis_ai_assistant-0.3.24 → jarvis_ai_assistant-0.3.26}/src/jarvis/jarvis_tools/registry.py +0 -0
- {jarvis_ai_assistant-0.3.24 → jarvis_ai_assistant-0.3.26}/src/jarvis/jarvis_tools/retrieve_memory.py +0 -0
- {jarvis_ai_assistant-0.3.24 → jarvis_ai_assistant-0.3.26}/src/jarvis/jarvis_tools/rewrite_file.py +0 -0
- {jarvis_ai_assistant-0.3.24 → jarvis_ai_assistant-0.3.26}/src/jarvis/jarvis_tools/save_memory.py +0 -0
- {jarvis_ai_assistant-0.3.24 → jarvis_ai_assistant-0.3.26}/src/jarvis/jarvis_tools/search_web.py +0 -0
- {jarvis_ai_assistant-0.3.24 → jarvis_ai_assistant-0.3.26}/src/jarvis/jarvis_tools/virtual_tty.py +0 -0
- {jarvis_ai_assistant-0.3.24 → jarvis_ai_assistant-0.3.26}/src/jarvis/jarvis_utils/__init__.py +0 -0
- {jarvis_ai_assistant-0.3.24 → jarvis_ai_assistant-0.3.26}/src/jarvis/jarvis_utils/builtin_replace_map.py +0 -0
- {jarvis_ai_assistant-0.3.24 → jarvis_ai_assistant-0.3.26}/src/jarvis/jarvis_utils/clipboard.py +0 -0
- {jarvis_ai_assistant-0.3.24 → jarvis_ai_assistant-0.3.26}/src/jarvis/jarvis_utils/embedding.py +0 -0
- {jarvis_ai_assistant-0.3.24 → jarvis_ai_assistant-0.3.26}/src/jarvis/jarvis_utils/file_processors.py +0 -0
- {jarvis_ai_assistant-0.3.24 → jarvis_ai_assistant-0.3.26}/src/jarvis/jarvis_utils/globals.py +0 -0
- {jarvis_ai_assistant-0.3.24 → jarvis_ai_assistant-0.3.26}/src/jarvis/jarvis_utils/http.py +0 -0
- {jarvis_ai_assistant-0.3.24 → jarvis_ai_assistant-0.3.26}/src/jarvis/jarvis_utils/methodology.py +0 -0
- {jarvis_ai_assistant-0.3.24 → jarvis_ai_assistant-0.3.26}/src/jarvis/jarvis_utils/output.py +0 -0
- {jarvis_ai_assistant-0.3.24 → jarvis_ai_assistant-0.3.26}/src/jarvis/jarvis_utils/tag.py +0 -0
- {jarvis_ai_assistant-0.3.24 → jarvis_ai_assistant-0.3.26}/src/jarvis_ai_assistant.egg-info/SOURCES.txt +0 -0
- {jarvis_ai_assistant-0.3.24 → jarvis_ai_assistant-0.3.26}/src/jarvis_ai_assistant.egg-info/dependency_links.txt +0 -0
- {jarvis_ai_assistant-0.3.24 → jarvis_ai_assistant-0.3.26}/src/jarvis_ai_assistant.egg-info/entry_points.txt +0 -0
- {jarvis_ai_assistant-0.3.24 → jarvis_ai_assistant-0.3.26}/src/jarvis_ai_assistant.egg-info/requires.txt +0 -0
- {jarvis_ai_assistant-0.3.24 → jarvis_ai_assistant-0.3.26}/src/jarvis_ai_assistant.egg-info/top_level.txt +0 -0
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
4
4
|
|
5
5
|
[project]
|
6
6
|
name = "jarvis-ai-assistant"
|
7
|
-
version = "0.3.
|
7
|
+
version = "0.3.26"
|
8
8
|
description = "Jarvis: An AI assistant that uses tools to interact with the system"
|
9
9
|
readme = "README.md"
|
10
10
|
authors = [{ name = "skyfire", email = "skyfireitdiy@hotmail.com" }]
|
@@ -3,7 +3,7 @@ from setuptools import setup, find_packages # type: ignore
|
|
3
3
|
|
4
4
|
setup(
|
5
5
|
name="jarvis-ai-assistant",
|
6
|
-
version="0.3.
|
6
|
+
version="0.3.26",
|
7
7
|
author="skyfire",
|
8
8
|
author_email="skyfireitdiy@hotmail.com",
|
9
9
|
description="An AI assistant that uses various tools to interact with the system",
|
{jarvis_ai_assistant-0.3.24 → jarvis_ai_assistant-0.3.26}/src/jarvis/jarvis_agent/__init__.py
RENAMED
@@ -662,6 +662,10 @@ class Agent:
|
|
662
662
|
if self.use_analysis:
|
663
663
|
self.task_analyzer.analysis_task(satisfaction_feedback)
|
664
664
|
|
665
|
+
# 当开启强制保存记忆时,在分析步骤之后触发一次记忆保存
|
666
|
+
if self.force_save_memory:
|
667
|
+
self.memory_manager.prompt_memory_save()
|
668
|
+
|
665
669
|
self._check_and_organize_memory()
|
666
670
|
|
667
671
|
if self.need_summary:
|
@@ -384,21 +384,21 @@ def handle_builtin_config_selector(
|
|
384
384
|
table.add_column("描述", style="white")
|
385
385
|
|
386
386
|
for idx, opt in enumerate(options, 1):
|
387
|
-
category = opt.get("category", "")
|
388
|
-
name = opt.get("name", "")
|
389
|
-
file_path = opt.get("file", "")
|
387
|
+
category = str(opt.get("category", ""))
|
388
|
+
name = str(opt.get("name", ""))
|
389
|
+
file_path = str(opt.get("file", ""))
|
390
390
|
# 描述列显示配置描述;若为 roles 同时显示角色数量与列表
|
391
391
|
if category == "roles":
|
392
392
|
count = opt.get("roles_count")
|
393
|
-
|
394
|
-
parts = []
|
393
|
+
details_val = opt.get("details", "")
|
394
|
+
parts: list[str] = []
|
395
395
|
if isinstance(count, int) and count > 0:
|
396
396
|
parts.append(f"{count} 个角色")
|
397
|
-
if
|
398
|
-
parts.append(
|
397
|
+
if isinstance(details_val, str) and details_val:
|
398
|
+
parts.append(details_val)
|
399
399
|
desc_display = "\n".join(parts) if parts else ""
|
400
400
|
else:
|
401
|
-
desc_display = opt.get("desc", "")
|
401
|
+
desc_display = str(opt.get("desc", ""))
|
402
402
|
table.add_row(str(idx), category, name, file_path, desc_display)
|
403
403
|
|
404
404
|
Console().print(table)
|
@@ -412,29 +412,29 @@ def handle_builtin_config_selector(
|
|
412
412
|
index = int(choice.strip())
|
413
413
|
if 1 <= index <= len(options):
|
414
414
|
sel = options[index - 1]
|
415
|
-
args = []
|
415
|
+
args: list[str] = []
|
416
416
|
|
417
417
|
if sel["category"] == "agent":
|
418
418
|
# jarvis-agent 支持 -f/--config(全局配置)与 -c/--agent-definition
|
419
|
-
args = [sel["cmd"], "-c", sel["file"]]
|
419
|
+
args = [str(sel["cmd"]), "-c", str(sel["file"])]
|
420
420
|
if model_group:
|
421
|
-
args += ["-g", model_group]
|
421
|
+
args += ["-g", str(model_group)]
|
422
422
|
if config_file:
|
423
|
-
args += ["-f", config_file]
|
423
|
+
args += ["-f", str(config_file)]
|
424
424
|
if task:
|
425
|
-
args += ["--task", task]
|
425
|
+
args += ["--task", str(task)]
|
426
426
|
|
427
427
|
elif sel["category"] == "multi_agent":
|
428
428
|
# jarvis-multi-agent 需要 -c/--config,用户输入通过 -i/--input 传递
|
429
|
-
args = [sel["cmd"], "-c", sel["file"]]
|
429
|
+
args = [str(sel["cmd"]), "-c", str(sel["file"])]
|
430
430
|
if task:
|
431
|
-
args += ["-i", task]
|
431
|
+
args += ["-i", str(task)]
|
432
432
|
|
433
433
|
elif sel["category"] == "roles":
|
434
434
|
# jarvis-platform-manager role 子命令,支持 -c/-t/-g
|
435
|
-
args = [sel["cmd"], "role", "-c", sel["file"]]
|
435
|
+
args = [str(sel["cmd"]), "role", "-c", str(sel["file"])]
|
436
436
|
if model_group:
|
437
|
-
args += ["-g", model_group]
|
437
|
+
args += ["-g", str(model_group)]
|
438
438
|
|
439
439
|
if args:
|
440
440
|
PrettyOutput.print(
|
{jarvis_ai_assistant-0.3.24 → jarvis_ai_assistant-0.3.26}/src/jarvis/jarvis_data/config_schema.json
RENAMED
@@ -165,6 +165,13 @@
|
|
165
165
|
"JARVIS_MAX_INPUT_TOKEN_COUNT": {
|
166
166
|
"type": "number",
|
167
167
|
"default": 32000
|
168
|
+
},
|
169
|
+
"ENV": {
|
170
|
+
"type": "object",
|
171
|
+
"description": "该模型组特定的环境变量,会覆盖全局 ENV 配置",
|
172
|
+
"additionalProperties": {
|
173
|
+
"type": "string"
|
174
|
+
}
|
168
175
|
}
|
169
176
|
},
|
170
177
|
"required": [
|
@@ -113,9 +113,9 @@ class GitCommitTool:
|
|
113
113
|
# 获取文件列表
|
114
114
|
files_cmd = ["git", "diff", "--cached", "--name-only"]
|
115
115
|
process = subprocess.Popen(
|
116
|
-
files_cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE
|
116
|
+
files_cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True
|
117
117
|
)
|
118
|
-
files_output = process.communicate()[0]
|
118
|
+
files_output = process.communicate()[0]
|
119
119
|
files = [f.strip() for f in files_output.split("\n") if f.strip()]
|
120
120
|
file_count = len(files)
|
121
121
|
|
@@ -124,8 +124,9 @@ class GitCommitTool:
|
|
124
124
|
["git", "diff", "--cached", "--exit-code"],
|
125
125
|
stdout=subprocess.PIPE,
|
126
126
|
stderr=subprocess.PIPE,
|
127
|
+
text=True,
|
127
128
|
)
|
128
|
-
diff = process.communicate()[0]
|
129
|
+
diff = process.communicate()[0]
|
129
130
|
|
130
131
|
try:
|
131
132
|
temp_diff_file_path = None
|
{jarvis_ai_assistant-0.3.24 → jarvis_ai_assistant-0.3.26}/src/jarvis/jarvis_platform/base.py
RENAMED
@@ -9,6 +9,7 @@ from typing_extensions import Self
|
|
9
9
|
from rich import box # type: ignore
|
10
10
|
from rich.live import Live # type: ignore
|
11
11
|
from rich.panel import Panel # type: ignore
|
12
|
+
from rich.status import Status # type: ignore
|
12
13
|
from rich.text import Text # type: ignore
|
13
14
|
|
14
15
|
from jarvis.jarvis_utils.config import (
|
@@ -120,23 +121,44 @@ class BasePlatform(ABC):
|
|
120
121
|
else:
|
121
122
|
response = ""
|
122
123
|
|
123
|
-
text_content = Text(overflow="fold") # 添加文本溢出处理
|
124
|
-
panel = Panel(
|
125
|
-
text_content,
|
126
|
-
title=f"[bold cyan]{self.name()}[/bold cyan]",
|
127
|
-
subtitle="[dim]思考中... (按 Ctrl+C 中断)[/dim]",
|
128
|
-
border_style="bright_blue",
|
129
|
-
box=box.ROUNDED,
|
130
|
-
expand=True # 允许面板自动调整大小
|
131
|
-
)
|
132
|
-
|
133
124
|
if not self.suppress_output:
|
134
125
|
if get_pretty_output():
|
135
|
-
|
126
|
+
chat_iterator = self.chat(message)
|
127
|
+
first_chunk = None
|
128
|
+
|
129
|
+
with Status(
|
130
|
+
f"🤔 {self.name()} 正在思考中...", spinner="dots", console=console
|
131
|
+
):
|
132
|
+
try:
|
133
|
+
while True:
|
134
|
+
first_chunk = next(chat_iterator)
|
135
|
+
if first_chunk:
|
136
|
+
break
|
137
|
+
except StopIteration:
|
138
|
+
return ""
|
139
|
+
|
140
|
+
text_content = Text(overflow="fold")
|
141
|
+
panel = Panel(
|
142
|
+
text_content,
|
143
|
+
title=f"[bold cyan]{self.name()}[/bold cyan]",
|
144
|
+
subtitle="[yellow]正在回答... (按 Ctrl+C 中断)[/yellow]",
|
145
|
+
border_style="bright_blue",
|
146
|
+
box=box.ROUNDED,
|
147
|
+
expand=True, # 允许面板自动调整大小
|
148
|
+
)
|
149
|
+
|
136
150
|
buffer = []
|
137
151
|
buffer_count = 0
|
138
152
|
with Live(panel, refresh_per_second=4, transient=False) as live:
|
139
|
-
|
153
|
+
# Process first chunk
|
154
|
+
response += first_chunk
|
155
|
+
buffer.append(first_chunk)
|
156
|
+
buffer_count += 1
|
157
|
+
|
158
|
+
# Process rest of the chunks
|
159
|
+
for s in chat_iterator:
|
160
|
+
if not s:
|
161
|
+
continue
|
140
162
|
response += s # Accumulate the full response string
|
141
163
|
buffer.append(s)
|
142
164
|
buffer_count += 1
|
@@ -144,13 +166,17 @@ class BasePlatform(ABC):
|
|
144
166
|
# 积累一定量或达到最后再更新,减少闪烁
|
145
167
|
if buffer_count >= 5 or s == "":
|
146
168
|
# Append buffered content to the Text object
|
147
|
-
text_content.append(
|
169
|
+
text_content.append(
|
170
|
+
"".join(buffer), style="bright_white"
|
171
|
+
)
|
148
172
|
buffer.clear()
|
149
173
|
buffer_count = 0
|
150
174
|
|
151
175
|
# --- Scrolling Logic ---
|
152
176
|
# Calculate available height in the panel
|
153
|
-
max_text_height =
|
177
|
+
max_text_height = (
|
178
|
+
console.height - 5
|
179
|
+
) # Leave space for borders/titles
|
154
180
|
if max_text_height <= 0:
|
155
181
|
max_text_height = 1
|
156
182
|
|
@@ -163,11 +189,15 @@ class BasePlatform(ABC):
|
|
163
189
|
# If content overflows, truncate to show only the last few lines
|
164
190
|
if len(lines) > max_text_height:
|
165
191
|
new_text = "\n".join(
|
166
|
-
text_content.plain.splitlines()[
|
192
|
+
text_content.plain.splitlines()[
|
193
|
+
-max_text_height:
|
194
|
+
]
|
167
195
|
)
|
168
196
|
text_content.plain = new_text
|
169
197
|
|
170
|
-
panel.subtitle =
|
198
|
+
panel.subtitle = (
|
199
|
+
"[yellow]正在回答... (按 Ctrl+C 中断)[/yellow]"
|
200
|
+
)
|
171
201
|
live.update(panel)
|
172
202
|
|
173
203
|
if is_immediate_abort() and get_interrupt():
|
@@ -175,7 +205,9 @@ class BasePlatform(ABC):
|
|
175
205
|
|
176
206
|
# Ensure any remaining content in the buffer is displayed
|
177
207
|
if buffer:
|
178
|
-
text_content.append(
|
208
|
+
text_content.append(
|
209
|
+
"".join(buffer), style="bright_white"
|
210
|
+
)
|
179
211
|
|
180
212
|
# At the end, display the entire response
|
181
213
|
text_content.plain = response
|
@@ -14,7 +14,7 @@ from langchain_community.document_loaders import (
|
|
14
14
|
from langchain_core.document_loaders.base import BaseLoader
|
15
15
|
from rich.markdown import Markdown
|
16
16
|
|
17
|
-
from jarvis.jarvis_utils.utils import init_env
|
17
|
+
from jarvis.jarvis_utils.utils import init_env, is_rag_installed, get_missing_rag_modules
|
18
18
|
from jarvis.jarvis_utils.config import (
|
19
19
|
get_rag_embedding_model,
|
20
20
|
get_rag_use_bm25,
|
@@ -357,6 +357,12 @@ def retrieve(
|
|
357
357
|
None, "--db-path", help="向量数据库的路径。覆盖全局配置。"
|
358
358
|
),
|
359
359
|
n_results: int = typer.Option(5, "--top-n", help="要检索的文档数量。"),
|
360
|
+
rewrite: bool = typer.Option(
|
361
|
+
True,
|
362
|
+
"--rewrite/--no-rewrite",
|
363
|
+
help="是否对查询进行LLM重写以提升召回,默认开启。",
|
364
|
+
show_default=True,
|
365
|
+
),
|
360
366
|
):
|
361
367
|
"""仅从RAG知识库检索文档并打印结果。"""
|
362
368
|
try:
|
@@ -371,6 +377,7 @@ def retrieve(
|
|
371
377
|
collection_name=collection_name,
|
372
378
|
use_bm25=use_bm25,
|
373
379
|
use_rerank=use_rerank,
|
380
|
+
use_query_rewrite=rewrite,
|
374
381
|
)
|
375
382
|
|
376
383
|
PrettyOutput.print(f"正在为问题检索文档: '{question}'", OutputType.INFO)
|
@@ -462,19 +469,15 @@ def query(
|
|
462
469
|
raise typer.Exit(code=1)
|
463
470
|
|
464
471
|
|
465
|
-
_RAG_INSTALLED = False
|
466
|
-
try:
|
467
|
-
import langchain # noqa
|
468
472
|
|
469
|
-
_RAG_INSTALLED = True
|
470
|
-
except ImportError:
|
471
|
-
pass
|
472
473
|
|
473
474
|
|
474
475
|
def _check_rag_dependencies():
|
475
|
-
if not
|
476
|
+
if not is_rag_installed():
|
477
|
+
missing = get_missing_rag_modules()
|
478
|
+
missing_str = f"缺少依赖: {', '.join(missing)}。" if missing else ""
|
476
479
|
PrettyOutput.print(
|
477
|
-
"RAG
|
480
|
+
f"RAG依赖项未安装或不完整。{missing_str}请运行 'pip install \"jarvis-ai-assistant[rag]\"' 后重试。",
|
478
481
|
OutputType.ERROR,
|
479
482
|
)
|
480
483
|
raise typer.Exit(code=1)
|
@@ -0,0 +1,239 @@
|
|
1
|
+
import torch
|
2
|
+
import os
|
3
|
+
from typing import List, cast
|
4
|
+
from langchain_huggingface import HuggingFaceEmbeddings
|
5
|
+
from huggingface_hub import snapshot_download
|
6
|
+
|
7
|
+
|
8
|
+
from .cache import EmbeddingCache
|
9
|
+
from jarvis.jarvis_utils.output import OutputType, PrettyOutput
|
10
|
+
|
11
|
+
|
12
|
+
class EmbeddingManager:
|
13
|
+
"""
|
14
|
+
管理本地嵌入模型的加载和使用,并带有缓存功能。
|
15
|
+
|
16
|
+
该类负责从Hugging Face加载指定的模型,并使用基于磁盘的缓存
|
17
|
+
来避免为相同文本重新计算嵌入。
|
18
|
+
"""
|
19
|
+
|
20
|
+
def __init__(self, model_name: str, cache_dir: str):
|
21
|
+
"""
|
22
|
+
初始化EmbeddingManager。
|
23
|
+
|
24
|
+
参数:
|
25
|
+
model_name: 要加载的Hugging Face模型的名称。
|
26
|
+
cache_dir: 用于存储嵌入缓存的目录。
|
27
|
+
"""
|
28
|
+
self.model_name = model_name
|
29
|
+
|
30
|
+
PrettyOutput.print(
|
31
|
+
f"初始化嵌入管理器, 模型: '{self.model_name}'...", OutputType.INFO
|
32
|
+
)
|
33
|
+
|
34
|
+
# 缓存的salt是模型名称,以防止冲突
|
35
|
+
self.cache = EmbeddingCache(cache_dir=cache_dir, salt=self.model_name)
|
36
|
+
self.model = self._load_model()
|
37
|
+
|
38
|
+
def _load_model(self) -> HuggingFaceEmbeddings:
|
39
|
+
"""根据配置加载Hugging Face嵌入模型。"""
|
40
|
+
model_kwargs = {"device": "cuda" if torch.cuda.is_available() else "cpu"}
|
41
|
+
encode_kwargs = {"normalize_embeddings": True}
|
42
|
+
|
43
|
+
try:
|
44
|
+
# First try to load model from local cache without any network access
|
45
|
+
try:
|
46
|
+
from sentence_transformers import SentenceTransformer
|
47
|
+
local_dir = None
|
48
|
+
# Prefer explicit local dir via env or direct path
|
49
|
+
|
50
|
+
if os.path.isdir(self.model_name):
|
51
|
+
return HuggingFaceEmbeddings(
|
52
|
+
model_name=self.model_name,
|
53
|
+
model_kwargs=model_kwargs,
|
54
|
+
encode_kwargs=encode_kwargs,
|
55
|
+
show_progress=False,
|
56
|
+
)
|
57
|
+
|
58
|
+
# Try common local cache directories for sentence-transformers and HF hub
|
59
|
+
try:
|
60
|
+
home = os.path.expanduser("~")
|
61
|
+
st_home = os.path.join(home, ".cache", "sentence_transformers")
|
62
|
+
torch_st_home = os.path.join(home, ".cache", "torch", "sentence_transformers")
|
63
|
+
# Build common name variants found in local caches
|
64
|
+
org, name = (
|
65
|
+
self.model_name.split("/", 1)
|
66
|
+
if "/" in self.model_name
|
67
|
+
else ("", self.model_name)
|
68
|
+
)
|
69
|
+
san1 = self.model_name.replace("/", "_")
|
70
|
+
san2 = self.model_name.replace("/", "__")
|
71
|
+
san3 = self.model_name.replace("/", "--")
|
72
|
+
# include plain 'name' for caches that drop org prefix
|
73
|
+
name_variants = list(dict.fromkeys([self.model_name, san1, san2, san3, name]))
|
74
|
+
candidates = []
|
75
|
+
for base in [st_home, torch_st_home]:
|
76
|
+
for nv in name_variants:
|
77
|
+
p = os.path.join(base, nv)
|
78
|
+
if os.path.isdir(p):
|
79
|
+
candidates.append(p)
|
80
|
+
# Fuzzy scan cache directory for entries that include variants
|
81
|
+
try:
|
82
|
+
for entry in os.listdir(base):
|
83
|
+
ep = os.path.join(base, entry)
|
84
|
+
if not os.path.isdir(ep):
|
85
|
+
continue
|
86
|
+
if (
|
87
|
+
(org and entry.startswith(f"{org}__") and name in entry)
|
88
|
+
or (san1 in entry)
|
89
|
+
or (name in entry)
|
90
|
+
):
|
91
|
+
candidates.append(ep)
|
92
|
+
except Exception:
|
93
|
+
pass
|
94
|
+
|
95
|
+
# Hugging Face Hub cache snapshots
|
96
|
+
hf_cache = os.path.join(home, ".cache", "huggingface", "hub")
|
97
|
+
if "/" in self.model_name:
|
98
|
+
org, name = self.model_name.split("/", 1)
|
99
|
+
models_dir = os.path.join(hf_cache, f"models--{org}--{name}", "snapshots")
|
100
|
+
if os.path.isdir(models_dir):
|
101
|
+
try:
|
102
|
+
snaps = sorted(
|
103
|
+
[os.path.join(models_dir, d) for d in os.listdir(models_dir)],
|
104
|
+
key=lambda p: os.path.getmtime(p),
|
105
|
+
reverse=True,
|
106
|
+
)
|
107
|
+
except Exception:
|
108
|
+
snaps = [os.path.join(models_dir, d) for d in os.listdir(models_dir)]
|
109
|
+
for sp in snaps:
|
110
|
+
if os.path.isdir(sp):
|
111
|
+
candidates.append(sp)
|
112
|
+
break
|
113
|
+
|
114
|
+
for cand in candidates:
|
115
|
+
try:
|
116
|
+
return HuggingFaceEmbeddings(
|
117
|
+
model_name=cand,
|
118
|
+
model_kwargs=model_kwargs,
|
119
|
+
encode_kwargs=encode_kwargs,
|
120
|
+
show_progress=False,
|
121
|
+
)
|
122
|
+
except Exception:
|
123
|
+
continue
|
124
|
+
except Exception:
|
125
|
+
pass
|
126
|
+
|
127
|
+
try:
|
128
|
+
# Try resolve local cached directory; do not hit network
|
129
|
+
local_dir = snapshot_download(repo_id=self.model_name, local_files_only=True)
|
130
|
+
except Exception:
|
131
|
+
local_dir = None
|
132
|
+
|
133
|
+
if local_dir:
|
134
|
+
return HuggingFaceEmbeddings(
|
135
|
+
model_name=local_dir,
|
136
|
+
model_kwargs=model_kwargs,
|
137
|
+
encode_kwargs=encode_kwargs,
|
138
|
+
show_progress=False,
|
139
|
+
)
|
140
|
+
|
141
|
+
|
142
|
+
|
143
|
+
# Fall back to remote download if local cache not found and not offline
|
144
|
+
return HuggingFaceEmbeddings(
|
145
|
+
model_name=self.model_name,
|
146
|
+
model_kwargs=model_kwargs,
|
147
|
+
encode_kwargs=encode_kwargs,
|
148
|
+
show_progress=True,
|
149
|
+
)
|
150
|
+
except Exception as _e:
|
151
|
+
# 如果已检测到本地候选路径(直接目录 / 本地缓存快照),则视为本地加载失败,
|
152
|
+
# 为避免在用户期望“本地优先不联网”的情况下触发联网,直接抛错并给出修复建议。
|
153
|
+
had_local_candidate = False
|
154
|
+
try:
|
155
|
+
had_local_candidate = (
|
156
|
+
os.path.isdir(self.model_name)
|
157
|
+
# 如果上面 snapshot_download 命中了本地缓存,会将 local_dir 设为非 None
|
158
|
+
or (locals().get("local_dir") is not None)
|
159
|
+
)
|
160
|
+
except Exception:
|
161
|
+
pass
|
162
|
+
|
163
|
+
if had_local_candidate:
|
164
|
+
PrettyOutput.print(
|
165
|
+
"检测到本地模型路径但加载失败。为避免触发网络访问,已中止远程回退。\n"
|
166
|
+
"请确认本地目录包含完整的 Transformers/Tokenizer 文件(如 config.json、model.safetensors、tokenizer.json/merges.txt 等),\n"
|
167
|
+
"或在配置中将 embedding_model 设置为该本地目录,或将模型放置到默认的 Hugging Face 缓存目录(例如 ~/.cache/huggingface/hub)。",
|
168
|
+
OutputType.ERROR,
|
169
|
+
)
|
170
|
+
raise
|
171
|
+
|
172
|
+
# 未发现任何本地候选,则保持原有行为:回退至远程下载
|
173
|
+
return HuggingFaceEmbeddings(
|
174
|
+
model_name=self.model_name,
|
175
|
+
model_kwargs=model_kwargs,
|
176
|
+
encode_kwargs=encode_kwargs,
|
177
|
+
show_progress=True,
|
178
|
+
)
|
179
|
+
except Exception as e:
|
180
|
+
PrettyOutput.print(
|
181
|
+
f"加载嵌入模型 '{self.model_name}' 时出错: {e}", OutputType.ERROR
|
182
|
+
)
|
183
|
+
PrettyOutput.print(
|
184
|
+
"请确保您已安装 'sentence_transformers' 和 'torch'。",
|
185
|
+
OutputType.WARNING,
|
186
|
+
)
|
187
|
+
raise
|
188
|
+
|
189
|
+
def embed_documents(self, texts: List[str]) -> List[List[float]]:
|
190
|
+
"""
|
191
|
+
使用缓存为文档列表计算嵌入。
|
192
|
+
|
193
|
+
参数:
|
194
|
+
texts: 要嵌入的文档(字符串)列表。
|
195
|
+
|
196
|
+
返回:
|
197
|
+
一个嵌入列表,每个文档对应一个嵌入。
|
198
|
+
"""
|
199
|
+
if not texts:
|
200
|
+
return []
|
201
|
+
|
202
|
+
# 检查缓存中是否已存在嵌入
|
203
|
+
cached_embeddings = self.cache.get_batch(texts)
|
204
|
+
|
205
|
+
texts_to_embed = []
|
206
|
+
indices_to_embed = []
|
207
|
+
for i, (text, cached) in enumerate(zip(texts, cached_embeddings)):
|
208
|
+
if cached is None:
|
209
|
+
texts_to_embed.append(text)
|
210
|
+
indices_to_embed.append(i)
|
211
|
+
|
212
|
+
# 为不在缓存中的文本计算嵌入
|
213
|
+
if texts_to_embed:
|
214
|
+
PrettyOutput.print(
|
215
|
+
f"缓存未命中。正在为 {len(texts_to_embed)}/{len(texts)} 个文档计算嵌入。",
|
216
|
+
OutputType.INFO,
|
217
|
+
)
|
218
|
+
new_embeddings = self.model.embed_documents(texts_to_embed)
|
219
|
+
|
220
|
+
# 将新的嵌入存储在缓存中
|
221
|
+
self.cache.set_batch(texts_to_embed, new_embeddings)
|
222
|
+
|
223
|
+
# 将新的嵌入放回结果列表中
|
224
|
+
for i, embedding in zip(indices_to_embed, new_embeddings):
|
225
|
+
cached_embeddings[i] = embedding
|
226
|
+
else:
|
227
|
+
PrettyOutput.print(
|
228
|
+
f"缓存命中。所有 {len(texts)} 个文档的嵌入均从缓存中检索。",
|
229
|
+
OutputType.SUCCESS,
|
230
|
+
)
|
231
|
+
|
232
|
+
return cast(List[List[float]], cached_embeddings)
|
233
|
+
|
234
|
+
def embed_query(self, text: str) -> List[float]:
|
235
|
+
"""
|
236
|
+
为单个查询计算嵌入。
|
237
|
+
查询通常不被缓存,但如果需要可以添加。
|
238
|
+
"""
|
239
|
+
return self.model.embed_query(text)
|
{jarvis_ai_assistant-0.3.24 → jarvis_ai_assistant-0.3.26}/src/jarvis/jarvis_rag/rag_pipeline.py
RENAMED
@@ -34,6 +34,7 @@ class JarvisRAGPipeline:
|
|
34
34
|
collection_name: str = "jarvis_rag_collection",
|
35
35
|
use_bm25: bool = True,
|
36
36
|
use_rerank: bool = True,
|
37
|
+
use_query_rewrite: bool = True,
|
37
38
|
):
|
38
39
|
"""
|
39
40
|
初始化RAG管道。
|
@@ -69,6 +70,8 @@ class JarvisRAGPipeline:
|
|
69
70
|
self.collection_name = collection_name
|
70
71
|
self.use_bm25 = use_bm25
|
71
72
|
self.use_rerank = use_rerank
|
73
|
+
# 查询重写开关(默认开启,可由CLI控制)
|
74
|
+
self.use_query_rewrite = use_query_rewrite
|
72
75
|
|
73
76
|
# 延迟加载的组件
|
74
77
|
self._embedding_manager: Optional[EmbeddingManager] = None
|
@@ -229,8 +232,15 @@ class JarvisRAGPipeline:
|
|
229
232
|
"""
|
230
233
|
# 0. 检测索引变更并可选更新(在重写query之前)
|
231
234
|
self._pre_search_update_index_if_needed()
|
232
|
-
# 1.
|
233
|
-
|
235
|
+
# 1. 将原始查询重写为多个查询(可配置)
|
236
|
+
if self.use_query_rewrite:
|
237
|
+
rewritten_queries = self._get_query_rewriter().rewrite(query_text)
|
238
|
+
else:
|
239
|
+
PrettyOutput.print(
|
240
|
+
"已关闭查询重写,将直接使用原始查询进行检索。",
|
241
|
+
OutputType.INFO,
|
242
|
+
)
|
243
|
+
rewritten_queries = [query_text]
|
234
244
|
|
235
245
|
# 2. 为每个重写的查询检索初始候选文档
|
236
246
|
PrettyOutput.print(
|
@@ -303,8 +313,15 @@ class JarvisRAGPipeline:
|
|
303
313
|
"""
|
304
314
|
# 0. 检测索引变更并可选更新(在重写query之前)
|
305
315
|
self._pre_search_update_index_if_needed()
|
306
|
-
# 1.
|
307
|
-
|
316
|
+
# 1. 重写查询(可配置)
|
317
|
+
if self.use_query_rewrite:
|
318
|
+
rewritten_queries = self._get_query_rewriter().rewrite(query_text)
|
319
|
+
else:
|
320
|
+
PrettyOutput.print(
|
321
|
+
"已关闭查询重写,将直接使用原始查询进行检索。",
|
322
|
+
OutputType.INFO,
|
323
|
+
)
|
324
|
+
rewritten_queries = [query_text]
|
308
325
|
|
309
326
|
# 2. 检索候选文档
|
310
327
|
PrettyOutput.print(
|
@@ -1,9 +1,11 @@
|
|
1
1
|
from typing import List
|
2
|
+
import os
|
2
3
|
|
3
4
|
from langchain.docstore.document import Document
|
4
5
|
from sentence_transformers.cross_encoder import ( # type: ignore
|
5
6
|
CrossEncoder,
|
6
7
|
)
|
8
|
+
from huggingface_hub import snapshot_download
|
7
9
|
from jarvis.jarvis_utils.output import OutputType, PrettyOutput
|
8
10
|
|
9
11
|
|
@@ -21,8 +23,28 @@ class Reranker:
|
|
21
23
|
model_name (str): 要使用的Cross-Encoder模型的名称。
|
22
24
|
"""
|
23
25
|
PrettyOutput.print(f"正在初始化重排模型: {model_name}...", OutputType.INFO)
|
24
|
-
|
25
|
-
|
26
|
+
try:
|
27
|
+
local_dir = None
|
28
|
+
|
29
|
+
if os.path.isdir(model_name):
|
30
|
+
self.model = CrossEncoder(model_name)
|
31
|
+
PrettyOutput.print("重排模型初始化成功。", OutputType.SUCCESS)
|
32
|
+
return
|
33
|
+
try:
|
34
|
+
# Prefer local cache; avoid any network access
|
35
|
+
local_dir = snapshot_download(repo_id=model_name, local_files_only=True)
|
36
|
+
except Exception:
|
37
|
+
local_dir = None
|
38
|
+
|
39
|
+
if local_dir:
|
40
|
+
self.model = CrossEncoder(local_dir)
|
41
|
+
else:
|
42
|
+
self.model = CrossEncoder(model_name)
|
43
|
+
|
44
|
+
PrettyOutput.print("重排模型初始化成功。", OutputType.SUCCESS)
|
45
|
+
except Exception as e:
|
46
|
+
PrettyOutput.print(f"初始化重排模型失败: {e}", OutputType.ERROR)
|
47
|
+
raise
|
26
48
|
|
27
49
|
def rerank(
|
28
50
|
self, query: str, documents: List[Document], top_n: int = 5
|