jarvis-ai-assistant 0.2.1__py3-none-any.whl → 0.2.3__py3-none-any.whl

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 (41) hide show
  1. jarvis/__init__.py +1 -1
  2. jarvis/jarvis_agent/jarvis.py +61 -59
  3. jarvis/jarvis_agent/main.py +42 -40
  4. jarvis/jarvis_agent/prompts.py +26 -4
  5. jarvis/jarvis_code_agent/code_agent.py +35 -31
  6. jarvis/jarvis_code_analysis/code_review.py +73 -39
  7. jarvis/jarvis_data/config_schema.json +67 -12
  8. jarvis/jarvis_git_squash/main.py +16 -12
  9. jarvis/jarvis_git_utils/git_commiter.py +25 -20
  10. jarvis/jarvis_methodology/main.py +34 -49
  11. jarvis/jarvis_multi_agent/main.py +28 -23
  12. jarvis/jarvis_platform/ai8.py +31 -22
  13. jarvis/jarvis_platform/kimi.py +31 -61
  14. jarvis/jarvis_platform/tongyi.py +71 -85
  15. jarvis/jarvis_platform/yuanbao.py +44 -50
  16. jarvis/jarvis_platform_manager/main.py +55 -90
  17. jarvis/jarvis_rag/cli.py +79 -23
  18. jarvis/jarvis_rag/query_rewriter.py +61 -12
  19. jarvis/jarvis_rag/rag_pipeline.py +143 -34
  20. jarvis/jarvis_rag/retriever.py +5 -5
  21. jarvis/jarvis_smart_shell/main.py +58 -87
  22. jarvis/jarvis_tools/cli/main.py +120 -153
  23. jarvis/jarvis_tools/generate_new_tool.py +22 -1
  24. jarvis/jarvis_tools/registry.py +1 -7
  25. jarvis/jarvis_tools/search_web.py +12 -10
  26. jarvis/jarvis_utils/config.py +92 -11
  27. jarvis/jarvis_utils/globals.py +29 -8
  28. jarvis/jarvis_utils/http.py +58 -79
  29. jarvis/jarvis_utils/input.py +114 -121
  30. jarvis/jarvis_utils/output.py +1 -1
  31. jarvis/jarvis_utils/utils.py +3 -0
  32. jarvis_ai_assistant-0.2.3.dist-info/METADATA +301 -0
  33. {jarvis_ai_assistant-0.2.1.dist-info → jarvis_ai_assistant-0.2.3.dist-info}/RECORD +37 -40
  34. {jarvis_ai_assistant-0.2.1.dist-info → jarvis_ai_assistant-0.2.3.dist-info}/entry_points.txt +0 -2
  35. jarvis/jarvis_git_details/__init__.py +0 -0
  36. jarvis/jarvis_git_details/main.py +0 -265
  37. jarvis/jarvis_platform/oyi.py +0 -357
  38. jarvis_ai_assistant-0.2.1.dist-info/METADATA +0 -845
  39. {jarvis_ai_assistant-0.2.1.dist-info → jarvis_ai_assistant-0.2.3.dist-info}/WHEEL +0 -0
  40. {jarvis_ai_assistant-0.2.1.dist-info → jarvis_ai_assistant-0.2.3.dist-info}/licenses/LICENSE +0 -0
  41. {jarvis_ai_assistant-0.2.1.dist-info → jarvis_ai_assistant-0.2.3.dist-info}/top_level.txt +0 -0
@@ -141,38 +141,47 @@
141
141
  "description": "思考操作模型名称",
142
142
  "default": "deep_seek"
143
143
  },
