jarvis-ai-assistant 0.1.159__py3-none-any.whl → 0.1.160__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.

Potentially problematic release.


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

jarvis/__init__.py CHANGED
@@ -1,3 +1,3 @@
1
1
  """Jarvis AI Assistant"""
2
2
 
3
- __version__ = "0.1.159"
3
+ __version__ = "0.1.160"
@@ -7,9 +7,8 @@ from typing import Any, Tuple
7
7
  from yaspin import yaspin
8
8
 
9
9
  from jarvis.jarvis_tools.file_operation import FileOperationTool
10
- from jarvis.jarvis_utils.config import INPUT_WINDOW_REVERSE_SIZE, get_max_input_token_count
11
- from jarvis.jarvis_utils.embedding import get_context_token_count
12
10
  from jarvis.jarvis_utils.output import OutputType, PrettyOutput
11
+ from jarvis.jarvis_utils.utils import is_context_overflow
13
12
 
14
13
 
15
14
  def file_input_handler(user_input: str, agent: Any) -> Tuple[str, bool]:
@@ -86,7 +85,7 @@ def file_input_handler(user_input: str, agent: Any) -> Tuple[str, bool]:
86
85
  spinner.text = "文件读取完成"
87
86
  spinner.ok("✅")
88
87
  prompt = result["stdout"] + "\n" + prompt
89
- if get_context_token_count(prompt) > get_max_input_token_count() - INPUT_WINDOW_REVERSE_SIZE:
88
+ if is_context_overflow(prompt):
90
89
  return old_prompt, False
91
90
 
92
91
  return prompt, False
@@ -2,20 +2,19 @@ import re
2
2
  from typing import Dict, Any, Tuple
3
3
  import os
4
4
 
5
- from yaspin import yaspin
5
+ from yaspin import yaspin # type: ignore
6
6
 
7
7
  from jarvis.jarvis_agent.output_handler import OutputHandler
8
8
  from jarvis.jarvis_platform.base import BasePlatform
9
9
  from jarvis.jarvis_platform.registry import PlatformRegistry
10
10
  from jarvis.jarvis_git_utils.git_commiter import GitCommitTool
11
11
  from jarvis.jarvis_tools.file_operation import FileOperationTool
12
- from jarvis.jarvis_utils.config import INPUT_WINDOW_REVERSE_SIZE, get_max_input_token_count, is_confirm_before_apply_patch
13
- from jarvis.jarvis_utils.embedding import get_context_token_count
12
+ from jarvis.jarvis_utils.config import is_confirm_before_apply_patch
14
13
  from jarvis.jarvis_utils.git_utils import get_commits_between, get_latest_commit_hash
15
14
  from jarvis.jarvis_utils.globals import add_read_file_record, has_read_file
16
15
  from jarvis.jarvis_utils.input import get_multiline_input
17
16
  from jarvis.jarvis_utils.output import OutputType, PrettyOutput
18
- from jarvis.jarvis_utils.utils import get_file_line_count, user_confirm, chat_with_files
17
+ from jarvis.jarvis_utils.utils import is_context_overflow, get_file_line_count, user_confirm
19
18
  from jarvis.jarvis_utils.tag import ot, ct
20
19
 
21
20
 
@@ -95,7 +94,7 @@ def add(a, b):
95
94
  - 保持代码风格一致性,遵循项目现有的编码规范
96
95
  - 在修改前仔细分析原代码的格式风格,确保补丁与之完全兼容
97
96
  - 绝不提供完整文件内容,除非是新建文件
98
- - 每个文件的修改是独立的,不能出现"参照xxx文件的修改"这样的描述
97
+ - 每个文件的修改是独立的,不能出现“参照xxx文件的修改”这样的描述
99
98
  - 不要出现未实现的代码,如:TODO
100
99
  """
101
100
 
@@ -377,6 +376,7 @@ def handle_small_code_operation(filepath: str, patch_content: str) -> bool:
377
376
  try:
378
377
  model = PlatformRegistry().get_normal_platform()
379
378
  file_content = FileOperationTool().execute({"operation":"read", "files":[{"path":filepath}]})["stdout"]
379
+
380
380
  model.set_suppress_output(True)
381
381
 
382
382
  prompt = f"""
@@ -407,6 +407,7 @@ def handle_small_code_operation(filepath: str, patch_content: str) -> bool:
407
407
  {ot("MERGED_CODE")}
408
408
  [合并后的完整代码,包括所有空行和缩进]
409
409
  {ct("MERGED_CODE")}
410
+
410
411
  # 原始代码
411
412
  {file_content}
412
413
  """
@@ -466,18 +467,23 @@ def handle_small_code_operation(filepath: str, patch_content: str) -> bool:
466
467
  return False
467
468
 
468
469
 
470
+
469
471
  def handle_large_code_operation(filepath: str, patch_content: str, model: BasePlatform) -> bool:
470
472
  """处理大型代码文件的补丁操作,使用差异化补丁格式"""
471
473
  with yaspin(text=f"正在处理文件 {filepath}...", color="cyan") as spinner:
472
474
  try:
473
475
  file_content = FileOperationTool().execute({"operation":"read", "files":[{"path":filepath}]})["stdout"]
474
-
475
- # 检查是否需要特殊处理大文件
476
- need_special_handling = get_context_token_count(file_content) > get_max_input_token_count() - INPUT_WINDOW_REVERSE_SIZE
477
-
476
+ need_upload_file = is_context_overflow(file_content)
477
+ upload_success = False
478
+ # 读取原始文件内容
479
+ with spinner.hidden():
480
+ if need_upload_file and model.upload_files([filepath]):
481
+ upload_success = True
482
+
483
+
478
484
  model.set_suppress_output(True)
479
485
 
480
- prompt = f"""
486
+ main_prompt = f"""
481
487
  # 代码补丁生成专家指南
482
488
 
483
489
  ## 任务描述
@@ -487,8 +493,7 @@ def handle_large_code_operation(filepath: str, patch_content: str, model: BasePl
487
493
  ```
488
494
  {patch_content}
489
495
  ```
490
- """
491
- suffix_prompt = """
496
+
492
497
  ## 补丁生成要求
493
498
  1. **精确性**:严格按照补丁的意图修改代码
494
499
  2. **格式一致性**:严格保持原始代码的格式风格
@@ -523,77 +528,68 @@ def handle_large_code_operation(filepath: str, patch_content: str, model: BasePl
523
528
  <<<<<< REPLACE
524
529
  {ct("DIFF")}
525
530
  """
526
- if need_special_handling:
527
- # 尝试上传文件
528
- upload_success = False
529
- with spinner.hidden():
530
- if model.upload_files([filepath]):
531
- upload_success = True
532
-
533
- if upload_success:
534
- response = model.chat_until_success(prompt + suffix_prompt)
531
+
532
+ for _ in range(3):
533
+ file_prompt = ""
534
+ if not need_upload_file:
535
+ file_prompt = f"""
536
+ # 原始代码
537
+ {file_content}
538
+ """
539
+ response = model.chat_until_success(main_prompt + file_prompt)
535
540
  else:
