jarvis-ai-assistant 0.1.131__py3-none-any.whl → 0.1.134__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/__init__.py +165 -285
- jarvis/jarvis_agent/jarvis.py +143 -0
- jarvis/jarvis_agent/main.py +0 -2
- jarvis/jarvis_agent/patch.py +70 -48
- jarvis/jarvis_agent/shell_input_handler.py +1 -1
- jarvis/jarvis_code_agent/code_agent.py +169 -117
- jarvis/jarvis_dev/main.py +327 -626
- jarvis/jarvis_git_squash/main.py +10 -31
- jarvis/jarvis_lsp/base.py +0 -42
- jarvis/jarvis_lsp/cpp.py +0 -15
- jarvis/jarvis_lsp/go.py +0 -15
- jarvis/jarvis_lsp/python.py +0 -19
- jarvis/jarvis_lsp/registry.py +0 -62
- jarvis/jarvis_lsp/rust.py +0 -15
- jarvis/jarvis_multi_agent/__init__.py +19 -69
- jarvis/jarvis_multi_agent/main.py +43 -0
- jarvis/jarvis_platform/ai8.py +7 -32
- jarvis/jarvis_platform/base.py +2 -7
- jarvis/jarvis_platform/kimi.py +3 -144
- jarvis/jarvis_platform/ollama.py +54 -68
- jarvis/jarvis_platform/openai.py +0 -4
- jarvis/jarvis_platform/oyi.py +0 -75
- jarvis/jarvis_platform/registry.py +2 -16
- jarvis/jarvis_platform/yuanbao.py +264 -0
- jarvis/jarvis_rag/file_processors.py +138 -0
- jarvis/jarvis_rag/main.py +1305 -425
- jarvis/jarvis_tools/ask_codebase.py +216 -43
- jarvis/jarvis_tools/code_review.py +158 -113
- jarvis/jarvis_tools/create_sub_agent.py +0 -1
- jarvis/jarvis_tools/execute_python_script.py +58 -0
- jarvis/jarvis_tools/execute_shell.py +13 -26
- jarvis/jarvis_tools/execute_shell_script.py +1 -1
- jarvis/jarvis_tools/file_analyzer.py +282 -0
- jarvis/jarvis_tools/file_operation.py +1 -1
- jarvis/jarvis_tools/find_caller.py +278 -0
- jarvis/jarvis_tools/find_symbol.py +295 -0
- jarvis/jarvis_tools/function_analyzer.py +331 -0
- jarvis/jarvis_tools/git_commiter.py +5 -5
- jarvis/jarvis_tools/methodology.py +88 -53
- jarvis/jarvis_tools/project_analyzer.py +308 -0
- jarvis/jarvis_tools/rag.py +0 -5
- jarvis/jarvis_tools/read_code.py +24 -3
- jarvis/jarvis_tools/read_webpage.py +195 -81
- jarvis/jarvis_tools/registry.py +132 -11
- jarvis/jarvis_tools/search_web.py +22 -307
- jarvis/jarvis_tools/tool_generator.py +8 -10
- jarvis/jarvis_utils/__init__.py +1 -0
- jarvis/jarvis_utils/config.py +80 -76
- jarvis/jarvis_utils/embedding.py +344 -45
- jarvis/jarvis_utils/git_utils.py +9 -1
- jarvis/jarvis_utils/input.py +7 -6
- jarvis/jarvis_utils/methodology.py +384 -15
- jarvis/jarvis_utils/output.py +5 -3
- jarvis/jarvis_utils/utils.py +60 -8
- {jarvis_ai_assistant-0.1.131.dist-info → jarvis_ai_assistant-0.1.134.dist-info}/METADATA +8 -16
- jarvis_ai_assistant-0.1.134.dist-info/RECORD +82 -0
- {jarvis_ai_assistant-0.1.131.dist-info → jarvis_ai_assistant-0.1.134.dist-info}/entry_points.txt +4 -3
- jarvis/jarvis_codebase/__init__.py +0 -0
- jarvis/jarvis_codebase/main.py +0 -1011
- jarvis/jarvis_tools/lsp_find_definition.py +0 -150
- jarvis/jarvis_tools/lsp_find_references.py +0 -127
- jarvis/jarvis_tools/treesitter_analyzer.py +0 -331
- jarvis/jarvis_treesitter/README.md +0 -104
- jarvis/jarvis_treesitter/__init__.py +0 -20
- jarvis/jarvis_treesitter/database.py +0 -258
- jarvis/jarvis_treesitter/example.py +0 -115
- jarvis/jarvis_treesitter/grammar_builder.py +0 -182
- jarvis/jarvis_treesitter/language.py +0 -117
- jarvis/jarvis_treesitter/symbol.py +0 -31
- jarvis/jarvis_treesitter/tools_usage.md +0 -121
- jarvis_ai_assistant-0.1.131.dist-info/RECORD +0 -85
- {jarvis_ai_assistant-0.1.131.dist-info → jarvis_ai_assistant-0.1.134.dist-info}/LICENSE +0 -0
- {jarvis_ai_assistant-0.1.131.dist-info → jarvis_ai_assistant-0.1.134.dist-info}/WHEEL +0 -0
- {jarvis_ai_assistant-0.1.131.dist-info → jarvis_ai_assistant-0.1.134.dist-info}/top_level.txt +0 -0
|
@@ -1,319 +1,34 @@
|
|
|
1
|
-
from typing import Dict, Any, List
|
|
2
1
|
|
|
3
|
-
from regex import W
|
|
4
|
-
from yaspin import yaspin
|
|
5
|
-
from jarvis.jarvis_platform.registry import PlatformRegistry
|
|
6
|
-
from jarvis.jarvis_tools.read_webpage import WebpageTool
|
|
7
|
-
from playwright.sync_api import sync_playwright
|
|
8
|
-
from urllib.parse import quote
|
|
9
2
|
|
|
10
|
-
from jarvis.jarvis_utils.config import get_max_token_count
|
|
11
|
-
from jarvis.jarvis_utils.embedding import get_context_token_count
|
|
12
|
-
from jarvis.jarvis_utils.output import OutputType, PrettyOutput
|
|
13
3
|
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
with yaspin(text="正在启动浏览器...", color="cyan") as spinner:
|
|
19
|
-
browser = p.chromium.launch(
|
|
20
|
-
headless=True, # Headless mode
|
|
21
|
-
args=['--disable-gpu', '--no-sandbox', '--disable-dev-shm-usage']
|
|
22
|
-
)
|
|
23
|
-
spinner.text = "浏览器启动完成"
|
|
24
|
-
spinner.ok("✅")
|
|
25
|
-
|
|
26
|
-
# Create a new page and set timeout
|
|
27
|
-
with yaspin(text="正在创建新页面...", color="cyan") as spinner:
|
|
28
|
-
page = browser.new_page(
|
|
29
|
-
user_agent='Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/121.0.0.0 Safari/537.36',
|
|
30
|
-
viewport={'width': 1920, 'height': 1080}
|
|
31
|
-
)
|
|
32
|
-
spinner.text = "新页面创建完成"
|
|
33
|
-
spinner.ok("✅")
|
|
34
|
-
|
|
35
|
-
# Set page timeout
|
|
36
|
-
with yaspin(text="正在设置页面超时...", color="cyan") as spinner:
|
|
37
|
-
page.set_default_timeout(60000)
|
|
38
|
-
spinner.text = "页面超时设置完成"
|
|
39
|
-
spinner.ok("✅")
|
|
40
|
-
|
|
41
|
-
# Visit search page
|
|
42
|
-
with yaspin(text=f"正在搜索 {query}...", color="cyan") as spinner:
|
|
43
|
-
url = f"https://www.bing.com/search?q={quote(query)}&form=QBLH&sp=-1"
|
|
44
|
-
page.goto(url, wait_until="networkidle")
|
|
45
|
-
spinner.text = "搜索完成"
|
|
46
|
-
spinner.ok("✅")
|
|
47
|
-
|
|
48
|
-
# Wait for search results to load
|
|
49
|
-
with yaspin(text="正在等待搜索结果加载...", color="cyan") as spinner:
|
|
50
|
-
page.wait_for_selector("#b_results", state="visible", timeout=30000)
|
|
51
|
-
# Wait for a moment to ensure the results are fully loaded
|
|
52
|
-
page.wait_for_timeout(1000)
|
|
53
|
-
spinner.text = "搜索结果加载完成"
|
|
54
|
-
spinner.ok("✅")
|
|
55
|
-
|
|
56
|
-
# Extract search results
|
|
57
|
-
with yaspin(text="正在提取搜索结果...", color="cyan") as spinner:
|
|
58
|
-
summaries = page.evaluate("""() => {
|
|
59
|
-
const results = [];
|
|
60
|
-
const elements = document.querySelectorAll("#b_results > .b_algo");
|
|
61
|
-
|
|
62
|
-
for (const el of elements) {
|
|
63
|
-
const titleEl = el.querySelector("h2");
|
|
64
|
-
const linkEl = titleEl ? titleEl.querySelector("a") : null;
|
|
65
|
-
const abstractEl = el.querySelector(".b_caption p");
|
|
66
|
-
|
|
67
|
-
if (linkEl) {
|
|
68
|
-
results.push({
|
|
69
|
-
title: titleEl.innerText.trim(),
|
|
70
|
-
href: linkEl.href,
|
|
71
|
-
abstract: abstractEl ? abstractEl.innerText.trim() : ""
|
|
72
|
-
});
|
|
73
|
-
}
|
|
74
|
-
}
|
|
75
|
-
return results;
|
|
76
|
-
}""")
|
|
77
|
-
spinner.text = "搜索结果提取完成"
|
|
78
|
-
spinner.ok("✅")
|
|
4
|
+
import os
|
|
5
|
+
import statistics
|
|
6
|
+
from typing import Any, Dict
|
|
7
|
+
from jarvis.jarvis_platform.registry import PlatformRegistry
|
|
79
8
|
|
|
80
|
-
with yaspin(text="正在关闭浏览器...", color="cyan") as spinner:
|
|
81
|
-
browser.close()
|
|
82
|
-
spinner.text = "浏览器关闭完成"
|
|
83
|
-
spinner.ok("✅")
|
|
84
|
-
return summaries
|
|
85
|
-
|
|
86
|
-
except Exception as error:
|
|
87
|
-
PrettyOutput.print(f"搜索错误:{str(error)}", OutputType.ERROR)
|
|
88
|
-
return None
|
|
89
9
|
|
|
90
|
-
class
|
|
10
|
+
class SearchWebTool:
|
|
91
11
|
name = "search_web"
|
|
92
|
-
description = "
|
|
12
|
+
description = "搜索互联网上的信息"
|
|
93
13
|
parameters = {
|
|
94
14
|
"type": "object",
|
|
95
15
|
"properties": {
|
|
96
|
-
"query": {
|
|
97
|
-
|
|
98
|
-
"description": "搜索关键词"
|
|
99
|
-
},
|
|
100
|
-
"question": {
|
|
101
|
-
"type": "string",
|
|
102
|
-
"description": "要回答的具体问题,用于从搜索结果中提取相关信息"
|
|
103
|
-
},
|
|
104
|
-
"max_results": {
|
|
105
|
-
"type": "integer",
|
|
106
|
-
"description": "最大搜索结果数量",
|
|
107
|
-
"default": 3
|
|
108
|
-
}
|
|
109
|
-
},
|
|
110
|
-
"required": ["query", "question"]
|
|
16
|
+
"query": {"type": "string", "description": "具体的问题"}
|
|
17
|
+
}
|
|
111
18
|
}
|
|
112
19
|
|
|
113
|
-
def __init__(self):
|
|
114
|
-
"""Initialize the search tool, need to pass in the language model for information extraction"""
|
|
115
|
-
self.model = PlatformRegistry.get_global_platform_registry().get_normal_platform()
|
|
116
|
-
self.webpage_tool = WebpageTool()
|
|
117
|
-
|
|
118
|
-
def _search(self, query: str, max_results: int) -> List[Dict]:
|
|
119
|
-
"""Execute search request"""
|
|
120
|
-
try:
|
|
121
|
-
results = bing_search(query)
|
|
122
|
-
if not results:
|
|
123
|
-
return []
|
|
124
|
-
|
|
125
|
-
# Format search results
|
|
126
|
-
formatted_results = []
|
|
127
|
-
for result in results[:max_results]:
|
|
128
|
-
formatted_results.append({
|
|
129
|
-
"title": result.get("title", ""),
|
|
130
|
-
"href": result.get("href", ""),
|
|
131
|
-
"body": result.get("abstract", "")
|
|
132
|
-
})
|
|
133
|
-
return formatted_results
|
|
134
|
-
except Exception as e:
|
|
135
|
-
PrettyOutput.print(f"搜索请求失败:{str(e)}", OutputType.ERROR)
|
|
136
|
-
return []
|
|
137
|
-
|
|
138
|
-
def _extract_info(self, contents: List[str], question: str) -> str:
|
|
139
|
-
"""Use language model to extract key information from web content"""
|
|
140
|
-
try:
|
|
141
|
-
# Reserve tokens for prompt and response
|
|
142
|
-
max_tokens = get_max_token_count()
|
|
143
|
-
reserved_tokens = 2000 # Reserve tokens for prompt template and response
|
|
144
|
-
available_tokens = max_tokens - reserved_tokens
|
|
145
|
-
|
|
146
|
-
# Split contents into batches
|
|
147
|
-
batches = []
|
|
148
|
-
current_batch = []
|
|
149
|
-
current_tokens = 0
|
|
150
|
-
|
|
151
|
-
for content in contents:
|
|
152
|
-
content_tokens = get_context_token_count(content)
|
|
153
|
-
|
|
154
|
-
# If adding this content would exceed limit, start new batch
|
|
155
|
-
if current_tokens + content_tokens > available_tokens:
|
|
156
|
-
if current_batch:
|
|
157
|
-
batches.append(current_batch)
|
|
158
|
-
current_batch = [content]
|
|
159
|
-
current_tokens = content_tokens
|
|
160
|
-
else:
|
|
161
|
-
current_batch.append(content)
|
|
162
|
-
current_tokens += content_tokens
|
|
163
|
-
|
|
164
|
-
# Add final batch
|
|
165
|
-
if current_batch:
|
|
166
|
-
batches.append(current_batch)
|
|
167
|
-
|
|
168
|
-
# Process each batch
|
|
169
|
-
batch_results = []
|
|
170
|
-
for i, batch in enumerate(batches, 1):
|
|
171
|
-
prompt = f"""请根据以下搜索结果回答以下问题:{question}
|
|
172
|
-
|
|
173
|
-
搜索结果内容 (第 {i} 批/{len(batches)}):
|
|
174
|
-
{'-' * 40}
|
|
175
|
-
{''.join(batch)}
|
|
176
|
-
{'-' * 40}
|
|
177
|
-
|
|
178
|
-
请提取与问题相关的关键信息。重点关注:
|
|
179
|
-
1. 相关事实和细节
|
|
180
|
-
2. 保持客观性
|
|
181
|
-
3. 在适当的时候引用来源
|
|
182
|
-
4. 注明任何不确定性
|
|
183
|
-
|
|
184
|
-
请将您的回答格式化为对本批次搜索结果的清晰总结。"""
|
|
185
|
-
|
|
186
|
-
response = self.model.chat_until_success(prompt)
|
|
187
|
-
batch_results.append(response)
|
|
188
|
-
|
|
189
|
-
# If only one batch, return its result directly
|
|
190
|
-
if len(batch_results) == 1:
|
|
191
|
-
return batch_results[0]
|
|
192
|
-
|
|
193
|
-
# Synthesize results from all batches
|
|
194
|
-
batch_findings = '\n\n'.join(f'Batch {i+1}:\n{result}' for i, result in enumerate(batch_results))
|
|
195
|
-
separator = '-' * 40
|
|
196
|
-
|
|
197
|
-
synthesis_prompt = f"""请通过综合多个批次的搜索结果,为原始问题提供一个全面的回答。
|
|
198
|
-
|
|
199
|
-
原始问题: {question}
|
|
200
|
-
|
|
201
|
-
各批次的发现:
|
|
202
|
-
{separator}
|
|
203
|
-
{batch_findings}
|
|
204
|
-
{separator}
|
|
205
|
-
|
|
206
|
-
请综合出一个最终答案,要求:
|
|
207
|
-
1. 整合所有批次的关键见解
|
|
208
|
-
2. 解决不同来源之间的矛盾
|
|
209
|
-
3. 保持清晰的来源归属
|
|
210
|
-
4. 承认任何剩余的不确定性
|
|
211
|
-
5. 提供对原始问题的连贯完整的回答"""
|
|
212
|
-
|
|
213
|
-
final_response = self.model.chat_until_success(synthesis_prompt)
|
|
214
|
-
return final_response
|
|
215
|
-
|
|
216
|
-
except Exception as e:
|
|
217
|
-
return f"信息提取失败:{str(e)}"
|
|
218
|
-
|
|
219
|
-
def execute(self, args: Dict) -> Dict[str, Any]:
|
|
220
|
-
"""Execute search and extract information"""
|
|
221
|
-
try:
|
|
222
|
-
query = args["query"]
|
|
223
|
-
question = args["question"]
|
|
224
|
-
max_results = args.get("max_results", 3)
|
|
225
|
-
|
|
226
|
-
# Print search information
|
|
227
|
-
PrettyOutput.print(f"搜索关键词: {query}", OutputType.INFO)
|
|
228
|
-
PrettyOutput.print(f"相关问题: {question}", OutputType.INFO)
|
|
229
|
-
|
|
230
|
-
# Get search results
|
|
231
|
-
results = self._search(query, max_results)
|
|
232
|
-
if not results:
|
|
233
|
-
return {
|
|
234
|
-
"success": False,
|
|
235
|
-
"stdout": "",
|
|
236
|
-
"stderr": "No search results found"
|
|
237
|
-
}
|
|
238
|
-
|
|
239
|
-
contents = []
|
|
240
|
-
for i, result in enumerate(results, 1):
|
|
241
|
-
try:
|
|
242
|
-
PrettyOutput.print(f"正在读取结果 {i}/{len(results)}... {result['title']} - {result['href']}", OutputType.PROGRESS)
|
|
243
|
-
webpage_result = self.webpage_tool.execute({"url": result["href"]})
|
|
244
|
-
if webpage_result["success"]:
|
|
245
|
-
contents.append(f"\nSource {i}: {result['href']}\n")
|
|
246
|
-
contents.append(webpage_result["stdout"])
|
|
247
|
-
except Exception as e:
|
|
248
|
-
PrettyOutput.print(f"读取结果失败 {i}: {str(e)}", OutputType.WARNING)
|
|
249
|
-
continue
|
|
250
|
-
|
|
251
|
-
if not contents:
|
|
252
|
-
return {
|
|
253
|
-
"success": False,
|
|
254
|
-
"stdout": "",
|
|
255
|
-
"stderr": "No valid search results found"
|
|
256
|
-
}
|
|
257
|
-
|
|
258
|
-
# Extract information
|
|
259
|
-
with yaspin(text="正在提取信息...", color="cyan") as spinner:
|
|
260
|
-
analysis = self._extract_info(contents, question)
|
|
261
|
-
spinner.text = "信息提取完成"
|
|
262
|
-
spinner.ok("✅")
|
|
263
|
-
|
|
264
|
-
return {
|
|
265
|
-
"success": True,
|
|
266
|
-
"stdout": f"Search analysis results:\n\n{analysis}",
|
|
267
|
-
"stderr": ""
|
|
268
|
-
}
|
|
269
|
-
|
|
270
|
-
except Exception as e:
|
|
271
|
-
return {
|
|
272
|
-
"success": False,
|
|
273
|
-
"stdout": "",
|
|
274
|
-
"stderr": f"Search failed: {str(e)}"
|
|
275
|
-
}
|
|
276
|
-
|
|
277
|
-
def main():
|
|
278
|
-
"""Command line directly run search tool"""
|
|
279
|
-
import argparse
|
|
280
|
-
import sys
|
|
281
|
-
|
|
282
|
-
parser = argparse.ArgumentParser(description='Bing search tool')
|
|
283
|
-
parser.add_argument('query', help='Search keywords')
|
|
284
|
-
parser.add_argument('--max', type=int, default=5, help='Maximum number of results (default 5)')
|
|
285
|
-
parser.add_argument('--url-only', action='store_true', help='Only display URL')
|
|
286
|
-
args = parser.parse_args()
|
|
287
|
-
|
|
288
|
-
try:
|
|
289
|
-
PrettyOutput.print(f"搜索: {args.query}", OutputType.INFO)
|
|
290
|
-
|
|
291
|
-
results = bing_search(args.query)
|
|
292
|
-
|
|
293
|
-
if not results:
|
|
294
|
-
PrettyOutput.print("未找到搜索结果", OutputType.WARNING)
|
|
295
|
-
sys.exit(1)
|
|
296
|
-
|
|
297
|
-
PrettyOutput.print(f"\n找到 {len(results)} 个结果:", OutputType.INFO)
|
|
298
|
-
|
|
299
|
-
for i, result in enumerate(results[:args.max], 1):
|
|
300
|
-
output = []
|
|
301
|
-
output.append(f"\n{'-'*50}")
|
|
302
|
-
if args.url_only:
|
|
303
|
-
output.append(f"{i}. {result['href']}")
|
|
304
|
-
else:
|
|
305
|
-
output.append(f"{i}. {result['title']}")
|
|
306
|
-
output.append(f"链接: {result['href']}")
|
|
307
|
-
if result['abstract']:
|
|
308
|
-
output.append(f"摘要: {result['abstract']}")
|
|
309
|
-
PrettyOutput.print("\n".join(output), OutputType.INFO)
|
|
310
|
-
|
|
311
|
-
except KeyboardInterrupt:
|
|
312
|
-
PrettyOutput.print("搜索已取消", OutputType.WARNING)
|
|
313
|
-
sys.exit(1)
|
|
314
|
-
except Exception as e:
|
|
315
|
-
PrettyOutput.print(f"执行错误: {str(e)}", OutputType.ERROR)
|
|
316
|
-
sys.exit(1)
|
|
317
20
|
|
|
318
|
-
|
|
319
|
-
|
|
21
|
+
@staticmethod
|
|
22
|
+
def check() -> bool:
|
|
23
|
+
return os.getenv("YUANBAO_COOKIES", "") != "" and os.getenv("YUANBAO_AGENT_ID", "") != ""
|
|
24
|
+
|
|
25
|
+
def execute(self, args: Dict[str, Any]) -> Dict[str, Any]: # type: ignore
|
|
26
|
+
query = args.get("query")
|
|
27
|
+
model = PlatformRegistry().create_platform("yuanbao")
|
|
28
|
+
model.set_suppress_output(False) # type: ignore
|
|
29
|
+
model.set_model_name("deep_seek") # type: ignore
|
|
30
|
+
return {
|
|
31
|
+
"stdout": model.chat_until_success(query), # type: ignore
|
|
32
|
+
"stderr": "",
|
|
33
|
+
"success": True,
|
|
34
|
+
}
|
|
@@ -7,6 +7,7 @@ from typing import Dict, Any
|
|
|
7
7
|
|
|
8
8
|
from yaspin import yaspin
|
|
9
9
|
from jarvis.jarvis_platform.registry import PlatformRegistry
|
|
10
|
+
from jarvis.jarvis_utils.utils import ct, ot
|
|
10
11
|
|
|
11
12
|
class ToolGenerator:
|
|
12
13
|
"""工具生成器类,用于自动创建与Jarvis系统集成的新工具"""
|
|
@@ -41,7 +42,7 @@ class ToolGenerator:
|
|
|
41
42
|
包含执行结果的字典,包含success、stdout和stderr字段
|
|
42
43
|
"""
|
|
43
44
|
# 获取代码生成平台实例
|
|
44
|
-
model = PlatformRegistry.get_global_platform_registry().
|
|
45
|
+
model = PlatformRegistry.get_global_platform_registry().get_normal_platform()
|
|
45
46
|
|
|
46
47
|
try:
|
|
47
48
|
tool_name = arguments["tool_name"]
|
|
@@ -112,8 +113,7 @@ class ToolGenerator:
|
|
|
112
113
|
Returns:
|
|
113
114
|
格式化后的提示字符串
|
|
114
115
|
"""
|
|
115
|
-
example_code = '''
|
|
116
|
-
<TOOL>
|
|
116
|
+
example_code = ot("TOOL")+'''
|
|
117
117
|
from typing import Dict, Any
|
|
118
118
|
from jarvis.utils import OutputType, PrettyOutput
|
|
119
119
|
from jarvis.jarvis_platform.registry import PlatformRegistry
|
|
@@ -148,7 +148,7 @@ class CustomTool:
|
|
|
148
148
|
try:
|
|
149
149
|
# 在此实现工具逻辑
|
|
150
150
|
# 使用LLM
|
|
151
|
-
# model = PlatformRegistry.get_global_platform_registry().
|
|
151
|
+
# model = PlatformRegistry.get_global_platform_registry().get_normal_platform()
|
|
152
152
|
# result = model.chat_until_success(prompt)
|
|
153
153
|
|
|
154
154
|
result = "工具执行结果"
|
|
@@ -163,8 +163,7 @@ class CustomTool:
|
|
|
163
163
|
"stdout": "",
|
|
164
164
|
"stderr": str(e)
|
|
165
165
|
}
|
|
166
|
-
|
|
167
|
-
'''
|
|
166
|
+
''' + ct("TOOL")
|
|
168
167
|
|
|
169
168
|
return f'''创建一个与Jarvis系统集成的Python工具类。请遵循以下要求:
|
|
170
169
|
1. 类名: {tool_name.capitalize()}Tool
|
|
@@ -183,9 +182,9 @@ class CustomTool:
|
|
|
183
182
|
8. 仅返回Python实现代码
|
|
184
183
|
9. 代码应该是完整且可直接使用的
|
|
185
184
|
10. 按照以下格式输出代码:
|
|
186
|
-
|
|
185
|
+
{ot("TOOL")}
|
|
187
186
|
{example_code}
|
|
188
|
-
|
|
187
|
+
{ct("TOOL")}
|
|
189
188
|
|
|
190
189
|
示例:
|
|
191
190
|
{example_code}
|
|
@@ -199,8 +198,7 @@ class CustomTool:
|
|
|
199
198
|
Returns:
|
|
200
199
|
提取到的Python代码字符串
|
|
201
200
|
"""
|
|
202
|
-
|
|
203
|
-
sm = re.search(r'<TOOL>(.*?)</TOOL>', response, re.DOTALL)
|
|
201
|
+
sm = re.search(ot("TOOL")+r'(.*?)'+ct("TOOL"), response, re.DOTALL)
|
|
204
202
|
if sm:
|
|
205
203
|
return sm.group(1)
|
|
206
204
|
return ""
|
jarvis/jarvis_utils/__init__.py
CHANGED
jarvis/jarvis_utils/config.py
CHANGED
|
@@ -11,12 +11,12 @@ import os
|
|
|
11
11
|
"""
|
|
12
12
|
def get_max_token_count() -> int:
|
|
13
13
|
"""
|
|
14
|
-
|
|
14
|
+
获取模型允许的最大token数量。
|
|
15
15
|
|
|
16
|
-
|
|
17
|
-
int:
|
|
16
|
+
返回:
|
|
17
|
+
int: 模型能处理的最大token数量。
|
|
18
18
|
"""
|
|
19
|
-
return int(os.getenv('JARVIS_MAX_TOKEN_COUNT', '
|
|
19
|
+
return int(os.getenv('JARVIS_MAX_TOKEN_COUNT', '64000')) # 默认64k
|
|
20
20
|
|
|
21
21
|
def get_thread_count() -> int:
|
|
22
22
|
"""
|
|
@@ -26,14 +26,6 @@ def get_thread_count() -> int:
|
|
|
26
26
|
int: 线程数,默认为1
|
|
27
27
|
"""
|
|
28
28
|
return int(os.getenv('JARVIS_THREAD_COUNT', '1'))
|
|
29
|
-
def dont_use_local_model() -> bool:
|
|
30
|
-
"""
|
|
31
|
-
检查是否应避免使用本地模型。
|
|
32
|
-
|
|
33
|
-
返回:
|
|
34
|
-
bool: 如果不使用本地模型则返回True,默认为False
|
|
35
|
-
"""
|
|
36
|
-
return os.getenv('JARVIS_DONT_USE_LOCAL_MODEL', 'false') == 'true'
|
|
37
29
|
|
|
38
30
|
def is_auto_complete() -> bool:
|
|
39
31
|
"""
|
|
@@ -44,30 +36,7 @@ def is_auto_complete() -> bool:
|
|
|
44
36
|
"""
|
|
45
37
|
return os.getenv('JARVIS_AUTO_COMPLETE', 'false') == 'true'
|
|
46
38
|
|
|
47
|
-
|
|
48
|
-
"""
|
|
49
|
-
检查是否应使用方法论。
|
|
50
|
-
|
|
51
|
-
返回:
|
|
52
|
-
bool: 如果使用方法论则返回True,默认为True
|
|
53
|
-
"""
|
|
54
|
-
return os.getenv('JARVIS_USE_METHODOLOGY', 'true') == 'true'
|
|
55
|
-
def is_record_methodology() -> bool:
|
|
56
|
-
"""
|
|
57
|
-
检查是否应记录方法论。
|
|
58
|
-
|
|
59
|
-
返回:
|
|
60
|
-
bool: 如果记录方法论则返回True,默认为True
|
|
61
|
-
"""
|
|
62
|
-
return os.getenv('JARVIS_RECORD_METHODOLOGY', 'true') == 'true'
|
|
63
|
-
def is_need_summary() -> bool:
|
|
64
|
-
"""
|
|
65
|
-
检查是否需要生成摘要。
|
|
66
|
-
|
|
67
|
-
返回:
|
|
68
|
-
bool: 如果需要摘要则返回True,默认为True
|
|
69
|
-
"""
|
|
70
|
-
return os.getenv('JARVIS_NEED_SUMMARY', 'true') == 'true'
|
|
39
|
+
|
|
71
40
|
def get_min_paragraph_length() -> int:
|
|
72
41
|
"""
|
|
73
42
|
获取文本处理的最小段落长度。
|
|
@@ -97,65 +66,36 @@ def get_normal_platform_name() -> str:
|
|
|
97
66
|
获取正常操作的平台名称。
|
|
98
67
|
|
|
99
68
|
返回:
|
|
100
|
-
str: 平台名称,默认为'
|
|
69
|
+
str: 平台名称,默认为'yuanbao'
|
|
101
70
|
"""
|
|
102
|
-
return os.getenv('JARVIS_PLATFORM', '
|
|
71
|
+
return os.getenv('JARVIS_PLATFORM', 'yuanbao')
|
|
103
72
|
def get_normal_model_name() -> str:
|
|
104
73
|
"""
|
|
105
74
|
获取正常操作的模型名称。
|
|
106
75
|
|
|
107
76
|
返回:
|
|
108
|
-
str: 模型名称,默认为'
|
|
77
|
+
str: 模型名称,默认为'deep_seek'
|
|
109
78
|
"""
|
|
110
|
-
return os.getenv('JARVIS_MODEL', '
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
获取代码生成的平台名称。
|
|
114
|
-
|
|
115
|
-
返回:
|
|
116
|
-
str: 平台名称,默认为'kimi'
|
|
117
|
-
"""
|
|
118
|
-
return os.getenv('JARVIS_CODEGEN_PLATFORM', os.getenv('JARVIS_PLATFORM', 'kimi'))
|
|
119
|
-
def get_codegen_model_name() -> str:
|
|
120
|
-
"""
|
|
121
|
-
获取代码生成的模型名称。
|
|
122
|
-
|
|
123
|
-
返回:
|
|
124
|
-
str: 模型名称,默认为'kimi'
|
|
125
|
-
"""
|
|
126
|
-
return os.getenv('JARVIS_CODEGEN_MODEL', os.getenv('JARVIS_MODEL', 'kimi'))
|
|
79
|
+
return os.getenv('JARVIS_MODEL', 'deep_seek_v3')
|
|
80
|
+
|
|
81
|
+
|
|
127
82
|
def get_thinking_platform_name() -> str:
|
|
128
83
|
"""
|
|
129
84
|
获取思考操作的平台名称。
|
|
130
85
|
|
|
131
86
|
返回:
|
|
132
|
-
str: 平台名称,默认为'
|
|
87
|
+
str: 平台名称,默认为'yuanbao'
|
|
133
88
|
"""
|
|
134
|
-
return os.getenv('JARVIS_THINKING_PLATFORM', os.getenv('JARVIS_PLATFORM', '
|
|
89
|
+
return os.getenv('JARVIS_THINKING_PLATFORM', os.getenv('JARVIS_PLATFORM', 'yuanbao'))
|
|
135
90
|
def get_thinking_model_name() -> str:
|
|
136
91
|
"""
|
|
137
92
|
获取思考操作的模型名称。
|
|
138
93
|
|
|
139
94
|
返回:
|
|
140
|
-
str: 模型名称,默认为'
|
|
141
|
-
"""
|
|
142
|
-
return os.getenv('JARVIS_THINKING_MODEL', os.getenv('JARVIS_MODEL', 'kimi'))
|
|
143
|
-
def get_cheap_platform_name() -> str:
|
|
144
|
-
"""
|
|
145
|
-
获取低成本操作的平台名称。
|
|
146
|
-
|
|
147
|
-
返回:
|
|
148
|
-
str: 平台名称,默认为'kimi'
|
|
149
|
-
"""
|
|
150
|
-
return os.getenv('JARVIS_CHEAP_PLATFORM', os.getenv('JARVIS_PLATFORM', 'kimi'))
|
|
151
|
-
def get_cheap_model_name() -> str:
|
|
152
|
-
"""
|
|
153
|
-
获取低成本操作的模型名称。
|
|
154
|
-
|
|
155
|
-
返回:
|
|
156
|
-
str: 模型名称,默认为'kimi'
|
|
95
|
+
str: 模型名称,默认为'deep_seek'
|
|
157
96
|
"""
|
|
158
|
-
return os.getenv('
|
|
97
|
+
return os.getenv('JARVIS_THINKING_MODEL', os.getenv('JARVIS_MODEL', 'deep_seek'))
|
|
98
|
+
|
|
159
99
|
def is_execute_tool_confirm() -> bool:
|
|
160
100
|
"""
|
|
161
101
|
检查工具执行是否需要确认。
|
|
@@ -172,3 +112,67 @@ def is_confirm_before_apply_patch() -> bool:
|
|
|
172
112
|
bool: 如果需要确认则返回True,默认为False
|
|
173
113
|
"""
|
|
174
114
|
return os.getenv('JARVIS_CONFIRM_BEFORE_APPLY_PATCH', 'false') == 'true'
|
|
115
|
+
|
|
116
|
+
def get_rag_ignored_paths() -> list:
|
|
117
|
+
"""
|
|
118
|
+
获取RAG索引时需要忽略的路径列表。
|
|
119
|
+
|
|
120
|
+
首先尝试从.jarvis/rag_ignore.txt文件中读取,
|
|
121
|
+
如果该文件不存在,则返回默认忽略列表。
|
|
122
|
+
|
|
123
|
+
返回:
|
|
124
|
+
list: 忽略路径的列表,默认包含常见忽略路径
|
|
125
|
+
"""
|
|
126
|
+
# 默认忽略路径
|
|
127
|
+
default_ignored = [
|
|
128
|
+
'.git',
|
|
129
|
+
'__pycache__',
|
|
130
|
+
'node_modules',
|
|
131
|
+
'.jarvis',
|
|
132
|
+
'.jarvis-*',
|
|
133
|
+
'target',
|
|
134
|
+
'venv',
|
|
135
|
+
'env',
|
|
136
|
+
'.env',
|
|
137
|
+
'.venv',
|
|
138
|
+
'.idea',
|
|
139
|
+
'.vscode',
|
|
140
|
+
'dist',
|
|
141
|
+
'build',
|
|
142
|
+
'*.pyc',
|
|
143
|
+
'*.pyo',
|
|
144
|
+
'*.so',
|
|
145
|
+
'*.o',
|
|
146
|
+
'*.a',
|
|
147
|
+
'*.pyd',
|
|
148
|
+
'*.dll',
|
|
149
|
+
'*.exe',
|
|
150
|
+
'*.bin',
|
|
151
|
+
'*.obj',
|
|
152
|
+
'*.out',
|
|
153
|
+
'*.jpg',
|
|
154
|
+
'*.jpeg',
|
|
155
|
+
'*.png',
|
|
156
|
+
'*.gif',
|
|
157
|
+
'*.tiff',
|
|
158
|
+
'*.pdf',
|
|
159
|
+
'*.zip',
|
|
160
|
+
'*.tar',
|
|
161
|
+
'*.tar.gz',
|
|
162
|
+
'*.gz',
|
|
163
|
+
'*.bz2',
|
|
164
|
+
'*.xz',
|
|
165
|
+
'*.rar'
|
|
166
|
+
]
|
|
167
|
+
|
|
168
|
+
# 尝试从配置文件中读取
|
|
169
|
+
try:
|
|
170
|
+
config_path = os.path.join('.jarvis', 'rag_ignore.txt')
|
|
171
|
+
if os.path.exists(config_path):
|
|
172
|
+
with open(config_path, 'r') as f:
|
|
173
|
+
custom_ignored = [line.strip() for line in f if line.strip() and not line.startswith('#')]
|
|
174
|
+
return custom_ignored
|
|
175
|
+
except Exception:
|
|
176
|
+
pass
|
|
177
|
+
|
|
178
|
+
return default_ignored
|