jarvis-ai-assistant 0.1.178__py3-none-any.whl → 0.1.179__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 +130 -79
- jarvis/jarvis_agent/builtin_input_handler.py +1 -1
- jarvis/jarvis_agent/jarvis.py +9 -13
- jarvis/jarvis_agent/main.py +4 -2
- jarvis/jarvis_code_agent/code_agent.py +34 -23
- jarvis/jarvis_code_agent/lint.py +164 -0
- jarvis/jarvis_code_analysis/checklists/loader.py +6 -20
- jarvis/jarvis_code_analysis/code_review.py +8 -6
- jarvis/jarvis_dev/main.py +1 -8
- jarvis/jarvis_git_details/main.py +1 -1
- jarvis/jarvis_git_squash/main.py +5 -3
- jarvis/jarvis_git_utils/git_commiter.py +24 -23
- jarvis/jarvis_mcp/sse_mcp_client.py +6 -4
- jarvis/jarvis_mcp/stdio_mcp_client.py +5 -4
- jarvis/jarvis_mcp/streamable_mcp_client.py +404 -0
- jarvis/jarvis_methodology/main.py +10 -9
- jarvis/jarvis_multi_agent/main.py +3 -1
- jarvis/jarvis_platform/base.py +14 -8
- jarvis/jarvis_platform/human.py +3 -1
- jarvis/jarvis_platform/kimi.py +10 -7
- jarvis/jarvis_platform/openai.py +4 -1
- jarvis/jarvis_platform/registry.py +6 -2
- jarvis/jarvis_platform/yuanbao.py +13 -10
- jarvis/jarvis_platform_manager/main.py +11 -9
- jarvis/jarvis_smart_shell/main.py +1 -0
- jarvis/jarvis_tools/ask_codebase.py +4 -3
- jarvis/jarvis_tools/ask_user.py +2 -1
- jarvis/jarvis_tools/base.py +3 -1
- jarvis/jarvis_tools/chdir.py +2 -1
- jarvis/jarvis_tools/cli/main.py +1 -0
- jarvis/jarvis_tools/code_plan.py +5 -3
- jarvis/jarvis_tools/create_code_agent.py +5 -2
- jarvis/jarvis_tools/create_sub_agent.py +1 -3
- jarvis/jarvis_tools/edit_file.py +3 -3
- jarvis/jarvis_tools/execute_script.py +1 -1
- jarvis/jarvis_tools/file_analyzer.py +5 -3
- jarvis/jarvis_tools/file_operation.py +4 -7
- jarvis/jarvis_tools/find_methodology.py +4 -2
- jarvis/jarvis_tools/generate_new_tool.py +2 -1
- jarvis/jarvis_tools/methodology.py +3 -4
- jarvis/jarvis_tools/read_code.py +2 -1
- jarvis/jarvis_tools/read_webpage.py +3 -1
- jarvis/jarvis_tools/registry.py +22 -13
- jarvis/jarvis_tools/rewrite_file.py +2 -1
- jarvis/jarvis_tools/search_web.py +1 -0
- jarvis/jarvis_tools/virtual_tty.py +5 -4
- jarvis/jarvis_utils/__init__.py +2 -0
- jarvis/jarvis_utils/builtin_replace_map.py +1 -1
- jarvis/jarvis_utils/config.py +31 -1
- jarvis/jarvis_utils/embedding.py +4 -3
- jarvis/jarvis_utils/file_processors.py +1 -0
- jarvis/jarvis_utils/git_utils.py +55 -25
- jarvis/jarvis_utils/globals.py +4 -2
- jarvis/jarvis_utils/input.py +14 -7
- jarvis/jarvis_utils/methodology.py +6 -4
- jarvis/jarvis_utils/output.py +10 -6
- jarvis/jarvis_utils/utils.py +89 -13
- {jarvis_ai_assistant-0.1.178.dist-info → jarvis_ai_assistant-0.1.179.dist-info}/METADATA +45 -33
- jarvis_ai_assistant-0.1.179.dist-info/RECORD +98 -0
- jarvis_ai_assistant-0.1.178.dist-info/RECORD +0 -96
- {jarvis_ai_assistant-0.1.178.dist-info → jarvis_ai_assistant-0.1.179.dist-info}/WHEEL +0 -0
- {jarvis_ai_assistant-0.1.178.dist-info → jarvis_ai_assistant-0.1.179.dist-info}/entry_points.txt +0 -0
- {jarvis_ai_assistant-0.1.178.dist-info → jarvis_ai_assistant-0.1.179.dist-info}/licenses/LICENSE +0 -0
- {jarvis_ai_assistant-0.1.178.dist-info → jarvis_ai_assistant-0.1.179.dist-info}/top_level.txt +0 -0
jarvis/__init__.py
CHANGED
jarvis/jarvis_agent/__init__.py
CHANGED
|
@@ -1,26 +1,33 @@
|
|
|
1
1
|
# -*- coding: utf-8 -*-
|
|
2
|
+
# 标准库导入
|
|
2
3
|
import datetime
|
|
3
4
|
import platform
|
|
4
|
-
from typing import Any, Callable, List, Optional, Tuple, Union
|
|
5
|
+
from typing import Any, Callable, List, Optional, Protocol, Tuple, Union
|
|
5
6
|
|
|
6
|
-
|
|
7
|
+
# 第三方库导入
|
|
8
|
+
from yaspin import yaspin # type: ignore
|
|
7
9
|
|
|
8
|
-
|
|
10
|
+
# 本地库导入
|
|
11
|
+
# jarvis_agent 相关
|
|
12
|
+
# jarvis_platform 相关
|
|
9
13
|
from jarvis.jarvis_platform.base import BasePlatform
|
|
10
14
|
from jarvis.jarvis_platform.registry import PlatformRegistry
|
|
11
|
-
|
|
15
|
+
# jarvis_utils 相关
|
|
16
|
+
from jarvis.jarvis_utils.config import (get_max_token_count,
|
|
17
|
+
get_max_tool_call_count,
|
|
18
|
+
is_auto_complete,
|
|
19
|
+
is_execute_tool_confirm,
|
|
20
|
+
is_use_analysis, is_use_methodology)
|
|
12
21
|
from jarvis.jarvis_utils.embedding import get_context_token_count
|
|
13
|
-
from jarvis.jarvis_utils.
|
|
14
|
-
|
|
15
|
-
from jarvis.jarvis_utils.globals import make_agent_name, set_agent, delete_agent
|
|
22
|
+
from jarvis.jarvis_utils.globals import (delete_agent, make_agent_name,
|
|
23
|
+
set_agent)
|
|
16
24
|
from jarvis.jarvis_utils.input import get_multiline_input
|
|
17
|
-
from jarvis.jarvis_utils.
|
|
25
|
+
from jarvis.jarvis_utils.methodology import (load_methodology,
|
|
26
|
+
upload_methodology)
|
|
27
|
+
from jarvis.jarvis_utils.output import OutputType, PrettyOutput
|
|
18
28
|
from jarvis.jarvis_utils.tag import ct, ot
|
|
19
29
|
from jarvis.jarvis_utils.utils import user_confirm
|
|
20
30
|
|
|
21
|
-
from jarvis.jarvis_platform.registry import PlatformRegistry
|
|
22
|
-
|
|
23
|
-
|
|
24
31
|
origin_agent_system_prompt = f"""
|
|
25
32
|
<role>
|
|
26
33
|
# 🤖 角色
|
|
@@ -105,14 +112,20 @@ origin_agent_system_prompt = f"""
|
|
|
105
112
|
|
|
106
113
|
|
|
107
114
|
class OutputHandlerProtocol(Protocol):
|
|
108
|
-
def name(self) -> str:
|
|
109
|
-
|
|
110
|
-
def prompt(self) -> str: ...
|
|
111
|
-
def handle(self, response: str, agent: Any) -> Tuple[bool, Any]: ...
|
|
115
|
+
def name(self) -> str:
|
|
116
|
+
...
|
|
112
117
|
|
|
118
|
+
def can_handle(self, response: str) -> bool:
|
|
119
|
+
...
|
|
113
120
|
|
|
114
|
-
|
|
121
|
+
def prompt(self) -> str:
|
|
122
|
+
...
|
|
115
123
|
|
|
124
|
+
def handle(self, response: str, agent: Any) -> Tuple[bool, Any]:
|
|
125
|
+
...
|
|
126
|
+
|
|
127
|
+
|
|
128
|
+
class Agent:
|
|
116
129
|
def set_summary_prompt(self, summary_prompt: str):
|
|
117
130
|
"""设置任务完成时的总结提示模板。
|
|
118
131
|
|
|
@@ -129,29 +142,31 @@ class Agent:
|
|
|
129
142
|
2. 重置对话长度计数器
|
|
130
143
|
3. 清空当前提示
|
|
131
144
|
"""
|
|
132
|
-
self.model.reset()
|
|
145
|
+
self.model.reset() # type: ignore
|
|
133
146
|
self.conversation_length = 0
|
|
134
147
|
self.prompt = ""
|
|
135
148
|
|
|
136
149
|
def __del__(self):
|
|
137
150
|
delete_agent(self.name)
|
|
138
151
|
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
152
|
+
def __init__(
|
|
153
|
+
self,
|
|
154
|
+
system_prompt: str,
|
|
155
|
+
name: str = "Jarvis",
|
|
156
|
+
description: str = "",
|
|
157
|
+
platform: Union[Optional[BasePlatform], Optional[str]] = None,
|
|
158
|
+
model_name: Optional[str] = None,
|
|
159
|
+
summary_prompt: Optional[str] = None,
|
|
160
|
+
auto_complete: Optional[bool] = None,
|
|
161
|
+
output_handler: List[OutputHandlerProtocol] = [],
|
|
162
|
+
use_tools: List[str] = [],
|
|
163
|
+
input_handler: Optional[List[Callable[[str, Any], Tuple[str, bool]]]] = None,
|
|
164
|
+
execute_tool_confirm: Optional[bool] = None,
|
|
165
|
+
need_summary: bool = True,
|
|
166
|
+
multiline_inputer: Optional[Callable[[str], str]] = None,
|
|
167
|
+
use_methodology: Optional[bool] = None,
|
|
168
|
+
use_analysis: Optional[bool] = None,
|
|
169
|
+
):
|
|
155
170
|
"""初始化Jarvis Agent实例
|
|
156
171
|
|
|
157
172
|
参数:
|
|
@@ -169,6 +184,7 @@ class Agent:
|
|
|
169
184
|
need_summary: 是否需要生成总结
|
|
170
185
|
multiline_inputer: 多行输入处理器
|
|
171
186
|
use_methodology: 是否使用方法论
|
|
187
|
+
use_analysis: 是否使用任务分析
|
|
172
188
|
"""
|
|
173
189
|
self.name = make_agent_name(name)
|
|
174
190
|
self.description = description
|
|
@@ -182,7 +198,9 @@ class Agent:
|
|
|
182
198
|
else:
|
|
183
199
|
self.model = platform
|
|
184
200
|
else:
|
|
185
|
-
self.model =
|
|
201
|
+
self.model = (
|
|
202
|
+
PlatformRegistry.get_global_platform_registry().get_normal_platform()
|
|
203
|
+
)
|
|
186
204
|
|
|
187
205
|
if model_name is not None:
|
|
188
206
|
self.model.set_model_name(model_name)
|
|
@@ -190,13 +208,20 @@ class Agent:
|
|
|
190
208
|
self.model.set_suppress_output(False)
|
|
191
209
|
|
|
192
210
|
from jarvis.jarvis_tools.registry import ToolRegistry
|
|
211
|
+
|
|
193
212
|
self.output_handler = output_handler if output_handler else [ToolRegistry()]
|
|
194
213
|
self.set_use_tools(use_tools)
|
|
195
214
|
|
|
196
|
-
self.multiline_inputer =
|
|
197
|
-
|
|
198
|
-
|
|
215
|
+
self.multiline_inputer = (
|
|
216
|
+
multiline_inputer if multiline_inputer else get_multiline_input
|
|
217
|
+
)
|
|
199
218
|
|
|
219
|
+
self.use_methodology = (
|
|
220
|
+
use_methodology if use_methodology is not None else is_use_methodology()
|
|
221
|
+
)
|
|
222
|
+
self.use_analysis = (
|
|
223
|
+
use_analysis if use_analysis is not None else is_use_analysis()
|
|
224
|
+
)
|
|
200
225
|
self.prompt = ""
|
|
201
226
|
self.conversation_length = 0 # Use length counter instead
|
|
202
227
|
self.system_prompt = system_prompt
|
|
@@ -209,10 +234,16 @@ class Agent:
|
|
|
209
234
|
self.max_tool_call_count = get_max_tool_call_count()
|
|
210
235
|
self.after_tool_call_cb: Optional[Callable[[Agent], None]] = None
|
|
211
236
|
|
|
237
|
+
self.execute_tool_confirm = (
|
|
238
|
+
execute_tool_confirm
|
|
239
|
+
if execute_tool_confirm is not None
|
|
240
|
+
else is_execute_tool_confirm()
|
|
241
|
+
)
|
|
212
242
|
|
|
213
|
-
self.
|
|
214
|
-
|
|
215
|
-
|
|
243
|
+
self.summary_prompt = (
|
|
244
|
+
summary_prompt
|
|
245
|
+
if summary_prompt
|
|
246
|
+
else f"""<report>
|
|
216
247
|
请生成任务执行的简明总结报告,包括:
|
|
217
248
|
|
|
218
249
|
<content>
|
|
@@ -228,9 +259,12 @@ class Agent:
|
|
|
228
259
|
</format>
|
|
229
260
|
</report>
|
|
230
261
|
"""
|
|
262
|
+
)
|
|
231
263
|
|
|
232
|
-
self.max_token_count =
|
|
233
|
-
self.auto_complete =
|
|
264
|
+
self.max_token_count = get_max_token_count()
|
|
265
|
+
self.auto_complete = (
|
|
266
|
+
auto_complete if auto_complete is not None else is_auto_complete()
|
|
267
|
+
)
|
|
234
268
|
welcome_message = f"{name} 初始化完成 - 使用 {self.model.name()} 模型"
|
|
235
269
|
|
|
236
270
|
PrettyOutput.print(welcome_message, OutputType.SYSTEM)
|
|
@@ -243,7 +277,9 @@ class Agent:
|
|
|
243
277
|
|
|
244
278
|
# 添加工具列表概览
|
|
245
279
|
action_prompt += "\n<overview>\n## Action List\n"
|
|
246
|
-
action_prompt +=
|
|
280
|
+
action_prompt += (
|
|
281
|
+
"[" + ", ".join([handler.name() for handler in self.output_handler]) + "]"
|
|
282
|
+
)
|
|
247
283
|
action_prompt += "\n</overview>"
|
|
248
284
|
|
|
249
285
|
# 添加每个工具的详细说明
|
|
@@ -253,8 +289,10 @@ class Agent:
|
|
|
253
289
|
# 获取工具的提示词并确保格式正确
|
|
254
290
|
handler_prompt = handler.prompt().strip()
|
|
255
291
|
# 调整缩进以保持层级结构
|
|
256
|
-
handler_prompt = "\n".join(
|
|
257
|
-
|
|
292
|
+
handler_prompt = "\n".join(
|
|
293
|
+
" " + line if line.strip() else line
|
|
294
|
+
for line in handler_prompt.split("\n")
|
|
295
|
+
)
|
|
258
296
|
action_prompt += handler_prompt + "\n</tool>\n"
|
|
259
297
|
|
|
260
298
|
# 添加工具使用总结
|
|
@@ -272,23 +310,25 @@ class Agent:
|
|
|
272
310
|
</actions>
|
|
273
311
|
"""
|
|
274
312
|
|
|
275
|
-
self.model.set_system_message(
|
|
313
|
+
self.model.set_system_message(
|
|
314
|
+
f"""
|
|
276
315
|
{self.system_prompt}
|
|
277
316
|
|
|
278
317
|
{action_prompt}
|
|
279
|
-
"""
|
|
318
|
+
"""
|
|
319
|
+
)
|
|
280
320
|
self.first = True
|
|
281
321
|
|
|
282
322
|
def set_use_tools(self, use_tools):
|
|
283
323
|
"""设置要使用的工具列表"""
|
|
284
324
|
from jarvis.jarvis_tools.registry import ToolRegistry
|
|
325
|
+
|
|
285
326
|
for handler in self.output_handler:
|
|
286
327
|
if isinstance(handler, ToolRegistry):
|
|
287
328
|
if use_tools:
|
|
288
329
|
handler.use_tools(use_tools)
|
|
289
330
|
break
|
|
290
331
|
|
|
291
|
-
|
|
292
332
|
def set_addon_prompt(self, addon_prompt: str):
|
|
293
333
|
"""设置附加提示。
|
|
294
334
|
|
|
@@ -297,7 +337,7 @@ class Agent:
|
|
|
297
337
|
"""
|
|
298
338
|
self.addon_prompt = addon_prompt
|
|
299
339
|
|
|
300
|
-
def set_after_tool_call_cb(self, cb: Callable[[Any], None]):
|
|
340
|
+
def set_after_tool_call_cb(self, cb: Callable[[Any], None]): # type: ignore
|
|
301
341
|
"""设置工具调用后回调函数。
|
|
302
342
|
|
|
303
343
|
参数:
|
|
@@ -308,6 +348,7 @@ class Agent:
|
|
|
308
348
|
def get_tool_registry(self) -> Optional[Any]:
|
|
309
349
|
"""获取工具注册表实例"""
|
|
310
350
|
from jarvis.jarvis_tools.registry import ToolRegistry
|
|
351
|
+
|
|
311
352
|
for handler in self.output_handler:
|
|
312
353
|
if isinstance(handler, ToolRegistry):
|
|
313
354
|
return handler
|
|
@@ -321,10 +362,14 @@ class Agent:
|
|
|
321
362
|
|
|
322
363
|
"""
|
|
323
364
|
# 结构化系统指令
|
|
324
|
-
action_handlers =
|
|
365
|
+
action_handlers = ", ".join([handler.name() for handler in self.output_handler])
|
|
325
366
|
|
|
326
367
|
# 任务完成提示
|
|
327
|
-
complete_prompt =
|
|
368
|
+
complete_prompt = (
|
|
369
|
+
f"- 输出{ot('!!!COMPLETE!!!')}"
|
|
370
|
+
if need_complete and self.auto_complete
|
|
371
|
+
else ""
|
|
372
|
+
)
|
|
328
373
|
|
|
329
374
|
addon_prompt = f"""
|
|
330
375
|
[系统提示开始]
|
|
@@ -335,8 +380,7 @@ class Agent:
|
|
|
335
380
|
- 仅包含一个操作
|
|
336
381
|
- 如果信息不明确,请请求用户补充
|
|
337
382
|
- 如果执行过程中连续失败5次,请使用ask_user询问用户操作
|
|
338
|
-
- 操作列表:
|
|
339
|
-
{action_handlers}
|
|
383
|
+
- 操作列表:{action_handlers}
|
|
340
384
|
[系统提示结束]
|
|
341
385
|
|
|
342
386
|
请继续。
|
|
@@ -377,8 +421,7 @@ class Agent:
|
|
|
377
421
|
if self.conversation_length > self.max_token_count:
|
|
378
422
|
message = self._summarize_and_clear_history() + "\n\n" + message
|
|
379
423
|
self.conversation_length += get_context_token_count(message)
|
|
380
|
-
return self.model.chat_until_success(message)
|
|
381
|
-
|
|
424
|
+
return self.model.chat_until_success(message) # type: ignore
|
|
382
425
|
|
|
383
426
|
def _summarize_and_clear_history(self) -> str:
|
|
384
427
|
"""总结当前对话并清理历史记录
|
|
@@ -399,7 +442,6 @@ class Agent:
|
|
|
399
442
|
# Create a new model instance to summarize, avoid affecting the main conversation
|
|
400
443
|
|
|
401
444
|
with yaspin(text="正在总结对话历史...", color="cyan") as spinner:
|
|
402
|
-
|
|
403
445
|
summary_prompt = """
|
|
404
446
|
<summary_request>
|
|
405
447
|
<objective>
|
|
@@ -425,9 +467,9 @@ class Agent:
|
|
|
425
467
|
|
|
426
468
|
try:
|
|
427
469
|
with spinner.hidden():
|
|
428
|
-
summary = self.model.chat_until_success(self.prompt + "\n" + summary_prompt)
|
|
470
|
+
summary = self.model.chat_until_success(self.prompt + "\n" + summary_prompt) # type: ignore
|
|
429
471
|
|
|
430
|
-
self.model.reset()
|
|
472
|
+
self.model.reset() # type: ignore
|
|
431
473
|
|
|
432
474
|
# 清空当前对话历史,但保留系统消息
|
|
433
475
|
self.conversation_length = 0 # Reset conversation length
|
|
@@ -435,7 +477,7 @@ class Agent:
|
|
|
435
477
|
# 添加总结作为新的上下文
|
|
436
478
|
spinner.text = "总结对话历史完成"
|
|
437
479
|
spinner.ok("✅")
|
|
438
|
-
return
|
|
480
|
+
return f"""<summary>
|
|
439
481
|
<header>
|
|
440
482
|
以下是之前对话的关键信息总结:
|
|
441
483
|
</header>
|
|
@@ -475,18 +517,29 @@ class Agent:
|
|
|
475
517
|
if handler.can_handle(response):
|
|
476
518
|
tool_list.append(handler)
|
|
477
519
|
if len(tool_list) > 1:
|
|
478
|
-
PrettyOutput.print(
|
|
479
|
-
|
|
520
|
+
PrettyOutput.print(
|
|
521
|
+
f"操作失败:检测到多个操作。一次只能执行一个操作。尝试执行的操作:{', '.join([handler.name() for handler in tool_list])}",
|
|
522
|
+
OutputType.WARNING,
|
|
523
|
+
)
|
|
524
|
+
return (
|
|
525
|
+
False,
|
|
526
|
+
f"操作失败:检测到多个操作。一次只能执行一个操作。尝试执行的操作:{', '.join([handler.name() for handler in tool_list])}",
|
|
527
|
+
)
|
|
480
528
|
if len(tool_list) == 0:
|
|
481
529
|
return False, ""
|
|
482
|
-
if
|
|
530
|
+
if (
|
|
531
|
+
self.max_tool_call_count > 0
|
|
532
|
+
and self.tool_call_count >= self.max_tool_call_count
|
|
533
|
+
):
|
|
483
534
|
if user_confirm(f"工具调用次数超过限制,是否继续执行?", True):
|
|
484
535
|
self.reset_tool_call_count()
|
|
485
536
|
else:
|
|
486
537
|
return False, ""
|
|
487
538
|
if self.execute_tool_confirm:
|
|
488
539
|
self.reset_tool_call_count()
|
|
489
|
-
if not self.execute_tool_confirm or user_confirm(
|
|
540
|
+
if not self.execute_tool_confirm or user_confirm(
|
|
541
|
+
f"需要执行{tool_list[0].name()}确认执行?", True
|
|
542
|
+
):
|
|
490
543
|
with yaspin(text=f"正在执行{tool_list[0].name()}...", color="cyan") as spinner:
|
|
491
544
|
with spinner.hidden():
|
|
492
545
|
result = tool_list[0].handle(response, self)
|
|
@@ -495,11 +548,10 @@ class Agent:
|
|
|
495
548
|
self.tool_call_count += 1
|
|
496
549
|
return result
|
|
497
550
|
return False, ""
|
|
498
|
-
|
|
551
|
+
|
|
499
552
|
def reset_tool_call_count(self):
|
|
500
553
|
self.tool_call_count = 0
|
|
501
554
|
|
|
502
|
-
|
|
503
555
|
def _complete_task(self) -> str:
|
|
504
556
|
"""完成任务并生成总结(如果需要)
|
|
505
557
|
|
|
@@ -511,13 +563,13 @@ class Agent:
|
|
|
511
563
|
2. 对于子Agent: 可能会生成总结(如果启用)
|
|
512
564
|
3. 使用spinner显示生成状态
|
|
513
565
|
"""
|
|
514
|
-
if self.
|
|
566
|
+
if self.use_analysis:
|
|
515
567
|
self._analysis_task()
|
|
516
568
|
if self.need_summary:
|
|
517
569
|
with yaspin(text="正在生成总结...", color="cyan") as spinner:
|
|
518
570
|
self.prompt = self.summary_prompt
|
|
519
571
|
with spinner.hidden():
|
|
520
|
-
ret = self.model.chat_until_success(self.prompt)
|
|
572
|
+
ret = self.model.chat_until_success(self.prompt) # type: ignore
|
|
521
573
|
spinner.text = "总结生成完成"
|
|
522
574
|
spinner.ok("✅")
|
|
523
575
|
return ret
|
|
@@ -676,7 +728,7 @@ arguments:
|
|
|
676
728
|
|
|
677
729
|
self.prompt = analysis_prompt
|
|
678
730
|
with spinner.hidden():
|
|
679
|
-
response = self.model.chat_until_success(self.prompt)
|
|
731
|
+
response = self.model.chat_until_success(self.prompt) # type: ignore
|
|
680
732
|
|
|
681
733
|
with spinner.hidden():
|
|
682
734
|
self._call_tools(response)
|
|
@@ -686,7 +738,6 @@ arguments:
|
|
|
686
738
|
spinner.text = "分析失败"
|
|
687
739
|
spinner.fail("❌")
|
|
688
740
|
|
|
689
|
-
|
|
690
741
|
def run(self, user_input: str) -> Any:
|
|
691
742
|
"""处理用户输入并执行任务
|
|
692
743
|
|
|
@@ -708,9 +759,8 @@ arguments:
|
|
|
708
759
|
self.prompt = f"{user_input}"
|
|
709
760
|
|
|
710
761
|
if self.first and self.use_methodology:
|
|
711
|
-
|
|
712
762
|
# 先尝试上传方法轮
|
|
713
|
-
platform = self.model if hasattr(self.model,
|
|
763
|
+
platform = self.model if hasattr(self.model, "upload_files") else None
|
|
714
764
|
if platform and upload_methodology(platform):
|
|
715
765
|
self.prompt = f"{user_input}\n\n方法论已上传到平台,请参考平台上的方法论内容"
|
|
716
766
|
else:
|
|
@@ -719,7 +769,7 @@ arguments:
|
|
|
719
769
|
msg, _ = handler(msg, self)
|
|
720
770
|
# 上传失败则回退到本地加载
|
|
721
771
|
self.prompt = f"{user_input}\n\n以下是历史类似问题的执行经验,可参考:\n{load_methodology(msg, self.get_tool_registry())}"
|
|
722
|
-
|
|
772
|
+
|
|
723
773
|
self.first = False
|
|
724
774
|
|
|
725
775
|
self.conversation_length = get_context_token_count(self.prompt)
|
|
@@ -729,7 +779,9 @@ arguments:
|
|
|
729
779
|
|
|
730
780
|
current_response = self._call_model(self.prompt, True)
|
|
731
781
|
self.prompt = ""
|
|
732
|
-
self.conversation_length += get_context_token_count(
|
|
782
|
+
self.conversation_length += get_context_token_count(
|
|
783
|
+
current_response
|
|
784
|
+
)
|
|
733
785
|
|
|
734
786
|
need_return, self.prompt = self._call_tools(current_response)
|
|
735
787
|
|
|
@@ -744,11 +796,13 @@ arguments:
|
|
|
744
796
|
|
|
745
797
|
if self.auto_complete and ot("!!!COMPLETE!!!") in current_response:
|
|
746
798
|
return self._complete_task()
|
|
747
|
-
|
|
799
|
+
|
|
748
800
|
self.reset_tool_call_count()
|
|
749
801
|
|
|
750
802
|
# 获取用户输入
|
|
751
|
-
user_input = self.multiline_inputer(
|
|
803
|
+
user_input = self.multiline_inputer(
|
|
804
|
+
f"{self.name}: 请输入,或输入空行来结束当前任务:"
|
|
805
|
+
)
|
|
752
806
|
|
|
753
807
|
if user_input:
|
|
754
808
|
self.prompt = user_input
|
|
@@ -777,8 +831,5 @@ arguments:
|
|
|
777
831
|
用于重置Agent状态而不影响系统消息
|
|
778
832
|
"""
|
|
779
833
|
self.prompt = ""
|
|
780
|
-
self.model.reset()
|
|
834
|
+
self.model.reset() # type: ignore
|
|
781
835
|
self.conversation_length = 0 # 重置对话长度
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
# -*- coding: utf-8 -*-
|
|
2
2
|
import re
|
|
3
3
|
from typing import Any, Tuple
|
|
4
|
-
from jarvis.jarvis_utils.config import get_replace_map
|
|
5
4
|
|
|
5
|
+
from jarvis.jarvis_utils.config import get_replace_map
|
|
6
6
|
|
|
7
7
|
|
|
8
8
|
def builtin_input_handler(user_input: str, agent: Any) -> Tuple[str, bool]:
|
jarvis/jarvis_agent/jarvis.py
CHANGED
|
@@ -2,24 +2,20 @@
|
|
|
2
2
|
import argparse
|
|
3
3
|
import os
|
|
4
4
|
import sys
|
|
5
|
+
from typing import Dict
|
|
5
6
|
|
|
6
|
-
from typing import Dict, List, Tuple # 增加必要的类型导入
|
|
7
|
-
|
|
8
|
-
from jarvis.jarvis_utils.config import get_data_dir
|
|
9
|
-
from prompt_toolkit import prompt
|
|
10
7
|
import yaml
|
|
8
|
+
from prompt_toolkit import prompt
|
|
11
9
|
from yaspin import yaspin
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
)
|
|
10
|
+
|
|
11
|
+
from jarvis.jarvis_agent import (Agent, OutputType, PrettyOutput,
|
|
12
|
+
get_multiline_input,
|
|
13
|
+
origin_agent_system_prompt, user_confirm)
|
|
14
|
+
from jarvis.jarvis_agent.builtin_input_handler import builtin_input_handler
|
|
15
|
+
from jarvis.jarvis_agent.shell_input_handler import shell_input_handler
|
|
19
16
|
from jarvis.jarvis_tools.registry import ToolRegistry
|
|
17
|
+
from jarvis.jarvis_utils.config import get_data_dir
|
|
20
18
|
from jarvis.jarvis_utils.utils import init_env
|
|
21
|
-
from jarvis.jarvis_agent.shell_input_handler import shell_input_handler
|
|
22
|
-
from jarvis.jarvis_agent.builtin_input_handler import builtin_input_handler
|
|
23
19
|
|
|
24
20
|
|
|
25
21
|
def _load_tasks() -> Dict[str, str]:
|
jarvis/jarvis_agent/main.py
CHANGED
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
# -*- coding: utf-8 -*-
|
|
2
2
|
import argparse
|
|
3
|
-
import yaml
|
|
4
3
|
import os
|
|
4
|
+
|
|
5
|
+
import yaml
|
|
6
|
+
|
|
5
7
|
from jarvis.jarvis_agent import Agent
|
|
6
8
|
from jarvis.jarvis_utils.input import get_multiline_input
|
|
7
|
-
from jarvis.jarvis_utils.output import
|
|
9
|
+
from jarvis.jarvis_utils.output import OutputType, PrettyOutput
|
|
8
10
|
from jarvis.jarvis_utils.utils import init_env
|
|
9
11
|
|
|
10
12
|
|
|
@@ -4,34 +4,33 @@
|
|
|
4
4
|
该模块提供CodeAgent类,用于处理代码修改任务。
|
|
5
5
|
"""
|
|
6
6
|
|
|
7
|
+
import argparse
|
|
7
8
|
import os
|
|
8
|
-
import sys
|
|
9
9
|
import subprocess
|
|
10
|
-
import
|
|
11
|
-
from typing import Any, Dict,
|
|
10
|
+
import sys
|
|
11
|
+
from typing import Any, Dict, List, Optional, Tuple
|
|
12
12
|
|
|
13
|
-
# 忽略yaspin的类型检查
|
|
14
|
-
from jarvis.jarvis_utils.config import is_confirm_before_apply_patch
|
|
15
13
|
from yaspin import yaspin # type: ignore
|
|
16
14
|
|
|
15
|
+
from jarvis import __version__
|
|
17
16
|
from jarvis.jarvis_agent import Agent
|
|
18
17
|
from jarvis.jarvis_agent.builtin_input_handler import builtin_input_handler
|
|
19
18
|
from jarvis.jarvis_agent.shell_input_handler import shell_input_handler
|
|
20
|
-
|
|
19
|
+
# 忽略yaspin的类型检查
|
|
20
|
+
from jarvis.jarvis_code_agent.lint import get_lint_tools
|
|
21
21
|
from jarvis.jarvis_git_utils.git_commiter import GitCommitTool
|
|
22
|
+
from jarvis.jarvis_platform.registry import PlatformRegistry
|
|
22
23
|
from jarvis.jarvis_tools.registry import ToolRegistry
|
|
23
|
-
from jarvis.jarvis_utils.
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
has_uncommitted_changes
|
|
30
|
-
)
|
|
24
|
+
from jarvis.jarvis_utils.config import is_confirm_before_apply_patch
|
|
25
|
+
from jarvis.jarvis_utils.git_utils import (find_git_root, get_commits_between,
|
|
26
|
+
get_diff, get_diff_file_list,
|
|
27
|
+
get_latest_commit_hash,
|
|
28
|
+
handle_commit_workflow,
|
|
29
|
+
has_uncommitted_changes)
|
|
31
30
|
from jarvis.jarvis_utils.input import get_multiline_input
|
|
32
31
|
from jarvis.jarvis_utils.output import OutputType, PrettyOutput
|
|
33
32
|
from jarvis.jarvis_utils.utils import init_env, user_confirm
|
|
34
|
-
|
|
33
|
+
|
|
35
34
|
|
|
36
35
|
class CodeAgent:
|
|
37
36
|
"""Jarvis系统的代码修改代理。
|
|
@@ -49,7 +48,6 @@ class CodeAgent:
|
|
|
49
48
|
"search_web",
|
|
50
49
|
"ask_user",
|
|
51
50
|
"ask_codebase",
|
|
52
|
-
"lsp_get_diagnostics",
|
|
53
51
|
"read_code",
|
|
54
52
|
"methodology",
|
|
55
53
|
"chdir",
|
|
@@ -327,7 +325,9 @@ class CodeAgent:
|
|
|
327
325
|
project_info.append(f"代码统计:\n{loc_stats}")
|
|
328
326
|
if commits_info:
|
|
329
327
|
commits_str = "\n".join(
|
|
330
|
-
f"提交 {i+1}: {commit['hash'][:7]} - {commit['message']} ({len(commit['files'])}个文件)"
|
|
328
|
+
f"提交 {i+1}: {commit['hash'][:7]} - {commit['message']} ({len(commit['files'])}个文件)\n" +
|
|
329
|
+
"\n".join(f" - {file}" for file in commit['files'][:5]) +
|
|
330
|
+
("\n ..." if len(commit['files']) > 5 else "")
|
|
331
331
|
for i, commit in enumerate(commits_info)
|
|
332
332
|
)
|
|
333
333
|
project_info.append(f"最近提交:\n{commits_str}")
|
|
@@ -354,6 +354,8 @@ class CodeAgent:
|
|
|
354
354
|
final_ret = ""
|
|
355
355
|
diff = get_diff()
|
|
356
356
|
if diff:
|
|
357
|
+
# 获取修改的文件列表
|
|
358
|
+
modified_files = get_diff_file_list()
|
|
357
359
|
start_hash = get_latest_commit_hash()
|
|
358
360
|
PrettyOutput.print(diff, OutputType.CODE, lang="diff")
|
|
359
361
|
commited = handle_commit_workflow()
|
|
@@ -372,13 +374,22 @@ class CodeAgent:
|
|
|
372
374
|
final_ret += f"# 应用补丁:\n```diff\n{diff}\n```"
|
|
373
375
|
|
|
374
376
|
# 修改后的提示逻辑
|
|
377
|
+
lint_tools_info = "\n".join(
|
|
378
|
+
f" - {file}: 使用 {'、'.join(get_lint_tools(file))}"
|
|
379
|
+
for file in modified_files
|
|
380
|
+
if get_lint_tools(file)
|
|
381
|
+
)
|
|
375
382
|
addon_prompt = """
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
383
|
+
1. 请对以下修改的文件进行静态扫描:
|
|
384
|
+
""" + "\n".join(f" - {file}" for file in modified_files) + (
|
|
385
|
+
f"""
|
|
386
|
+
2. 建议使用以下lint工具进行检查:
|
|
387
|
+
{lint_tools_info}""" if lint_tools_info else ""
|
|
388
|
+
) + """
|
|
389
|
+
3. 如果本次修改引入了警告和错误,请根据警告和错误信息修复代码
|
|
390
|
+
4. 在引入的警告和错误都被修复的前提下,如果用户的需求未完成,请继续修改代码,如果已经完成,请终止,不要实现任何超出用户需求外的内容
|
|
391
|
+
5. 如果有任何信息不明确,调用工具获取信息
|
|
392
|
+
6. 每次响应必须且只能包含一个操作
|
|
382
393
|
"""
|
|
383
394
|
|
|
384
395
|
agent.set_addon_prompt(addon_prompt)
|