536
- # 使用chat_with_files生成补丁
537
- response = chat_with_files(
538
- [filepath],
539
- model,
540
- prompt,
541
- suffix_prompt
542
- )
543
- else:
544
- # 上下文足够,直接在prompt中包含文件内容
545
- prompt += f"""
546
- # 原始文件内容
547
- ```
548
- {file_content}
549
- ```
550
- """
551
- response = model.chat_until_success(prompt + suffix_prompt)
552
-
553
- # 解析差异化补丁
554
- diff_blocks = re.finditer(ot("DIFF")+r'\s*>{4,} SEARCH\n?(.*?)\n?={4,}\n?(.*?)\s*<{4,} REPLACE\n?'+ct("DIFF"),
555
- response, re.DOTALL)
556
-
557
- # 读取原始文件内容
558
- with open(filepath, 'r', encoding='utf-8', errors="ignore") as f:
559
- file_content = f.read()
560
-
561
- # 应用所有差异化补丁
562
- modified_content = file_content
563
- patch_count = 0
564
- success = True
565
- for match in diff_blocks:
566
- search_text = match.group(1).strip()
567
- replace_text = match.group(2).strip()
568
- patch_count += 1
569
- # 检查搜索文本是否存在于文件中
570
- if search_text in modified_content:
571
- # 如果有多处,报错
572
- if modified_content.count(search_text) > 1:
573
- prompt = f"补丁 #{patch_count} 应用失败:找到多个匹配的代码段"
574
- spinner.write(f"❌ 补丁 #{patch_count} 应用失败:找到多个匹配的代码段")
541
+ if upload_success:
542
+ response = model.chat_until_success(main_prompt)
543
+ else:
544
+ response = model.chat_big_content(file_content, main_prompt)
545
+
546
+ # 解析差异化补丁
547
+ diff_blocks = re.finditer(ot("DIFF")+r'\s*>{4,} SEARCH\n?(.*?)\n?={4,}\n?(.*?)\s*<{4,} REPLACE\n?'+ct("DIFF"),
548
+ response, re.DOTALL)
549
+
550
+ # 读取原始文件内容
551
+ with open(filepath, 'r', encoding='utf-8', errors="ignore") as f:
552
+ file_content = f.read()
553
+
554
+ # 应用所有差异化补丁
555
+ modified_content = file_content
556
+ patch_count = 0
557
+ success = True
558
+ for match in diff_blocks:
559
+ search_text = match.group(1).strip()
560
+ replace_text = match.group(2).strip()
561
+ patch_count += 1
562
+ # 检查搜索文本是否存在于文件中
563
+ if search_text in modified_content:
564
+ # 如果有多处,报错
565
+ if modified_content.count(search_text) > 1:
566
+ prompt = f"补丁 #{patch_count} 应用失败:找到多个匹配的代码段"
567
+ spinner.write(f"❌ 补丁 #{patch_count} 应用失败:找到多个匹配的代码段")
568
+ success = False
569
+ break
570
+ # 应用替换
571
+ modified_content = modified_content.replace(
572
+ search_text, replace_text)
573
+ spinner.write(f"✅ 补丁 #{patch_count} 应用成功")
574
+ else:
575
+ spinner.write(f"❌ 补丁 #{patch_count} 应用失败:无法找到匹配的代码段")
576
+ prompt = f"补丁 #{patch_count} 应用失败:无法找到匹配的代码段"
575
577
  success = False
576
578
  break
577
- # 应用替换
578
- modified_content = modified_content.replace(
579
- search_text, replace_text)
580
- spinner.write(f"✅ 补丁 #{patch_count} 应用成功")
581
- else:
582
- spinner.write(f"❌ 补丁 #{patch_count} 应用失败:无法找到匹配的代码段")
583
- prompt = f"补丁 #{patch_count} 应用失败:无法找到匹配的代码段"
584
- success = False
585
- break
586
- if not success:
587
- revert_file(filepath)
588
- return False
579
+ if not success:
580
+ revert_file(filepath)
581
+ continue
589
582
 
590
- # 写入修改后的内容
591
- with open(filepath, 'w', encoding='utf-8', errors="ignore") as f:
592
- f.write(modified_content)
583
+ # 写入修改后的内容
584
+ with open(filepath, 'w', encoding='utf-8', errors="ignore") as f:
585
+ f.write(modified_content)
593
586
 
594
- spinner.text = f"文件 {filepath} 修改完成,应用了 {patch_count} 个补丁"
595
- spinner.ok("✅")
596
- return True
587
+ spinner.text = f"文件 {filepath} 修改完成,应用了 {patch_count} 个补丁"
588
+ spinner.ok("✅")
589
+ return True
590
+ spinner.text = f"文件 {filepath} 修改失败"
591
+ spinner.fail("❌")
592
+ return False
597
593
 
598
594
  except Exception as e:
599
595
  spinner.text = f"文件修改失败: {str(e)}"
@@ -10,10 +10,8 @@ from jarvis.jarvis_tools.read_code import ReadCodeTool
10
10
  from jarvis.jarvis_tools.registry import ToolRegistry
11
11
  from jarvis.jarvis_agent import Agent
12
12
 
13
- from jarvis.jarvis_utils.config import INPUT_WINDOW_REVERSE_SIZE, get_max_input_token_count
14
- from jarvis.jarvis_utils.embedding import get_context_token_count
15
13
  from jarvis.jarvis_utils.output import OutputType, PrettyOutput
16
- from jarvis.jarvis_utils.utils import init_env, chat_with_files
14
+ from jarvis.jarvis_utils.utils import init_env, is_context_overflow
17
15
  from jarvis.jarvis_utils.tag import ot, ct
18
16
  from jarvis.jarvis_code_analysis.checklists.loader import get_language_checklist
19
17
 
@@ -587,28 +585,27 @@ class CodeReviewTool:
587
585
  temp_file.flush()
588
586
 
589
587
  try:
590
- # 检查文件大小
591
- is_large_file = get_context_token_count(diff_output) > get_max_input_token_count() - INPUT_WINDOW_REVERSE_SIZE
588
+ upload_success = False
589
+ # Check if content is too large
590
+ is_large_content = is_context_overflow(diff_output)
592
591
 
593
- if is_large_file:
594
- # 文件较大,尝试上传
595
- upload_success = False
596
- with yaspin(text="正在上传代码差异文件...", color="cyan") as spinner:
597
- if agent.model and hasattr(agent.model, 'upload_files'):
598
- upload_success = agent.model.upload_files([temp_file_path])
599
- if upload_success:
600
- spinner.ok("✅")
601
- PrettyOutput.print(f"已成功上传代码差异文件", OutputType.SUCCESS)
602
- else:
603
- spinner.fail("❌")
604
- PrettyOutput.print(f"文件上传失败,将使用chat_with_files处理", OutputType.WARNING)
592
+ # Upload the file to the agent's model
593
+ with yaspin(text="正在上传代码差异文件...", color="cyan") as spinner:
594
+ if is_large_content and agent.model and hasattr(agent.model, 'upload_files'):
595
+ upload_success = agent.model.upload_files([temp_file_path])
596
+ if upload_success:
597
+ spinner.ok("✅")
598
+ PrettyOutput.print(f"已成功上传代码差异文件", OutputType.SUCCESS)
605
599
  else:
606
600
  spinner.fail("❌")
607
- PrettyOutput.print(f"模型不支持文件上传,将使用chat_with_files处理", OutputType.WARNING)
608
-
609
- if upload_success:
610
- # 文件上传成功,使用上传的文件
611
- complete_prompt = user_prompt + f"""
601
+ PrettyOutput.print(f"上传代码差异文件失败,将使用分块处理", OutputType.WARNING)
602
+ else:
603
+ upload_success = False
604
+
605
+ # Prepare the prompt based on upload status
606
+ if upload_success:
607
+ # When file is uploaded, reference it in the prompt
608
+ complete_prompt = user_prompt + f"""
612
609
 
613
610
  我已上传了一个包含代码差异的文件。该文件包含:
614
611
  - 审查类型: {review_type}
@@ -616,20 +613,17 @@ class CodeReviewTool:
616
613
  - 检测到的编程语言: {', '.join(detected_languages) if detected_languages else '未检测到特定语言'}
617
614
 
