jarvis-ai-assistant 0.1.78__tar.gz → 0.1.79__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.

Potentially problematic release.


This version of jarvis-ai-assistant might be problematic. Click here for more details.

Files changed (44) hide show
  1. {jarvis_ai_assistant-0.1.78/src/jarvis_ai_assistant.egg-info → jarvis_ai_assistant-0.1.79}/PKG-INFO +1 -1
  2. {jarvis_ai_assistant-0.1.78 → jarvis_ai_assistant-0.1.79}/pyproject.toml +1 -1
  3. {jarvis_ai_assistant-0.1.78 → jarvis_ai_assistant-0.1.79}/setup.py +1 -1
  4. {jarvis_ai_assistant-0.1.78 → jarvis_ai_assistant-0.1.79}/src/jarvis/__init__.py +1 -1
  5. {jarvis_ai_assistant-0.1.78 → jarvis_ai_assistant-0.1.79}/src/jarvis/agent.py +15 -13
  6. {jarvis_ai_assistant-0.1.78 → jarvis_ai_assistant-0.1.79}/src/jarvis/rag/main.py +3 -2
  7. jarvis_ai_assistant-0.1.79/src/jarvis/tools/ask_user.py +67 -0
  8. jarvis_ai_assistant-0.1.79/src/jarvis/tools/chdir.py +89 -0
  9. {jarvis_ai_assistant-0.1.78 → jarvis_ai_assistant-0.1.79}/src/jarvis/tools/registry.py +41 -1
  10. {jarvis_ai_assistant-0.1.78 → jarvis_ai_assistant-0.1.79/src/jarvis_ai_assistant.egg-info}/PKG-INFO +1 -1
  11. {jarvis_ai_assistant-0.1.78 → jarvis_ai_assistant-0.1.79}/src/jarvis_ai_assistant.egg-info/SOURCES.txt +2 -0
  12. {jarvis_ai_assistant-0.1.78 → jarvis_ai_assistant-0.1.79}/LICENSE +0 -0
  13. {jarvis_ai_assistant-0.1.78 → jarvis_ai_assistant-0.1.79}/MANIFEST.in +0 -0
  14. {jarvis_ai_assistant-0.1.78 → jarvis_ai_assistant-0.1.79}/README.md +0 -0
  15. {jarvis_ai_assistant-0.1.78 → jarvis_ai_assistant-0.1.79}/setup.cfg +0 -0
  16. {jarvis_ai_assistant-0.1.78 → jarvis_ai_assistant-0.1.79}/src/jarvis/jarvis_codebase/__init__.py +0 -0
  17. {jarvis_ai_assistant-0.1.78 → jarvis_ai_assistant-0.1.79}/src/jarvis/jarvis_codebase/main.py +0 -0
  18. {jarvis_ai_assistant-0.1.78 → jarvis_ai_assistant-0.1.79}/src/jarvis/jarvis_coder/__init__.py +0 -0
  19. {jarvis_ai_assistant-0.1.78 → jarvis_ai_assistant-0.1.79}/src/jarvis/jarvis_coder/main.py +0 -0
  20. {jarvis_ai_assistant-0.1.78 → jarvis_ai_assistant-0.1.79}/src/jarvis/main.py +0 -0
  21. {jarvis_ai_assistant-0.1.78 → jarvis_ai_assistant-0.1.79}/src/jarvis/models/__init__.py +0 -0
  22. {jarvis_ai_assistant-0.1.78 → jarvis_ai_assistant-0.1.79}/src/jarvis/models/ai8.py +0 -0
  23. {jarvis_ai_assistant-0.1.78 → jarvis_ai_assistant-0.1.79}/src/jarvis/models/base.py +0 -0
  24. {jarvis_ai_assistant-0.1.78 → jarvis_ai_assistant-0.1.79}/src/jarvis/models/kimi.py +0 -0
  25. {jarvis_ai_assistant-0.1.78 → jarvis_ai_assistant-0.1.79}/src/jarvis/models/openai.py +0 -0
  26. {jarvis_ai_assistant-0.1.78 → jarvis_ai_assistant-0.1.79}/src/jarvis/models/oyi.py +0 -0
  27. {jarvis_ai_assistant-0.1.78 → jarvis_ai_assistant-0.1.79}/src/jarvis/models/registry.py +0 -0
  28. {jarvis_ai_assistant-0.1.78 → jarvis_ai_assistant-0.1.79}/src/jarvis/rag/__init__.py +0 -0
  29. {jarvis_ai_assistant-0.1.78 → jarvis_ai_assistant-0.1.79}/src/jarvis/tools/__init__.py +0 -0
  30. {jarvis_ai_assistant-0.1.78 → jarvis_ai_assistant-0.1.79}/src/jarvis/tools/base.py +0 -0
  31. {jarvis_ai_assistant-0.1.78 → jarvis_ai_assistant-0.1.79}/src/jarvis/tools/codebase_qa.py +0 -0
  32. {jarvis_ai_assistant-0.1.78 → jarvis_ai_assistant-0.1.79}/src/jarvis/tools/coder.py +0 -0
  33. {jarvis_ai_assistant-0.1.78 → jarvis_ai_assistant-0.1.79}/src/jarvis/tools/file_ops.py +0 -0
  34. {jarvis_ai_assistant-0.1.78 → jarvis_ai_assistant-0.1.79}/src/jarvis/tools/generator.py +0 -0
  35. {jarvis_ai_assistant-0.1.78 → jarvis_ai_assistant-0.1.79}/src/jarvis/tools/methodology.py +0 -0
  36. {jarvis_ai_assistant-0.1.78 → jarvis_ai_assistant-0.1.79}/src/jarvis/tools/search.py +0 -0
  37. {jarvis_ai_assistant-0.1.78 → jarvis_ai_assistant-0.1.79}/src/jarvis/tools/shell.py +0 -0
  38. {jarvis_ai_assistant-0.1.78 → jarvis_ai_assistant-0.1.79}/src/jarvis/tools/sub_agent.py +0 -0
  39. {jarvis_ai_assistant-0.1.78 → jarvis_ai_assistant-0.1.79}/src/jarvis/tools/webpage.py +0 -0
  40. {jarvis_ai_assistant-0.1.78 → jarvis_ai_assistant-0.1.79}/src/jarvis/utils.py +0 -0
  41. {jarvis_ai_assistant-0.1.78 → jarvis_ai_assistant-0.1.79}/src/jarvis_ai_assistant.egg-info/dependency_links.txt +0 -0
  42. {jarvis_ai_assistant-0.1.78 → jarvis_ai_assistant-0.1.79}/src/jarvis_ai_assistant.egg-info/entry_points.txt +0 -0
  43. {jarvis_ai_assistant-0.1.78 → jarvis_ai_assistant-0.1.79}/src/jarvis_ai_assistant.egg-info/requires.txt +0 -0
  44. {jarvis_ai_assistant-0.1.78 → jarvis_ai_assistant-0.1.79}/src/jarvis_ai_assistant.egg-info/top_level.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: jarvis-ai-assistant
