jarvis-ai-assistant 0.1.89__tar.gz → 0.1.91__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 (53) hide show
  1. {jarvis_ai_assistant-0.1.89/src/jarvis_ai_assistant.egg-info → jarvis_ai_assistant-0.1.91}/PKG-INFO +4 -7
  2. {jarvis_ai_assistant-0.1.89 → jarvis_ai_assistant-0.1.91}/README.md +3 -6
  3. {jarvis_ai_assistant-0.1.89 → jarvis_ai_assistant-0.1.91}/pyproject.toml +3 -3
  4. {jarvis_ai_assistant-0.1.89 → jarvis_ai_assistant-0.1.91}/setup.py +2 -2
  5. {jarvis_ai_assistant-0.1.89 → jarvis_ai_assistant-0.1.91}/src/jarvis/__init__.py +1 -1
  6. {jarvis_ai_assistant-0.1.89 → jarvis_ai_assistant-0.1.91}/src/jarvis/agent.py +3 -3
  7. {jarvis_ai_assistant-0.1.89 → jarvis_ai_assistant-0.1.91}/src/jarvis/jarvis_codebase/main.py +3 -2
  8. jarvis_ai_assistant-0.1.91/src/jarvis/jarvis_platform/main.py +121 -0
  9. {jarvis_ai_assistant-0.1.89 → jarvis_ai_assistant-0.1.91}/src/jarvis/jarvis_rag/main.py +42 -14
  10. {jarvis_ai_assistant-0.1.89 → jarvis_ai_assistant-0.1.91}/src/jarvis/jarvis_smart_shell/main.py +0 -6
  11. {jarvis_ai_assistant-0.1.89 → jarvis_ai_assistant-0.1.91}/src/jarvis/models/ai8.py +36 -44
  12. {jarvis_ai_assistant-0.1.89 → jarvis_ai_assistant-0.1.91}/src/jarvis/models/base.py +10 -1
  13. {jarvis_ai_assistant-0.1.89 → jarvis_ai_assistant-0.1.91}/src/jarvis/models/kimi.py +7 -2
  14. {jarvis_ai_assistant-0.1.89 → jarvis_ai_assistant-0.1.91}/src/jarvis/models/ollama.py +7 -12
  15. {jarvis_ai_assistant-0.1.89 → jarvis_ai_assistant-0.1.91}/src/jarvis/models/openai.py +12 -3
  16. {jarvis_ai_assistant-0.1.89 → jarvis_ai_assistant-0.1.91}/src/jarvis/models/oyi.py +15 -21
  17. {jarvis_ai_assistant-0.1.89 → jarvis_ai_assistant-0.1.91}/src/jarvis/models/registry.py +12 -1
  18. {jarvis_ai_assistant-0.1.89 → jarvis_ai_assistant-0.1.91}/src/jarvis/tools/ask_user.py +4 -14
  19. {jarvis_ai_assistant-0.1.89 → jarvis_ai_assistant-0.1.91}/src/jarvis/tools/codebase_qa.py +1 -1
  20. jarvis_ai_assistant-0.1.91/src/jarvis/tools/rag.py +134 -0
  21. jarvis_ai_assistant-0.1.91/src/jarvis/tools/thinker.py +203 -0
  22. {jarvis_ai_assistant-0.1.89 → jarvis_ai_assistant-0.1.91}/src/jarvis/utils.py +3 -5
  23. {jarvis_ai_assistant-0.1.89 → jarvis_ai_assistant-0.1.91/src/jarvis_ai_assistant.egg-info}/PKG-INFO +4 -7
  24. {jarvis_ai_assistant-0.1.89 → jarvis_ai_assistant-0.1.91}/src/jarvis_ai_assistant.egg-info/SOURCES.txt +4 -6
  25. {jarvis_ai_assistant-0.1.89 → jarvis_ai_assistant-0.1.91}/src/jarvis_ai_assistant.egg-info/entry_points.txt +1 -1
  26. jarvis_ai_assistant-0.1.89/src/jarvis/jarvis_coder/git_utils.py +0 -67
  27. jarvis_ai_assistant-0.1.89/src/jarvis/jarvis_coder/main.py +0 -358
  28. jarvis_ai_assistant-0.1.89/src/jarvis/jarvis_coder/model_utils.py +0 -30
  29. jarvis_ai_assistant-0.1.89/src/jarvis/jarvis_coder/patch_handler.py +0 -390
  30. jarvis_ai_assistant-0.1.89/src/jarvis/tools/coder.py +0 -69
  31. {jarvis_ai_assistant-0.1.89 → jarvis_ai_assistant-0.1.91}/LICENSE +0 -0
  32. {jarvis_ai_assistant-0.1.89 → jarvis_ai_assistant-0.1.91}/MANIFEST.in +0 -0
  33. {jarvis_ai_assistant-0.1.89 → jarvis_ai_assistant-0.1.91}/setup.cfg +0 -0
  34. {jarvis_ai_assistant-0.1.89 → jarvis_ai_assistant-0.1.91}/src/jarvis/jarvis_codebase/__init__.py +0 -0
  35. {jarvis_ai_assistant-0.1.89/src/jarvis/jarvis_coder → jarvis_ai_assistant-0.1.91/src/jarvis/jarvis_platform}/__init__.py +0 -0
  36. {jarvis_ai_assistant-0.1.89 → jarvis_ai_assistant-0.1.91}/src/jarvis/jarvis_rag/__init__.py +0 -0
  37. {jarvis_ai_assistant-0.1.89 → jarvis_ai_assistant-0.1.91}/src/jarvis/jarvis_smart_shell/__init__.py +0 -0
  38. {jarvis_ai_assistant-0.1.89 → jarvis_ai_assistant-0.1.91}/src/jarvis/main.py +0 -0
  39. {jarvis_ai_assistant-0.1.89 → jarvis_ai_assistant-0.1.91}/src/jarvis/models/__init__.py +0 -0
  40. {jarvis_ai_assistant-0.1.89 → jarvis_ai_assistant-0.1.91}/src/jarvis/tools/__init__.py +0 -0
  41. {jarvis_ai_assistant-0.1.89 → jarvis_ai_assistant-0.1.91}/src/jarvis/tools/base.py +0 -0
  42. {jarvis_ai_assistant-0.1.89 → jarvis_ai_assistant-0.1.91}/src/jarvis/tools/chdir.py +0 -0
  43. {jarvis_ai_assistant-0.1.89 → jarvis_ai_assistant-0.1.91}/src/jarvis/tools/file_ops.py +0 -0
  44. {jarvis_ai_assistant-0.1.89 → jarvis_ai_assistant-0.1.91}/src/jarvis/tools/generator.py +0 -0
  45. {jarvis_ai_assistant-0.1.89 → jarvis_ai_assistant-0.1.91}/src/jarvis/tools/methodology.py +0 -0
  46. {jarvis_ai_assistant-0.1.89 → jarvis_ai_assistant-0.1.91}/src/jarvis/tools/registry.py +0 -0
  47. {jarvis_ai_assistant-0.1.89 → jarvis_ai_assistant-0.1.91}/src/jarvis/tools/search.py +0 -0
  48. {jarvis_ai_assistant-0.1.89 → jarvis_ai_assistant-0.1.91}/src/jarvis/tools/shell.py +0 -0
  49. {jarvis_ai_assistant-0.1.89 → jarvis_ai_assistant-0.1.91}/src/jarvis/tools/sub_agent.py +0 -0
  50. {jarvis_ai_assistant-0.1.89 → jarvis_ai_assistant-0.1.91}/src/jarvis/tools/webpage.py +0 -0
  51. {jarvis_ai_assistant-0.1.89 → jarvis_ai_assistant-0.1.91}/src/jarvis_ai_assistant.egg-info/dependency_links.txt +0 -0
  52. {jarvis_ai_assistant-0.1.89 → jarvis_ai_assistant-0.1.91}/src/jarvis_ai_assistant.egg-info/requires.txt +0 -0
  53. {jarvis_ai_assistant-0.1.89 → jarvis_ai_assistant-0.1.91}/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.89