618
615
  请基于上传的代码差异文件进行全面审查,并生成详细的代码审查报告。"""
619
- result = agent.run(complete_prompt)
620
- else:
621
- # 文件上传失败,使用chat_with_files
622
- PrettyOutput.print("使用chat_with_files处理大文件...", OutputType.INFO)
623
- result = chat_with_files(
624
- [temp_file_path],
625
- agent.model,
626
- user_prompt,
627
- "请基于以上代码差异进行全面审查,并生成详细的代码审查报告。"
628
- )
629
- else:
630
- # 文件较小,直接包含在prompt中
631
- complete_prompt = user_prompt + "\n\n代码差异内容:\n```diff\n" + diff_output + "\n```"
616
+ # Run the agent with the prompt
632
617
  result = agent.run(complete_prompt)
618
+ else:
619
+ # If upload failed or not needed, handle based on context size
620
+ if is_large_content and agent.model and hasattr(agent.model, 'chat_big_content'):
621
+ # Use chat_big_content for large content when upload fails
622
+ result = agent.model.chat_big_content(diff_output, user_prompt)
623
+ else:
624
+ # Include the diff directly in the prompt for smaller content
625
+ complete_prompt = user_prompt + "\n\n代码差异内容:\n```diff\n" + diff_output + "\n```"
626
+ result = agent.run(complete_prompt)
633
627
  finally:
634
628
  # Clean up the temporary file
635
629
  if os.path.exists(temp_file_path):
@@ -10,11 +10,9 @@ import sys
10
10
  import argparse
11
11
  import os
12
12
 
13
- from jarvis.jarvis_utils.config import INPUT_WINDOW_REVERSE_SIZE, get_max_input_token_count
14
- from jarvis.jarvis_utils.embedding import get_context_token_count
15
13
  from jarvis.jarvis_utils.git_utils import find_git_root, has_uncommitted_changes
16
14
  from jarvis.jarvis_utils.output import OutputType, PrettyOutput
17
- from jarvis.jarvis_utils.utils import init_env, chat_with_files
15
+ from jarvis.jarvis_utils.utils import init_env, is_context_overflow
18
16
  from jarvis.jarvis_utils.tag import ot, ct
19
17
 
20
18
 
@@ -107,7 +105,7 @@ class GitCommitTool:
107
105
  diff = process.communicate()[0].decode()
108
106
  spinner.write(f"✅ 获取差异 ({file_count} 个文件)")
109
107
  try:
110
- temp_diff_file = None
108
+ temp_diff_file_path = None
111
109
  # 生成提交信息
112
110
  spinner.text = "正在生成提交消息..."
113
111
 
@@ -132,13 +130,12 @@ class GitCommitTool:
132
130
 
133
131
  # 获取模型并尝试上传文件
134
132
  platform = PlatformRegistry().get_normal_platform()
133
+ upload_success = False
135
134
 
136
- # 检查文件大小
137
- is_large_file = get_context_token_count(diff) > get_max_input_token_count() - INPUT_WINDOW_REVERSE_SIZE
135
+ # Check if content is too large
136
+ is_large_content = is_context_overflow(diff)
138
137
 
139
- if is_large_file:
140
- # 文件较大,尝试上传
141
- upload_success = False
138
+ if is_large_content and hasattr(platform, 'upload_files'):
142
139
  spinner.text = "正在上传代码差异文件..."
143
140
  try:
144
141
  with spinner.hidden():
@@ -148,72 +145,43 @@ class GitCommitTool:
148
145
  temp_diff_file.write(diff)
149
146
  temp_diff_file.flush()
150
147
  spinner.write(f"✅ 差异内容已写入临时文件")
151
-
152
- if hasattr(platform, 'upload_files'):
153
- upload_success = platform.upload_files([temp_diff_file_path])
154
- if upload_success:
155
- spinner.write(" 成功上传代码差异文件")
156
- else:
157
- spinner.write("⚠️ 上传代码差异文件失败,将使用chat_with_files处理")
158
- else:
159
- spinner.write("⚠️ 模型不支持文件上传,将使用chat_with_files处理")
148
+ upload_success = platform.upload_files([temp_diff_file_path])
149
+ if upload_success:
150
+ spinner.write("✅ 成功上传代码差异文件")
151
+ else:
152
+ spinner.write("⚠️ 上传代码差异文件失败,将使用分块处理")
160
153
  except Exception as e:
161
154
  spinner.write(f"⚠️ 上传文件时出错: {str(e)}")
162
155
  upload_success = False
163
-
164
- if upload_success:
165
- # 使用上传的文件
166
- prompt = base_prompt + f'''
156
+
157
+ # 根据上传状态准备完整的提示
158
+ if upload_success:
159
+ # 使用上传的文件
160
+ prompt = base_prompt + f'''
167
161
  # 变更概述
168
162
  - 变更文件数量: {file_count} 个文件
169
163
  - 已上传包含完整代码差异的文件
170
164
 
171
165
  请详细分析已上传的代码差异文件,生成符合上述格式的提交信息。
172
166
  '''
173
- else:
174
- # 使用chat_with_files处理大文件
175
- spinner.write("使用chat_with_files处理大文件...")
176
- commit_message = chat_with_files(
177
- [temp_diff_file_path],
178
- platform,
179
- base_prompt,
180
- "请基于以上代码差异生成符合格式的提交信息。"
181
- )
182
- commit_message = self._extract_commit_message(commit_message)
183
- if commit_message:
184
- spinner.write("✅ 生成提交消息")
185
- # 执行提交
186
- spinner.text = "正在准备提交..."
187
- with tempfile.NamedTemporaryFile(mode='w', delete=True) as tmp_file:
188
- tmp_file.write(commit_message)
189
- tmp_file.flush()
190
- spinner.text = "正在执行提交..."
191
- commit_cmd = ["git", "commit", "-F", tmp_file.name]
192
- subprocess.Popen(
193
- commit_cmd,
194
- stdout=subprocess.DEVNULL,
195
- stderr=subprocess.DEVNULL
196
- ).wait()
197
- spinner.write("✅ 提交")
198
- return {
199
- "success": True,
200
- "stdout": yaml.safe_dump({
201
- "commit_hash": self._get_last_commit_hash(),
202
- "commit_message": commit_message
203
- }),
204
- "stderr": ""
205
- }
206
167
  else:
207
- # 文件较小,直接在提示中包含差异内容
208
- prompt = base_prompt + f'''
168
+ # 如果上传失败但内容较大,使用chat_big_content
169
+ if is_large_content and hasattr(platform, 'chat_big_content'):
170
+ spinner.text = "正在使用分块处理生成提交信息..."
171
+ commit_message = platform.chat_big_content(diff, base_prompt)
172
+ else:
173
+ # 直接在提示中包含差异内容
174
+ prompt = base_prompt + f'''
209
175
  # 分析材料
210
176
  {diff}
211
177
  '''
178
+ commit_message = platform.chat_until_success(prompt)
212
179
 
213
180
  # 尝试生成提交信息
214
181
  spinner.text = "正在生成提交消息..."
215
182
  while True:
216
- commit_message = platform.chat_until_success(prompt)
183
+ if not upload_success and not is_large_content:
184
+ commit_message = platform.chat_until_success(prompt)
217
185
  commit_message = self._extract_commit_message(commit_message)
218
186
  # 如果成功提取,就跳出循环
219
187
  if commit_message:
@@ -246,7 +214,7 @@ class GitCommitTool:
246
214
  spinner.ok("✅")
247
215
  finally:
248
216
  # 清理临时差异文件
249
- if temp_diff_file is not None and os.path.exists(temp_diff_file_path):
217
+ if temp_diff_file_path is not None and os.path.exists(temp_diff_file_path):
250
218
  try:
251
219
  os.unlink(temp_diff_file_path)
252
220
  except Exception as e:
@@ -11,14 +11,14 @@ import hashlib
11
11
  import os
12
12
  import json
13
13
  import argparse
14
- import yaml
14
+ import yaml # type: ignore
15
15
  from jarvis.jarvis_utils.methodology import (
16
16
  _get_methodology_directory,
17
17
  _load_all_methodologies
18
18
  )
19
19
  from jarvis.jarvis_platform.registry import PlatformRegistry
20
20
  from jarvis.jarvis_utils.output import PrettyOutput, OutputType
21
- from yaspin import yaspin
21
+ from yaspin import yaspin # type: ignore
22
22
 
23
23
  def import_methodology(input_file):
24
24
  """导入方法论文件(合并策略)"""
@@ -1,6 +1,8 @@
1
1
  from abc import ABC, abstractmethod
2
2
  import re
3
3
  from typing import List, Tuple
4
+ from jarvis.jarvis_utils.config import get_max_input_token_count
5
+ from jarvis.jarvis_utils.embedding import split_text_into_chunks
4
6
  from jarvis.jarvis_utils.globals import clear_read_file_record
5
7
  from jarvis.jarvis_utils.output import OutputType, PrettyOutput
6
8
  from jarvis.jarvis_utils.utils import get_context_token_count, while_success, while_true
@@ -37,38 +39,49 @@ class BasePlatform(ABC):
37
39
  @abstractmethod
38
40
  def upload_files(self, file_list: List[str]) -> bool:
39
41
  raise NotImplementedError("upload_files is not implemented")
42
+
43
+ def chat_big_content(self, content: str, prompt: str) -> str:
44
+ prefix_prompt = f"""
45
+ 我将分多次提供大量的上下文内容,在我明确告诉你内容已经全部提供完毕之前,每次仅需要输出“已收到”。
46
+ """
47
+ self.chat_until_success(prefix_prompt)
48
+ split_content = split_text_into_chunks(content, get_max_input_token_count() - 1024)
49
+ for chunk in split_content:
50
+ self.chat_until_success(f"<part_content>{chunk}</part_content>")
51
+ return self.chat_until_success(f"内容已经全部提供完毕\n\n{prompt}")
40
52
 
53
+
54
+ def _chat(self, message: str):
55
+ import time
56
+ start_time = time.time()
57
+ response = self.chat(message)
58
+
59
+ end_time = time.time()
60
+ duration = end_time - start_time
61
+ char_count = len(response)
62
+
63
+ # Calculate token count and tokens per second
64
+ try:
65
+ token_count = get_context_token_count(response)
66
+ tokens_per_second = token_count / duration if duration > 0 else 0
67
+ except Exception as e:
68
+ PrettyOutput.print(f"Tokenization failed: {str(e)}", OutputType.WARNING)
69
+ token_count = 0
70
+ tokens_per_second = 0
71
+
72
+ # Print statistics
73
+ if not self.suppress_output:
74
+ PrettyOutput.print(
75
+ f"对话完成 - 耗时: {duration:.2f}秒, 输出字符数: {char_count}, 输出Token数量: {token_count}, 每秒Token数量: {tokens_per_second:.2f}",
76
+ OutputType.INFO,
77
+ )
78
+
79
+ # Keep original think tag handling
80
+ response = re.sub(ot("think")+r'.*?'+ct("think"), '', response, flags=re.DOTALL)
81
+ return response
82
+
41
83
  def chat_until_success(self, message: str) -> str:
42
- def _chat():
43
- import time
44
- start_time = time.time()
45
- response = self.chat(message)
46
-
47
- end_time = time.time()
48
- duration = end_time - start_time
49
- char_count = len(response)
50
-
51
- # Calculate token count and tokens per second
52
- try:
53
- token_count = get_context_token_count(response)
54
- tokens_per_second = token_count / duration if duration > 0 else 0
55
- except Exception as e:
56
- PrettyOutput.print(f"Tokenization failed: {str(e)}", OutputType.WARNING)
57
- token_count = 0
58
- tokens_per_second = 0
59
-
60
- # Print statistics
61
- if not self.suppress_output:
62
- PrettyOutput.print(
63
- f"对话完成 - 耗时: {duration:.2f}秒, 输出字符数: {char_count}, 输出Token数量: {token_count}, 每秒Token数量: {tokens_per_second:.2f}",
64
- OutputType.INFO,
65
- )
66
-
67
- # Keep original think tag handling
68
- response = re.sub(ot("think")+r'.*?'+ct("think"), '', response, flags=re.DOTALL)
69
- return response
70
-
71
- return while_true(lambda: while_success(lambda: _chat(), 5), 5)
84
+ return while_true(lambda: while_success(lambda: self._chat(message), 5), 5)
72
85
 
73
86
  @abstractmethod
74
87
  def name(self) -> str:
@@ -1,5 +1,5 @@
1
1
  from typing import Dict, List, Tuple
2
- import requests
2
+ import requests # type: ignore
3
3
  import json
4
4
  import os
5
5
  import mimetypes
@@ -178,7 +178,7 @@ class KimiModel(BasePlatform):
178
178
  if not file_list:
179
179
  return True
180
180
 
181
- from yaspin import yaspin
181
+ from yaspin import yaspin # type: ignore
182
182
 
183
183
  if not self.chat_id:
184
184
  with yaspin(text="创建聊天会话...", color="yellow") as spinner:
@@ -3,8 +3,8 @@ import os
3
3
 
4
4
  from jarvis.jarvis_platform.registry import PlatformRegistry
5
5
  from jarvis.jarvis_utils.output import OutputType, PrettyOutput
6
- from yaspin import yaspin
7
- from yaspin.spinners import Spinners
6
+ from yaspin import yaspin # type: ignore
7
+ from yaspin.spinners import Spinners # type: ignore
8
8
 
9
9
  class FileAnalyzerTool:
10
10
  name = "file_analyzer"
@@ -2,7 +2,7 @@ from typing import Dict, Any
2
2
  import os
3
3
  from pathlib import Path
4
4
 
5
- from yaspin import yaspin
5
+ from yaspin import yaspin # type: ignore
6
6
 
7
7
  from jarvis.jarvis_utils.globals import add_read_file_record
8
8
  from jarvis.jarvis_utils.output import OutputType, PrettyOutput
@@ -31,7 +31,7 @@ class WebpageTool:
31
31
 
32
32
  # Create Yuanbao model instance
33
33
  model = PlatformRegistry().get_normal_platform()
34
- model.web = True
34
+ model.set_web(True)
35
35
  model.set_suppress_output(False) # type: ignore
36
36
 
37
37
  # Construct prompt based on want parameter
@@ -3,6 +3,7 @@ from pathlib import Path
3
3
  import re
4
4
  import sys
5
5
  import tempfile
6
+ import os
6
7
  from typing import Any, Callable, Dict, List, Optional, Tuple
7
8
 
8
9
  import yaml
@@ -10,14 +11,9 @@ import yaml
10
11
  from jarvis.jarvis_agent.output_handler import OutputHandler
11
12
  from jarvis.jarvis_platform.registry import PlatformRegistry
12
13
  from jarvis.jarvis_tools.base import Tool
13
- from jarvis.jarvis_utils.config import (
14
- INPUT_WINDOW_REVERSE_SIZE,
15
- get_max_input_token_count,
16
- get_data_dir,
17
- )
18
- from jarvis.jarvis_utils.embedding import get_context_token_count
14
+ from jarvis.jarvis_utils.config import get_data_dir
19
15
  from jarvis.jarvis_utils.output import OutputType, PrettyOutput
20
- from jarvis.jarvis_utils.utils import init_env
16
+ from jarvis.jarvis_utils.utils import init_env, is_context_overflow
21
17
  from jarvis.jarvis_utils.tag import ot, ct
22
18
  from jarvis.jarvis_mcp.stdio_mcp_client import StdioMcpClient
23
19
  from jarvis.jarvis_mcp.sse_mcp_client import SSEMcpClient
@@ -175,9 +171,6 @@ class ToolRegistry(OutputHandler):
175
171
  self._load_builtin_tools()
176
172
  self._load_external_tools()
177
173
  self._load_mcp_tools()
178
- self.max_input_token_count = (
179
- get_max_input_token_count() - INPUT_WINDOW_REVERSE_SIZE
180
- )
181
174
 
182
175
  def use_tools(self, name: List[str]) -> None:
183
176
  """使用指定工具