144
- "JARVIS_MODEL_GROUP": {
144
+ "JARVIS_LLM_GROUP": {
145
145
  "type": "string",
146
- "description": "选择一个预定义的模型组"
146
+ "description": "选择一个预定义的模型组",
147
+ "default": ""
147
148
  },
148
- "JARVIS_MODEL_GROUPS": {
149
+ "JARVIS_LLM_GROUPS": {
149
150
  "type": "array",
150
151
  "description": "预定义的模型配置组",
152
+ "default": [],
151
153
  "items": {
152
154
  "type": "object",
153
155
  "additionalProperties": {
154
156
  "type": "object",
155
157
  "properties": {
156
158
  "JARVIS_PLATFORM": {
157
- "type": "string"
159
+ "type": "string",
160
+ "default": "yuanbao"
158
161
  },
159
162
  "JARVIS_MODEL": {
160
- "type": "string"
163
+ "type": "string",
164
+ "default": "deep_seek_v3"
161
165
  },
162
166
  "JARVIS_THINKING_PLATFORM": {
163
- "type": "string"
167
+ "type": "string",
168
+ "default": "yuanbao"
164
169
  },
165
170
  "JARVIS_THINKING_MODEL": {
166
- "type": "string"
171
+ "type": "string",
172
+ "default": "deep_seek"
167
173
  },
168
174
  "JARVIS_MAX_TOKEN_COUNT": {
169
- "type": "number"
175
+ "type": "number",
176
+ "default": 960000
170
177
  },
171
178
  "JARVIS_MAX_INPUT_TOKEN_COUNT": {
172
- "type": "number"
179
+ "type": "number",
180
+ "default": 32000
173
181
  },
174
182
  "JARVIS_MAX_BIG_CONTENT_SIZE": {
175
- "type": "number"
183
+ "type": "number",
184
+ "default": 160000
176
185
  }
177
186
  },
178
187
  "required": [
@@ -235,9 +244,43 @@
235
244
  "description": "是否启用静态代码分析",
236
245
  "default": true
237
246
  },
247
+ "JARVIS_RAG_GROUP": {
248
+ "type": "string",
249
+ "description": "选择一个预定义的RAG配置组",
250
+ "default": ""
251
+ },
252
+ "JARVIS_RAG_GROUPS": {
253
+ "type": "array",
254
+ "description": "预定义的RAG配置组",
255
+ "default": [],
256
+ "items": {
257
+ "type": "object",
258
+ "additionalProperties": {
259
+ "type": "object",
260
+ "properties": {
261
+ "embedding_model": {
262
+ "type": "string",
263
+ "default": "BAAI/bge-base-zh-v1.5"
264
+ },
265
+ "rerank_model": {
266
+ "type": "string",
267
+ "default": "BAAI/bge-reranker-base"
268
+ },
269
+ "use_bm25": {
270
+ "type": "boolean",
271
+ "default": true
272
+ },
273
+ "use_rerank": {
274
+ "type": "boolean",
275
+ "default": true
276
+ }
277
+ }
278
+ }
279
+ }
280
+ },
238
281
  "JARVIS_RAG": {
239
282
  "type": "object",
240
- "description": "RAG框架的配置",
283
+ "description": "RAG框架的顶层配置。注意:此处的设置将覆盖任何由JARVIS_RAG_GROUP选择的组配置。",
241
284
  "properties": {
242
285
  "embedding_model": {
243
286
  "type": "string",
@@ -248,11 +291,23 @@
248
291
  "type": "string",
249
292
  "default": "BAAI/bge-reranker-base",
250
293
  "description": "用于RAG的rerank模型的名称, 默认为 'BAAI/bge-reranker-base'"
294
+ },
295
+ "use_bm25": {
296
+ "type": "boolean",
297
+ "default": true,
298
+ "description": "是否在RAG中为检索使用BM25, 默认为 true"
299
+ },
300
+ "use_rerank": {
301
+ "type": "boolean",
302
+ "default": true,
303
+ "description": "是否在RAG中为检索使用rerank, 默认为 true"
251
304
  }
252
305
  },
253
306
  "default": {
254
307
  "embedding_model": "BAAI/bge-base-zh-v1.5",
255
- "rerank_model": "BAAI/bge-reranker-base"
308
+ "rerank_model": "BAAI/bge-reranker-base",
309
+ "use_bm25": true,
310
+ "use_rerank": true
256
311
  }
257
312
  },
258
313
  "JARVIS_REPLACE_MAP": {
@@ -1,14 +1,16 @@
1
1
  # -*- coding: utf-8 -*-
2
- import argparse
3
2
  import subprocess
4
- import sys
5
3
  from typing import Dict
6
4
 
5
+ import typer
6
+
7
7
  from jarvis.jarvis_git_utils.git_commiter import GitCommitTool
8
8
  from jarvis.jarvis_utils.output import OutputType, PrettyOutput
9
9
  from jarvis.jarvis_utils.utils import init_env
10
10
  from jarvis.jarvis_utils.input import user_confirm
11
11
 
12
+ app = typer.Typer(help="Git squash tool")
13
+
12
14
 
13
15
  class GitSquashTool:
14
16
  name = "git_squash_agent"
@@ -49,18 +51,20 @@ class GitSquashTool:
49
51
  PrettyOutput.print(f"压缩提交失败: {str(e)}", OutputType.WARNING)
50
52
 
51
53
 
52
- def main():
54
+ @app.command()
55
+ def cli(
56
+ commit_hash: str = typer.Argument(..., help="Base commit hash to squash from"),
57
+ lang: str = typer.Option("Chinese", "--lang", help="Language for commit messages"),
58
+ ):
53
59
  init_env("欢迎使用 Jarvis-GitSquash,您的Git压缩助手已准备就绪!")
54
- parser = argparse.ArgumentParser(description="Git squash tool")
55
- parser.add_argument("commit_hash", type=str, help="Base commit hash to squash from")
56
- parser.add_argument(
57
- "--lang", type=str, default="Chinese", help="Language for commit messages"
58
- )
59
- args = parser.parse_args()
60
-
61
60
  tool = GitSquashTool()
62
- tool.execute({"commit_hash": args.commit_hash, "lang": args.lang})
61
+ tool.execute({"commit_hash": commit_hash, "lang": lang})
62
+
63
+
64
+ def main():
65
+ """Application entry point"""
66
+ app()
63
67
 
64
68
 
65
69
  if __name__ == "__main__":
66
- sys.exit(main())
70
+ main()
@@ -1,5 +1,4 @@
1
1
  # -*- coding: utf-8 -*-
2
- import argparse
3
2
  import os
4
3
  import re
5
4
  import subprocess
@@ -7,6 +6,7 @@ import sys
7
6
  import tempfile
8
7
  from typing import Any, Dict, Optional
9
8
 
9
+ import typer
10
10
  import yaml # type: ignore
11
11
 
12
12
  from jarvis.jarvis_platform.registry import PlatformRegistry
@@ -21,6 +21,8 @@ from jarvis.jarvis_utils.output import OutputType, PrettyOutput
21
21
  from jarvis.jarvis_utils.tag import ct, ot
22
22
  from jarvis.jarvis_utils.utils import init_env, is_context_overflow
23
23
 
24
+ app = typer.Typer(help="Git commit tool")
25
+
24
26
 
25
27
  class GitCommitTool:
26
28
  name = "git_commit_agent"
@@ -305,34 +307,37 @@ commit信息
305
307
  os.chdir(original_dir)
306
308
 
307
309
 
308
- def main():
309
- init_env("欢迎使用 Jarvis-GitCommitTool,您的Git提交助手已准备就绪!")
310
- parser = argparse.ArgumentParser(description="Git commit tool")
311
- parser.add_argument(
312
- "--root-dir", type=str, default=".", help="Root directory of the Git repository"
313
- )
314
- parser.add_argument(
310
+ @app.command()
311
+ def cli(
312
+ root_dir: str = typer.Option(
313
+ ".", "--root-dir", help="Root directory of the Git repository"
314
+ ),
315
+ prefix: str = typer.Option(
316
+ "",
315
317
  "--prefix",
316
- type=str,
317
- default="",
318
318
  help="Prefix to prepend to commit message (separated by space)",
319
- )
320
- parser.add_argument(
319
+ ),
320
+ suffix: str = typer.Option(
321
+ "",
321
322
  "--suffix",
322
- type=str,
323
- default="",
324
323
  help="Suffix to append to commit message (separated by newline)",
325
- )
326
- args = parser.parse_args()
324
+ ),
325
+ ):
326
+ init_env("欢迎使用 Jarvis-GitCommitTool,您的Git提交助手已准备就绪!")
327
327
  tool = GitCommitTool()
328
328
  tool.execute(
329
329
  {
330
- "root_dir": args.root_dir,
331
- "prefix": args.prefix if hasattr(args, "prefix") else "",
332
- "suffix": args.suffix if hasattr(args, "suffix") else "",
330
+ "root_dir": root_dir,
331
+ "prefix": prefix,
332
+ "suffix": suffix,
333
333
  }
334
334
  )
335
335
 
336
336
 
337
+ def main():
338
+ """Application entry point"""
339
+ app()
340
+
341
+
337
342
  if __name__ == "__main__":
338
- sys.exit(main())
343
+ main()
@@ -8,11 +8,13 @@
8
8
  - 列出所有方法论
9
9
  """
10
10
 
11
- import argparse
12
11
  import hashlib
13
12
  import json
14
13
  import os
14
+ import sys
15
+ from typing import Optional
15
16
 
17
+ import typer
16
18
  import yaml # type: ignore
17
19
 
18
20
  from jarvis.jarvis_platform.registry import PlatformRegistry
@@ -22,8 +24,13 @@ from jarvis.jarvis_utils.methodology import (
22
24
  )
23
25
  from jarvis.jarvis_utils.output import OutputType, PrettyOutput
24
26
 
27
+ app = typer.Typer(help="方法论管理工具")
25
28
 
26
- def import_methodology(input_file):
29
+
30
+ @app.command("import")
31
+ def import_methodology(
32
+ input_file: str = typer.Argument(..., help="要导入的方法论文件路径")
33
+ ):
27
34
  """导入方法论文件(合并策略)"""
28
35
  try:
29
36
  # 加载现有方法论
@@ -56,9 +63,13 @@ def import_methodology(input_file):
56
63
  )
57
64
  except (json.JSONDecodeError, OSError) as e:
58
65
  PrettyOutput.print(f"导入失败: {str(e)}", OutputType.ERROR)
66
+ raise typer.Exit(code=1)
59
67
 
60
68
 
61
- def export_methodology(output_file):
69
+ @app.command("export")
70
+ def export_methodology(
71
+ output_file: str = typer.Argument(..., help="导出文件路径")
72
+ ):
62
73
  """导出当前方法论到单个文件"""
63
74
  try:
64
75
  methodologies = _load_all_methodologies()
@@ -72,8 +83,10 @@ def export_methodology(output_file):
72
83
  )
73
84
  except (OSError, TypeError) as e:
74
85
  PrettyOutput.print(f"导出失败: {str(e)}", OutputType.ERROR)
86
+ raise typer.Exit(code=1)
75
87
 
76
88
 
89
+ @app.command("list")
77
90
  def list_methodologies():
78
91
  """列出所有方法论"""
79
92
  try:
@@ -88,9 +101,13 @@ def list_methodologies():
88
101
  PrettyOutput.print(f"{i}. {problem_type}", OutputType.INFO)
89
102
  except (OSError, json.JSONDecodeError) as e:
90
103
  PrettyOutput.print(f"列出方法论失败: {str(e)}", OutputType.ERROR)
104
+ raise typer.Exit(code=1)
91
105
 
92
106
 
93
- def extract_methodology(input_file):
107
+ @app.command("extract")
108
+ def extract_methodology(
109
+ input_file: str = typer.Argument(..., help="要提取方法论的文本文件路径")
110
+ ):
94
111
  """从文本文件中提取方法论"""
95
112
  try:
96
113
  # 读取文本文件内容
@@ -135,7 +152,7 @@ def extract_methodology(input_file):
135
152
  except Exception as e:
136
153
  print("❌ 提取失败")
137
154
  PrettyOutput.print(f"提取方法论失败: {str(e)}", OutputType.ERROR)
138
- return
155
+ raise typer.Exit(code=1)
139
156
 
140
157
  # 提取YAML部分
141
158
  methodologies_start = response.find("<methodologies>") + len("<methodologies>")
@@ -145,7 +162,7 @@ def extract_methodology(input_file):
145
162
  PrettyOutput.print(
146
163
  "大模型未返回有效的<methodologies>格式", OutputType.ERROR
147
164
  )
148
- return
165
+ raise typer.Exit(code=1)
149
166
 
150
167
  yaml_content = response[methodologies_start:methodologies_end].strip()
151
168
 
@@ -157,7 +174,7 @@ def extract_methodology(input_file):
157
174
  except (yaml.YAMLError, KeyError, TypeError) as e:
158
175
  print("❌ YAML解析失败")
159
176
  PrettyOutput.print(f"YAML解析错误: {str(e)}", OutputType.ERROR)
160
- return
177
+ raise typer.Exit(code=1)
161
178
 
162
179
  if not extracted_methodologies:
163
180
  print("❌ 未提取到有效方法论")
@@ -190,9 +207,11 @@ def extract_methodology(input_file):
190
207
  )
191
208
  except Exception as e:
192
209
  PrettyOutput.print(f"提取失败: {str(e)}", OutputType.ERROR)
210
+ raise typer.Exit(code=1)
193
211
 
194
212
 
195
- def extract_methodology_from_url(url):
213
+ @app.command("extract-url")
214
+ def extract_methodology_from_url(url: str = typer.Argument(..., help="要提取方法论的URL")):
196
215
  """从URL提取方法论"""
197
216
  try:
198
217
  # 获取平台实例
@@ -234,7 +253,7 @@ def extract_methodology_from_url(url):
234
253
  except Exception as e:
235
254
  print("❌ 提取失败")
236
255
  PrettyOutput.print(f"提取方法论失败: {str(e)}", OutputType.ERROR)
237
- return
256
+ raise typer.Exit(code=1)
238
257
 
239
258
  # 提取YAML部分
240
259
  methodologies_start = response.find("<methodologies>") + len("<methodologies>")
@@ -244,7 +263,7 @@ def extract_methodology_from_url(url):
244
263
  PrettyOutput.print(
245
264
  "大模型未返回有效的<methodologies>格式", OutputType.ERROR
246
265
  )
247
- return
266
+ raise typer.Exit(code=1)
248
267
 
249
268
  yaml_content = response[methodologies_start:methodologies_end].strip()
250
269
 
@@ -256,7 +275,7 @@ def extract_methodology_from_url(url):
256
275
  except (yaml.YAMLError, KeyError, TypeError) as e:
257
276
  print("❌ YAML解析失败")
258
277
  PrettyOutput.print(f"YAML解析错误: {str(e)}", OutputType.ERROR)
259
- return
278
+ raise typer.Exit(code=1)
260
279
 
261
280
  if not extracted_methodologies:
262
281
  print("❌ 未提取到有效方法论")
@@ -289,46 +308,12 @@ def extract_methodology_from_url(url):
289
308
  )
290
309
  except Exception as e:
291
310
  PrettyOutput.print(f"从URL提取失败: {str(e)}", OutputType.ERROR)
311
+ raise typer.Exit(code=1)
292
312
 
293
313
 
294
- def main():
295
- """方法论管理工具主函数"""
296
- parser = argparse.ArgumentParser(description="方法论管理工具")
297
- subparsers = parser.add_subparsers(dest="command", required=True)
298
-
299
- # import命令
300
- import_parser = subparsers.add_parser("import", help="导入方法论文件(合并策略)")
301
- import_parser.add_argument("input_file", type=str, help="要导入的方法论文件路径")
302
-
303
- # export命令
304
- export_parser = subparsers.add_parser("export", help="导出当前方法论到单个文件")
305
- export_parser.add_argument("output_file", type=str, help="导出文件路径")
306
-
307
- # list命令
308
- subparsers.add_parser("list", help="列出所有方法论")
309
-
310
- # extract命令
311
- extract_parser = subparsers.add_parser("extract", help="从文本文件中提取方法论")
312
- extract_parser.add_argument(
313
- "input_file", type=str, help="要提取方法论的文本文件路径"
314
- )
315
-
316
- # extract-url命令
317
- extract_url_parser = subparsers.add_parser("extract-url", help="从URL提取方法论")
318
- extract_url_parser.add_argument("url", type=str, help="要提取方法论的URL")
319
-
320
- args = parser.parse_args()
321
-
322
- if args.command == "import":
323
- import_methodology(args.input_file)
324
- elif args.command == "export":
325
- export_methodology(args.output_file)
326
- elif args.command == "list":
327
- list_methodologies()
328
- elif args.command == "extract":
329
- extract_methodology(args.input_file)
330
- elif args.command == "extract-url":
331
- extract_methodology_from_url(args.url)
314
+ def main() -> None:
315
+ """Application entry point"""
316
+ app()
332
317
 
333
318
 
334
319
  if __name__ == "__main__":
@@ -1,27 +1,26 @@
1
1
  # -*- coding: utf-8 -*-
2
+ from typing import Optional
3
+
4
+ import typer
2
5
  import yaml
3
6
 
4
7
  from jarvis.jarvis_multi_agent import MultiAgent
5
8
  from jarvis.jarvis_utils.input import get_multiline_input
6
9
  from jarvis.jarvis_utils.utils import init_env
7
10
 
11
+ app = typer.Typer(help="多智能体系统启动器")
8
12
 
9
- def main():
10
- """从YAML配置文件初始化并运行多智能体系统
11
13
 
12
- Returns:
13
- 最终处理结果
14
- """
14
+ @app.command()
15
+ def cli(
16
+ config: str = typer.Option(..., "--config", "-c", help="YAML配置文件路径"),
17
+ user_input: Optional[str] = typer.Option(None, "--input", "-i", help="用户输入(可选)"),
18
+ ):
19
+ """从YAML配置文件初始化并运行多智能体系统"""
15
20
  init_env("欢迎使用 Jarvis-MultiAgent,您的多智能体系统已准备就绪!")
16
- import argparse
17
-
18
- parser = argparse.ArgumentParser(description="多智能体系统启动器")
19
- parser.add_argument("--config", "-c", required=True, help="YAML配置文件路径")
20
- parser.add_argument("--input", "-i", help="用户输入(可选)")
21
- args = parser.parse_args()
22
21
 
23
22
  try:
24
- with open(args.config, "r", errors="ignore") as f:
23
+ with open(config, "r", errors="ignore") as f:
25
24
  config_data = yaml.safe_load(f)
26
25
 
27
26
  # 获取agents配置
@@ -33,20 +32,26 @@ def main():
33
32
 
34
33
  # 创建并运行多智能体系统
35
34
  multi_agent = MultiAgent(agents_config, main_agent_name)
36
- user_input = (
37
- args.input
38
- if args.input is not None
35
+ final_input = (
36
+ user_input
37
+ if user_input is not None
39
38
  else get_multiline_input("请输入内容(输入空行结束):")
40
39
  )
41
- if user_input == "":
42
- return
43
- return multi_agent.run(user_input)
40
+ if not final_input:
41
+ raise typer.Exit(code=0)
42
+ multi_agent.run(final_input)
43
+
44
+ except typer.Exit:
45
+ raise
46
+ except (ValueError, RuntimeError, yaml.YAMLError) as e:
47
+ PrettyOutput.print(f"错误: {str(e)}", OutputType.ERROR)
48
+ raise typer.Exit(code=1)
49
+
44
50
 
45
- except yaml.YAMLError as e:
46
- raise ValueError(f"YAML配置文件解析错误: {str(e)}")
47
- except Exception as e:
48
- raise RuntimeError(f"多智能体系统初始化失败: {str(e)}")
51
+ def main() -> None:
52
+ """Application entry point."""
53
+ app()
49
54
 
50
55
 
51
56
  if __name__ == "__main__":
52
- result = main()
57
+ main()
@@ -32,15 +32,21 @@ class AI8Model(BasePlatform):
32
32
 
33
33
  self.headers = {
34
34
  "Authorization": self.token,
35
+ "sec-ch-ua-platform": '"Windows"',
36
+ "sec-ch-ua": '"Not)A;Brand";v="8", "Chromium";v="138", "Google Chrome";v="138"',
37
+ "sec-ch-ua-mobile": "?0",
35
38
  "Content-Type": "application/json",
36
39
  "Accept": "application/json, text/plain, */*",
37
- "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36",
38
- "X-APP-VERSION": "2.3.0",
40
+ "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36",
41
+ "X-APP-VERSION": "2.4.2",
39
42
  "Origin": self.BASE_URL,
40
43
  "Referer": f"{self.BASE_URL}/chat?_userMenuKey=chat",
41
44
  "Sec-Fetch-Site": "same-origin",
42
45
  "Sec-Fetch-Mode": "cors",
43
46
  "Sec-Fetch-Dest": "empty",
47
+ "Accept-Language": "zh-CN,zh;q=0.9",
48
+ "Accept-Encoding": "gzip, deflate, br, zstd",
49
+ "Connection": "keep-alive",
44
50
  }
45
51
 
46
52
  self.model_name = os.getenv("JARVIS_MODEL") or "deepseek-chat"
@@ -60,7 +66,14 @@ class AI8Model(BasePlatform):
60
66
  # 1. 创建会话
61
67
  response = while_success(
62
68
  lambda: http.post(
63
- f"{self.BASE_URL}/api/chat/session", headers=self.headers, json={}
69
+ f"{self.BASE_URL}/api/chat/session",
70
+ headers=self.headers,
71
+ json={
72
+ "mcp": [],
73
+ "model": self.model_name,
74
+ "plugins": [],
75
+ "rags": [],
76
+ },
64
77
  ),
65
78
  sleep_time=5,
66
79
  )
@@ -83,6 +96,7 @@ class AI8Model(BasePlatform):
83
96
  "plugins": [],
84
97
  "localPlugins": None,
85
98
  "useAppId": 0,
99
+ "temperature": 0,
86
100
  }
87
101
 
88
102
  response = while_success(
@@ -127,33 +141,30 @@ class AI8Model(BasePlatform):
127
141
  "files": [],
128
142
  }
129
143
 
144
+ # 为流式请求构造专用的请求头,避免 'Accept' 和 'accept' 键冲突
145
+ stream_headers = self.headers.copy()
146
+ stream_headers["Accept"] = "text/event-stream" # 添加流式专用的accept头
147
+
130
148
  # 使用stream_post进行流式请求
131
149
  response_stream = while_success(
132
150
  lambda: http.stream_post(
133
151
  f"{self.BASE_URL}/api/chat/completions",
134
- headers=self.headers,
152
+ headers=stream_headers,
135
153
  json=payload,
136
154
  ),
137
155
  sleep_time=5,
138
156
  )
139
157
 
140
158
  # 处理流式响应
141
- for chunk in response_stream:
142
- if chunk:
159
+ for line in response_stream:
160
+ if line and line.startswith("data: "):
143
161
  try:
144
- line = chunk.decode("utf-8")
145
- if line.startswith("data: "):
146
- try:
147
- data = json.loads(line[6:])
148
- if data.get("type") == "string":
149
- chunk_data = data.get("data", "")
150
- if chunk_data:
151
- yield chunk_data
152
-
153
- except json.JSONDecodeError:
154
- continue
155
-
156
- except UnicodeDecodeError:
162
+ data = json.loads(line[6:])
163
+ if data.get("type") == "string":
164
+ chunk_data = data.get("data", "")
165
+ if chunk_data:
166
+ yield chunk_data
167
+ except json.JSONDecodeError:
157
168
  continue
158
169
 
159
170
  return None
@@ -239,9 +250,7 @@ class AI8Model(BasePlatform):
239
250
  PrettyOutput.print(f"会话文件未找到: {file_path}", OutputType.ERROR)
240
251
  return False
241
252
  except KeyError as e:
242
- PrettyOutput.print(
243
- f"恢复失败: 会话文件格式不正确,缺少键 {e}", OutputType.ERROR
244
- )
253
+ PrettyOutput.print(f"恢复失败: 会话文件格式不正确,缺少键 {e}", OutputType.ERROR)
245
254
  return False
246
255
  except Exception as e:
247
256
  PrettyOutput.print(f"恢复会话失败: {str(e)}", OutputType.ERROR)