3
+ Version: 0.1.91
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
@@ -129,11 +129,13 @@ Jarvis supports configuration through environment variables that can be set in t
129
129
  |---------|------|--------|------|
130
130
  | JARVIS_PLATFORM | AI platform to use, supports kimi/openai/ai8 etc | kimi | Yes |
131
131
  | JARVIS_MODEL | Model name to use | - | No |
132
- | JARVIS_THREAD_COUNT | Number of threads for parallel processing | 10 | No |
133
132
  | JARVIS_CODEGEN_PLATFORM | AI platform for code generation | Same as JARVIS_PLATFORM | No |
134
133
  | JARVIS_CODEGEN_MODEL | Model name for code generation | Same as JARVIS_MODEL | No |
135
134
  | JARVIS_CHEAP_PLATFORM | AI platform for cheap operations | Same as JARVIS_PLATFORM | No |
136
135
  | JARVIS_CHEAP_MODEL | Model name for cheap operations | Same as JARVIS_MODEL | No |
136
+ | JARVIS_THINKING_PLATFORM | AI platform for thinking | Same as JARVIS_PLATFORM | No |
137
+ | JARVIS_THINKING_MODEL | Model name for thinking | Same as JARVIS_MODEL | No |
138
+ | JARVIS_THREAD_COUNT | Number of threads for parallel processing | 10 | No |
137
139
  | OPENAI_API_KEY | API key for OpenAI platform | - | Required for OpenAI |