@@ -618,46 +611,45 @@ class ToolRegistry(OutputHandler):
618
611
  result["stdout"], result.get("stderr", "")
619
612
  )
620
613
 
621
- # 处理结果
622
- if get_context_token_count(output) > self.max_input_token_count:
623
- with tempfile.NamedTemporaryFile(
624
- mode="w", suffix=".txt", delete=False
625
- ) as tmp_file:
614
+ # 检查内容是否过大
615
+ is_large_content = is_context_overflow(output)
616
+
617
+ if is_large_content:
618
+ # 创建临时文件
619
+ with tempfile.NamedTemporaryFile(mode="w", suffix=".txt", delete=False) as tmp_file:
626
620
  output_file = tmp_file.name
627
621
  tmp_file.write(output)
628
622
  tmp_file.flush()
629
- platform: Any = PlatformRegistry().get_normal_platform()
630
- if platform:
631
- platform.set_suppress_output(False)
632
- try:
623
+
624
+ try:
625
+ # 获取平台实例
626
+ platform = PlatformRegistry().get_normal_platform()
627
+ if platform and hasattr(platform, 'upload_files'):
628
+ platform.set_suppress_output(False)
633
629
  # 尝试上传文件
634
- if platform.upload_files([output_file]):
635
- prompt = f"""该文件为工具执行结果,请阅读文件内容,并根据文件提取出以下信息:{want}
636
-
637
- 注意:
638
- 1. 请仔细阅读文件内容,确保提取的信息准确完整
639
- 2. 如果文件内容包含错误信息,请特别关注并提取
640
- 3. 提取的信息应该直接回答用户的问题,不要包含无关内容"""
630
+ upload_success = platform.upload_files([output_file])
631
+
632
+ if upload_success:
633
+ # 使用上传的文件生成摘要
634
+ prompt = f"该文件为工具执行结果,请阅读文件内容,并根据文件提取出以下信息:{want}"
641
635
  return f"""工具调用原始输出过长,以下是根据输出提出的信息:
642
636
 
643
637
  {platform.chat_until_success(prompt)}"""