3
- Version: 0.1.78
3
+ Version: 0.1.79
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
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "jarvis-ai-assistant"
7
- version = "0.1.78"
7
+ version = "0.1.79"
8
8
  description = "Jarvis: An AI assistant that uses tools to interact with the system"
9
9
  readme = "README.md"
10
10
  authors = [{ name = "Your Name", email = "your.email@example.com" }]
@@ -2,7 +2,7 @@ from setuptools import setup, find_packages
2
2
 
3
3
  setup(
4
4
  name="jarvis-ai-assistant",
5
- version="0.1.78",
5
+ version="0.1.79",
6
6
  author="skyfire",
7
7
  author_email="skyfireitdiy@hotmail.com",
8
8
  description="An AI assistant that uses various tools to interact with the system",
@@ -1,3 +1,3 @@
1
1
  """Jarvis AI Assistant"""
2
2
 
3
- __version__ = "0.1.78"
3
+ __version__ = "0.1.79"
@@ -29,10 +29,11 @@ class Agent:
29
29
  self.name = name
30
30
  self.is_sub_agent = is_sub_agent
31
31
  self.prompt = ""
32
- self.conversation_turns = 0
32
+ self.conversation_length = 0 # 改用长度计数器
33
33
 
34
- # 从环境变量加载嵌入模型配置
34
+ # 从环境变量加载配置
35
35
  self.embedding_dimension = 1536 # Default for many embedding models
36
+ self.max_context_length = int(os.getenv('JARVIS_MAX_CONTEXT_LENGTH', '30720')) # 默认30k
36
37
 
37
38
  # 初始化嵌入模型
38
39
  try:
@@ -222,6 +223,7 @@ class Agent:
222
223
 
223
224
  # 清空当前对话历史,但保留系统消息
224
225
  self.model.delete_chat()
226
+ self.conversation_length = 0 # 重置对话长度
225
227
 
226
228
  # 添加总结作为新的上下文
227
229
  self.prompt = f"""以下是之前对话的关键信息总结:
@@ -230,9 +232,7 @@ class Agent:
230
232
 
231
233
  请基于以上信息继续完成任务。
232
234
  """
233
-
234
- # 重置对话轮数
235
- self.conversation_turns = 0
235
+ self.conversation_length = len(self.prompt) # 设置新的起始长度
236
236
 
237
237
  except Exception as e:
238
238
  PrettyOutput.print(f"总结对话历史失败: {str(e)}", OutputType.ERROR)
@@ -318,6 +318,7 @@ class Agent:
318
318
  tools_prompt = ""
319
319
 
320
320
  # 选择工具
321
+ PrettyOutput.section("选择工具", OutputType.PLANNING)
321
322
  tools = self.tool_registry.get_all_tools()
322
323
  if tools:
323
324
  tools_prompt += "可用工具:\n"
@@ -330,8 +331,7 @@ class Agent:
330
331
  # 显示任务开始
331
332
  PrettyOutput.section(f"开始新任务: {self.name}", OutputType.PLANNING)
332
333
 
333
- self.clear_history()
334
- self.conversation_turns = 0
334
+ self.clear_history()
335
335
 
336
336
  self.model.set_system_message(f"""你是 {self.name},一个问题处理能力强大的 AI 助手。
337
337
 
@@ -400,14 +400,15 @@ arguments:
400
400
  # 显示思考状态
401
401
  PrettyOutput.print("分析任务...", OutputType.PROGRESS)
402
402
 
403
- # 增加对话轮次
404
- self.conversation_turns += 1
403
+ # 累加对话长度
404
+ self.conversation_length += len(self.prompt)
405
405
 
406
- # 如果对话超过10轮,在提示中添加提醒
407
- if self.conversation_turns > 10:
408
- self.prompt = f"{self.prompt}\n(提示:当前对话已超过10轮,建议使用 !<<SUMMARIZE>>! 指令总结对话历史,避免token超限)"
406
+ # 如果对话历史长度超过限制,在提示中添加提醒
407
+ if self.conversation_length > self.max_context_length:
408
+ self.prompt = f"{self.prompt}\n(提示:当前对话历史长度已超过{self.max_context_length}字符,建议使用 !<<SUMMARIZE>>! 指令总结对话历史,避免token超限)"
409
409
 
410
410
  current_response = self._call_model(self.prompt)
411
+ self.conversation_length += len(current_response) # 添加响应长度
411
412
 
412
413
  # 检查是否需要总结对话历史
413
414
  if "!<<SUMMARIZE>>!" in current_response:
@@ -462,6 +463,7 @@ arguments:
462
463
  """清除对话历史,只保留系统提示"""
463
464
  self.prompt = ""
464
465
  self.model.reset()
465
- self.conversation_turns = 0 # 重置对话轮次
466
+ self.conversation_length = 0 # 重置对话长度
467
+
466
468
 
467
469
 
@@ -373,7 +373,7 @@ class RAGTool:
373
373
  for file in files:
374
374
  file_path = os.path.join(root, file)
375
375
  # 跳过大文件
376
- if os.path.getsize(file_path) > 10 * 1024 * 1024: # 10MB
376
+ if os.path.getsize(file_path) > 100 * 1024 * 1024: # 100MB
377
377
  PrettyOutput.print(f"跳过大文件: {file_path}",
378
378
  output_type=OutputType.WARNING)
379
379
  continue
@@ -412,7 +412,8 @@ class RAGTool:
412
412
  文档和相似度得分的列表
413
413
  """
414
414
  if not self.index:
415
- raise ValueError("索引未构建,请先调用build_index()")
415
+ PrettyOutput.print("索引未构建,正在构建...", output_type=OutputType.INFO)
416
+ self.build_index(self.root_dir)
416
417
 
417
418
  # 获取查询的向量表示
418
419
  query_vector = self._get_embedding(query)
@@ -0,0 +1,67 @@
1
+ from typing import Dict, Any
2
+ from jarvis.tools.base import Tool
3
+ from jarvis.utils import get_multiline_input, PrettyOutput, OutputType
4
+
5
+ class AskUserTool(Tool):
6
+ def __init__(self):
7
+ super().__init__(
8
+ name="ask_user",
9
+ description="""当缺少完成任务的信息或有关键决策信息缺失时,询问用户。
10
+ 用户可以输入多行文本,空行结束输入。
11
+
12
+ 使用场景:
13
+ 1. 需要用户提供更多信息来完成任务
14
+ 2. 需要用户做出关键决策
15
+ 3. 需要用户确认某些重要操作
16
+ 4. 需要用户提供额外信息
17
+
18
+ 参数说明:
19
+ - question: 要询问用户的问题,应该清晰明确""",
20
+ parameters={
21
+ "type": "object",
22
+ "properties": {
23
+ "question": {
24
+ "type": "string",
25
+ "description": "要询问用户的问题"
26
+ }
27
+ },
28
+ "required": ["question"]
29
+ }
30
+ )
31
+
32
+ def execute(self, args: Dict[str, Any]) -> Dict[str, Any]:
33
+ """执行询问用户操作
34
+
35
+ Args:
36
+ args: 包含问题的字典
37
+
38
+ Returns:
39
+ Dict: 包含用户响应的字典
40
+ """
41
+ try:
42
+ question = args["question"]
43
+
44
+ # 显示问题
45
+ PrettyOutput.print("\n问题:", OutputType.QUESTION)
46
+ PrettyOutput.print(question, OutputType.QUESTION)
47
+
48
+ # 获取用户输入
49
+ PrettyOutput.print("\n请输入您的回答(输入空行结束):", OutputType.INPUT)
50
+ user_response = get_multiline_input()
51
+
52
+ if user_response == "__interrupt__":
53
+ return {
54
+ "success": False,
55
+ "error": "用户取消了输入"
56
+ }
57
+
58
+ return {
59
+ "success": True,
60
+ "stdout": user_response
61
+ }
62
+
63
+ except Exception as e:
64
+ return {
65
+ "success": False,
66
+ "error": f"询问用户失败: {str(e)}"
67
+ }
@@ -0,0 +1,89 @@
1
+ from typing import Dict, Any
2
+ import os
3
+ from jarvis.utils import PrettyOutput, OutputType
4
+
5
+ class ChdirTool:
6
+ """修改当前工作目录的工具"""
7
+
8
+ name = "chdir"
9
+ description = "修改当前工作目录"
10
+ parameters = {
11
+ "type": "object",
12
+ "properties": {
13
+ "path": {
14
+ "type": "string",
15
+ "description": "要切换到的目录路径,支持相对路径和绝对路径"
16
+ }
17
+ },
18
+ "required": ["path"]
19
+ }
20
+
21
+ def execute(self, args: Dict[str, Any]) -> Dict[str, Any]:
22
+ """执行目录切换
23
+
24
+ Args:
25
+ args: 包含 path 参数的字典
26
+
27
+ Returns:
28
+ 执行结果字典,包含:
29
+ - success: 是否成功
30
+ - stdout: 成功时的输出信息
31
+ - error: 失败时的错误信息
32
+ """
33
+ try:
34
+ path = os.path.expanduser(args["path"]) # 展开 ~ 等路径
35
+ path = os.path.abspath(path) # 转换为绝对路径
36
+
37
+ # 检查目录是否存在
38
+ if not os.path.exists(path):
39
+ return {
40
+ "success": False,
41
+ "error": f"目录不存在: {path}"
42
+ }
43
+
44
+ # 检查是否是目录
45
+ if not os.path.isdir(path):
46
+ return {
47
+ "success": False,
48
+ "error": f"路径不是目录: {path}"
49
+ }
50
+
51
+ # 尝试切换目录
52
+ old_path = os.getcwd()
53
+ os.chdir(path)
54
+
55
+ return {
56
+ "success": True,
57
+ "stdout": f"已切换工作目录:\n从: {old_path}\n到: {path}",
58
+ "stderr": ""
59
+ }
60
+
61
+ except PermissionError:
62
+ return {
63
+ "success": False,
64
+ "error": f"没有权限访问目录: {path}"
65
+ }
66
+ except Exception as e:
67
+ return {
68
+ "success": False,
69
+ "error": f"切换目录失败: {str(e)}"
70
+ }
71
+
72
+ def main():
73
+ """命令行直接运行工具"""
74
+ import argparse
75
+
76
+ parser = argparse.ArgumentParser(description='修改当前工作目录')
77
+ parser.add_argument('path', help='要切换到的目录路径')
78
+ args = parser.parse_args()
79
+
80
+ tool = ChdirTool()
81
+ result = tool.execute({"path": args.path})
82
+
83
+ if result["success"]:
84
+ PrettyOutput.print(result["stdout"], OutputType.SUCCESS)
85
+ else:
86
+ PrettyOutput.print(result["error"], OutputType.ERROR)
87
+
88
+ if __name__ == "__main__":
89
+ main()
@@ -1,6 +1,6 @@
1
-
2
1
  import importlib
3
2
  import json
3
+ import os
4
4
  from pathlib import Path
5
5
  import sys
6
6
  from typing import Any, Callable, Dict, List, Optional
@@ -19,6 +19,7 @@ class ToolRegistry:
19
19
  # 加载内置工具和外部工具
20
20
  self._load_builtin_tools()
21
21
  self._load_external_tools()
22
+ self.max_context_length = int(os.getenv('JARVIS_MAX_CONTEXT_LENGTH', '30720')) # 默认30k
22
23
 
23
24
  @staticmethod
24
25
  def get_global_tool_registry():
@@ -173,12 +174,51 @@ class ToolRegistry:
173
174
  output = "\n\n".join(output_parts)
174
175
  output = "没有输出和错误" if not output else output
175
176
  PrettyOutput.section("执行成功", OutputType.SUCCESS)
177
+
178
+ # 如果输出超过4k字符,使用大模型总结
179
+ if len(output) > 4096:
180
+ try:
181
+ PrettyOutput.print("输出较长,正在总结...", OutputType.PROGRESS)
182
+ model = PlatformRegistry.get_global_platform_registry().get_normal_platform()
183
+
184
+ # 如果输出超过30k,只取最后30k字符
185
+ if len(output) > self.max_context_length:
186
+ output_to_summarize = output[-self.max_context_length:]
187
+ truncation_notice = "\n(注意: 由于输出过长,仅总结最后30720字符)"
188
+ else:
189
+ output_to_summarize = output
190
+ truncation_notice = ""
191
+
192
+ prompt = f"""请总结以下工具执行结果,提取关键信息和重要结果。注意:
193
+ 1. 保留所有重要的数值、路径、错误信息等关键数据
194
+ 2. 保持结果的准确性
195
+ 3. 用简洁的语言描述主要内容
196
+ 4. 如果有错误信息,确保包含在总结中
197
+
198
+ 工具名称: {name}
199
+ 执行结果:
200
+ {output_to_summarize}
201
+
202
+ 请提供总结:"""
203
+
204
+ summary = model.chat(prompt)
205
+ output = f"""--- 原始输出较长,以下是总结 ---{truncation_notice}
206
+
207
+ {summary}
208
+
209
+ --- 总结结束 ---"""
210
+
211
+ except Exception as e:
212
+ PrettyOutput.print(f"总结失败: {str(e)}", OutputType.WARNING)
213
+ output = f"输出较长 ({len(output)} 字符),建议查看原始输出。\n前300字符预览:\n{output[:300]}..."
214
+
176
215
  else:
177
216
  error_msg = result["error"]
178
217
  output = f"执行失败: {error_msg}"
179
218
  PrettyOutput.section("执行失败", OutputType.ERROR)
180
219
 
181
220
  return output
221
+
182
222
  except Exception as e:
183
223
  PrettyOutput.print(f"执行工具失败: {str(e)}", OutputType.ERROR)
184
224
  return f"Tool call failed: {str(e)}"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: jarvis-ai-assistant
3
- Version: 0.1.78
3
+ Version: 0.1.79
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
@@ -21,7 +21,9 @@ src/jarvis/models/registry.py
21
21
  src/jarvis/rag/__init__.py
22
22
  src/jarvis/rag/main.py
23
23
  src/jarvis/tools/__init__.py
24
+ src/jarvis/tools/ask_user.py
24
25
  src/jarvis/tools/base.py
26
+ src/jarvis/tools/chdir.py
25
27
  src/jarvis/tools/codebase_qa.py
26
28
  src/jarvis/tools/coder.py
27
29
  src/jarvis/tools/file_ops.py