138
140
  | OPENAI_API_BASE | Base URL for OpenAI API | https://api.deepseek.com | No |
139
141
  | OPENAI_MODEL_NAME | Model name for OpenAI | deepseek-chat | No |
@@ -150,11 +152,6 @@ Jarvis supports configuration through environment variables that can be set in t
150
152
  jarvis
151
153
  ```
152
154
 
153
- ### Code Generation
154
- ```bash
155
- jarvis-coder
156
- ```
157
-
158
155
  ### Codebase Search
159
156
  ```bash
160
157
  # Generate codebase index
@@ -65,11 +65,13 @@ Jarvis supports configuration through environment variables that can be set in t
65
65
  |---------|------|--------|------|
66
66
  | JARVIS_PLATFORM | AI platform to use, supports kimi/openai/ai8 etc | kimi | Yes |
67
67
  | JARVIS_MODEL | Model name to use | - | No |
68
- | JARVIS_THREAD_COUNT | Number of threads for parallel processing | 10 | No |
69
68
  | JARVIS_CODEGEN_PLATFORM | AI platform for code generation | Same as JARVIS_PLATFORM | No |
70
69
  | JARVIS_CODEGEN_MODEL | Model name for code generation | Same as JARVIS_MODEL | No |
71
70
  | JARVIS_CHEAP_PLATFORM | AI platform for cheap operations | Same as JARVIS_PLATFORM | No |
72
71
  | JARVIS_CHEAP_MODEL | Model name for cheap operations | Same as JARVIS_MODEL | No |
72
+ | JARVIS_THINKING_PLATFORM | AI platform for thinking | Same as JARVIS_PLATFORM | No |
73
+ | JARVIS_THINKING_MODEL | Model name for thinking | Same as JARVIS_MODEL | No |
74
+ | JARVIS_THREAD_COUNT | Number of threads for parallel processing | 10 | No |
73
75
  | OPENAI_API_KEY | API key for OpenAI platform | - | Required for OpenAI |
74
76
  | OPENAI_API_BASE | Base URL for OpenAI API | https://api.deepseek.com | No |
75
77
  | OPENAI_MODEL_NAME | Model name for OpenAI | deepseek-chat | No |
@@ -86,11 +88,6 @@ Jarvis supports configuration through environment variables that can be set in t
86
88
  jarvis
87
89
  ```
88
90
 
89
- ### Code Generation
90
- ```bash
91
- jarvis-coder
92
- ```
93
-
94
91
  ### Codebase Search
95
92
  ```bash
96
93
  # Generate codebase index
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "jarvis-ai-assistant"
7
- version = "0.1.89"
7
+ version = "0.1.91"
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" }]
@@ -46,8 +46,8 @@ Homepage = "https://github.com/skyfireitdiy/Jarvis"
46
46
 
47
47
  [project.scripts]
48
48
  jarvis = "jarvis.main:main"
49
- jarvis-coder = "jarvis.jarvis_coder.main:main"
50
49
  jarvis-codebase = "jarvis.jarvis_codebase.main:main"
51
50
  jarvis-rag = "jarvis.jarvis_rag.main:main"
52
51
  jarvis-smart-shell = "jarvis.jarvis_smart_shell.main:main"
