jarvis-ai-assistant 0.1.195__tar.gz → 0.1.196__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (106) hide show
  1. {jarvis_ai_assistant-0.1.195/src/jarvis_ai_assistant.egg-info → jarvis_ai_assistant-0.1.196}/PKG-INFO +2 -1
  2. {jarvis_ai_assistant-0.1.195 → jarvis_ai_assistant-0.1.196}/README.md +1 -0
  3. {jarvis_ai_assistant-0.1.195 → jarvis_ai_assistant-0.1.196}/pyproject.toml +1 -1
  4. {jarvis_ai_assistant-0.1.195 → jarvis_ai_assistant-0.1.196}/setup.py +1 -1
  5. {jarvis_ai_assistant-0.1.195 → jarvis_ai_assistant-0.1.196}/src/jarvis/__init__.py +1 -1
  6. {jarvis_ai_assistant-0.1.195 → jarvis_ai_assistant-0.1.196}/src/jarvis/jarvis_agent/__init__.py +47 -26
  7. {jarvis_ai_assistant-0.1.195 → jarvis_ai_assistant-0.1.196}/src/jarvis/jarvis_data/config_schema.json +5 -0
  8. {jarvis_ai_assistant-0.1.195 → jarvis_ai_assistant-0.1.196}/src/jarvis/jarvis_utils/config.py +10 -0
  9. jarvis_ai_assistant-0.1.196/src/jarvis/jarvis_utils/jarvis_history.py +96 -0
  10. {jarvis_ai_assistant-0.1.195 → jarvis_ai_assistant-0.1.196/src/jarvis_ai_assistant.egg-info}/PKG-INFO +2 -1
  11. jarvis_ai_assistant-0.1.195/src/jarvis/jarvis_utils/jarvis_history.py +0 -43
  12. {jarvis_ai_assistant-0.1.195 → jarvis_ai_assistant-0.1.196}/LICENSE +0 -0
  13. {jarvis_ai_assistant-0.1.195 → jarvis_ai_assistant-0.1.196}/MANIFEST.in +0 -0
  14. {jarvis_ai_assistant-0.1.195 → jarvis_ai_assistant-0.1.196}/setup.cfg +0 -0
  15. {jarvis_ai_assistant-0.1.195 → jarvis_ai_assistant-0.1.196}/src/jarvis/jarvis_agent/builtin_input_handler.py +0 -0
  16. {jarvis_ai_assistant-0.1.195 → jarvis_ai_assistant-0.1.196}/src/jarvis/jarvis_agent/jarvis.py +0 -0
  17. {jarvis_ai_assistant-0.1.195 → jarvis_ai_assistant-0.1.196}/src/jarvis/jarvis_agent/main.py +0 -0
  18. {jarvis_ai_assistant-0.1.195 → jarvis_ai_assistant-0.1.196}/src/jarvis/jarvis_agent/output_handler.py +0 -0
  19. {jarvis_ai_assistant-0.1.195 → jarvis_ai_assistant-0.1.196}/src/jarvis/jarvis_agent/shell_input_handler.py +0 -0
  20. {jarvis_ai_assistant-0.1.195 → jarvis_ai_assistant-0.1.196}/src/jarvis/jarvis_code_agent/__init__.py +0 -0
  21. {jarvis_ai_assistant-0.1.195 → jarvis_ai_assistant-0.1.196}/src/jarvis/jarvis_code_agent/code_agent.py +0 -0
  22. {jarvis_ai_assistant-0.1.195 → jarvis_ai_assistant-0.1.196}/src/jarvis/jarvis_code_agent/lint.py +0 -0
  23. {jarvis_ai_assistant-0.1.195 → jarvis_ai_assistant-0.1.196}/src/jarvis/jarvis_code_analysis/checklists/__init__.py +0 -0
  24. {jarvis_ai_assistant-0.1.195 → jarvis_ai_assistant-0.1.196}/src/jarvis/jarvis_code_analysis/checklists/c_cpp.py +0 -0
  25. {jarvis_ai_assistant-0.1.195 → jarvis_ai_assistant-0.1.196}/src/jarvis/jarvis_code_analysis/checklists/csharp.py +0 -0
  26. {jarvis_ai_assistant-0.1.195 → jarvis_ai_assistant-0.1.196}/src/jarvis/jarvis_code_analysis/checklists/data_format.py +0 -0
  27. {jarvis_ai_assistant-0.1.195 → jarvis_ai_assistant-0.1.196}/src/jarvis/jarvis_code_analysis/checklists/devops.py +0 -0
  28. {jarvis_ai_assistant-0.1.195 → jarvis_ai_assistant-0.1.196}/src/jarvis/jarvis_code_analysis/checklists/docs.py +0 -0
  29. {jarvis_ai_assistant-0.1.195 → jarvis_ai_assistant-0.1.196}/src/jarvis/jarvis_code_analysis/checklists/go.py +0 -0
  30. {jarvis_ai_assistant-0.1.195 → jarvis_ai_assistant-0.1.196}/src/jarvis/jarvis_code_analysis/checklists/infrastructure.py +0 -0
  31. {jarvis_ai_assistant-0.1.195 → jarvis_ai_assistant-0.1.196}/src/jarvis/jarvis_code_analysis/checklists/java.py +0 -0
  32. {jarvis_ai_assistant-0.1.195 → jarvis_ai_assistant-0.1.196}/src/jarvis/jarvis_code_analysis/checklists/javascript.py +0 -0
  33. {jarvis_ai_assistant-0.1.195 → jarvis_ai_assistant-0.1.196}/src/jarvis/jarvis_code_analysis/checklists/kotlin.py +0 -0
  34. {jarvis_ai_assistant-0.1.195 → jarvis_ai_assistant-0.1.196}/src/jarvis/jarvis_code_analysis/checklists/loader.py +0 -0
  35. {jarvis_ai_assistant-0.1.195 → jarvis_ai_assistant-0.1.196}/src/jarvis/jarvis_code_analysis/checklists/php.py +0 -0
  36. {jarvis_ai_assistant-0.1.195 → jarvis_ai_assistant-0.1.196}/src/jarvis/jarvis_code_analysis/checklists/python.py +0 -0
  37. {jarvis_ai_assistant-0.1.195 → jarvis_ai_assistant-0.1.196}/src/jarvis/jarvis_code_analysis/checklists/ruby.py +0 -0
  38. {jarvis_ai_assistant-0.1.195 → jarvis_ai_assistant-0.1.196}/src/jarvis/jarvis_code_analysis/checklists/rust.py +0 -0
  39. {jarvis_ai_assistant-0.1.195 → jarvis_ai_assistant-0.1.196}/src/jarvis/jarvis_code_analysis/checklists/shell.py +0 -0
  40. {jarvis_ai_assistant-0.1.195 → jarvis_ai_assistant-0.1.196}/src/jarvis/jarvis_code_analysis/checklists/sql.py +0 -0
  41. {jarvis_ai_assistant-0.1.195 → jarvis_ai_assistant-0.1.196}/src/jarvis/jarvis_code_analysis/checklists/swift.py +0 -0
  42. {jarvis_ai_assistant-0.1.195 → jarvis_ai_assistant-0.1.196}/src/jarvis/jarvis_code_analysis/checklists/web.py +0 -0
  43. {jarvis_ai_assistant-0.1.195 → jarvis_ai_assistant-0.1.196}/src/jarvis/jarvis_code_analysis/code_review.py +0 -0
  44. {jarvis_ai_assistant-0.1.195 → jarvis_ai_assistant-0.1.196}/src/jarvis/jarvis_data/huggingface.tar.gz +0 -0
  45. {jarvis_ai_assistant-0.1.195 → jarvis_ai_assistant-0.1.196}/src/jarvis/jarvis_dev/main.py +0 -0
  46. {jarvis_ai_assistant-0.1.195 → jarvis_ai_assistant-0.1.196}/src/jarvis/jarvis_git_details/__init__.py +0 -0
  47. {jarvis_ai_assistant-0.1.195 → jarvis_ai_assistant-0.1.196}/src/jarvis/jarvis_git_details/main.py +0 -0
  48. {jarvis_ai_assistant-0.1.195 → jarvis_ai_assistant-0.1.196}/src/jarvis/jarvis_git_squash/__init__.py +0 -0
  49. {jarvis_ai_assistant-0.1.195 → jarvis_ai_assistant-0.1.196}/src/jarvis/jarvis_git_squash/main.py +0 -0
  50. {jarvis_ai_assistant-0.1.195 → jarvis_ai_assistant-0.1.196}/src/jarvis/jarvis_git_utils/git_commiter.py +0 -0
  51. {jarvis_ai_assistant-0.1.195 → jarvis_ai_assistant-0.1.196}/src/jarvis/jarvis_mcp/__init__.py +0 -0
  52. {jarvis_ai_assistant-0.1.195 → jarvis_ai_assistant-0.1.196}/src/jarvis/jarvis_mcp/sse_mcp_client.py +0 -0
  53. {jarvis_ai_assistant-0.1.195 → jarvis_ai_assistant-0.1.196}/src/jarvis/jarvis_mcp/stdio_mcp_client.py +0 -0
  54. {jarvis_ai_assistant-0.1.195 → jarvis_ai_assistant-0.1.196}/src/jarvis/jarvis_mcp/streamable_mcp_client.py +0 -0
  55. {jarvis_ai_assistant-0.1.195 → jarvis_ai_assistant-0.1.196}/src/jarvis/jarvis_methodology/main.py +0 -0
  56. {jarvis_ai_assistant-0.1.195 → jarvis_ai_assistant-0.1.196}/src/jarvis/jarvis_multi_agent/__init__.py +0 -0
  57. {jarvis_ai_assistant-0.1.195 → jarvis_ai_assistant-0.1.196}/src/jarvis/jarvis_multi_agent/main.py +0 -0
  58. {jarvis_ai_assistant-0.1.195 → jarvis_ai_assistant-0.1.196}/src/jarvis/jarvis_platform/__init__.py +0 -0
  59. {jarvis_ai_assistant-0.1.195 → jarvis_ai_assistant-0.1.196}/src/jarvis/jarvis_platform/base.py +0 -0
  60. {jarvis_ai_assistant-0.1.195 → jarvis_ai_assistant-0.1.196}/src/jarvis/jarvis_platform/human.py +0 -0
  61. {jarvis_ai_assistant-0.1.195 → jarvis_ai_assistant-0.1.196}/src/jarvis/jarvis_platform/kimi.py +0 -0
  62. {jarvis_ai_assistant-0.1.195 → jarvis_ai_assistant-0.1.196}/src/jarvis/jarvis_platform/openai.py +0 -0
  63. {jarvis_ai_assistant-0.1.195 → jarvis_ai_assistant-0.1.196}/src/jarvis/jarvis_platform/registry.py +0 -0
  64. {jarvis_ai_assistant-0.1.195 → jarvis_ai_assistant-0.1.196}/src/jarvis/jarvis_platform/tongyi.py +0 -0
  65. {jarvis_ai_assistant-0.1.195 → jarvis_ai_assistant-0.1.196}/src/jarvis/jarvis_platform/yuanbao.py +0 -0
  66. {jarvis_ai_assistant-0.1.195 → jarvis_ai_assistant-0.1.196}/src/jarvis/jarvis_platform_manager/__init__.py +0 -0
  67. {jarvis_ai_assistant-0.1.195 → jarvis_ai_assistant-0.1.196}/src/jarvis/jarvis_platform_manager/main.py +0 -0
  68. {jarvis_ai_assistant-0.1.195 → jarvis_ai_assistant-0.1.196}/src/jarvis/jarvis_smart_shell/__init__.py +0 -0
  69. {jarvis_ai_assistant-0.1.195 → jarvis_ai_assistant-0.1.196}/src/jarvis/jarvis_smart_shell/main.py +0 -0
  70. {jarvis_ai_assistant-0.1.195 → jarvis_ai_assistant-0.1.196}/src/jarvis/jarvis_tools/__init__.py +0 -0
  71. {jarvis_ai_assistant-0.1.195 → jarvis_ai_assistant-0.1.196}/src/jarvis/jarvis_tools/ask_user.py +0 -0
  72. {jarvis_ai_assistant-0.1.195 → jarvis_ai_assistant-0.1.196}/src/jarvis/jarvis_tools/base.py +0 -0
  73. {jarvis_ai_assistant-0.1.195 → jarvis_ai_assistant-0.1.196}/src/jarvis/jarvis_tools/chdir.py +0 -0
  74. {jarvis_ai_assistant-0.1.195 → jarvis_ai_assistant-0.1.196}/src/jarvis/jarvis_tools/cli/__init__.py +0 -0
  75. {jarvis_ai_assistant-0.1.195 → jarvis_ai_assistant-0.1.196}/src/jarvis/jarvis_tools/cli/main.py +0 -0
  76. {jarvis_ai_assistant-0.1.195 → jarvis_ai_assistant-0.1.196}/src/jarvis/jarvis_tools/code_plan.py +0 -0
  77. {jarvis_ai_assistant-0.1.195 → jarvis_ai_assistant-0.1.196}/src/jarvis/jarvis_tools/create_code_agent.py +0 -0
  78. {jarvis_ai_assistant-0.1.195 → jarvis_ai_assistant-0.1.196}/src/jarvis/jarvis_tools/create_sub_agent.py +0 -0
  79. {jarvis_ai_assistant-0.1.195 → jarvis_ai_assistant-0.1.196}/src/jarvis/jarvis_tools/edit_file.py +0 -0
  80. {jarvis_ai_assistant-0.1.195 → jarvis_ai_assistant-0.1.196}/src/jarvis/jarvis_tools/execute_script.py +0 -0
  81. {jarvis_ai_assistant-0.1.195 → jarvis_ai_assistant-0.1.196}/src/jarvis/jarvis_tools/file_analyzer.py +0 -0
  82. {jarvis_ai_assistant-0.1.195 → jarvis_ai_assistant-0.1.196}/src/jarvis/jarvis_tools/file_operation.py +0 -0
  83. {jarvis_ai_assistant-0.1.195 → jarvis_ai_assistant-0.1.196}/src/jarvis/jarvis_tools/generate_new_tool.py +0 -0
  84. {jarvis_ai_assistant-0.1.195 → jarvis_ai_assistant-0.1.196}/src/jarvis/jarvis_tools/methodology.py +0 -0
  85. {jarvis_ai_assistant-0.1.195 → jarvis_ai_assistant-0.1.196}/src/jarvis/jarvis_tools/read_code.py +0 -0
  86. {jarvis_ai_assistant-0.1.195 → jarvis_ai_assistant-0.1.196}/src/jarvis/jarvis_tools/read_webpage.py +0 -0
  87. {jarvis_ai_assistant-0.1.195 → jarvis_ai_assistant-0.1.196}/src/jarvis/jarvis_tools/registry.py +0 -0
  88. {jarvis_ai_assistant-0.1.195 → jarvis_ai_assistant-0.1.196}/src/jarvis/jarvis_tools/rewrite_file.py +0 -0
  89. {jarvis_ai_assistant-0.1.195 → jarvis_ai_assistant-0.1.196}/src/jarvis/jarvis_tools/search_web.py +0 -0
  90. {jarvis_ai_assistant-0.1.195 → jarvis_ai_assistant-0.1.196}/src/jarvis/jarvis_tools/virtual_tty.py +0 -0
  91. {jarvis_ai_assistant-0.1.195 → jarvis_ai_assistant-0.1.196}/src/jarvis/jarvis_utils/__init__.py +0 -0
  92. {jarvis_ai_assistant-0.1.195 → jarvis_ai_assistant-0.1.196}/src/jarvis/jarvis_utils/builtin_replace_map.py +0 -0
  93. {jarvis_ai_assistant-0.1.195 → jarvis_ai_assistant-0.1.196}/src/jarvis/jarvis_utils/embedding.py +0 -0
  94. {jarvis_ai_assistant-0.1.195 → jarvis_ai_assistant-0.1.196}/src/jarvis/jarvis_utils/file_processors.py +0 -0
  95. {jarvis_ai_assistant-0.1.195 → jarvis_ai_assistant-0.1.196}/src/jarvis/jarvis_utils/git_utils.py +0 -0
  96. {jarvis_ai_assistant-0.1.195 → jarvis_ai_assistant-0.1.196}/src/jarvis/jarvis_utils/globals.py +0 -0
  97. {jarvis_ai_assistant-0.1.195 → jarvis_ai_assistant-0.1.196}/src/jarvis/jarvis_utils/input.py +0 -0
  98. {jarvis_ai_assistant-0.1.195 → jarvis_ai_assistant-0.1.196}/src/jarvis/jarvis_utils/methodology.py +0 -0
  99. {jarvis_ai_assistant-0.1.195 → jarvis_ai_assistant-0.1.196}/src/jarvis/jarvis_utils/output.py +0 -0
  100. {jarvis_ai_assistant-0.1.195 → jarvis_ai_assistant-0.1.196}/src/jarvis/jarvis_utils/tag.py +0 -0
  101. {jarvis_ai_assistant-0.1.195 → jarvis_ai_assistant-0.1.196}/src/jarvis/jarvis_utils/utils.py +0 -0
  102. {jarvis_ai_assistant-0.1.195 → jarvis_ai_assistant-0.1.196}/src/jarvis_ai_assistant.egg-info/SOURCES.txt +0 -0
  103. {jarvis_ai_assistant-0.1.195 → jarvis_ai_assistant-0.1.196}/src/jarvis_ai_assistant.egg-info/dependency_links.txt +0 -0
  104. {jarvis_ai_assistant-0.1.195 → jarvis_ai_assistant-0.1.196}/src/jarvis_ai_assistant.egg-info/entry_points.txt +0 -0
  105. {jarvis_ai_assistant-0.1.195 → jarvis_ai_assistant-0.1.196}/src/jarvis_ai_assistant.egg-info/requires.txt +0 -0
  106. {jarvis_ai_assistant-0.1.195 → jarvis_ai_assistant-0.1.196}/src/jarvis_ai_assistant.egg-info/top_level.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: jarvis-ai-assistant
