jarvis-ai-assistant 0.1.195__tar.gz → 0.1.197__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.197}/PKG-INFO +2 -1
  2. {jarvis_ai_assistant-0.1.195 → jarvis_ai_assistant-0.1.197}/README.md +1 -0
  3. {jarvis_ai_assistant-0.1.195 → jarvis_ai_assistant-0.1.197}/pyproject.toml +1 -1
  4. {jarvis_ai_assistant-0.1.195 → jarvis_ai_assistant-0.1.197}/setup.py +1 -1
  5. {jarvis_ai_assistant-0.1.195 → jarvis_ai_assistant-0.1.197}/src/jarvis/__init__.py +1 -1
  6. {jarvis_ai_assistant-0.1.195 → jarvis_ai_assistant-0.1.197}/src/jarvis/jarvis_agent/__init__.py +73 -32
  7. {jarvis_ai_assistant-0.1.195 → jarvis_ai_assistant-0.1.197}/src/jarvis/jarvis_data/config_schema.json +5 -0
  8. {jarvis_ai_assistant-0.1.195 → jarvis_ai_assistant-0.1.197}/src/jarvis/jarvis_utils/config.py +10 -0
  9. jarvis_ai_assistant-0.1.197/src/jarvis/jarvis_utils/jarvis_history.py +98 -0
  10. {jarvis_ai_assistant-0.1.195 → jarvis_ai_assistant-0.1.197/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.197}/LICENSE +0 -0
  13. {jarvis_ai_assistant-0.1.195 → jarvis_ai_assistant-0.1.197}/MANIFEST.in +0 -0
  14. {jarvis_ai_assistant-0.1.195 → jarvis_ai_assistant-0.1.197}/setup.cfg +0 -0
  15. {jarvis_ai_assistant-0.1.195 → jarvis_ai_assistant-0.1.197}/src/jarvis/jarvis_agent/builtin_input_handler.py +0 -0
  16. {jarvis_ai_assistant-0.1.195 → jarvis_ai_assistant-0.1.197}/src/jarvis/jarvis_agent/jarvis.py +0 -0
  17. {jarvis_ai_assistant-0.1.195 → jarvis_ai_assistant-0.1.197}/src/jarvis/jarvis_agent/main.py +0 -0
  18. {jarvis_ai_assistant-0.1.195 → jarvis_ai_assistant-0.1.197}/src/jarvis/jarvis_agent/output_handler.py +0 -0
  19. {jarvis_ai_assistant-0.1.195 → jarvis_ai_assistant-0.1.197}/src/jarvis/jarvis_agent/shell_input_handler.py +0 -0
  20. {jarvis_ai_assistant-0.1.195 → jarvis_ai_assistant-0.1.197}/src/jarvis/jarvis_code_agent/__init__.py +0 -0
  21. {jarvis_ai_assistant-0.1.195 → jarvis_ai_assistant-0.1.197}/src/jarvis/jarvis_code_agent/code_agent.py +0 -0
  22. {jarvis_ai_assistant-0.1.195 → jarvis_ai_assistant-0.1.197}/src/jarvis/jarvis_code_agent/lint.py +0 -0
  23. {jarvis_ai_assistant-0.1.195 → jarvis_ai_assistant-0.1.197}/src/jarvis/jarvis_code_analysis/checklists/__init__.py +0 -0
  24. {jarvis_ai_assistant-0.1.195 → jarvis_ai_assistant-0.1.197}/src/jarvis/jarvis_code_analysis/checklists/c_cpp.py +0 -0
  25. {jarvis_ai_assistant-0.1.195 → jarvis_ai_assistant-0.1.197}/src/jarvis/jarvis_code_analysis/checklists/csharp.py +0 -0
  26. {jarvis_ai_assistant-0.1.195 → jarvis_ai_assistant-0.1.197}/src/jarvis/jarvis_code_analysis/checklists/data_format.py +0 -0
  27. {jarvis_ai_assistant-0.1.195 → jarvis_ai_assistant-0.1.197}/src/jarvis/jarvis_code_analysis/checklists/devops.py +0 -0
  28. {jarvis_ai_assistant-0.1.195 → jarvis_ai_assistant-0.1.197}/src/jarvis/jarvis_code_analysis/checklists/docs.py +0 -0
  29. {jarvis_ai_assistant-0.1.195 → jarvis_ai_assistant-0.1.197}/src/jarvis/jarvis_code_analysis/checklists/go.py +0 -0
  30. {jarvis_ai_assistant-0.1.195 → jarvis_ai_assistant-0.1.197}/src/jarvis/jarvis_code_analysis/checklists/infrastructure.py +0 -0
  31. {jarvis_ai_assistant-0.1.195 → jarvis_ai_assistant-0.1.197}/src/jarvis/jarvis_code_analysis/checklists/java.py +0 -0
  32. {jarvis_ai_assistant-0.1.195 → jarvis_ai_assistant-0.1.197}/src/jarvis/jarvis_code_analysis/checklists/javascript.py +0 -0
  33. {jarvis_ai_assistant-0.1.195 → jarvis_ai_assistant-0.1.197}/src/jarvis/jarvis_code_analysis/checklists/kotlin.py +0 -0
  34. {jarvis_ai_assistant-0.1.195 → jarvis_ai_assistant-0.1.197}/src/jarvis/jarvis_code_analysis/checklists/loader.py +0 -0
  35. {jarvis_ai_assistant-0.1.195 → jarvis_ai_assistant-0.1.197}/src/jarvis/jarvis_code_analysis/checklists/php.py +0 -0
  36. {jarvis_ai_assistant-0.1.195 → jarvis_ai_assistant-0.1.197}/src/jarvis/jarvis_code_analysis/checklists/python.py +0 -0
  37. {jarvis_ai_assistant-0.1.195 → jarvis_ai_assistant-0.1.197}/src/jarvis/jarvis_code_analysis/checklists/ruby.py +0 -0
  38. {jarvis_ai_assistant-0.1.195 → jarvis_ai_assistant-0.1.197}/src/jarvis/jarvis_code_analysis/checklists/rust.py +0 -0
  39. {jarvis_ai_assistant-0.1.195 → jarvis_ai_assistant-0.1.197}/src/jarvis/jarvis_code_analysis/checklists/shell.py +0 -0
  40. {jarvis_ai_assistant-0.1.195 → jarvis_ai_assistant-0.1.197}/src/jarvis/jarvis_code_analysis/checklists/sql.py +0 -0
  41. {jarvis_ai_assistant-0.1.195 → jarvis_ai_assistant-0.1.197}/src/jarvis/jarvis_code_analysis/checklists/swift.py +0 -0
  42. {jarvis_ai_assistant-0.1.195 → jarvis_ai_assistant-0.1.197}/src/jarvis/jarvis_code_analysis/checklists/web.py +0 -0
  43. {jarvis_ai_assistant-0.1.195 → jarvis_ai_assistant-0.1.197}/src/jarvis/jarvis_code_analysis/code_review.py +0 -0
  44. {jarvis_ai_assistant-0.1.195 → jarvis_ai_assistant-0.1.197}/src/jarvis/jarvis_data/huggingface.tar.gz +0 -0
  45. {jarvis_ai_assistant-0.1.195 → jarvis_ai_assistant-0.1.197}/src/jarvis/jarvis_dev/main.py +0 -0
  46. {jarvis_ai_assistant-0.1.195 → jarvis_ai_assistant-0.1.197}/src/jarvis/jarvis_git_details/__init__.py +0 -0
  47. {jarvis_ai_assistant-0.1.195 → jarvis_ai_assistant-0.1.197}/src/jarvis/jarvis_git_details/main.py +0 -0
  48. {jarvis_ai_assistant-0.1.195 → jarvis_ai_assistant-0.1.197}/src/jarvis/jarvis_git_squash/__init__.py +0 -0
  49. {jarvis_ai_assistant-0.1.195 → jarvis_ai_assistant-0.1.197}/src/jarvis/jarvis_git_squash/main.py +0 -0
  50. {jarvis_ai_assistant-0.1.195 → jarvis_ai_assistant-0.1.197}/src/jarvis/jarvis_git_utils/git_commiter.py +0 -0
  51. {jarvis_ai_assistant-0.1.195 → jarvis_ai_assistant-0.1.197}/src/jarvis/jarvis_mcp/__init__.py +0 -0
  52. {jarvis_ai_assistant-0.1.195 → jarvis_ai_assistant-0.1.197}/src/jarvis/jarvis_mcp/sse_mcp_client.py +0 -0
  53. {jarvis_ai_assistant-0.1.195 → jarvis_ai_assistant-0.1.197}/src/jarvis/jarvis_mcp/stdio_mcp_client.py +0 -0
  54. {jarvis_ai_assistant-0.1.195 → jarvis_ai_assistant-0.1.197}/src/jarvis/jarvis_mcp/streamable_mcp_client.py +0 -0
  55. {jarvis_ai_assistant-0.1.195 → jarvis_ai_assistant-0.1.197}/src/jarvis/jarvis_methodology/main.py +0 -0
  56. {jarvis_ai_assistant-0.1.195 → jarvis_ai_assistant-0.1.197}/src/jarvis/jarvis_multi_agent/__init__.py +0 -0
  57. {jarvis_ai_assistant-0.1.195 → jarvis_ai_assistant-0.1.197}/src/jarvis/jarvis_multi_agent/main.py +0 -0
  58. {jarvis_ai_assistant-0.1.195 → jarvis_ai_assistant-0.1.197}/src/jarvis/jarvis_platform/__init__.py +0 -0
  59. {jarvis_ai_assistant-0.1.195 → jarvis_ai_assistant-0.1.197}/src/jarvis/jarvis_platform/base.py +0 -0
  60. {jarvis_ai_assistant-0.1.195 → jarvis_ai_assistant-0.1.197}/src/jarvis/jarvis_platform/human.py +0 -0
  61. {jarvis_ai_assistant-0.1.195 → jarvis_ai_assistant-0.1.197}/src/jarvis/jarvis_platform/kimi.py +0 -0
  62. {jarvis_ai_assistant-0.1.195 → jarvis_ai_assistant-0.1.197}/src/jarvis/jarvis_platform/openai.py +0 -0
  63. {jarvis_ai_assistant-0.1.195 → jarvis_ai_assistant-0.1.197}/src/jarvis/jarvis_platform/registry.py +0 -0
  64. {jarvis_ai_assistant-0.1.195 → jarvis_ai_assistant-0.1.197}/src/jarvis/jarvis_platform/tongyi.py +0 -0
  65. {jarvis_ai_assistant-0.1.195 → jarvis_ai_assistant-0.1.197}/src/jarvis/jarvis_platform/yuanbao.py +0 -0
  66. {jarvis_ai_assistant-0.1.195 → jarvis_ai_assistant-0.1.197}/src/jarvis/jarvis_platform_manager/__init__.py +0 -0
  67. {jarvis_ai_assistant-0.1.195 → jarvis_ai_assistant-0.1.197}/src/jarvis/jarvis_platform_manager/main.py +0 -0
  68. {jarvis_ai_assistant-0.1.195 → jarvis_ai_assistant-0.1.197}/src/jarvis/jarvis_smart_shell/__init__.py +0 -0
  69. {jarvis_ai_assistant-0.1.195 → jarvis_ai_assistant-0.1.197}/src/jarvis/jarvis_smart_shell/main.py +0 -0
  70. {jarvis_ai_assistant-0.1.195 → jarvis_ai_assistant-0.1.197}/src/jarvis/jarvis_tools/__init__.py +0 -0
  71. {jarvis_ai_assistant-0.1.195 → jarvis_ai_assistant-0.1.197}/src/jarvis/jarvis_tools/ask_user.py +0 -0
  72. {jarvis_ai_assistant-0.1.195 → jarvis_ai_assistant-0.1.197}/src/jarvis/jarvis_tools/base.py +0 -0
  73. {jarvis_ai_assistant-0.1.195 → jarvis_ai_assistant-0.1.197}/src/jarvis/jarvis_tools/chdir.py +0 -0
  74. {jarvis_ai_assistant-0.1.195 → jarvis_ai_assistant-0.1.197}/src/jarvis/jarvis_tools/cli/__init__.py +0 -0
  75. {jarvis_ai_assistant-0.1.195 → jarvis_ai_assistant-0.1.197}/src/jarvis/jarvis_tools/cli/main.py +0 -0
  76. {jarvis_ai_assistant-0.1.195 → jarvis_ai_assistant-0.1.197}/src/jarvis/jarvis_tools/code_plan.py +0 -0
  77. {jarvis_ai_assistant-0.1.195 → jarvis_ai_assistant-0.1.197}/src/jarvis/jarvis_tools/create_code_agent.py +0 -0
  78. {jarvis_ai_assistant-0.1.195 → jarvis_ai_assistant-0.1.197}/src/jarvis/jarvis_tools/create_sub_agent.py +0 -0
  79. {jarvis_ai_assistant-0.1.195 → jarvis_ai_assistant-0.1.197}/src/jarvis/jarvis_tools/edit_file.py +0 -0
  80. {jarvis_ai_assistant-0.1.195 → jarvis_ai_assistant-0.1.197}/src/jarvis/jarvis_tools/execute_script.py +0 -0
  81. {jarvis_ai_assistant-0.1.195 → jarvis_ai_assistant-0.1.197}/src/jarvis/jarvis_tools/file_analyzer.py +0 -0
  82. {jarvis_ai_assistant-0.1.195 → jarvis_ai_assistant-0.1.197}/src/jarvis/jarvis_tools/file_operation.py +0 -0
  83. {jarvis_ai_assistant-0.1.195 → jarvis_ai_assistant-0.1.197}/src/jarvis/jarvis_tools/generate_new_tool.py +0 -0
  84. {jarvis_ai_assistant-0.1.195 → jarvis_ai_assistant-0.1.197}/src/jarvis/jarvis_tools/methodology.py +0 -0
  85. {jarvis_ai_assistant-0.1.195 → jarvis_ai_assistant-0.1.197}/src/jarvis/jarvis_tools/read_code.py +0 -0
  86. {jarvis_ai_assistant-0.1.195 → jarvis_ai_assistant-0.1.197}/src/jarvis/jarvis_tools/read_webpage.py +0 -0
  87. {jarvis_ai_assistant-0.1.195 → jarvis_ai_assistant-0.1.197}/src/jarvis/jarvis_tools/registry.py +0 -0
  88. {jarvis_ai_assistant-0.1.195 → jarvis_ai_assistant-0.1.197}/src/jarvis/jarvis_tools/rewrite_file.py +0 -0
  89. {jarvis_ai_assistant-0.1.195 → jarvis_ai_assistant-0.1.197}/src/jarvis/jarvis_tools/search_web.py +0 -0
  90. {jarvis_ai_assistant-0.1.195 → jarvis_ai_assistant-0.1.197}/src/jarvis/jarvis_tools/virtual_tty.py +0 -0
  91. {jarvis_ai_assistant-0.1.195 → jarvis_ai_assistant-0.1.197}/src/jarvis/jarvis_utils/__init__.py +0 -0
  92. {jarvis_ai_assistant-0.1.195 → jarvis_ai_assistant-0.1.197}/src/jarvis/jarvis_utils/builtin_replace_map.py +0 -0
  93. {jarvis_ai_assistant-0.1.195 → jarvis_ai_assistant-0.1.197}/src/jarvis/jarvis_utils/embedding.py +0 -0
  94. {jarvis_ai_assistant-0.1.195 → jarvis_ai_assistant-0.1.197}/src/jarvis/jarvis_utils/file_processors.py +0 -0
  95. {jarvis_ai_assistant-0.1.195 → jarvis_ai_assistant-0.1.197}/src/jarvis/jarvis_utils/git_utils.py +0 -0
  96. {jarvis_ai_assistant-0.1.195 → jarvis_ai_assistant-0.1.197}/src/jarvis/jarvis_utils/globals.py +0 -0
  97. {jarvis_ai_assistant-0.1.195 → jarvis_ai_assistant-0.1.197}/src/jarvis/jarvis_utils/input.py +0 -0
  98. {jarvis_ai_assistant-0.1.195 → jarvis_ai_assistant-0.1.197}/src/jarvis/jarvis_utils/methodology.py +0 -0
  99. {jarvis_ai_assistant-0.1.195 → jarvis_ai_assistant-0.1.197}/src/jarvis/jarvis_utils/output.py +0 -0
  100. {jarvis_ai_assistant-0.1.195 → jarvis_ai_assistant-0.1.197}/src/jarvis/jarvis_utils/tag.py +0 -0
  101. {jarvis_ai_assistant-0.1.195 → jarvis_ai_assistant-0.1.197}/src/jarvis/jarvis_utils/utils.py +0 -0
  102. {jarvis_ai_assistant-0.1.195 → jarvis_ai_assistant-0.1.197}/src/jarvis_ai_assistant.egg-info/SOURCES.txt +0 -0
  103. {jarvis_ai_assistant-0.1.195 → jarvis_ai_assistant-0.1.197}/src/jarvis_ai_assistant.egg-info/dependency_links.txt +0 -0
  104. {jarvis_ai_assistant-0.1.195 → jarvis_ai_assistant-0.1.197}/src/jarvis_ai_assistant.egg-info/entry_points.txt +0 -0
  105. {jarvis_ai_assistant-0.1.195 → jarvis_ai_assistant-0.1.197}/src/jarvis_ai_assistant.egg-info/requires.txt +0 -0
  106. {jarvis_ai_assistant-0.1.195 → jarvis_ai_assistant-0.1.197}/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.197
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_COUNT` | 0 | 使用N次历史记录作为上下文记忆 |
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_COUNT` | 0 | 使用N次历史记录作为上下文记忆 |
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.197"
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.197",
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.197"
@@ -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
@@ -467,13 +473,25 @@ class Agent:
467
473
  注意:
468
474
  当上下文长度超过最大值时使用
469
475
  """
470
- summary = self.generate_summary()
471
- self.clear_history() # type: ignore
476
+ need_summary = True
477
+ tmp_file_name = ""
478
+ try:
479
+ if self.model and self.model.support_upload_files():
480
+ need_summary = False
481
+ if need_summary:
482
+ summary = self.generate_summary()
483
+ else:
484
+ import tempfile
485
+ tmp_file = tempfile.NamedTemporaryFile(delete=False)
486
+ tmp_file_name = tmp_file.name
487
+ self.history.save_history(tmp_file_name)
488
+ self.clear_history() # type: ignore
472
489
 
473
- if not summary:
474
- return ""
490
+ if need_summary:
491
+ if not summary:
492
+ return ""
475
493
 
476
- return f"""
494
+ return f"""
477
495
  以下是之前对话的关键信息总结:
478
496
 
479
497
  <content>
@@ -481,7 +499,15 @@ class Agent:
481
499
  </content>
482
500
 
483
501
  请基于以上信息继续完成任务。请注意,这是之前对话的摘要,上下文长度已超过限制而被重置。请直接继续任务,无需重复已完成的步骤。如有需要,可以询问用户以获取更多信息。
484
- """
502
+ """
503
+ else:
504
+ if self.model and self.model.upload_files([tmp_file_name]):
505
+ return "上传的文件是历史对话信息,请基于历史对话信息继续完成任务。"
506
+ else:
507
+ return ""
508
+ finally:
509
+ if tmp_file_name:
510
+ os.remove(tmp_file_name)
485
511
 
486
512
  def _call_tools(self, response: str) -> Tuple[bool, Any]:
487
513
  """调用工具执行响应
