jarvis-ai-assistant 0.1.149__py3-none-any.whl → 0.1.151__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 +1 -1
- jarvis/jarvis_agent/jarvis.py +7 -5
- jarvis/jarvis_git_utils/git_commiter.py +7 -0
- jarvis/jarvis_lsp/registry.py +2 -1
- jarvis/jarvis_mcp/__init__.py +65 -0
- jarvis/jarvis_mcp/local_mcp_client.py +326 -0
- jarvis/jarvis_mcp/remote_mcp_client.py +590 -0
- jarvis/jarvis_platform/kimi.py +3 -2
- jarvis/jarvis_platform/registry.py +2 -4
- jarvis/jarvis_platform/yuanbao.py +4 -4
- jarvis/jarvis_tools/ask_codebase.py +3 -10
- jarvis/jarvis_tools/file_operation.py +7 -26
- jarvis/jarvis_tools/methodology.py +2 -1
- jarvis/jarvis_tools/registry.py +168 -21
- jarvis/jarvis_utils/config.py +15 -9
- jarvis/jarvis_utils/embedding.py +2 -2
- jarvis/jarvis_utils/file_processors.py +0 -262
- jarvis/jarvis_utils/input.py +7 -1
- jarvis/jarvis_utils/methodology.py +4 -4
- jarvis/jarvis_utils/utils.py +5 -5
- {jarvis_ai_assistant-0.1.149.dist-info → jarvis_ai_assistant-0.1.151.dist-info}/METADATA +43 -18
- {jarvis_ai_assistant-0.1.149.dist-info → jarvis_ai_assistant-0.1.151.dist-info}/RECORD +26 -23
- {jarvis_ai_assistant-0.1.149.dist-info → jarvis_ai_assistant-0.1.151.dist-info}/WHEEL +1 -1
- {jarvis_ai_assistant-0.1.149.dist-info → jarvis_ai_assistant-0.1.151.dist-info}/entry_points.txt +0 -0
- {jarvis_ai_assistant-0.1.149.dist-info → jarvis_ai_assistant-0.1.151.dist-info/licenses}/LICENSE +0 -0
- {jarvis_ai_assistant-0.1.149.dist-info → jarvis_ai_assistant-0.1.151.dist-info}/top_level.txt +0 -0
|
@@ -156,10 +156,9 @@ class AskCodebaseTool:
|
|
|
156
156
|
2. 使用fd命令查找可能相关的文件
|
|
157
157
|
3. 使用rg命令搜索关键词和代码模式
|
|
158
158
|
4. 使用read_code工具直接读取和分析相关文件内容
|
|
159
|
-
5.
|
|
160
|
-
6.
|
|
161
|
-
7.
|
|
162
|
-
8. 优先查阅README文件、文档目录和项目文档
|
|
159
|
+
5. 根据文件内容提供具体、准确的回答
|
|
160
|
+
6. 确保分析的完整性,收集充分的信息后再得出结论,不要在只掌握部分信息就得出结论
|
|
161
|
+
7. 优先查阅README文件、文档目录和项目文档
|
|
163
162
|
|
|
164
163
|
## 分析步骤
|
|
165
164
|
1. **确定项目的编程语言**:
|
|
@@ -186,12 +185,6 @@ class AskCodebaseTool:
|
|
|
186
185
|
- 提供基于直接分析代码的具体回答
|
|
187
186
|
- 引用具体文件和代码片段作为依据
|
|
188
187
|
|
|
189
|
-
## 关于RAG工具使用
|
|
190
|
-
- RAG工具应作为最后选择,仅在fd、rg和read_code都无法解决问题时使用
|
|
191
|
-
- 必须通过查看实际代码文件验证RAG返回的每条重要信息
|
|
192
|
-
- 对于关键发现,始终使用`read_code`工具查看原始文件内容进行求证
|
|
193
|
-
- 如发现RAG结果与实际代码不符,以实际代码为准
|
|
194
|
-
|
|
195
188
|
## 输出要求
|
|
196
189
|
- 提供准确、具体的回答,避免模糊不清的描述
|
|
197
190
|
- 引用具体文件路径和代码片段作为依据
|
|
@@ -8,15 +8,14 @@ from jarvis.jarvis_utils.globals import add_read_file_record
|
|
|
8
8
|
from jarvis.jarvis_utils.output import OutputType, PrettyOutput
|
|
9
9
|
# 导入文件处理器
|
|
10
10
|
from jarvis.jarvis_utils.file_processors import (
|
|
11
|
-
TextFileProcessor
|
|
12
|
-
PPTProcessor, ExcelProcessor
|
|
11
|
+
TextFileProcessor
|
|
13
12
|
)
|
|
14
13
|
|
|
15
14
|
|
|
16
15
|
|
|
17
16
|
class FileOperationTool:
|
|
18
17
|
name = "file_operation"
|
|
19
|
-
description = "
|
|
18
|
+
description = "文件批量操作工具,可批量读写多个文件,仅支持文本文件,适用于需要同时处理多个文件的场景(读取配置文件、保存生成内容等)"
|
|
20
19
|
parameters = {
|
|
21
20
|
"type": "object",
|
|
22
21
|
"properties": {
|
|
@@ -44,10 +43,6 @@ class FileOperationTool:
|
|
|
44
43
|
def _get_file_processor(self, file_path: str):
|
|
45
44
|
"""获取适合处理指定文件的处理器"""
|
|
46
45
|
processors = [
|
|
47
|
-
PDFProcessor, # PDF文件处理器
|
|
48
|
-
DocxProcessor, # Word文档处理器
|
|
49
|
-
PPTProcessor, # PowerPoint演示文稿处理器
|
|
50
|
-
ExcelProcessor, # Excel表格处理器
|
|
51
46
|
TextFileProcessor # 文本文件处理器(放在最后作为兜底)
|
|
52
47
|
]
|
|
53
48
|
|
|
@@ -126,25 +121,11 @@ class FileOperationTool:
|
|
|
126
121
|
"stderr": f"读取文本文件失败: {str(e)}"
|
|
127
122
|
}
|
|
128
123
|
else:
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
file_type_names = {
|
|
135
|
-
PDFProcessor: "PDF文档",
|
|
136
|
-
DocxProcessor: "Word文档",
|
|
137
|
-
PPTProcessor: "PowerPoint演示文稿",
|
|
138
|
-
ExcelProcessor: "Excel表格"
|
|
139
|
-
}
|
|
140
|
-
file_type = file_type_names.get(processor, file_extension)
|
|
141
|
-
file_info = f"\n文件: {abs_path} ({file_type})"
|
|
142
|
-
except Exception as e:
|
|
143
|
-
return {
|
|
144
|
-
"success": False,
|
|
145
|
-
"stdout": "",
|
|
146
|
-
"stderr": f"提取 {file_extension} 文件内容失败: {str(e)}"
|
|
147
|
-
}
|
|
124
|
+
return {
|
|
125
|
+
"success": False,
|
|
126
|
+
"stdout": "",
|
|
127
|
+
"stderr": f"不支持的文件类型: {file_extension}"
|
|
128
|
+
}
|
|
148
129
|
|
|
149
130
|
# 构建输出信息
|
|
150
131
|
output = f"{file_info}\n{content}" + "\n\n"
|
|
@@ -3,6 +3,7 @@ import json
|
|
|
3
3
|
import hashlib
|
|
4
4
|
from typing import Dict, Any
|
|
5
5
|
|
|
6
|
+
from jarvis.jarvis_utils.config import get_data_dir
|
|
6
7
|
from jarvis.jarvis_utils.output import OutputType, PrettyOutput
|
|
7
8
|
|
|
8
9
|
|
|
@@ -35,7 +36,7 @@ class MethodologyTool:
|
|
|
35
36
|
|
|
36
37
|
def __init__(self):
|
|
37
38
|
"""初始化经验管理工具"""
|
|
38
|
-
self.methodology_dir = os.path.
|
|
39
|
+
self.methodology_dir = os.path.join(get_data_dir(), "methodologies")
|
|
39
40
|
self._ensure_dir_exists()
|
|
40
41
|
|
|
41
42
|
def _ensure_dir_exists(self):
|
jarvis/jarvis_tools/registry.py
CHANGED
|
@@ -10,10 +10,13 @@ import yaml
|
|
|
10
10
|
from jarvis.jarvis_agent.output_handler import OutputHandler
|
|
11
11
|
from jarvis.jarvis_platform.registry import PlatformRegistry
|
|
12
12
|
from jarvis.jarvis_tools.base import Tool
|
|
13
|
-
from jarvis.jarvis_utils.config import INPUT_WINDOW_REVERSE_SIZE, get_max_input_token_count
|
|
13
|
+
from jarvis.jarvis_utils.config import INPUT_WINDOW_REVERSE_SIZE, get_max_input_token_count, get_data_dir
|
|
14
14
|
from jarvis.jarvis_utils.embedding import get_context_token_count
|
|
15
15
|
from jarvis.jarvis_utils.output import OutputType, PrettyOutput
|
|
16
16
|
from jarvis.jarvis_utils.utils import ct, ot, init_env
|
|
17
|
+
from jarvis.jarvis_mcp.local_mcp_client import LocalMcpClient
|
|
18
|
+
from jarvis.jarvis_mcp.remote_mcp_client import RemoteMcpClient
|
|
19
|
+
from jarvis.jarvis_mcp import McpClient
|
|
17
20
|
|
|
18
21
|
|
|
19
22
|
|
|
@@ -131,11 +134,12 @@ class ToolRegistry(OutputHandler):
|
|
|
131
134
|
# 加载内置工具和外部工具
|
|
132
135
|
self._load_builtin_tools()
|
|
133
136
|
self._load_external_tools()
|
|
137
|
+
self._load_mcp_tools()
|
|
134
138
|
self.max_input_token_count = get_max_input_token_count() - INPUT_WINDOW_REVERSE_SIZE
|
|
135
139
|
|
|
136
140
|
def use_tools(self, name: List[str]) -> None:
|
|
137
141
|
"""使用指定工具
|
|
138
|
-
|
|
142
|
+
|
|
139
143
|
参数:
|
|
140
144
|
name: 要使用的工具名称列表
|
|
141
145
|
"""
|
|
@@ -146,12 +150,22 @@ class ToolRegistry(OutputHandler):
|
|
|
146
150
|
|
|
147
151
|
def dont_use_tools(self, names: List[str]) -> None:
|
|
148
152
|
"""从注册表中移除指定工具
|
|
149
|
-
|
|
153
|
+
|
|
150
154
|
参数:
|
|
151
155
|
names: 要移除的工具名称列表
|
|
152
156
|
"""
|
|
153
157
|
self.tools = {name: tool for name, tool in self.tools.items() if name not in names}
|
|
154
158
|
|
|
159
|
+
def _load_mcp_tools(self) -> None:
|
|
160
|
+
"""从jarvis_data/tools/mcp加载工具"""
|
|
161
|
+
mcp_tools_dir = Path(get_data_dir()) / 'mcp'
|
|
162
|
+
if not mcp_tools_dir.exists():
|
|
163
|
+
return
|
|
164
|
+
|
|
165
|
+
# 遍历目录中的所有.yaml文件
|
|
166
|
+
for file_path in mcp_tools_dir.glob("*.yaml"):
|
|
167
|
+
self.register_mcp_tool_by_file(str(file_path))
|
|
168
|
+
|
|
155
169
|
def _load_builtin_tools(self) -> None:
|
|
156
170
|
"""从内置工具目录加载工具"""
|
|
157
171
|
tools_dir = Path(__file__).parent
|
|
@@ -165,8 +179,8 @@ class ToolRegistry(OutputHandler):
|
|
|
165
179
|
self.register_tool_by_file(str(file_path))
|
|
166
180
|
|
|
167
181
|
def _load_external_tools(self) -> None:
|
|
168
|
-
"""
|
|
169
|
-
external_tools_dir = Path
|
|
182
|
+
"""从jarvis_data/tools加载外部工具"""
|
|
183
|
+
external_tools_dir = Path(get_data_dir()) / 'tools'
|
|
170
184
|
if not external_tools_dir.exists():
|
|
171
185
|
return
|
|
172
186
|
|
|
@@ -178,6 +192,139 @@ class ToolRegistry(OutputHandler):
|
|
|
178
192
|
|
|
179
193
|
self.register_tool_by_file(str(file_path))
|
|
180
194
|
|
|
195
|
+
def register_mcp_tool_by_file(self, file_path: str) -> bool:
|
|
196
|
+
"""从指定文件加载并注册工具
|
|
197
|
+
|
|
198
|
+
参数:
|
|
199
|
+
file_path: 工具文件的路径
|
|
200
|
+
|
|
201
|
+
返回:
|
|
202
|
+
bool: 工具是否加载成功
|
|
203
|
+
"""
|
|
204
|
+
try:
|
|
205
|
+
config = yaml.safe_load(open(file_path, 'r', encoding='utf-8'))
|
|
206
|
+
if 'type' not in config:
|
|
207
|
+
PrettyOutput.print(f"文件 {file_path} 缺少type字段", OutputType.WARNING)
|
|
208
|
+
return False
|
|
209
|
+
|
|
210
|
+
# 检查enable标志
|
|
211
|
+
if not config.get('enable', True):
|
|
212
|
+
PrettyOutput.print(f"文件 {file_path} 已禁用(enable=false),跳过注册", OutputType.INFO)
|
|
213
|
+
return False
|
|
214
|
+
|
|
215
|
+
name = config.get('name', Path(file_path).stem)
|
|
216
|
+
|
|
217
|
+
|
|
218
|
+
# 注册资源工具
|
|
219
|
+
def create_resource_list_func(client: McpClient):
|
|
220
|
+
def execute(arguments: Dict[str, Any]) -> Dict[str, Any]:
|
|
221
|
+
args = arguments.copy()
|
|
222
|
+
args.pop('agent', None)
|
|
223
|
+
args.pop('want', None)
|
|
224
|
+
ret = client.get_resource_list()
|
|
225
|
+
PrettyOutput.print(f"MCP {name} 资源列表:\n{yaml.safe_dump(ret)}", OutputType.TOOL)
|
|
226
|
+
return {
|
|
227
|
+
'success': True,
|
|
228
|
+
'stdout': yaml.safe_dump(ret),
|
|
229
|
+
'stderr': ''
|
|
230
|
+
}
|
|
231
|
+
return execute
|
|
232
|
+
|
|
233
|
+
def create_resource_get_func(client: McpClient):
|
|
234
|
+
def execute(arguments: Dict[str, Any]) -> Dict[str, Any]:
|
|
235
|
+
args = arguments.copy()
|
|
236
|
+
args.pop('agent', None)
|
|
237
|
+
args.pop('want', None)
|
|
238
|
+
if 'uri' not in args:
|
|
239
|
+
return {
|
|
240
|
+
'success': False,
|
|
241
|
+
'stdout': '',
|
|
242
|
+
'stderr': '缺少必需的uri参数'
|
|
243
|
+
}
|
|
244
|
+
ret = client.get_resource(args['uri'])
|
|
245
|
+
PrettyOutput.print(f"MCP {name} 获取资源:\n{yaml.safe_dump(ret)}", OutputType.TOOL)
|
|
246
|
+
return ret
|
|
247
|
+
return execute
|
|
248
|
+
|
|
249
|
+
def create_mcp_execute_func(tool_name: str, client: McpClient):
|
|
250
|
+
def execute(arguments: Dict[str, Any]) -> Dict[str, Any]:
|
|
251
|
+
args = arguments.copy()
|
|
252
|
+
args.pop('agent', None)
|
|
253
|
+
args.pop('want', None)
|
|
254
|
+
ret = client.execute(tool_name, args)
|
|
255
|
+
PrettyOutput.print(f"MCP {name} {tool_name} 执行结果:\n{yaml.safe_dump(ret)}", OutputType.TOOL)
|
|
256
|
+
return ret
|
|
257
|
+
return execute
|
|
258
|
+
|
|
259
|
+
if config['type'] == 'local':
|
|
260
|
+
if 'command' not in config:
|
|
261
|
+
PrettyOutput.print(f"文件 {file_path} 缺少command字段", OutputType.WARNING)
|
|
262
|
+
return False
|
|
263
|
+
elif config['type'] == 'remote':
|
|
264
|
+
if 'base_url' not in config:
|
|
265
|
+
PrettyOutput.print(f"文件 {file_path} 缺少base_url字段", OutputType.WARNING)
|
|
266
|
+
return False
|
|
267
|
+
else:
|
|
268
|
+
PrettyOutput.print(f"文件 {file_path} 类型错误: {config['type']}", OutputType.WARNING)
|
|
269
|
+
return False
|
|
270
|
+
|
|
271
|
+
# 创建MCP客户端
|
|
272
|
+
mcp_client: McpClient = LocalMcpClient(config) if config['type'] == 'local' else RemoteMcpClient(config)
|
|
273
|
+
|
|
274
|
+
# 获取工具信息
|
|
275
|
+
tools = mcp_client.get_tool_list()
|
|
276
|
+
if not tools:
|
|
277
|
+
PrettyOutput.print(f"从 {file_path} 获取工具列表失败", OutputType.WARNING)
|
|
278
|
+
return False
|
|
279
|
+
|
|
280
|
+
# 注册每个工具
|
|
281
|
+
for tool in tools:
|
|
282
|
+
|
|
283
|
+
# 注册工具
|
|
284
|
+
self.register_tool(
|
|
285
|
+
name=f"{name}.tool_call.{tool['name']}",
|
|
286
|
+
description=tool['description'],
|
|
287
|
+
parameters=tool['parameters'],
|
|
288
|
+
func=create_mcp_execute_func(tool['name'], mcp_client)
|
|
289
|
+
)
|
|
290
|
+
|
|
291
|
+
|
|
292
|
+
# 注册资源列表工具
|
|
293
|
+
self.register_tool(
|
|
294
|
+
name=f"{name}.resource.get_resource_list",
|
|
295
|
+
description=f"获取{name}MCP服务器上的资源列表",
|
|
296
|
+
parameters={
|
|
297
|
+
'type': 'object',
|
|
298
|
+
'properties': {},
|
|
299
|
+
'required': []
|
|
300
|
+
},
|
|
301
|
+
func=create_resource_list_func(mcp_client)
|
|
302
|
+
)
|
|
303
|
+
|
|
304
|
+
# 注册获取资源工具
|
|
305
|
+
self.register_tool(
|
|
306
|
+
name=f"{name}.resource.get_resource",
|
|
307
|
+
description=f"获取{name}MCP服务器上的指定资源",
|
|
308
|
+
parameters={
|
|
309
|
+
'type': 'object',
|
|
310
|
+
'properties': {
|
|
311
|
+
'uri': {
|
|
312
|
+
'type': 'string',
|
|
313
|
+
'description': '资源的URI标识符'
|
|
314
|
+
}
|
|
315
|
+
},
|
|
316
|
+
'required': ['uri']
|
|
317
|
+
},
|
|
318
|
+
func=create_resource_get_func(mcp_client)
|
|
319
|
+
)
|
|
320
|
+
|
|
321
|
+
return True
|
|
322
|
+
|
|
323
|
+
|
|
324
|
+
except Exception as e:
|
|
325
|
+
PrettyOutput.print(f"文件 {file_path} 加载失败: {str(e)}", OutputType.WARNING)
|
|
326
|
+
return False
|
|
327
|
+
|
|
181
328
|
def register_tool_by_file(self, file_path: str) -> bool:
|
|
182
329
|
"""从指定文件加载并注册工具
|
|
183
330
|
|
|
@@ -243,12 +390,12 @@ class ToolRegistry(OutputHandler):
|
|
|
243
390
|
except Exception as e:
|
|
244
391
|
PrettyOutput.print(f"从 {Path(file_path).name} 加载工具失败: {str(e)}", OutputType.ERROR)
|
|
245
392
|
return False
|
|
246
|
-
|
|
393
|
+
|
|
247
394
|
@staticmethod
|
|
248
395
|
def _has_tool_calls_block(content: str) -> bool:
|
|
249
396
|
"""从内容中提取工具调用块"""
|
|
250
397
|
return re.search(ot("TOOL_CALL")+r'(.*?)'+ct("TOOL_CALL"), content, re.DOTALL) is not None
|
|
251
|
-
|
|
398
|
+
|
|
252
399
|
@staticmethod
|
|
253
400
|
def _extract_tool_calls(content: str) -> Tuple[Dict[str, Dict[str, Any]], str]:
|
|
254
401
|
"""从内容中提取工具调用。
|
|
@@ -271,20 +418,20 @@ class ToolRegistry(OutputHandler):
|
|
|
271
418
|
if 'name' in msg and 'arguments' in msg and 'want' in msg:
|
|
272
419
|
ret.append(msg)
|
|
273
420
|
else:
|
|
274
|
-
return {}, f"""工具调用格式错误,请检查工具调用格式。
|
|
275
|
-
|
|
276
|
-
{tool_call_help}"""
|
|
421
|
+
return {}, f"""工具调用格式错误,请检查工具调用格式。
|
|
422
|
+
|
|
423
|
+
{tool_call_help}"""
|
|
277
424
|
except Exception as e:
|
|
278
|
-
return {}, f"""工具调用格式错误,请检查工具调用格式。
|
|
279
|
-
|
|
280
|
-
{tool_call_help}"""
|
|
425
|
+
return {}, f"""工具调用格式错误,请检查工具调用格式。
|
|
426
|
+
|
|
427
|
+
{tool_call_help}"""
|
|
281
428
|
if len(ret) > 1:
|
|
282
429
|
return {}, "检测到多个工具调用,请一次只处理一个工具调用。"
|
|
283
430
|
return ret[0] if ret else {}, ""
|
|
284
431
|
|
|
285
|
-
def register_tool(self, name: str, description: str, parameters:
|
|
432
|
+
def register_tool(self, name: str, description: str, parameters: Any, func: Callable[..., Dict[str, Any]]) -> None:
|
|
286
433
|
"""注册新工具
|
|
287
|
-
|
|
434
|
+
|
|
288
435
|
参数:
|
|
289
436
|
name: 工具名称
|
|
290
437
|
description: 工具描述
|
|
@@ -295,10 +442,10 @@ class ToolRegistry(OutputHandler):
|
|
|
295
442
|
|
|
296
443
|
def get_tool(self, name: str) -> Optional[Tool]:
|
|
297
444
|
"""获取工具
|
|
298
|
-
|
|
445
|
+
|
|
299
446
|
参数:
|
|
300
447
|
name: 工具名称
|
|
301
|
-
|
|
448
|
+
|
|
302
449
|
返回:
|
|
303
450
|
Optional[Tool]: 找到的工具实例,如果不存在则返回None
|
|
304
451
|
"""
|
|
@@ -306,7 +453,7 @@ class ToolRegistry(OutputHandler):
|
|
|
306
453
|
|
|
307
454
|
def get_all_tools(self) -> List[Dict[str, Any]]:
|
|
308
455
|
"""获取所有工具(Ollama格式定义)
|
|
309
|
-
|
|
456
|
+
|
|
310
457
|
返回:
|
|
311
458
|
List[Dict[str, Any]]: 包含所有工具信息的列表
|
|
312
459
|
"""
|
|
@@ -314,11 +461,11 @@ class ToolRegistry(OutputHandler):
|
|
|
314
461
|
|
|
315
462
|
def execute_tool(self, name: str, arguments: Dict[str, Any]) -> Dict[str, Any]:
|
|
316
463
|
"""执行指定工具
|
|
317
|
-
|
|
464
|
+
|
|
318
465
|
参数:
|
|
319
466
|
name: 工具名称
|
|
320
467
|
arguments: 工具参数
|
|
321
|
-
|
|
468
|
+
|
|
322
469
|
返回:
|
|
323
470
|
Dict[str, Any]: 包含执行结果的字典,包含success、stdout和stderr字段
|
|
324
471
|
"""
|
|
@@ -380,7 +527,7 @@ class ToolRegistry(OutputHandler):
|
|
|
380
527
|
return f"""工具调用原始输出过长,以下是根据输出提出的信息:
|
|
381
528
|
|
|
382
529
|
{platform.chat_until_success(prompt)}"""
|
|
383
|
-
|
|
530
|
+
|
|
384
531
|
return output
|
|
385
532
|
|
|
386
533
|
except Exception as e:
|
jarvis/jarvis_utils/config.py
CHANGED
|
@@ -29,16 +29,8 @@ def get_max_input_token_count() -> int:
|
|
|
29
29
|
返回:
|
|
30
30
|
int: 模型能处理的最大输入token数量。
|
|
31
31
|
"""
|
|
32
|
-
return int(os.getenv('JARVIS_MAX_INPUT_TOKEN_COUNT', '
|
|
32
|
+
return int(os.getenv('JARVIS_MAX_INPUT_TOKEN_COUNT', '64000'))
|
|
33
33
|
|
|
34
|
-
def get_thread_count() -> int:
|
|
35
|
-
"""
|
|
36
|
-
获取用于并行处理的线程数。
|
|
37
|
-
|
|
38
|
-
返回:
|
|
39
|
-
int: 线程数,默认为1
|
|
40
|
-
"""
|
|
41
|
-
return int(os.getenv('JARVIS_THREAD_COUNT', '1'))
|
|
42
34
|
|
|
43
35
|
def is_auto_complete() -> bool:
|
|
44
36
|
"""
|
|
@@ -118,3 +110,17 @@ def get_max_tool_call_count() -> int:
|
|
|
118
110
|
int: 最大连续工具调用次数,默认为20
|
|
119
111
|
"""
|
|
120
112
|
return int(os.getenv('JARVIS_MAX_TOOL_CALL_COUNT', '20'))
|
|
113
|
+
|
|
114
|
+
|
|
115
|
+
def get_data_dir() -> str:
|
|
116
|
+
"""
|
|
117
|
+
获取Jarvis数据存储目录路径。
|
|
118
|
+
|
|
119
|
+
返回:
|
|
120
|
+
str: 数据目录路径,优先从JARVIS_DATA_PATH环境变量获取,
|
|
121
|
+
如果未设置或为空,则使用~/.jarvis作为默认值
|
|
122
|
+
"""
|
|
123
|
+
data_path = os.getenv('JARVIS_DATA_PATH', '').strip()
|
|
124
|
+
if not data_path:
|
|
125
|
+
return os.path.expanduser('~/.jarvis')
|
|
126
|
+
return data_path
|
jarvis/jarvis_utils/embedding.py
CHANGED
|
@@ -4,9 +4,9 @@ from typing import List
|
|
|
4
4
|
import functools
|
|
5
5
|
|
|
6
6
|
from jarvis.jarvis_utils.output import PrettyOutput, OutputType
|
|
7
|
+
from jarvis.jarvis_utils.config import get_data_dir
|
|
7
8
|
|
|
8
9
|
# 全局缓存,避免重复加载模型
|
|
9
|
-
_global_models = {}
|
|
10
10
|
_global_tokenizers = {}
|
|
11
11
|
|
|
12
12
|
def get_context_token_count(text: str) -> int:
|
|
@@ -155,7 +155,7 @@ def load_tokenizer() -> AutoTokenizer:
|
|
|
155
155
|
AutoTokenizer: 加载的分词器
|
|
156
156
|
"""
|
|
157
157
|
model_name = "gpt2"
|
|
158
|
-
cache_dir = os.path.
|
|
158
|
+
cache_dir = os.path.join(get_data_dir(), "huggingface", "hub")
|
|
159
159
|
|
|
160
160
|
# 检查全局缓存
|
|
161
161
|
if model_name in _global_tokenizers:
|