3
- Version: 0.1.195
3
+ Version: 0.1.196
4
4
  Summary: Jarvis: An AI assistant that uses tools to interact with the system
5
5
  Home-page: https://github.com/skyfireitdiy/Jarvis
6
6
  Author: skyfire
@@ -538,6 +538,7 @@ OPENAI_API_BASE: https://api.openai.com/v1
538
538
  | `JARVIS_PRINT_PROMPT` | false | 是否打印提示 |
539
539
  | `JARVIS_USE_METHODOLOGY` | true | 是否启用方法论功能 |
540
540
  | `JARVIS_USE_ANALYSIS` | true | 是否启用任务分析功能 |
541
+ | `JARVIS_USE_HISTORY` | false | 是否启用历史记录功能 |
541
542
  | `JARVIS_DATA_PATH` | ~/.jarvis | Jarvis数据存储目录路径 |
542
543
 
543
544
  ## 🛠️ 工具说明 <a id="tools"></a>
@@ -468,6 +468,7 @@ OPENAI_API_BASE: https://api.openai.com/v1
468
468
  | `JARVIS_PRINT_PROMPT` | false | 是否打印提示 |
469
469
  | `JARVIS_USE_METHODOLOGY` | true | 是否启用方法论功能 |
470
470
  | `JARVIS_USE_ANALYSIS` | true | 是否启用任务分析功能 |