644
- else:
645
- # 上传失败,使用chat_with_files
646
- PrettyOutput.print("⚠️ 上传文件失败,将使用chat_with_files处理", OutputType.WARNING)
647
- from jarvis.jarvis_utils.utils import chat_with_files
648
- prompt = f"""请阅读以下文件内容,并根据文件提取出以下信息:{want}
649
-
650
- 注意:
651
- 1. 请仔细阅读文件内容,确保提取的信息准确完整
652
- 2. 如果文件内容包含错误信息,请特别关注并提取
653
- 3. 提取的信息应该直接回答用户的问题,不要包含无关内容"""
638
+ elif hasattr(platform, 'chat_big_content'):
639
+ # 如果上传失败但支持大内容处理,使用chat_big_content
640
+ prompt = f"以下内容为工具执行结果,请阅读内容,并根据内容提取出以下信息:{want}\n\n{output}"
654
641
  return f"""工具调用原始输出过长,以下是根据输出提出的信息:
655
642
 
656
- {chat_with_files([output_file], platform, prompt, "")}"""
657
- except Exception as e:
658
- PrettyOutput.print(f"处理大文件时出错: {str(e)}", OutputType.ERROR)
659
- return self._truncate_output(output)
660
- return self._truncate_output(output)
643
+ {platform.chat_big_content(output, prompt)}"""
644
+
645
+ # 如果都不支持,返回截断的输出
646
+ return self._truncate_output(output)
647
+ finally:
648
+ # 清理临时文件
649
+ try:
650
+ os.unlink(output_file)
651
+ except Exception:
652
+ pass
661
653
 
662
654
  return output
663
655
 
@@ -16,7 +16,7 @@ class SearchWebTool:
16
16
  def execute(self, args: Dict[str, Any]) -> Dict[str, Any]: # type: ignore
17
17
  query = args.get("query")
18
18
  model = PlatformRegistry().get_normal_platform()
19
- model.web = True
19
+ model.set_web(True)
20
20
  model.set_suppress_output(False) # type: ignore
21
21
  return {
22
22
  "stdout": model.chat_until_success(query), # type: ignore
@@ -11,10 +11,10 @@ import json
11
11
  import tempfile
12
12
  from typing import Dict, Optional
13
13
 
14
- from jarvis.jarvis_utils.config import INPUT_WINDOW_REVERSE_SIZE, get_max_input_token_count, get_data_dir
15
- from jarvis.jarvis_utils.embedding import get_context_token_count
14
+ from jarvis.jarvis_utils.config import get_data_dir
16
15
  from jarvis.jarvis_utils.output import PrettyOutput, OutputType
17
16
  from jarvis.jarvis_platform.registry import PlatformRegistry
17
+ from jarvis.jarvis_utils.utils import is_context_overflow
18
18
 
19
19
  def _get_methodology_directory() -> str:
20
20
  """
@@ -101,7 +101,7 @@ def load_methodology(user_input: str) -> str:
101
101
  返回:
102
102
  str: 相关的方法论提示,如果未找到方法论则返回空字符串
103
103
  """
104
- from yaspin import yaspin
104
+ from yaspin import yaspin # type: ignore
105
105
 
106
106
  # 获取方法论目录
107
107
  methodology_dir = _get_methodology_directory()
@@ -121,33 +121,21 @@ def load_methodology(user_input: str) -> str:
121
121
 
122
122
  # 获取当前平台
123
123
  platform = PlatformRegistry().get_normal_platform()
124
+ if not platform:
125
+ return ""
126
+
127
+ # 构建基础提示信息
128
+ base_prompt = f"""以下是所有可用的方法论内容:
129
+
130
+ """
131
+ # 构建完整内容
132
+ full_content = base_prompt
133
+ for problem_type, content in methodologies.items():
134
+ full_content += f"## {problem_type}\n\n{content}\n\n---\n\n"
124
135
 
125
- # 检查是否需要特殊处理大文件
126
- if get_context_token_count(user_input) > get_max_input_token_count() - INPUT_WINDOW_REVERSE_SIZE:
127
- # 创建临时文件
128
- with yaspin(text="创建方法论临时文件...", color="yellow") as spinner:
129
- temp_file_path = _create_methodology_temp_file(methodologies)
130
- if not temp_file_path:
131
- spinner.text = "创建方法论临时文件失败"
132
- spinner.fail("❌")
133
- return ""
134
- spinner.text = f"创建方法论临时文件完成: {temp_file_path}"
135
- spinner.ok("✅")
136
-
137
- # 尝试上传文件
138
- upload_success = False
139
- try:
140
- if platform.upload_files([temp_file_path]):
141
- upload_success = True
142
- spinner.write("✅ 成功上传方法论文件")
143
- else:
144
- spinner.write("⚠️ 上传方法论文件失败,将使用chat_with_files处理")
145
- except Exception as e:
146
- spinner.write(f"⚠️ 上传文件时出错: {str(e)}")
147
- upload_success = False
148
-
149
- # 构建提示信息
150
- prompt = f"""请根据以下方法论内容,总结出与以下用户需求相关的方法论: {user_input}
136
+ # 添加用户输入和输出要求
137
+ full_content += f"""
138
+ 请根据以上方法论内容,总结出与以下用户需求相关的方法论: {user_input}
151
139
 
152
140
  请按以下格式回复:
153
141
  ### 与该任务/需求相关的方法论
@@ -157,24 +145,48 @@ def load_methodology(user_input: str) -> str:
157
145
  [总结的方法论内容]
158
146
 
159
147
  如果没有匹配的方法论,请输出:没有历史方法论可参考
160
- 除以上要求外,不要输出任何内容"""
161
-
162
- if upload_success:
163
- # 使用上传的文件
164
- return platform.chat_until_success(prompt)
165
- else:
166
- # 使用chat_with_files处理大文件
167
- from jarvis.jarvis_utils.utils import chat_with_files
168
- return chat_with_files([temp_file_path], platform, prompt, "")
169
- else:
170
- # 上下文足够,直接在prompt中包含方法论内容
171
- prompt = f"""以下是所有可用的方法论内容:
172
-
148
+ 除以上要求外,不要输出任何内容
173
149
  """