@@ -782,31 +808,9 @@ arguments:
782
808
  set_agent(self.name, self)
783
809
 
784
810
  while True:
811
+ history_md = ""
785
812
  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
813
+ history_md = self._first_run()
810
814
  try:
811
815
  current_response = self._call_model(self.prompt, True)
812
816
  self.prompt = ""
@@ -849,6 +853,8 @@ arguments:
849
853
  return self._complete_task()
850
854
 
851
855
  except Exception as e:
856
+ if history_md:
857
+ os.remove(history_md)
852
858
  PrettyOutput.print(f"任务失败: {str(e)}", OutputType.ERROR)
853
859
  return f"Task failed: {str(e)}"
854
860
 
@@ -856,6 +862,41 @@ arguments:
856
862
  PrettyOutput.print(f"任务失败: {str(e)}", OutputType.ERROR)
857
863
  return f"Task failed: {str(e)}"
858
864
 
865
+ def _first_run(self):
866
+ history_md = ""
867
+ if self.history_count > 0 and self.model and self.model.support_upload_files():
868
+ import tempfile
869
+ timestamp = datetime.datetime.now().strftime("%Y%m%d_%H%M%S")
870
+ history_md = str(Path(tempfile.gettempdir())/f"{self.name}_history_{timestamp}.md")
871
+ self.history.export_history_to_markdown(tempfile.gettempdir(), history_md, max_files=self.history_count)
872
+ self.files.append(history_md)
873
+
874
+ # 如果有上传文件,先上传文件
875
+ if self.model and self.model.support_upload_files():
876
+ if self.use_methodology:
877
+ if not upload_methodology(self.model, other_files=self.files):
878
+ if self.files:
879
+ PrettyOutput.print("文件上传失败,将忽略文件列表", OutputType.WARNING)
880
+ # 上传失败则回退到本地加载
881
+ msg = self.prompt
882
+ for handler in self.input_handler:
883
+ msg, _ = handler(msg, self)
884
+ self.prompt = f"{self.prompt}\n\n以下是历史类似问题的执行经验,可参考:\n{load_methodology(msg, self.get_tool_registry())}"
885
+ elif self.files:
886
+ if not self.model.upload_files(self.files):
887
+ PrettyOutput.print("文件上传失败,将忽略文件列表", OutputType.WARNING)
888
+ else:
889
+ if self.files:
890
+ PrettyOutput.print("不支持上传文件,将忽略文件列表", OutputType.WARNING)
891
+ if self.use_methodology:
892
+ msg = self.prompt
893
+ for handler in self.input_handler:
894
+ msg, _ = handler(msg, self)
895
+ self.prompt = f"{self.prompt}\n\n以下是历史类似问题的执行经验,可参考:\n{load_methodology(msg, self.get_tool_registry())}"
896
+
897
+ self.first = False
898
+ return history_md
899
+
859
900
  def clear_history(self):