471
+ | `JARVIS_USE_HISTORY` | false | 是否启用历史记录功能 |
471
472
  | `JARVIS_DATA_PATH` | ~/.jarvis | Jarvis数据存储目录路径 |
472
473
 
473
474
  ## 🛠️ 工具说明 <a id="tools"></a>
@@ -8,7 +8,7 @@ default = true
8
8
 
9
9
  [project]
10
10
  name = "jarvis-ai-assistant"
11
- version = "0.1.195"
11
+ version = "0.1.196"
12
12
  description = "Jarvis: An AI assistant that uses tools to interact with the system"
13
13
  readme = "README.md"
14
14
  authors = [{ name = "skyfire", email = "skyfireitdiy@hotmail.com" }]
@@ -3,7 +3,7 @@ from setuptools import setup, find_packages
3
3
 
4
4
  setup(
5
5
  name="jarvis-ai-assistant",
6
- version="0.1.195",
6
+ version="0.1.196",
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",
@@ -1,4 +1,4 @@
1
1
  # -*- coding: utf-8 -*-
2
2
  """Jarvis AI Assistant"""
3
3
 
4
- __version__ = "0.1.195"
4
+ __version__ = "0.1.196"
@@ -1,6 +1,7 @@
1
1
  # -*- coding: utf-8 -*-
2
2
  # 标准库导入
3
3
  import datetime
4
+ import os
4
5
  from pathlib import Path
5
6
  import platform
6
7
  from typing import Any, Callable, Dict, List, Optional, Protocol, Tuple, Union
@@ -18,7 +19,7 @@ from jarvis.jarvis_utils.config import (get_data_dir, get_max_token_count,
18
19
  get_max_tool_call_count,
19
20
  is_auto_complete,
20
21
  is_execute_tool_confirm,
21
- is_use_analysis, is_use_methodology)
22
+ is_use_analysis, get_history_count, is_use_methodology)
22
23
  from jarvis.jarvis_utils.embedding import get_context_token_count