174
- for problem_type, content in methodologies.items():
175
- prompt += f"## {problem_type}\n\n{content}\n\n---\n\n"
176
-
177
- prompt += f"""
150
+
151
+ # 检查内容是否过大
152
+ is_large_content = is_context_overflow(full_content)
153
+ temp_file_path = None
154
+
155
+ try:
156
+ if is_large_content:
157
+ # 创建临时文件
158
+ with yaspin(text="创建方法论临时文件...", color="yellow") as spinner:
159
+ temp_file_path = _create_methodology_temp_file(methodologies)
160
+ if not temp_file_path:
161
+ spinner.text = "创建方法论临时文件失败"
162
+ spinner.fail("❌")
163
+ return ""
164
+ spinner.text = f"创建方法论临时文件完成: {temp_file_path}"
165
+ spinner.ok("✅")
166
+
167
+ # 尝试上传文件
168
+ if hasattr(platform, 'upload_files'):
169
+ platform.set_suppress_output(False)
170
+ upload_success = platform.upload_files([temp_file_path])
171
+
172
+ if upload_success:
173
+ # 使用上传的文件生成摘要
174
+ return platform.chat_until_success(base_prompt + f"""
175
+ 请根据已上传的方法论文件内容,总结出与以下用户需求相关的方法论: {user_input}
176
+
177
+ 请按以下格式回复:
178
+ ### 与该任务/需求相关的方法论
179
+ 1. [方法论名字]
180
+ 2. [方法论名字]
181
+ ### 根据以上方法论,总结出方法论内容
182
+ [总结的方法论内容]
183
+
184
+ 如果没有匹配的方法论,请输出:没有历史方法论可参考
185
+ 除以上要求外,不要输出任何内容
186
+ """)
187
+ elif hasattr(platform, 'chat_big_content'):
188
+ # 如果上传失败但支持大内容处理,使用chat_big_content
189
+ return platform.chat_big_content(full_content, base_prompt + f"""
178
190
  请根据以上方法论内容,总结出与以下用户需求相关的方法论: {user_input}
179
191
 
180
192
  请按以下格式回复:
@@ -185,22 +197,20 @@ def load_methodology(user_input: str) -> str:
185
197
  [总结的方法论内容]
186
198
 
187
199
  如果没有匹配的方法论,请输出:没有历史方法论可参考
188
- 除以上要求外,不要输出任何内容"""
189
- return platform.chat_until_success(prompt)
200
+ 除以上要求外,不要输出任何内容
201
+ """)
202
+
203
+ # 如果内容不大或上传失败,直接使用chat_until_success
204
+ return platform.chat_until_success(full_content)
205
+
206
+ finally:
207
+ # 清理临时文件
208
+ if temp_file_path and os.path.exists(temp_file_path):
209
+ try:
210
+ os.remove(temp_file_path)
211
+ except Exception:
212
+ pass
190
213
 
191
214
  except Exception as e:
192
215
  PrettyOutput.print(f"加载方法论失败: {str(e)}", OutputType.ERROR)
193
- # 清理临时文件
194
- if 'temp_file_path' in locals() and temp_file_path and os.path.exists(temp_file_path):
195
- try:
196
- os.remove(temp_file_path)
197
- except:
198
- pass
199
216
  return ""
200
- finally:
201
- # 确保清理临时文件
202
- if 'temp_file_path' in locals() and temp_file_path and os.path.exists(temp_file_path):
203
- try:
204
- os.remove(temp_file_path)
205
- except:
206
- pass
@@ -3,8 +3,8 @@ import time
3
3
  import hashlib
4
4
  from pathlib import Path
5
5
  from typing import List, Any, Callable
6
- from jarvis.jarvis_utils.config import get_max_input_token_count, get_data_dir
7
- from jarvis.jarvis_utils.embedding import get_context_token_count, split_text_into_chunks
6
+ from jarvis.jarvis_utils.config import INPUT_WINDOW_REVERSE_SIZE, get_max_input_token_count, get_data_dir
7
+ from jarvis.jarvis_utils.embedding import get_context_token_count
8
8
  from jarvis.jarvis_utils.input import get_single_line_input
9
9
  from jarvis.jarvis_utils.output import PrettyOutput, OutputType
10
10
  def init_env() -> None:
@@ -130,13 +130,6 @@ def is_long_context(files: List[str]) -> bool:
130
130
  return total_tokens > threshold
131
131
 
132
132
 
133
- def chat_with_files(files: List[str], platform: Any, prompt_prefix: str, prompt_suffix: str) -> str:
134
- from jarvis.jarvis_platform.base import BasePlatform
135
- from jarvis.jarvis_tools.file_operation import FileOperationTool
136
- platform_: BasePlatform = platform
137
- file_content = FileOperationTool().execute({"operation":"read", "files":files})["stdout"]
138
- file_content_chuck = split_text_into_chunks(file_content, get_max_input_token_count()-2048)
139
- platform_.chat_until_success(prompt_prefix)
140
- for file_content_chunk in file_content_chuck:
141
- platform_.chat_until_success(file_content_chunk)
142
- return platform_.chat_until_success(prompt_suffix)
133
+ def is_context_overflow(file_content: str) -> bool:
134
+ """判断文件内容是否超出上下文限制"""
135
+ return get_context_token_count(file_content) > get_max_input_token_count() - INPUT_WINDOW_REVERSE_SIZE
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: jarvis-ai-assistant
3
- Version: 0.1.159
3
+ Version: 0.1.160
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
@@ -194,7 +194,7 @@ jarvis-methodology --help
194
194
  ### 环境变量配置
195
195
  | 变量名称 | 默认值 | 说明 |
196
196
  |----------|--------|------|
197
- | `JARVIS_MAX_TOKEN_COUNT` | 102400000 | 上下文最大token数量 |
197
+ | `JARVIS_MAX_TOKEN_COUNT` | 102400000 | 上下文窗口的最大token数量 |
198
198
  | `JARVIS_MAX_INPUT_TOKEN_COUNT` | 32000 | 输入的最大token数量 |
199
199
  | `JARVIS_AUTO_COMPLETE` | false | 是否启用自动完成功能(任务判定完成的时候会自动终止) |
200
200
  | `JARVIS_SHELL_NAME` | bash | 系统shell名称 |