53
- jss = "jarvis.jarvis_smart_shell.main:main"
52
+ jss = "jarvis.jarvis_smart_shell.main:main"
53
+ jarvis-platform = "jarvis.jarvis_platform.main:main"
@@ -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.89",
5
+ version="0.1.91",
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",
@@ -31,11 +31,11 @@ setup(
31
31
  entry_points={
32
32
  "console_scripts": [
33
33
  "jarvis=jarvis.main:main",
34
- "jarvis-coder=jarvis.jarvis_coder.main:main",
35
34
  "jarvis-codebase=jarvis.jarvis_codebase.main:main",
36
35
  "jarvis-rag=jarvis.jarvis_rag.main:main",
37
36
  "jarvis-smart-shell=jarvis.jarvis_smart_shell.main:main",
38
37
  "jss=jarvis.jarvis_smart_shell.main:main",
38
+ "jarvis-platform=jarvis.jarvis_platform.main:main",
39
39
  ],
40
40
  },
41
41
  python_requires=">=3.8",
@@ -1,3 +1,3 @@
1
1
  """Jarvis AI Assistant"""
2
2
 
3
- __version__ = "0.1.89"
3
+ __version__ = "0.1.91"
@@ -132,7 +132,7 @@ class Agent:
132
132
  embedding = self.embedding_model.encode([text],
133
133
  convert_to_tensor=True,
134
134
  normalize_embeddings=True)
135
- vector = np.array(embedding, dtype=np.float32)
135
+ vector = np.array(embedding.cpu().numpy(), dtype=np.float32)
136
136
  return vector[0] # 返回第一个向量,因为我们只编码了一个文本
137
137
  except Exception as e:
138
138
  PrettyOutput.print(f"创建方法论嵌入向量失败: {str(e)}", OutputType.ERROR)
@@ -337,7 +337,7 @@ class Agent:
337
337
 
338
338
  self.model.set_system_message(f"""你是 {self.name},一个问题处理能力强大的 AI 助手。
339
339
 
340
- 你会严格按照以下步骤处理问题:
340
+ 如果用户需要执行任务,你会严格按照以下步骤处理问题:
341
341
  1. 问题重述:确认理解问题
342
342
  2. 根因分析(如果是问题分析类需要,其他不需要)
343
343
  3. 设定目标:需要可达成,可检验的一个或多个目标
@@ -388,7 +388,7 @@ arguments:
388
388
  -------------------------------------------------------------
389
389
 
390
390
  """)
391
- self.prompt = f"用户任务: {user_input}"
391
+ self.prompt = f"{user_input}"
392
392
 
393
393
  while True:
394
394
  try:
@@ -20,6 +20,7 @@ class CodeBase:
20
20
  os.chdir(self.root_dir)
21
21
  self.thread_count = get_thread_count()
22
22
  self.max_context_length = get_max_context_length()
23
+ self.index = None
23
24
 
24
25
  # 初始化数据目录
25
26
  self.data_dir = os.path.join(self.root_dir, ".jarvis-codebase")
@@ -473,10 +474,10 @@ class CodeBase:
473
474
  def search_similar(self, query: str, top_k: int = 30) -> List[Tuple[str, float, str]]:
474
475
  """搜索关联文件"""
475
476
  try:
477
+ if self.index is None:
478
+ return []
476
479
  # 生成多个查询变体以提高召回率
477
480
  model = PlatformRegistry.get_global_platform_registry().get_normal_platform()
478
- model.set_suppress_output(True)
479
-
480
481
  prompt = f"""请根据以下查询,生成3个不同的表述,每个表述都要完整表达原始查询的意思。这些表述将用于代码搜索,要保持专业性和准确性。
481
482
  原始查询: {query}
482
483
 
@@ -0,0 +1,121 @@
1
+ from jarvis.models.registry import PlatformRegistry
2
+ from jarvis.utils import PrettyOutput, OutputType, load_env_from_file, get_multiline_input
3
+
4
+ def list_platforms():
5
+ """列出所有支持的平台和模型"""
6
+ registry = PlatformRegistry.get_global_platform_registry()
7
+ platforms = registry.get_available_platforms()
8
+
9
+ PrettyOutput.section("支持的平台和模型", OutputType.SUCCESS)
10
+
11
+ for platform_name in platforms:
12
+ # 创建平台实例
13
+ platform = registry.create_platform(platform_name)
14
+ if not platform:
15
+ continue
16
+
17
+ # 获取平台支持的模型列表
18
+ try:
19
+ models = platform.get_model_list()
20
+
21
+ # 打印平台名称
22
+ PrettyOutput.section(f"{platform_name}", OutputType.SUCCESS)
23
+
24
+ # 打印模型列表
25
+ if models:
26
+ for model_name, description in models:
27
+ if description:
28
+ PrettyOutput.print(f" • {model_name} - {description}", OutputType.SUCCESS)
29
+ else:
30
+ PrettyOutput.print(f" • {model_name}", OutputType.SUCCESS)
31
+ else:
32
+ PrettyOutput.print(" 没有可用的模型信息", OutputType.WARNING)
33
+
34
+ except Exception as e:
35
+ PrettyOutput.print(f"获取 {platform_name} 平台模型列表失败: {str(e)}", OutputType.ERROR)
36
+
37
+ def chat_with_model(platform_name: str, model_name: str):
38
+ """与指定平台和模型进行对话"""
39
+ registry = PlatformRegistry.get_global_platform_registry()
40
+
41
+ # 创建平台实例
42
+ platform = registry.create_platform(platform_name)
43
+ if not platform:
44
+ PrettyOutput.print(f"创建平台 {platform_name} 失败", OutputType.ERROR)
45
+ return
46
+
47
+ try:
48
+ # 设置模型
49
+ platform.set_model_name(model_name)
50
+ PrettyOutput.print(f"已连接到 {platform_name} 平台的 {model_name} 模型", OutputType.SUCCESS)
51
+
52
+ # 开始对话循环
53
+ while True:
54
+ # 获取用户输入
55
+ user_input = get_multiline_input("")
56
+
57
+ # 检查是否取消输入
58
+ if user_input == "__interrupt__":
59
+ break
60
+
61
+ # 检查是否为空输入
62
+ if not user_input.strip():
63
+ continue
64
+
65
+ try:
66
+ # 发送到模型并获取回复
67
+ response = platform.chat(user_input)
68
+ if not response:
69
+ PrettyOutput.print("未获得有效回复", OutputType.WARNING)
70
+
71
+ except Exception as e:
72
+ PrettyOutput.print(f"对话失败: {str(e)}", OutputType.ERROR)
73
+
74
+ except Exception as e:
75
+ PrettyOutput.print(f"初始化对话失败: {str(e)}", OutputType.ERROR)
76
+ finally:
77
+ # 清理资源
78
+ try:
79
+ platform.delete_chat()
80
+ except:
81
+ pass
82
+
83
+ def info_command(args):
84
+ """处理 info 子命令"""
85
+ list_platforms()
86
+
87
+ def chat_command(args):
88
+ """处理 chat 子命令"""
89
+ if not args.platform or not args.model:
90
+ PrettyOutput.print("请指定平台和模型。使用 'jarvis info' 查看可用的平台和模型。", OutputType.ERROR)
91
+ return
92
+ chat_with_model(args.platform, args.model)
93
+
94
+ def main():
95
+ """主函数"""
96
+ import argparse
97
+
98
+ load_env_from_file()
99
+
100
+ parser = argparse.ArgumentParser(description='Jarvis AI Platform')
101
+ subparsers = parser.add_subparsers(dest='command', help='可用的子命令')
102
+
103
+ # info 子命令
104
+ info_parser = subparsers.add_parser('info', help='显示支持的平台和模型信息')
105
+
106
+ # chat 子命令
107
+ chat_parser = subparsers.add_parser('chat', help='与指定的平台和模型进行对话')
108
+ chat_parser.add_argument('--platform', '-p', help='指定要使用的平台')
109
+ chat_parser.add_argument('--model', '-m', help='指定要使用的模型')
110
+
111
+ args = parser.parse_args()
112
+
113
+ if args.command == 'info':
114
+ info_command(args)
115
+ elif args.command == 'chat':
116
+ chat_command(args)
117
+ else:
118
+ parser.print_help()
119
+
120
+ if __name__ == "__main__":
121
+ main()
@@ -144,6 +144,7 @@ class RAGTool:
144
144
  self.min_paragraph_length = int(os.environ.get("JARVIS_MIN_PARAGRAPH_LENGTH", "50")) # 最小段落长度
145
145
  self.max_paragraph_length = int(os.environ.get("JARVIS_MAX_PARAGRAPH_LENGTH", "1000")) # 最大段落长度
146
146
  self.context_window = int(os.environ.get("JARVIS_CONTEXT_WINDOW", "5")) # 上下文窗口大小,默认前后各5个片段
147
+ self.max_context_length = int(get_max_context_length() * 0.8)
147
148
 
148
149
  # 初始化数据目录
149
150
  self.data_dir = os.path.join(self.root_dir, ".jarvis-rag")
@@ -163,7 +164,6 @@ class RAGTool:
163
164
  self.cache_path = os.path.join(self.data_dir, "cache.pkl")
164
165
  self.documents: List[Document] = []
165
166
  self.index = None
166
- self.max_context_length = get_max_context_length()
167
167
 
168
168
  # 加载缓存
169
169
  self._load_cache()
@@ -400,7 +400,7 @@ class RAGTool:
400
400
  PrettyOutput.print(f"成功索引了 {len(self.documents)} 个文档片段",
401
401
  output_type=OutputType.SUCCESS)
402
402
 
403
- def search(self, query: str, top_k: int = 5) -> List[Tuple[Document, float]]:
403
+ def search(self, query: str, top_k: int = 30) -> List[Tuple[Document, float]]:
404
404
  """优化搜索策略"""
405
405
  if not self.index:
406
406
  PrettyOutput.print("索引未构建,正在构建...", output_type=OutputType.INFO)
@@ -557,27 +557,55 @@ class RAGTool:
557
557
  results = self.query(question)
558
558
  if not results:
559
559
  return None
560
+
561
+ # 显示找到的文档片段
562
+ for doc in results:
563
+ PrettyOutput.print(f"文件: {doc.metadata['file_path']}", output_type=OutputType.INFO)
564
+ PrettyOutput.print(f"片段 {doc.metadata['chunk_index'] + 1}/{doc.metadata['total_chunks']}",
565
+ output_type=OutputType.INFO)
566
+ PrettyOutput.print("\n内容:", output_type=OutputType.INFO)
567
+ content = doc.content.encode('utf-8', errors='replace').decode('utf-8')
568
+ PrettyOutput.print(content, output_type=OutputType.INFO)
569
+
570
+ # 构建基础提示词
571
+ base_prompt = f"""请基于以下文档片段回答用户的问题。如果文档内容不足以完整回答问题,请明确指出。
572
+
573
+ 用户问题: {question}
560
574
 
561
- # 构建上下文
575
+ 相关文档片段:
576
+ """
577
+ end_prompt = "\n请提供准确、简洁的回答,如果文档内容不足以完整回答问题,请明确指出。"
578
+
579
+ # 计算可用于文档内容的最大长度
580
+ # 预留一些空间给模型回答
581
+ available_length = self.max_context_length - len(base_prompt) - len(end_prompt) - 500
582
+
583
+ # 构建上下文,同时控制总长度
562
584
  context = []
585
+ current_length = 0
586
+
563
587
  for doc in results:
564
- context.append(f"""
588
+ # 计算这个文档片段的内容长度
589
+ doc_content = f"""
565
590
  来源文件: {doc.metadata['file_path']}
566
591
  内容:
567
592
  {doc.content}
568
593
  ---
569
- """)
594
+ """
595
+ content_length = len(doc_content)
596
+
597
+ # 如果添加这个片段会超出限制,就停止添加
598
+ if current_length + content_length > available_length:
599
+ PrettyOutput.print("由于上下文长度限制,部分相关文档片段被省略",
600
+ output_type=OutputType.WARNING)
601
+ break
602
+
603
+ context.append(doc_content)
604
+ current_length += content_length
570
605
 
571
- # 构建提示词
572
- prompt = f"""请基于以下文档片段回答用户的问题。如果文档内容不足以完整回答问题,请明确指出。
606
+ # 构建完整的提示词
607
+ prompt = base_prompt + ''.join(context) + end_prompt
573
608
 