23
24
  from jarvis.jarvis_utils.globals import (delete_agent, get_interrupt,
24
25
  make_agent_name, set_agent,
@@ -159,6 +160,7 @@ class Agent:
159
160
  use_methodology: Optional[bool] = None,
160
161
  use_analysis: Optional[bool] = None,
161
162
  files: List[str] = [],
163
+ history_count: Optional[int] = None,
162
164
  ):
163
165
  self.files = files
164
166
  """初始化Jarvis Agent实例
@@ -238,7 +240,11 @@ class Agent:
238
240
  self.after_tool_call_cb: Optional[Callable[[Agent], None]] = None
239
241
 
240
242
  self.history = JarvisHistory()
241
- self.history.start_record(str(Path(get_data_dir())/"history"))
243
+ self.history_dir = str(Path(get_data_dir())/"history")
244
+ self.history.start_record(self.history_dir)
245
+
246
+ self.history_count = history_count if history_count is not None else get_history_count()
247
+
242
248
 
243
249
  self.execute_tool_confirm = (
244
250
  execute_tool_confirm
@@ -782,31 +788,9 @@ arguments:
782
788
  set_agent(self.name, self)
783
789
 
784
790
  while True:
791
+ history_md = ""
785
792
  if self.first:
786
- # 如果有上传文件,先上传文件
787
- if self.model and self.model.support_upload_files():
788
- if self.use_methodology:
789
- if not upload_methodology(self.model, other_files=self.files):
790
- if self.files:
791
- PrettyOutput.print("文件上传失败,将忽略文件列表", OutputType.WARNING)
792
- # 上传失败则回退到本地加载
793
- msg = self.prompt
794
- for handler in self.input_handler:
795
- msg, _ = handler(msg, self)
796
- self.prompt = f"{self.prompt}\n\n以下是历史类似问题的执行经验,可参考:\n{load_methodology(msg, self.get_tool_registry())}"
797
- elif self.files:
798
- if not self.model.upload_files(self.files):
799
- PrettyOutput.print("文件上传失败,将忽略文件列表", OutputType.WARNING)
800
- else:
801
- if self.files:
802
- PrettyOutput.print("不支持上传文件,将忽略文件列表", OutputType.WARNING)
803
- if self.use_methodology:
804
- msg = self.prompt
805
- for handler in self.input_handler:
806
- msg, _ = handler(msg, self)
807
- self.prompt = f"{self.prompt}\n\n以下是历史类似问题的执行经验,可参考:\n{load_methodology(msg, self.get_tool_registry())}"
808
-
809
- self.first = False
793
+ history_md = self._first_run()
810
794
  try:
811
795
  current_response = self._call_model(self.prompt, True)
812
796
  self.prompt = ""
@@ -849,6 +833,8 @@ arguments:
849
833
  return self._complete_task()
850
834
 
851
835
  except Exception as e:
836
+ if history_md:
837
+ os.remove(history_md)
852
838
  PrettyOutput.print(f"任务失败: {str(e)}", OutputType.ERROR)
853
839
  return f"Task failed: {str(e)}"
854
840
 
@@ -856,6 +842,41 @@ arguments:
856
842
  PrettyOutput.print(f"任务失败: {str(e)}", OutputType.ERROR)
857
843
  return f"Task failed: {str(e)}"
858
844
 
845
+ def _first_run(self):
846
+ history_md = ""
847
+ if self.history_count > 0 and self.model and self.model.support_upload_files():
848
+ import tempfile
849
+ timestamp = datetime.datetime.now().strftime("%Y%m%d_%H%M%S")
850
+ history_md = str(Path(tempfile.gettempdir())/f"{self.name}_history_{timestamp}.md")
851
+ self.history.export_history_to_markdown(tempfile.gettempdir(), history_md, max_files=self.history_count)
852
+ self.files.append(history_md)
853
+
854
+ # 如果有上传文件,先上传文件
855
+ if self.model and self.model.support_upload_files():
856
+ if self.use_methodology:
857
+ if not upload_methodology(self.model, other_files=self.files):
858
+ if self.files:
859
+ PrettyOutput.print("文件上传失败,将忽略文件列表", OutputType.WARNING)
860
+ # 上传失败则回退到本地加载
861
+ msg = self.prompt
862
+ for handler in self.input_handler:
863
+ msg, _ = handler(msg, self)
864
+ self.prompt = f"{self.prompt}\n\n以下是历史类似问题的执行经验,可参考:\n{load_methodology(msg, self.get_tool_registry())}"
865
+ elif self.files:
866
+ if not self.model.upload_files(self.files):
867
+ PrettyOutput.print("文件上传失败,将忽略文件列表", OutputType.WARNING)
868
+ else:
869
+ if self.files:
870
+ PrettyOutput.print("不支持上传文件,将忽略文件列表", OutputType.WARNING)
871
+ if self.use_methodology:
872
+ msg = self.prompt
873
+ for handler in self.input_handler:
874
+ msg, _ = handler(msg, self)
875
+ self.prompt = f"{self.prompt}\n\n以下是历史类似问题的执行经验,可参考:\n{load_methodology(msg, self.get_tool_registry())}"
876
+
877
+ self.first = False
878
+ return history_md
879
+
859
880
  def clear_history(self):
860
881
  """清空对话历史但保留系统提示