@@ -1,15 +1,15 @@
1
- jarvis/__init__.py,sha256=_IZ4qsot_luvb5GqI5sZmjlOdVcITvyPV8qcjgeUK4Y,50
1
+ jarvis/__init__.py,sha256=2BC-X3PyDiJd9_Z7-M3Dz_vjF41hQuACD5kortAXRDM,50
2
2
  jarvis/jarvis_agent/__init__.py,sha256=tii6khwfG971MJiMfKSLwlKTjB3iEv8ITE3JqYSkfQA,24824
3
3
  jarvis/jarvis_agent/builtin_input_handler.py,sha256=3rRA-7v_VUSFG1s7tTKhriq9vv0nsa3t69ReV0xH5gs,1505
4
- jarvis/jarvis_agent/file_input_handler.py,sha256=auBbBfS4Ux5ksczeRe9LtsmMm4hKrPxinW5leE9Rtyc,3575
4
+ jarvis/jarvis_agent/file_input_handler.py,sha256=88VqJLe3oO9GtIRsqyx3KwZl10Apob2ddFMH3HQ2RMg,3413
5
5
  jarvis/jarvis_agent/jarvis.py,sha256=6Bp_Y-E3RN6bDmDs5lN3uALL_Dhq-p_aIuVNELG1vtw,5898
6
6
  jarvis/jarvis_agent/main.py,sha256=Jlw_Tofh2C-sMVnkeOZBrwWJOWNH3IhsKDUn-WBlgU8,2602
7
7
  jarvis/jarvis_agent/output_handler.py,sha256=4limQ-Kf-YYvQjT5SMjJIyyvD1DVG8tINv1A_qbv4ho,405
8
- jarvis/jarvis_agent/patch.py,sha256=LjOlnd6AoG9RyzphmCdv9J514-aOX_bXG67lXXQxEvo,23673
8
+ jarvis/jarvis_agent/patch.py,sha256=qeRZ6r1qpgHnWpX5uOX4dB3qRCPI1ibk4J50NmoJ74s,23531
9
9
  jarvis/jarvis_agent/shell_input_handler.py,sha256=9IoGQCe6FF4HA2V5S11q63AtnWDZFpNeRd3hcqCAlBw,1237
10
10
  jarvis/jarvis_code_agent/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
11
11
  jarvis/jarvis_code_agent/code_agent.py,sha256=vi_g-LWdD5nn3RQsC1X8G2iNK8SrBADwFLUkflqtvKE,13723
12
- jarvis/jarvis_code_analysis/code_review.py,sha256=wCnj2qr4QhIvcItn8aOCqDqjrEjRnw7mtYHhlkK29xE,30599
12
+ jarvis/jarvis_code_analysis/code_review.py,sha256=gB9Xo0-FT6zciDzZb3jF6zxxWA_Aj8QU5008Tmu_Tr4,30192
13
13
  jarvis/jarvis_code_analysis/checklists/__init__.py,sha256=PCjlyxLa939613cAzS7pfEPgP57setO-1RvcdzzPivw,54
14
14
  jarvis/jarvis_code_analysis/checklists/c_cpp.py,sha256=8lfWmhImAxeTBdHPOgVXDjMllaq280Qki1ZOOSDBnvk,1293
15
15
  jarvis/jarvis_code_analysis/checklists/csharp.py,sha256=fg35Iima2nIsirEmAjianfAybVjwRYml9BtbSQFff7w,2396
@@ -35,7 +35,7 @@ jarvis/jarvis_git_details/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJW
35
35
  jarvis/jarvis_git_details/main.py,sha256=YowncVxYyJ3y2EvGrZhAJeR4yizXp6aB3dqvoYTepFY,6117
36
36
  jarvis/jarvis_git_squash/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
37
37
  jarvis/jarvis_git_squash/main.py,sha256=xBNkAl7_8_pQC-C6RcUImA1mEU4KTqhjtA57rG_mMJ8,2179
38
- jarvis/jarvis_git_utils/git_commiter.py,sha256=hP4rQqqKtgu9kw46oK9V8rOwG2IqxAXgNuv0YHX-Qd0,13712
38
+ jarvis/jarvis_git_utils/git_commiter.py,sha256=nOzM5Zio6CYxuo14YfZHrdr5rPS-yjM0_UbRhsXjPy4,11644
39
39
  jarvis/jarvis_lsp/base.py,sha256=f-76xgNijfQ4G3Q0t8IfOGtCu-q2TSQ7a_in6XwDb_8,2030
40
40
  jarvis/jarvis_lsp/cpp.py,sha256=ekci2M9_UtkCSEe9__72h26Gat93r9_knL2VmFr8X5M,3141
41
41
  jarvis/jarvis_lsp/go.py,sha256=sSypuQSP5X2YtrVMC8XCc5nXkgfG93SO7sC89lHzoR8,3458
@@ -45,13 +45,13 @@ jarvis/jarvis_lsp/rust.py,sha256=ICmQs5UVdMZwn5KjaF1YRXBCLUMtGF8Z9IwE5rqWkrU,368
45
45
  jarvis/jarvis_mcp/__init__.py,sha256=gi74_Yz5nsEFhrAyCg1Ovxsj-hLweLjMGoOaceL2yx4,2090
46
46
  jarvis/jarvis_mcp/sse_mcp_client.py,sha256=Qd09ymgZmxQvaFUzz8I3AI46v6AqmMbGaF0iBbExAGY,23459
47
47
  jarvis/jarvis_mcp/stdio_mcp_client.py,sha256=DtRO4dqBoxI8W0H0rVR5zxZLR0theKxRAQ-qzQE9qPg,11806
48
- jarvis/jarvis_methodology/main.py,sha256=i0sOKeGf9-87M0jY4q6sgw4dAPt800PHiZjseLAQmO0,11782
48
+ jarvis/jarvis_methodology/main.py,sha256=JrUqWKN0gQeiO_tY2Tn14pnT_jClqlNgpbBfoc-q8SM,11812
49
49
  jarvis/jarvis_multi_agent/__init__.py,sha256=SX8lBErhltKyYRM-rymrMz3sJ0Zl3hBXrpsPdFgzkQc,4399
50
50
  jarvis/jarvis_multi_agent/main.py,sha256=aGuUC3YQmahabqwDwZXJjfQLYsZ3KIZdf8DZDlVNMe4,1543
51
51
  jarvis/jarvis_platform/__init__.py,sha256=oD9i4ugZ2q6Hys3noLOvzPUUHqE2PJ_Je1r2dLLTscw,80
52
- jarvis/jarvis_platform/base.py,sha256=um9_BZgOJSg0nlmywYGAxwFRL-8409OnlvfgQkh5RUo,3406
52
+ jarvis/jarvis_platform/base.py,sha256=OfVG7jw-0han9yEooJLL0Sk3ZlgzItZwJOgRxZdFLfs,4085
53
53
  jarvis/jarvis_platform/human.py,sha256=WCzvBtQUMN7ys4rQl6UT7Zdp4x5RaGv1U4vBx7ROxfo,2438
54
- jarvis/jarvis_platform/kimi.py,sha256=GgUekusFzx2842K-PrES3c2oprLbPCjQhbyjU0UKycg,16637
54
+ jarvis/jarvis_platform/kimi.py,sha256=Wno9PFZ92v9fjBHS29sFUwoc6gk6akD7yelVaWOpp-Q,16667
55
55
  jarvis/jarvis_platform/registry.py,sha256=wvXTKXqAoW6GPaLKCPYhRB9QhVe1xfoVbVPBZAxl_uA,7716
56
56
  jarvis/jarvis_platform/yuanbao.py,sha256=9nIyg5Xx9rdUaJAK_Tj8HumOT5mwpa-V907dZGot-4E,21811
57
57
  jarvis/jarvis_platform_manager/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -67,15 +67,15 @@ jarvis/jarvis_tools/code_plan.py,sha256=jNa2rs4J3Fam8Q_RHE2_QvVch21TPp-Zfv-W6iQ3
