jarvis-ai-assistant 0.1.224__py3-none-any.whl → 0.2.0__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.
- jarvis/__init__.py +1 -1
- jarvis/jarvis_agent/__init__.py +33 -11
- jarvis/jarvis_agent/jarvis.py +87 -32
- jarvis/jarvis_agent/main.py +13 -2
- jarvis/jarvis_code_agent/code_agent.py +17 -4
- jarvis/jarvis_code_analysis/checklists/loader.py +20 -6
- jarvis/jarvis_code_analysis/code_review.py +14 -3
- jarvis/jarvis_data/config_schema.json +41 -0
- jarvis/jarvis_git_utils/git_commiter.py +9 -2
- jarvis/jarvis_mcp/sse_mcp_client.py +9 -7
- jarvis/jarvis_mcp/stdio_mcp_client.py +2 -2
- jarvis/jarvis_platform/base.py +28 -13
- jarvis/jarvis_platform_manager/main.py +18 -6
- jarvis/jarvis_rag/llm_interface.py +1 -3
- jarvis/jarvis_smart_shell/main.py +18 -12
- jarvis/jarvis_tools/ask_user.py +1 -0
- jarvis/jarvis_tools/generate_new_tool.py +1 -0
- jarvis/jarvis_tools/registry.py +17 -9
- jarvis/jarvis_tools/search_web.py +19 -9
- jarvis/jarvis_utils/builtin_replace_map.py +0 -1
- jarvis/jarvis_utils/config.py +80 -21
- jarvis/jarvis_utils/git_utils.py +2 -2
- jarvis/jarvis_utils/globals.py +17 -11
- jarvis/jarvis_utils/methodology.py +37 -23
- jarvis/jarvis_utils/output.py +2 -2
- jarvis/jarvis_utils/utils.py +138 -3
- {jarvis_ai_assistant-0.1.224.dist-info → jarvis_ai_assistant-0.2.0.dist-info}/METADATA +49 -12
- {jarvis_ai_assistant-0.1.224.dist-info → jarvis_ai_assistant-0.2.0.dist-info}/RECORD +32 -32
- {jarvis_ai_assistant-0.1.224.dist-info → jarvis_ai_assistant-0.2.0.dist-info}/WHEEL +0 -0
- {jarvis_ai_assistant-0.1.224.dist-info → jarvis_ai_assistant-0.2.0.dist-info}/entry_points.txt +0 -0
- {jarvis_ai_assistant-0.1.224.dist-info → jarvis_ai_assistant-0.2.0.dist-info}/licenses/LICENSE +0 -0
- {jarvis_ai_assistant-0.1.224.dist-info → jarvis_ai_assistant-0.2.0.dist-info}/top_level.txt +0 -0
jarvis/jarvis_platform/base.py
CHANGED
@@ -1,7 +1,10 @@
|
|
1
1
|
# -*- coding: utf-8 -*-
|
2
2
|
import re
|
3
3
|
from abc import ABC, abstractmethod
|
4
|
-
from
|
4
|
+
from types import TracebackType
|
5
|
+
from typing import Generator, List, Optional, Tuple, Type
|
6
|
+
|
7
|
+
from typing_extensions import Self
|
5
8
|
|
6
9
|
from rich import box # type: ignore
|
7
10
|
from rich.live import Live # type: ignore
|
@@ -28,9 +31,19 @@ class BasePlatform(ABC):
|
|
28
31
|
self.suppress_output = True # 添加输出控制标志
|
29
32
|
self.web = False # 添加web属性,默认false
|
30
33
|
self._saved = False
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
+
self.model_group: Optional[str] = None
|
35
|
+
|
36
|
+
def __enter__(self) -> Self:
|
37
|
+
"""Enter context manager"""
|
38
|
+
return self
|
39
|
+
|
40
|
+
def __exit__(
|
41
|
+
self,
|
42
|
+
exc_type: Optional[Type[BaseException]],
|
43
|
+
exc_val: Optional[BaseException],
|
44
|
+
exc_tb: Optional[TracebackType],
|
45
|
+
) -> None:
|
46
|
+
"""Exit context manager"""
|
34
47
|
if not self._saved:
|
35
48
|
self.delete_chat()
|
36
49
|
|
@@ -64,9 +77,11 @@ class BasePlatform(ABC):
|
|
64
77
|
|
65
78
|
input_token_count = get_context_token_count(message)
|
66
79
|
|
67
|
-
if input_token_count > get_max_input_token_count():
|
68
|
-
max_chunk_size =
|
69
|
-
|
80
|
+
if input_token_count > get_max_input_token_count(self.model_group):
|
81
|
+
max_chunk_size = (
|
82
|
+
get_max_input_token_count(self.model_group) - 1024
|
83
|
+
) # 留出一些余量
|
84
|
+
min_chunk_size = get_max_input_token_count(self.model_group) - 2048
|
70
85
|
inputs = split_text_into_chunks(message, max_chunk_size, min_chunk_size)
|
71
86
|
print("📤 正在提交长上下文...")
|
72
87
|
prefix_prompt = f"""
|
@@ -95,14 +110,10 @@ class BasePlatform(ABC):
|
|
95
110
|
):
|
96
111
|
response += trunk
|
97
112
|
|
98
|
-
print(
|
99
|
-
f"📤 提交第{submit_count}部分完成,当前进度:{length}/{len(message)}"
|
100
|
-
)
|
113
|
+
print(f"📤 提交第{submit_count}部分完成,当前进度:{length}/{len(message)}")
|
101
114
|
print("✅ 提交完成")
|
102
115
|
response += "\n" + while_true(
|
103
|
-
lambda: while_success(
|
104
|
-
lambda: self._chat("内容已经全部提供完毕,请根据内容继续"), 5
|
105
|
-
),
|
116
|
+
lambda: while_success(lambda: self._chat("内容已经全部提供完毕,请根据内容继续"), 5),
|
106
117
|
5,
|
107
118
|
)
|
108
119
|
else:
|
@@ -233,6 +244,10 @@ class BasePlatform(ABC):
|
|
233
244
|
"""Set whether to suppress output"""
|
234
245
|
self.suppress_output = suppress
|
235
246
|
|
247
|
+
def set_model_group(self, model_group: Optional[str]):
|
248
|
+
"""Set model group"""
|
249
|
+
self.model_group = model_group
|
250
|
+
|
236
251
|
def set_web(self, web: bool):
|
237
252
|
"""Set web flag"""
|
238
253
|
self.web = web
|
@@ -188,9 +188,13 @@ def chat_with_model(platform_name: str, model_name: str, system_prompt: str) ->
|
|
188
188
|
for entry in conversation_history:
|
189
189
|
file_obj.write(f"{entry['role']}: {entry['content']}\n\n")
|
190
190
|
|
191
|
-
PrettyOutput.print(
|
191
|
+
PrettyOutput.print(
|
192
|
+
f"所有对话已保存到 {file_path}", OutputType.SUCCESS
|
193
|
+
)
|
192
194
|
except Exception as exc:
|
193
|
-
PrettyOutput.print(
|
195
|
+
PrettyOutput.print(
|
196
|
+
f"保存所有对话失败: {str(exc)}", OutputType.ERROR
|
197
|
+
)
|
194
198
|
continue
|
195
199
|
|
196
200
|
# Check if it is a save_session command
|
@@ -211,7 +215,9 @@ def chat_with_model(platform_name: str, model_name: str, system_prompt: str) ->
|
|
211
215
|
file_path = file_path[1:-1]
|
212
216
|
|
213
217
|
if platform.save(file_path):
|
214
|
-
PrettyOutput.print(
|
218
|
+
PrettyOutput.print(
|
219
|
+
f"会话已保存到 {file_path}", OutputType.SUCCESS
|
220
|
+
)
|
215
221
|
else:
|
216
222
|
PrettyOutput.print("保存会话失败", OutputType.ERROR)
|
217
223
|
except Exception as exc:
|
@@ -237,7 +243,9 @@ def chat_with_model(platform_name: str, model_name: str, system_prompt: str) ->
|
|
237
243
|
|
238
244
|
if platform.restore(file_path):
|
239
245
|
conversation_history = [] # Clear local history after loading
|
240
|
-
PrettyOutput.print(
|
246
|
+
PrettyOutput.print(
|
247
|
+
f"会话已从 {file_path} 加载", OutputType.SUCCESS
|
248
|
+
)
|
241
249
|
else:
|
242
250
|
PrettyOutput.print("加载会话失败", OutputType.ERROR)
|
243
251
|
except Exception as exc:
|
@@ -433,8 +441,12 @@ def main() -> None:
|
|
433
441
|
service_parser.add_argument(
|
434
442
|
"--port", type=int, default=8000, help="服务端口 (默认: 8000)"
|
435
443
|
)
|
436
|
-
service_parser.add_argument(
|
437
|
-
|
444
|
+
service_parser.add_argument(
|
445
|
+
"--platform", "-p", help="指定默认平台,当客户端未指定平台时使用"
|
446
|
+
)
|
447
|
+
service_parser.add_argument(
|
448
|
+
"--model", "-m", help="指定默认模型,当客户端未指定平台时使用"
|
449
|
+
)
|
438
450
|
service_parser.set_defaults(func=service_command)
|
439
451
|
|
440
452
|
# role subcommand
|
@@ -101,9 +101,7 @@ class JarvisPlatform_LLM(LLMInterface):
|
|
101
101
|
try:
|
102
102
|
self.registry = PlatformRegistry.get_global_platform_registry()
|
103
103
|
self.platform: BasePlatform = self.registry.get_normal_platform()
|
104
|
-
self.platform.set_suppress_output(
|
105
|
-
False
|
106
|
-
) # 确保模型没有控制台输出
|
104
|
+
self.platform.set_suppress_output(False) # 确保模型没有控制台输出
|
107
105
|
print(f"🚀 已初始化 Jarvis 平台 LLM,模型: {self.platform.name()}")
|
108
106
|
except Exception as e:
|
109
107
|
print(f"❌ 初始化 Jarvis 平台 LLM 失败: {e}")
|
@@ -20,34 +20,37 @@ def execute_command(command: str, should_run: bool) -> None:
|
|
20
20
|
|
21
21
|
def _check_fish_shell() -> bool:
|
22
22
|
"""Check if current shell is fish
|
23
|
-
|
23
|
+
|
24
24
|
Returns:
|
25
25
|
bool: True if fish shell, False otherwise
|
26
26
|
"""
|
27
27
|
return get_shell_name() == "fish"
|
28
28
|
|
29
|
+
|
29
30
|
def _get_config_file() -> str:
|
30
31
|
"""Get fish config file path
|
31
|
-
|
32
|
+
|
32
33
|
Returns:
|
33
34
|
str: Path to fish config file
|
34
35
|
"""
|
35
36
|
return os.path.expanduser("~/.config/fish/config.fish")
|
36
37
|
|
38
|
+
|
37
39
|
def _get_markers() -> Tuple[str, str]:
|
38
40
|
"""Get start and end markers for JSS completion
|
39
|
-
|
41
|
+
|
40
42
|
Returns:
|
41
43
|
Tuple[str, str]: (start_marker, end_marker)
|
42
44
|
"""
|
43
45
|
return (
|
44
46
|
"# ===== JARVIS JSS FISH COMPLETION START =====",
|
45
|
-
"# ===== JARVIS JSS FISH COMPLETION END ====="
|
47
|
+
"# ===== JARVIS JSS FISH COMPLETION END =====",
|
46
48
|
)
|
47
49
|
|
50
|
+
|
48
51
|
def install_jss_completion() -> int:
|
49
52
|
"""Install JSS fish shell command completion
|
50
|
-
|
53
|
+
|
51
54
|
Returns:
|
52
55
|
int: 0 if success, 1 if failed
|
53
56
|
"""
|
@@ -70,7 +73,8 @@ def install_jss_completion() -> int:
|
|
70
73
|
return 0
|
71
74
|
|
72
75
|
with open(config_file, "a") as f:
|
73
|
-
f.write(
|
76
|
+
f.write(
|
77
|
+
f"""
|
74
78
|
{start_marker}
|
75
79
|
function fish_command_not_found
|
76
80
|
if test (string length "$argv") -lt 10
|
@@ -83,13 +87,15 @@ function __fish_command_not_found_handler --on-event fish_command_not_found
|
|
83
87
|
fish_command_not_found "$argv"
|
84
88
|
end
|
85
89
|
{end_marker}
|
86
|
-
"""
|
90
|
+
"""
|
91
|
+
)
|
87
92
|
print("JSS fish completion已安装,请执行: source ~/.config/fish/config.fish")
|
88
93
|
return 0
|
89
94
|
|
95
|
+
|
90
96
|
def uninstall_jss_completion() -> int:
|
91
97
|
"""Uninstall JSS fish shell command completion
|
92
|
-
|
98
|
+
|
93
99
|
Returns:
|
94
100
|
int: 0 if success, 1 if failed
|
95
101
|
"""
|
@@ -112,10 +118,10 @@ def uninstall_jss_completion() -> int:
|
|
112
118
|
return 0
|
113
119
|
|
114
120
|
new_content = content.split(start_marker)[0] + content.split(end_marker)[-1]
|
115
|
-
|
121
|
+
|
116
122
|
with open(config_file, "w") as f:
|
117
123
|
f.write(new_content)
|
118
|
-
|
124
|
+
|
119
125
|
print("JSS fish completion已卸载,请执行: source ~/.config/fish/config.fish")
|
120
126
|
return 0
|
121
127
|
|
@@ -205,7 +211,7 @@ Example:
|
|
205
211
|
install_parser.add_argument(
|
206
212
|
"--shell", choices=["fish"], default="fish", help="指定shell类型(仅支持fish)"
|
207
213
|
)
|
208
|
-
|
214
|
+
|
209
215
|
# 添加uninstall子命令
|
210
216
|
uninstall_parser = subparsers.add_parser(
|
211
217
|
"uninstall", help="卸载JSS fish shell命令补全功能"
|
@@ -232,7 +238,7 @@ Example:
|
|
232
238
|
print(f"错误: 不支持的shell类型: {args.shell}, 仅支持fish")
|
233
239
|
return 1
|
234
240
|
return uninstall_jss_completion()
|
235
|
-
|
241
|
+
|
236
242
|
# 处理request命令
|
237
243
|
if not args.request:
|
238
244
|
# 检查是否在交互式终端中运行
|
jarvis/jarvis_tools/ask_user.py
CHANGED
jarvis/jarvis_tools/registry.py
CHANGED
@@ -17,7 +17,7 @@ from jarvis.jarvis_tools.base import Tool
|
|
17
17
|
from jarvis.jarvis_utils.config import get_data_dir, get_tool_load_dirs
|
18
18
|
from jarvis.jarvis_utils.output import OutputType, PrettyOutput
|
19
19
|
from jarvis.jarvis_utils.tag import ct, ot
|
20
|
-
from jarvis.jarvis_utils.utils import is_context_overflow
|
20
|
+
from jarvis.jarvis_utils.utils import is_context_overflow, daily_check_git_updates
|
21
21
|
|
22
22
|
tool_call_help = f"""
|
23
23
|
<tool_system_guide>
|
@@ -124,7 +124,7 @@ class ToolRegistry(OutputHandlerProtocol):
|
|
124
124
|
"""加载工具"""
|
125
125
|
tools = self.get_all_tools()
|
126
126
|
if tools:
|
127
|
-
tools_prompt = "<tools_section>\n"
|
127
|
+
tools_prompt = f"{tool_call_help}\n<tools_section>\n"
|
128
128
|
tools_prompt += " <header>## 可用工具:</header>\n"
|
129
129
|
tools_prompt += " <tools_list>\n"
|
130
130
|
for tool in tools:
|
@@ -287,16 +287,18 @@ class ToolRegistry(OutputHandlerProtocol):
|
|
287
287
|
|
288
288
|
def _load_external_tools(self) -> None:
|
289
289
|
"""从jarvis_data/tools和配置的目录加载外部工具"""
|
290
|
-
tool_dirs = [Path(get_data_dir()) / "tools"] +
|
291
|
-
|
292
|
-
|
290
|
+
tool_dirs = [str(Path(get_data_dir()) / "tools")] + get_tool_load_dirs()
|
291
|
+
|
292
|
+
# --- 全局每日更新检查 ---
|
293
|
+
daily_check_git_updates(tool_dirs, "tools")
|
293
294
|
|
294
295
|
for tool_dir in tool_dirs:
|
295
|
-
|
296
|
+
p_tool_dir = Path(tool_dir)
|
297
|
+
if not p_tool_dir.exists() or not p_tool_dir.is_dir():
|
296
298
|
continue
|
297
299
|
|
298
300
|
# 遍历目录中的所有.py文件
|
299
|
-
for file_path in
|
301
|
+
for file_path in p_tool_dir.glob("*.py"):
|
300
302
|
# 跳过__init__.py
|
301
303
|
if file_path.name == "__init__.py":
|
302
304
|
continue
|
@@ -565,7 +567,10 @@ class ToolRegistry(OutputHandlerProtocol):
|
|
565
567
|
ot("TOOL_CALL") + r"(.*?)" + ct("TOOL_CALL"), content, re.DOTALL
|
566
568
|
)
|
567
569
|
if not data:
|
568
|
-
return
|
570
|
+
return (
|
571
|
+
{},
|
572
|
+
f"只有{ot('TOOL_CALL')}标签,未找到{ct('TOOL_CALL')}标签,调用格式错误,请检查工具调用格式。\n{tool_call_help}",
|
573
|
+
)
|
569
574
|
ret = []
|
570
575
|
for item in data:
|
571
576
|
try:
|
@@ -714,7 +719,10 @@ class ToolRegistry(OutputHandlerProtocol):
|
|
714
719
|
)
|
715
720
|
|
716
721
|
# 检查内容是否过大
|
717
|
-
|
722
|
+
model_group = None
|
723
|
+
if agent_instance.model:
|
724
|
+
model_group = agent_instance.model.model_group
|
725
|
+
is_large_content = is_context_overflow(output, model_group)
|
718
726
|
|
719
727
|
if is_large_content:
|
720
728
|
# 创建临时文件
|
@@ -3,7 +3,7 @@
|
|
3
3
|
from typing import Any, Dict
|
4
4
|
|
5
5
|
import httpx
|
6
|
-
from
|
6
|
+
from markdownify import markdownify as md
|
7
7
|
from ddgs import DDGS
|
8
8
|
|
9
9
|
from jarvis.jarvis_agent import Agent
|
@@ -27,7 +27,7 @@ class SearchWebTool:
|
|
27
27
|
"""Performs a web search, scrapes content, and summarizes the results."""
|
28
28
|
try:
|
29
29
|
PrettyOutput.print("▶️ 使用 DuckDuckGo 开始网页搜索...", OutputType.INFO)
|
30
|
-
results = list(DDGS().text(query, max_results=
|
30
|
+
results = list(DDGS().text(query, max_results=50))
|
31
31
|
|
32
32
|
if not results:
|
33
33
|
return {
|
@@ -36,19 +36,29 @@ class SearchWebTool:
|
|
36
36
|
"success": False,
|
37
37
|
}
|
38
38
|
|
39
|
-
urls = [r["href"] for r in results]
|
40
39
|
full_content = ""
|
41
40
|
visited_urls = []
|
41
|
+
visited_count = 0
|
42
|
+
|
43
|
+
for r in results:
|
44
|
+
if visited_count >= 10:
|
45
|
+
PrettyOutput.print("ℹ️ 已成功获取10个网页,停止抓取。", OutputType.INFO)
|
46
|
+
break
|
47
|
+
|
48
|
+
url = r["href"]
|
49
|
+
title = r.get("title", url)
|
42
50
|
|
43
|
-
for url in urls:
|
44
51
|
try:
|
45
|
-
PrettyOutput.print(
|
52
|
+
PrettyOutput.print(
|
53
|
+
f"📄 ({visited_count + 1}/10) 正在抓取: {title} ({url})",
|
54
|
+
OutputType.INFO,
|
55
|
+
)
|
46
56
|
response = http_get(url, timeout=10.0, follow_redirects=True)
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
full_content += body.get_text(" ", strip=True) + "\n\n"
|
57
|
+
content = md(response.text, strip=['script', 'style'])
|
58
|
+
if content:
|
59
|
+
full_content += content + "\n\n"
|
51
60
|
visited_urls.append(url)
|
61
|
+
visited_count += 1
|
52
62
|
except httpx.HTTPStatusError as e:
|
53
63
|
PrettyOutput.print(
|
54
64
|
f"⚠️ HTTP错误 {e.response.status_code} 访问 {url}",
|
jarvis/jarvis_utils/config.py
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
# -*- coding: utf-8 -*-
|
2
2
|
import os
|
3
3
|
from functools import lru_cache
|
4
|
-
from typing import Any, Dict, List
|
4
|
+
from typing import Any, Dict, List, Optional
|
5
5
|
|
6
6
|
import yaml # type: ignore
|
7
7
|
|
@@ -76,24 +76,26 @@ def get_replace_map() -> dict:
|
|
76
76
|
return {**BUILTIN_REPLACE_MAP, **file_map}
|
77
77
|
|
78
78
|
|
79
|
-
def get_max_token_count() -> int:
|
79
|
+
def get_max_token_count(model_group_override: Optional[str] = None) -> int:
|
80
80
|
"""
|
81
81
|
获取模型允许的最大token数量。
|
82
82
|
|
83
83
|
返回:
|
84
84
|
int: 模型能处理的最大token数量。
|
85
85
|
"""
|
86
|
-
|
86
|
+
config = _get_resolved_model_config(model_group_override)
|
87
|
+
return int(config.get("JARVIS_MAX_TOKEN_COUNT", "960000"))
|
87
88
|
|
88
89
|
|
89
|
-
def get_max_input_token_count() -> int:
|
90
|
+
def get_max_input_token_count(model_group_override: Optional[str] = None) -> int:
|
90
91
|
"""
|
91
92
|
获取模型允许的最大输入token数量。
|
92
93
|
|
93
94
|
返回:
|
94
95
|
int: 模型能处理的最大输入token数量。
|
95
96
|
"""
|
96
|
-
|
97
|
+
config = _get_resolved_model_config(model_group_override)
|
98
|
+
return int(config.get("JARVIS_MAX_INPUT_TOKEN_COUNT", "32000"))
|
97
99
|
|
98
100
|
|
99
101
|
def get_shell_name() -> str:
|
@@ -113,48 +115,94 @@ def get_shell_name() -> str:
|
|
113
115
|
return os.path.basename(shell_path).lower()
|
114
116
|
|
115
117
|
|
116
|
-
def
|
118
|
+
def _get_resolved_model_config(model_group_override: Optional[str] = None) -> Dict[str, Any]:
|
119
|
+
"""
|
120
|
+
解析并合并模型配置,处理模型组。
|
121
|
+
|
122
|
+
优先级顺序:
|
123
|
+
1. 单独的环境变量 (JARVIS_PLATFORM, JARVIS_MODEL, etc.)
|
124
|
+
2. JARVIS_MODEL_GROUP 中定义的组配置
|
125
|
+
3. 代码中的默认值
|
126
|
+
|
127
|
+
返回:
|
128
|
+
Dict[str, Any]: 解析后的模型配置字典
|
129
|
+
"""
|
130
|
+
group_config = {}
|
131
|
+
model_group_name = model_group_override or GLOBAL_CONFIG_DATA.get("JARVIS_MODEL_GROUP")
|
132
|
+
# The format is a list of single-key dicts: [{'group_name': {...}}, ...]
|
133
|
+
model_groups = GLOBAL_CONFIG_DATA.get("JARVIS_MODEL_GROUPS", [])
|
134
|
+
|
135
|
+
if model_group_name and isinstance(model_groups, list):
|
136
|
+
for group_item in model_groups:
|
137
|
+
if isinstance(group_item, dict) and model_group_name in group_item:
|
138
|
+
group_config = group_item[model_group_name]
|
139
|
+
break
|
140
|
+
|
141
|
+
# Start with group config
|
142
|
+
resolved_config = group_config.copy()
|
143
|
+
|
144
|
+
# Override with specific settings from GLOBAL_CONFIG_DATA
|
145
|
+
for key in [
|
146
|
+
"JARVIS_PLATFORM",
|
147
|
+
"JARVIS_MODEL",
|
148
|
+
"JARVIS_THINKING_PLATFORM",
|
149
|
+
"JARVIS_THINKING_MODEL",
|
150
|
+
"JARVIS_MAX_TOKEN_COUNT",
|
151
|
+
"JARVIS_MAX_INPUT_TOKEN_COUNT",
|
152
|
+
"JARVIS_MAX_BIG_CONTENT_SIZE",
|
153
|
+
]:
|
154
|
+
if key in GLOBAL_CONFIG_DATA:
|
155
|
+
resolved_config[key] = GLOBAL_CONFIG_DATA[key]
|
156
|
+
|
157
|
+
return resolved_config
|
158
|
+
|
159
|
+
|
160
|
+
def get_normal_platform_name(model_group_override: Optional[str] = None) -> str:
|
117
161
|
"""
|
118
162
|
获取正常操作的平台名称。
|
119
163
|
|
120
164
|
返回:
|
121
165
|
str: 平台名称,默认为'yuanbao'
|
122
166
|
"""
|
123
|
-
|
167
|
+
config = _get_resolved_model_config(model_group_override)
|
168
|
+
return config.get("JARVIS_PLATFORM", "yuanbao")
|
124
169
|
|
125
170
|
|
126
|
-
def get_normal_model_name() -> str:
|
171
|
+
def get_normal_model_name(model_group_override: Optional[str] = None) -> str:
|
127
172
|
"""
|
128
173
|
获取正常操作的模型名称。
|
129
174
|
|
130
175
|
返回:
|
131
|
-
str: 模型名称,默认为'
|
176
|
+
str: 模型名称,默认为'deep_seek_v3'
|
132
177
|
"""
|
133
|
-
|
178
|
+
config = _get_resolved_model_config(model_group_override)
|
179
|
+
return config.get("JARVIS_MODEL", "deep_seek_v3")
|
134
180
|
|
135
181
|
|
136
|
-
def get_thinking_platform_name() -> str:
|
182
|
+
def get_thinking_platform_name(model_group_override: Optional[str] = None) -> str:
|
137
183
|
"""
|
138
184
|
获取思考操作的平台名称。
|
139
185
|
|
140
186
|
返回:
|
141
|
-
str:
|
187
|
+
str: 平台名称,默认为正常操作平台
|
142
188
|
"""
|
143
|
-
|
144
|
-
|
189
|
+
config = _get_resolved_model_config(model_group_override)
|
190
|
+
# Fallback to normal platform if thinking platform is not specified
|
191
|
+
return config.get(
|
192
|
+
"JARVIS_THINKING_PLATFORM", get_normal_platform_name(model_group_override)
|
145
193
|
)
|
146
194
|
|
147
195
|
|
148
|
-
def get_thinking_model_name() -> str:
|
196
|
+
def get_thinking_model_name(model_group_override: Optional[str] = None) -> str:
|
149
197
|
"""
|
150
198
|
获取思考操作的模型名称。
|
151
199
|
|
152
200
|
返回:
|
153
|
-
str:
|
201
|
+
str: 模型名称,默认为正常操作模型
|
154
202
|
"""
|
155
|
-
|
156
|
-
|
157
|
-
)
|
203
|
+
config = _get_resolved_model_config(model_group_override)
|
204
|
+
# Fallback to normal model if thinking model is not specified
|
205
|
+
return config.get("JARVIS_THINKING_MODEL", get_normal_model_name(model_group_override))
|
158
206
|
|
159
207
|
|
160
208
|
def is_execute_tool_confirm() -> bool:
|
@@ -190,14 +238,15 @@ def get_data_dir() -> str:
|
|
190
238
|
)
|
191
239
|
|
192
240
|
|
193
|
-
def get_max_big_content_size() -> int:
|
241
|
+
def get_max_big_content_size(model_group_override: Optional[str] = None) -> int:
|
194
242
|
"""
|
195
243
|
获取最大大内容大小。
|
196
244
|
|
197
245
|
返回:
|
198
246
|
int: 最大大内容大小
|
199
247
|
"""
|
200
|
-
|
248
|
+
config = _get_resolved_model_config(model_group_override)
|
249
|
+
return int(config.get("JARVIS_MAX_BIG_CONTENT_SIZE", "160000"))
|
201
250
|
|
202
251
|
|
203
252
|
def get_pretty_output() -> bool:
|
@@ -240,6 +289,16 @@ def get_tool_load_dirs() -> List[str]:
|
|
240
289
|
return GLOBAL_CONFIG_DATA.get("JARVIS_TOOL_LOAD_DIRS", [])
|
241
290
|
|
242
291
|
|
292
|
+
def get_methodology_dirs() -> List[str]:
|
293
|
+
"""
|
294
|
+
获取方法论加载目录。
|
295
|
+
|
296
|
+
返回:
|
297
|
+
List[str]: 方法论加载目录列表
|
298
|
+
"""
|
299
|
+
return GLOBAL_CONFIG_DATA.get("JARVIS_METHODOLOGY_DIRS", [])
|
300
|
+
|
301
|
+
|
243
302
|
def is_print_prompt() -> bool:
|
244
303
|
"""
|
245
304
|
获取是否打印提示。
|
jarvis/jarvis_utils/git_utils.py
CHANGED
@@ -538,12 +538,12 @@ def get_recent_commits_with_files() -> List[Dict[str, Any]]:
|
|
538
538
|
return []
|
539
539
|
|
540
540
|
# 解析提交信息
|
541
|
-
commits = []
|
541
|
+
commits: List[Dict[str, Any]] = []
|
542
542
|
lines = result.stdout.splitlines()
|
543
543
|
for i in range(0, len(lines), 4):
|
544
544
|
if i + 3 >= len(lines):
|
545
545
|
break
|
546
|
-
commit = {
|
546
|
+
commit: Dict[str, Any] = {
|
547
547
|
"hash": lines[i],
|
548
548
|
"message": lines[i + 1],
|
549
549
|
"author": lines[i + 2],
|
jarvis/jarvis_utils/globals.py
CHANGED
@@ -11,7 +11,7 @@ import os
|
|
11
11
|
|
12
12
|
# 全局变量:保存最后一条消息
|
13
13
|
last_message: str = ""
|
14
|
-
from typing import Any, Set
|
14
|
+
from typing import Any, Dict, Set
|
15
15
|
|
16
16
|
import colorama
|
17
17
|
from rich.console import Console
|
@@ -22,7 +22,7 @@ colorama.init()
|
|
22
22
|
# 禁用tokenizers并行以避免多进程问题
|
23
23
|
os.environ["TOKENIZERS_PARALLELISM"] = "false"
|
24
24
|
# 全局代理管理
|
25
|
-
global_agents:
|
25
|
+
global_agents: Dict[str, Any] = {}
|
26
26
|
current_agent_name: str = ""
|
27
27
|
# 表示与大模型交互的深度(>0表示正在交互)
|
28
28
|
g_in_chat: int = 0
|
@@ -66,6 +66,19 @@ def make_agent_name(agent_name: str) -> str:
|
|
66
66
|
return agent_name
|
67
67
|
|
68
68
|
|
69
|
+
def get_agent(agent_name: str) -> Any:
|
70
|
+
"""
|
71
|
+
获取指定名称的代理实例。
|
72
|
+
|
73
|
+
参数:
|
74
|
+
agent_name: 代理名称
|
75
|
+
|
76
|
+
返回:
|
77
|
+
Any: 代理实例,如果不存在则返回None
|
78
|
+
"""
|
79
|
+
return global_agents.get(agent_name)
|
80
|
+
|
81
|
+
|
69
82
|
def set_agent(agent_name: str, agent: Any) -> None:
|
70
83
|
"""
|
71
84
|
设置当前代理并将其添加到全局代理集合中。
|
@@ -74,7 +87,7 @@ def set_agent(agent_name: str, agent: Any) -> None:
|
|
74
87
|
agent_name: 代理名称
|
75
88
|
agent: 代理对象
|
76
89
|
"""
|
77
|
-
global_agents
|
90
|
+
global_agents[agent_name] = agent
|
78
91
|
global current_agent_name
|
79
92
|
current_agent_name = agent_name
|
80
93
|
|
@@ -101,7 +114,7 @@ def delete_agent(agent_name: str) -> None:
|
|
101
114
|
agent_name: 要删除的代理名称
|
102
115
|
"""
|
103
116
|
if agent_name in global_agents:
|
104
|
-
global_agents
|
117
|
+
del global_agents[agent_name]
|
105
118
|
global current_agent_name
|
106
119
|
current_agent_name = ""
|
107
120
|
|
@@ -173,10 +186,3 @@ def get_last_message() -> str:
|
|
173
186
|
str: 最后一条消息
|
174
187
|
"""
|
175
188
|
return last_message
|
176
|
-
"""
|
177
|
-
获取当前中断信号状态。
|
178
|
-
|
179
|
-
返回:
|
180
|
-
int: 当前中断计数
|
181
|
-
"""
|
182
|
-
return g_interrupt
|