574
- 用户问题: {question}
575
-
576
- 相关文档片段:
577
- {''.join(context)}
578
-
579
- 请提供准确、简洁的回答,并在适当时引用具体的文档来源。
580
- """
581
609
  # 获取模型实例并生成回答
582
610
  model = PlatformRegistry.get_global_platform_registry().get_normal_platform()
583
611
  response = model.chat(prompt)
@@ -55,12 +55,6 @@ def process_request(request: str) -> Optional[str]:
55
55
  4. 不要添加任何换行或额外空格
56
56
  5. 如果需要多个命令,使用 && 连接
57
57
 
58
- 安全要求:
59
- - 生成的命令必须是安全的,不能包含危险操作
60
- - 如果需要sudo权限,要明确提示用户
61
- - 对于复杂操作,优先使用管道而不是临时文件
62
- - 确保命令的可移植性,优先使用通用的POSIX命令
63
-
64
58
  示例输入:
65
59
  "查找当前目录下的所有Python文件"
66
60
 
@@ -1,5 +1,5 @@
1
1
  import os
2
- from typing import Dict, List
2
+ from typing import Dict, List, Tuple
3
3
  from jarvis.models.base import BasePlatform
4
4
  from jarvis.utils import PrettyOutput, OutputType
5
5
  import requests
@@ -12,7 +12,9 @@ class AI8Model(BasePlatform):
12
12
  platform_name = "ai8"
13
13
  BASE_URL = "https://ai8.rcouyi.com"
14
14
 
15
- first_time = True
15
+ def get_model_list(self) -> List[Tuple[str, str]]:
16
+ """获取模型列表"""
17
+ return [(name,info['desc']) for name,info in self.models.items()]
16
18
 
17
19
  def __init__(self):
18
20
  """Initialize model"""
@@ -22,53 +24,13 @@ class AI8Model(BasePlatform):
22
24
  self.files = []
23
25
  self.models = {} # 存储模型信息
24
26
 
25
- # 获取可用模型列表
26
- available_models = self.get_available_models()
27
-
28
- if AI8Model.first_time:
29
- AI8Model.first_time = False
30
- if available_models:
31
- PrettyOutput.section("支持的模型", OutputType.SUCCESS)
32
- for model in self.models.values():
33
- # 格式化显示模型信息
34
- model_str = f"{model['value']:<30}"
35
-
36
- # 添加标签
37
- model_str += f"{model['label']}"
38
-
39
- # 添加标签和积分信息
40
- attrs = []
41
- if model['attr'].get('tag'):
42
- attrs.append(model['attr']['tag'])
43
- if model['attr'].get('integral'):
44
- attrs.append(model['attr']['integral'])
45
-
46
- # 添加特性标记
47
- features = []
48
- if model['attr'].get('multimodal'):
49
- features.append("多模态")
50
- if model['attr'].get('plugin'):
51
- features.append("插件支持")
52
- if model['attr'].get('onlyImg'):
53
- features.append("图像支持")
54
- if features:
55
- model_str += f" [{'|'.join(features)}]"
56
-
57
- # 添加备注
58
- if model['attr'].get('note'):
59
- model_str += f" - {model['attr']['note']}"
60
-
61
- PrettyOutput.print(model_str, OutputType.INFO)
62
- else:
63
- PrettyOutput.print("获取模型列表失败", OutputType.WARNING)
64
-
65
27
  self.token = os.getenv("AI8_API_KEY")
66
28
  if not self.token:
67
- raise Exception("AI8_API_KEY is not set")
29
+ PrettyOutput.print("AI8_API_KEY未设置", OutputType.WARNING)
68
30
 
69
31
 
70
32
  self.model_name = os.getenv("JARVIS_MODEL") or "deepseek-chat"
71
- if self.model_name not in self.models:
33
+ if self.model_name not in self.get_available_models():
72
34
  PrettyOutput.print(f"警告: 当前选择的模型 {self.model_name} 不在可用列表中", OutputType.WARNING)
73
35
 
74
36
 
@@ -283,6 +245,9 @@ class AI8Model(BasePlatform):
283
245
  List[str]: 可用模型名称列表
284
246
  """