67
67
  jarvis/jarvis_tools/create_code_agent.py,sha256=SRiQXZf57ViIDh6YSEmJkcoSKft0-y3iDfWF8f1bvZU,3387
68
68
  jarvis/jarvis_tools/create_sub_agent.py,sha256=wGiHukvi58wb1AKW5beP7R8VvApOn8TOeGmtXsmcETE,3001
69
69
  jarvis/jarvis_tools/execute_script.py,sha256=AeuC3yZIg-nBq_LTIyqxu-lG_uLG63lvwO28A6dRDYA,5715
70
- jarvis/jarvis_tools/file_analyzer.py,sha256=XCsFB4dZ9qy2q929hqi1rTngj6AtRtIaPx_W7lJAcpQ,4814
71
- jarvis/jarvis_tools/file_operation.py,sha256=sB1x0zI1dULXV7FG17wkiMQ7mQAEnXVd_5rakQ0Thik,9109
70
+ jarvis/jarvis_tools/file_analyzer.py,sha256=EVl7WqGgZoaQXqEX8vLynpqZDE3aug1hVBJbycT7YiY,4844
71
+ jarvis/jarvis_tools/file_operation.py,sha256=zbc1zX_aJ-9x1wpuUUbZOgg0aN8f5sd9ryaCQ-bi870,9124
72
72
  jarvis/jarvis_tools/find_methodology.py,sha256=TIUrezAql6wY3-wqnOPfGrO0tqS5N_-eU6YimCzaepM,2268
73
73
  jarvis/jarvis_tools/lsp_get_diagnostics.py,sha256=IYqv8jQwSK71sZpDBRolSDnYii8t0M7fzLthhMYTeGk,5322
74
74
  jarvis/jarvis_tools/methodology.py,sha256=gnlJojY4Dg5v9AAB5xcpKqpPIHs0tOYVtzTHkwOrWk0,5214
75
75
  jarvis/jarvis_tools/read_code.py,sha256=_X6D3AIgRD9YplSDnFhXOm8wQAZMA3pkkXy31SG33l0,6041
76
- jarvis/jarvis_tools/read_webpage.py,sha256=1AXXEX69fPJsPL7PBZDM1G4Z-MM13pUt34JXitsAFM4,2022
77
- jarvis/jarvis_tools/registry.py,sha256=ZI5MHhtHm6UvdarvIVu0Kg8BuqV4MIVvVGwOa8yWh74,27531
78
- jarvis/jarvis_tools/search_web.py,sha256=hMrcSnKcjH6YcV8WY4tangEid7y1L-QbyeXDlBofoy8,756
76
+ jarvis/jarvis_tools/read_webpage.py,sha256=ECcMnPnUpIeiSA1IRdUf7uLWMe34Ian9pExSxekwpcg,2025
77
+ jarvis/jarvis_tools/registry.py,sha256=6md5Fm-Uv0dhTHj0qubHRj0VQkNIcNn0A1cshBOQY5o,27109
78
+ jarvis/jarvis_tools/search_web.py,sha256=p1oahjSmSeBO9ZzgWkxIHsfcAGah22ju0xipXmuqnzg,759
79
79
  jarvis/jarvis_tools/virtual_tty.py,sha256=Rpn9VXUG17LQsY87F_O6UCjN_opXB05mpwozxYf-xVI,16372
80
80
  jarvis/jarvis_utils/__init__.py,sha256=KMg-KY5rZIhGTeOD5e2Xo5CU7DX1DUz4ULWAaTQ-ZNw,825
81
81
  jarvis/jarvis_utils/builtin_replace_map.py,sha256=Dt8YL4Sk5uALTMPT_n-lhshRWvFWPRPwV4stASOecQ8,4290
@@ -85,13 +85,13 @@ jarvis/jarvis_utils/file_processors.py,sha256=oNtVlz2JHcQ60NS6sgI-VsvYXOnsQgFUEV
85
85
  jarvis/jarvis_utils/git_utils.py,sha256=j_Jw6h7JD91XhMf0WD3MAH4URkLUBrrYCLnuLm1GeN4,5630
86
86
  jarvis/jarvis_utils/globals.py,sha256=Ed2d6diWXCgI74HVV_tI4qW7yXxLpNvQKN2yG0IH9hc,3388
87
87
  jarvis/jarvis_utils/input.py,sha256=zvL-JQSJvkmsZB7ApJsaVpk46BkpmJA3I_BnWSl_D-4,7299
88
- jarvis/jarvis_utils/methodology.py,sha256=OKD3OwScJgpTilrAt38Iu5Xlp3_i6joPZB82TE8PAZw,7592
88
+ jarvis/jarvis_utils/methodology.py,sha256=a1QJLqZ-_RwhL6i7C6mixhT1BmOvZ0mKmh3PTOiNT9M,7744
89
89
  jarvis/jarvis_utils/output.py,sha256=BmWdB1bmizv0xfU4Z___9p_xQodorriIcEgADVq9fk0,8416
90
90
  jarvis/jarvis_utils/tag.py,sha256=YtXBYuZWy8j8YbeQX2qRrHRQl6Gp2Vt7W4p-2yjo0a4,405
91
- jarvis/jarvis_utils/utils.py,sha256=Qds24SeHJZShb1w4CBp3uKT3zUiltAUFyvh_KfxvBkM,4936
92
- jarvis_ai_assistant-0.1.159.dist-info/licenses/LICENSE,sha256=AGgVgQmTqFvaztRtCAXsAMryUymB18gZif7_l2e1XOg,1063
93
- jarvis_ai_assistant-0.1.159.dist-info/METADATA,sha256=gID-zAYn10pXQXEjVrrgbu8m188dW2HV7QhOMlcyyDU,12660
94
- jarvis_ai_assistant-0.1.159.dist-info/WHEEL,sha256=0CuiUZ_p9E4cD6NyLD6UG80LBXYyiSYZOKDm5lp32xk,91
95
- jarvis_ai_assistant-0.1.159.dist-info/entry_points.txt,sha256=cKz_9SEpOvElTubKPMZMAdskD4GHz-NyKWRNssIVAWE,973
96
- jarvis_ai_assistant-0.1.159.dist-info/top_level.txt,sha256=1BOxyWfzOP_ZXj8rVTDnNCJ92bBGB0rwq8N1PCpoMIs,7
97
- jarvis_ai_assistant-0.1.159.dist-info/RECORD,,
91
+ jarvis/jarvis_utils/utils.py,sha256=neokG_C9Djw6shwLcBxpQmRF5KFp9P6v52bMJMEFozg,4487
92
+ jarvis_ai_assistant-0.1.160.dist-info/licenses/LICENSE,sha256=AGgVgQmTqFvaztRtCAXsAMryUymB18gZif7_l2e1XOg,1063
93
+ jarvis_ai_assistant-0.1.160.dist-info/METADATA,sha256=yjL-ZV1dnisJxbtkjiQH9fOeGGv0hI7SUGKIPWnz_h8,12669
94
+ jarvis_ai_assistant-0.1.160.dist-info/WHEEL,sha256=0CuiUZ_p9E4cD6NyLD6UG80LBXYyiSYZOKDm5lp32xk,91
95
+ jarvis_ai_assistant-0.1.160.dist-info/entry_points.txt,sha256=cKz_9SEpOvElTubKPMZMAdskD4GHz-NyKWRNssIVAWE,973
96
+ jarvis_ai_assistant-0.1.160.dist-info/top_level.txt,sha256=1BOxyWfzOP_ZXj8rVTDnNCJ92bBGB0rwq8N1PCpoMIs,7
97
+ jarvis_ai_assistant-0.1.160.dist-info/RECORD,,