860
901
  """清空对话历史但保留系统提示
861
902
 
@@ -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,98 @@
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 save_history(self, filename: str) -> None:
27
+ """Save recorded messages to YAML file"""
28
+
29
+ # Skip saving if records is empty
30
+ if not self.records:
31
+ return
32
+
33
+ # Ensure directory exists
34
+ os.makedirs(os.path.dirname(filename), exist_ok=True)
35
+
36
+ with open(filename, "w") as f:
37
+ yaml.safe_dump({"conversation": self.records}, f, allow_unicode=True)
38
+
39
+ def stop_record(self) -> None:
40
+ """Stop recording session and save messages"""
41
+ if not self.current_file:
42
+ raise RuntimeError("No recording session to stop.")
43
+
44
+ self.save_history(self.current_file)
45
+ self.current_file = None
46
+ self.records = []
47
+
48
+ @staticmethod
49
+ def export_history_to_markdown(
50
+ input_dir: str, output_file: str, max_files: Optional[int] = None
51
+ ) -> None:
52
+ """
53
+ Export all history files in the directory to a single markdown file
54
+
55
+ Args:
56
+ input_dir: Directory containing history YAML files
57
+ output_file: Path to output markdown file
58
+ max_files: Maximum number of history files to export (None for all)
59
+ """
60
+ # Find all history files in the directory
61
+ history_files = glob.glob(os.path.join(input_dir, "history_*.yaml"))
62
+
63
+ if not history_files:
64
+ raise FileNotFoundError(f"No history files found in {input_dir}")
65
+
66
+ # Sort files by modification time (newest first) and limit to max_files
67
+ history_files.sort(key=os.path.getmtime, reverse=True)
68
+ if max_files is not None:
69
+ history_files = history_files[:max_files]
70
+
71
+ # Ensure output directory exists
72
+ os.makedirs(os.path.dirname(output_file), exist_ok=True)
73
+
74
+ with open(output_file, "w", encoding="utf-8") as md_file:
75
+ md_file.write("# Jarvis Conversation History\n\n")
76
+
77
+ for history_file in sorted(history_files):
78
+ # Read YAML file
79
+ with open(history_file, "r", encoding="utf-8") as f:
80
+ data = yaml.safe_load(f)
81
+
82
+ if not data or "conversation" not in data:
83
+ continue
84
+
85
+ # Write file header with timestamp from filename
86
+ timestamp = os.path.basename(history_file)[
87
+ 8:-5
88
+ ] # Extract timestamp from "history_YYYYMMDD_HHMMSS.yaml"
89
+ md_file.write(
90
+ f"## Conversation at {timestamp[:4]}-{timestamp[4:6]}-{timestamp[6:8]} "
91
+ f"{timestamp[9:11]}:{timestamp[11:13]}:{timestamp[13:15]}\n\n"
92
+ )
93
+
94
+ # Write conversation messages
95
+ for msg in data["conversation"]:
96
+ md_file.write(f"**{msg['role']}**: {msg['message']}\n\n")
97
+
98
+ 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.197
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_COUNT` | 0 | 使用N次历史记录作为上下文记忆 |
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 = []