285
247
  try:
248
+ if self.models:
249
+ return list(self.models.keys())
250
+
286
251
  headers = {
287
252
  'Content-Type': 'application/json',
288
253
  'Accept': 'application/json, text/plain, */*',
@@ -311,6 +276,33 @@ class AI8Model(BasePlatform):
311
276
  model['value']: model
312
277
  for model in data['data']['models']
313
278
  }
279
+
280
+ for model in self.models.values():
281
+ # 添加标签
282
+ model_str = f"{model['label']}"
283
+
284
+ # 添加标签和积分信息
285
+ attrs = []
286
+ if model['attr'].get('tag'):
287
+ attrs.append(model['attr']['tag'])
288
+ if model['attr'].get('integral'):
289
+ attrs.append(model['attr']['integral'])
290
+
291
+ # 添加特性标记
292
+ features = []
293
+ if model['attr'].get('multimodal'):
294
+ features.append("多模态")
295
+ if model['attr'].get('plugin'):
296
+ features.append("插件支持")
297
+ if model['attr'].get('onlyImg'):
298
+ features.append("图像支持")
299
+ if features:
300
+ model_str += f" [{'|'.join(features)}]"
301
+
302
+ # 添加备注
303
+ if model['attr'].get('note'):
304
+ model_str += f" - {model['attr']['note']}"
305
+ model['desc'] = model_str
314
306
 