861
882
 
@@ -201,6 +201,11 @@
201
201
  "description": "是否打印提示",
202
202
  "default": false
203
203
  },
204
+ "JARVIS_USE_HISTORY_COUNT": {
205
+ "type": "number",
206
+ "description": "使用的历史记录数量",
207
+ "default": 0
208
+ },
204
209
  "JARVIS_REPLACE_MAP": {
205
210
  "type": "object",
206
211
  "description": "自定义替换映射表配置",
@@ -265,6 +265,16 @@ def is_print_prompt() -> bool:
265
265
  return GLOBAL_CONFIG_DATA.get("JARVIS_PRINT_PROMPT", False) == True
266
266
 
267
267
 
268
+ def get_history_count() -> int:
269
+ """
270
+ 获取是否启用历史记录功能。
271
+
272
+ 返回:
273
+ bool: 如果启用历史记录则返回True,默认为False
274
+ """
275
+ return GLOBAL_CONFIG_DATA.get("JARVIS_USE_HISTORY_COUNT", 0)
276
+
277
+
268
278
  def get_mcp_config() -> List[Dict[str, Any]]:
269
279
  """
270
280
  获取MCP配置列表。
@@ -0,0 +1,96 @@
1
+ import glob
2
+ import os
3
+ from datetime import datetime
4
+ from typing import Dict, List, Optional, Union
5
+
6
+ import yaml
7
+
8
+
9
+ class JarvisHistory:
10
+ def __init__(self):
11
+ self.records: List[Dict[str, str]] = []
12
+ self.current_file: Optional[str] = None
13
+
14
+ def start_record(self, data_dir: str) -> None:
15
+ """Start a new recording session with timestamped filename"""
16
+ timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
17
+ self.current_file = os.path.join(data_dir, f"history_{timestamp}.yaml")
18
+ self.records = []
19
+
20
+ def append_msg(self, role: str, msg: str) -> None:
21
+ """Append a message to current recording session"""
22
+ if not self.current_file:
23
+ raise RuntimeError("Recording not started. Call start_record first.")
24
+ self.records.append({"role": role, "message": msg})
25
+
26
+ def stop_record(self) -> None:
27
+ """Save recorded messages to YAML file"""
28
+ if not self.current_file:
29
+ raise RuntimeError("No recording session to stop.")
30
+
31
+ # Skip saving if records is empty
32
+ if not self.records:
33
+ self.current_file = None
34
+ self.records = []
35
+ return
36
+
37
+ # Ensure directory exists
38
+ os.makedirs(os.path.dirname(self.current_file), exist_ok=True)
39
+
40
+ with open(self.current_file, "w") as f:
41
+ yaml.safe_dump({"conversation": self.records}, f, allow_unicode=True)
42
+
43
+ self.current_file = None
44
+ self.records = []
45
+
46
+ @staticmethod
47
+ def export_history_to_markdown(
48
+ input_dir: str, output_file: str, max_files: Optional[int] = None
49
+ ) -> None:
50
+ """
51
+ Export all history files in the directory to a single markdown file
52
+
53
+ Args:
54
+ input_dir: Directory containing history YAML files
55
+ output_file: Path to output markdown file
56
+ max_files: Maximum number of history files to export (None for all)
57
+ """
58
+ # Find all history files in the directory
59
+ history_files = glob.glob(os.path.join(input_dir, "history_*.yaml"))
60
+
61
+ if not history_files:
62
+ raise FileNotFoundError(f"No history files found in {input_dir}")
63
+
64
+ # Sort files by modification time (newest first) and limit to max_files
65
+ history_files.sort(key=os.path.getmtime, reverse=True)
66
+ if max_files is not None:
67
+ history_files = history_files[:max_files]
68
+
69
+ # Ensure output directory exists
70
+ os.makedirs(os.path.dirname(output_file), exist_ok=True)
71
+
72
+ with open(output_file, "w", encoding="utf-8") as md_file:
73
+ md_file.write("# Jarvis Conversation History\n\n")
74
+
75
+ for history_file in sorted(history_files):
76
+ # Read YAML file
77
+ with open(history_file, "r", encoding="utf-8") as f:
78
+ data = yaml.safe_load(f)
79
+
80
+ if not data or "conversation" not in data:
81
+ continue
82
+
83
+ # Write file header with timestamp from filename
84
+ timestamp = os.path.basename(history_file)[
85
+ 8:-5
86
+ ] # Extract timestamp from "history_YYYYMMDD_HHMMSS.yaml"
87
+ md_file.write(
88
+ f"## Conversation at {timestamp[:4]}-{timestamp[4:6]}-{timestamp[6:8]} "
89
+ f"{timestamp[9:11]}:{timestamp[11:13]}:{timestamp[13:15]}\n\n"
90
+ )
91
+
92
+ # Write conversation messages
93
+ for msg in data["conversation"]:
94
+ md_file.write(f"**{msg['role']}**: {msg['message']}\n\n")
95
+
96
+ md_file.write("\n---\n\n")
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: jarvis-ai-assistant
3
- Version: 0.1.195
3
+ Version: 0.1.196
4
4
  Summary: Jarvis: An AI assistant that uses tools to interact with the system
5
5
  Home-page: https://github.com/skyfireitdiy/Jarvis
6
6
  Author: skyfire
@@ -538,6 +538,7 @@ OPENAI_API_BASE: https://api.openai.com/v1
538
538
  | `JARVIS_PRINT_PROMPT` | false | 是否打印提示 |
539
539
  | `JARVIS_USE_METHODOLOGY` | true | 是否启用方法论功能 |
540
540
  | `JARVIS_USE_ANALYSIS` | true | 是否启用任务分析功能 |
541
+ | `JARVIS_USE_HISTORY` | false | 是否启用历史记录功能 |
541
542
  | `JARVIS_DATA_PATH` | ~/.jarvis | Jarvis数据存储目录路径 |
542
543
 
543
544
  ## 🛠️ 工具说明 <a id="tools"></a>
@@ -1,43 +0,0 @@
1
- import os
2
- from datetime import datetime
3
- from typing import Dict, List, Optional
4
-
5
- import yaml
6
-
7
-
8
- class JarvisHistory:
9
- def __init__(self):
10
- self.records: List[Dict[str, str]] = []
11
- self.current_file: Optional[str] = None
12
-
13
- def start_record(self, data_dir: str) -> None:
14
- """Start a new recording session with timestamped filename"""
15
- timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
16
- self.current_file = os.path.join(data_dir, f"history_{timestamp}.yaml")
17
- self.records = []
18
-
19
- def append_msg(self, role: str, msg: str) -> None:
20
- """Append a message to current recording session"""
21
- if not self.current_file:
22
- raise RuntimeError("Recording not started. Call start_record first.")
23
- self.records.append({"role": role, "message": msg})
24
-
25
- def stop_record(self) -> None:
26
- """Save recorded messages to YAML file"""
27
- if not self.current_file:
28
- raise RuntimeError("No recording session to stop.")
29
-
30
- # Skip saving if records is empty
31
- if not self.records:
32
- self.current_file = None
33
- self.records = []
34
- return
35
-
36
- # Ensure directory exists
37
- os.makedirs(os.path.dirname(self.current_file), exist_ok=True)
38
-
39
- with open(self.current_file, "w") as f:
40
- yaml.safe_dump({"conversation": self.records}, f, allow_unicode=True)
41
-
42
- self.current_file = None
43
- self.records = []