315
307
  return list(self.models.keys())
316
308
 
@@ -1,5 +1,5 @@
1
1
  from abc import ABC, abstractmethod
2
- from typing import Dict, List
2
+ from typing import Dict, List, Tuple
3
3
 
4
4
 
5
5
  class BasePlatform(ABC):
@@ -14,6 +14,7 @@ class BasePlatform(ABC):
14
14
  """销毁模型"""
15
15
  self.delete_chat()
16
16
 
17
+ @abstractmethod
17
18
  def set_model_name(self, model_name: str):
18
19
  """设置模型名称"""
19
20
  raise NotImplementedError("set_model_name is not implemented")
@@ -23,10 +24,12 @@ class BasePlatform(ABC):
23
24
  """执行对话"""
24
25
  raise NotImplementedError("chat is not implemented")
25
26
 
27
+ @abstractmethod
26
28
  def upload_files(self, file_list: List[str]) -> List[Dict]:
27
29
  """上传文件"""
28
30
  raise NotImplementedError("upload_files is not implemented")
29
31
 
32
+ @abstractmethod
30
33
  def reset(self):
31
34
  """重置模型"""
32
35
  raise NotImplementedError("reset is not implemented")
@@ -41,9 +44,15 @@ class BasePlatform(ABC):
41
44
  """删除对话"""
42
45
  raise NotImplementedError("delete_chat is not implemented")
43
46
 
47
+ @abstractmethod
44
48
  def set_system_message(self, message: str):
45
49
  """设置系统消息"""
46
50
  raise NotImplementedError("set_system_message is not implemented")
51
+
52
+ @abstractmethod
53
+ def get_model_list(self) -> List[Tuple[str, str]]:
54
+ """获取模型列表"""
55
+ raise NotImplementedError("get_model_list is not implemented")
47
56
 
48
57
  def set_suppress_output(self, suppress: bool):
49
58
  """设置是否屏蔽输出"""
@@ -1,4 +1,4 @@
1
- from typing import Dict, List
1
+ from typing import Dict, List, Tuple
2
2
  import requests
3
3
  import json
4
4
  import os
@@ -12,12 +12,17 @@ class KimiModel(BasePlatform):
12
12
  """Kimi模型实现"""
13
13
 
14
14
  platform_name = "kimi"
15
+
16
+ def get_model_list(self) -> List[Tuple[str, str]]:
17
+ """获取模型列表"""
18
+ return [("kimi", "基于网页Kimi的封装,免费接口")]
15
19
 
16
20
  def __init__(self):
17
21
  """
18
22
  初始化Kimi模型
19
23
  """
20
24
  super().__init__()
25
+ self.chat_id = ""
21
26
  self.api_key = os.getenv("KIMI_API_KEY")
22
27
  if not self.api_key:
23
28
  PrettyOutput.print("\n需要设置 KIMI_API_KEY 才能使用 Jarvis。请按以下步骤操作:", OutputType.INFO)
@@ -35,7 +40,7 @@ class KimiModel(BasePlatform):
35
40
  PrettyOutput.print("\n 方法 2: 直接设置环境变量:", OutputType.INFO)
36
41
  PrettyOutput.print(" export KIMI_API_KEY=your_key_here", OutputType.INFO)
37
42
  PrettyOutput.print("\n设置完成后重新运行 Jarvis。", OutputType.INFO)
38
- raise Exception("KIMI_API_KEY is not set")
43
+ PrettyOutput.print("KIMI_API_KEY未设置", OutputType.WARNING)
39
44
  self.auth_header = f"Bearer {self.api_key}"
40
45
  self.chat_id = ""
41
46
  self.uploaded_files = [] # 存储已上传文件的信息
@@ -1,5 +1,5 @@
1
1
  import requests
2
- from typing import List, Dict
2
+ from typing import List, Dict, Tuple
3
3
  from jarvis.models.base import BasePlatform
4
4
  from jarvis.utils import OutputType, PrettyOutput
5
5
  import os
@@ -20,7 +20,6 @@ class OllamaPlatform(BasePlatform):
20
20
 
21
21
  # 检查 Ollama 服务是否可用
22
22
  try:
23
- PrettyOutput.print(f"正在连接 Ollama 服务 ({self.api_base})...", OutputType.INFO)
24
23
  response = requests.get(f"{self.api_base}/api/tags")
25
24
  response.raise_for_status()
26
25
  available_models = [model["name"] for model in response.json().get("models", [])]
@@ -32,16 +31,6 @@ class OllamaPlatform(BasePlatform):
32
31
  PrettyOutput.print(f" ollama pull {self.model_name}", OutputType.INFO)
33
32
  raise Exception("No available models found")
34
33
 
35
- PrettyOutput.print(f"可用模型: {', '.join(available_models)}", OutputType.INFO)
36
-
37
- if self.model_name not in available_models:
38
- PrettyOutput.print(f"\n警告:模型 {self.model_name} 未下载", OutputType.WARNING)
39
- PrettyOutput.print("\n请使用以下命令下载模型:", OutputType.INFO)
40
- PrettyOutput.print(f"ollama pull {self.model_name}", OutputType.INFO)
41
- raise Exception(f"Model {self.model_name} is not available")
42
-
43
- PrettyOutput.print(f"使用模型: {self.model_name}", OutputType.SUCCESS)
44
-
45
34
  except requests.exceptions.ConnectionError:
46
35
  PrettyOutput.print("\nOllama 服务未启动或无法连接", OutputType.ERROR)
47
36
  PrettyOutput.print("请确保已经:", OutputType.INFO)
@@ -53,6 +42,12 @@ class OllamaPlatform(BasePlatform):
53
42
  self.messages = []
54
43
  self.system_message = ""
55
44
 
45
+ def get_model_list(self) -> List[Tuple[str, str]]:
46
+ """获取模型列表"""
47
+ response = requests.get(f"{self.api_base}/api/tags")
48
+ response.raise_for_status()
49
+ return [(model["name"], "") for model in response.json().get("models", [])]
50
+
56
51
  def set_model_name(self, model_name: str):
57
52
  """设置模型名称"""
58
53
  self.model_name = model_name