jarvis-ai-assistant 0.3.30__py3-none-any.whl → 0.7.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 +289 -87
- jarvis/jarvis_agent/agent_manager.py +17 -8
- jarvis/jarvis_agent/edit_file_handler.py +374 -86
- jarvis/jarvis_agent/event_bus.py +1 -1
- jarvis/jarvis_agent/file_context_handler.py +79 -0
- jarvis/jarvis_agent/jarvis.py +601 -43
- jarvis/jarvis_agent/main.py +32 -2
- jarvis/jarvis_agent/rewrite_file_handler.py +141 -0
- jarvis/jarvis_agent/run_loop.py +38 -5
- jarvis/jarvis_agent/share_manager.py +8 -1
- jarvis/jarvis_agent/stdio_redirect.py +295 -0
- jarvis/jarvis_agent/task_analyzer.py +5 -2
- jarvis/jarvis_agent/task_planner.py +496 -0
- jarvis/jarvis_agent/utils.py +5 -1
- jarvis/jarvis_agent/web_bridge.py +189 -0
- jarvis/jarvis_agent/web_output_sink.py +53 -0
- jarvis/jarvis_agent/web_server.py +751 -0
- jarvis/jarvis_c2rust/__init__.py +26 -0
- jarvis/jarvis_c2rust/cli.py +613 -0
- jarvis/jarvis_c2rust/collector.py +258 -0
- jarvis/jarvis_c2rust/library_replacer.py +1122 -0
- jarvis/jarvis_c2rust/llm_module_agent.py +1300 -0
- jarvis/jarvis_c2rust/optimizer.py +960 -0
- jarvis/jarvis_c2rust/scanner.py +1681 -0
- jarvis/jarvis_c2rust/transpiler.py +2325 -0
- jarvis/jarvis_code_agent/build_validation_config.py +133 -0
- jarvis/jarvis_code_agent/code_agent.py +1171 -94
- jarvis/jarvis_code_agent/code_analyzer/__init__.py +62 -0
- jarvis/jarvis_code_agent/code_analyzer/base_language.py +74 -0
- jarvis/jarvis_code_agent/code_analyzer/build_validator/__init__.py +44 -0
- jarvis/jarvis_code_agent/code_analyzer/build_validator/base.py +102 -0
- jarvis/jarvis_code_agent/code_analyzer/build_validator/cmake.py +59 -0
- jarvis/jarvis_code_agent/code_analyzer/build_validator/detector.py +125 -0
- jarvis/jarvis_code_agent/code_analyzer/build_validator/fallback.py +69 -0
- jarvis/jarvis_code_agent/code_analyzer/build_validator/go.py +38 -0
- jarvis/jarvis_code_agent/code_analyzer/build_validator/java_gradle.py +44 -0
- jarvis/jarvis_code_agent/code_analyzer/build_validator/java_maven.py +38 -0
- jarvis/jarvis_code_agent/code_analyzer/build_validator/makefile.py +50 -0
- jarvis/jarvis_code_agent/code_analyzer/build_validator/nodejs.py +93 -0
- jarvis/jarvis_code_agent/code_analyzer/build_validator/python.py +129 -0
- jarvis/jarvis_code_agent/code_analyzer/build_validator/rust.py +54 -0
- jarvis/jarvis_code_agent/code_analyzer/build_validator/validator.py +154 -0
- jarvis/jarvis_code_agent/code_analyzer/build_validator.py +43 -0
- jarvis/jarvis_code_agent/code_analyzer/context_manager.py +363 -0
- jarvis/jarvis_code_agent/code_analyzer/context_recommender.py +18 -0
- jarvis/jarvis_code_agent/code_analyzer/dependency_analyzer.py +132 -0
- jarvis/jarvis_code_agent/code_analyzer/file_ignore.py +330 -0
- jarvis/jarvis_code_agent/code_analyzer/impact_analyzer.py +781 -0
- jarvis/jarvis_code_agent/code_analyzer/language_registry.py +185 -0
- jarvis/jarvis_code_agent/code_analyzer/language_support.py +89 -0
- jarvis/jarvis_code_agent/code_analyzer/languages/__init__.py +31 -0
- jarvis/jarvis_code_agent/code_analyzer/languages/c_cpp_language.py +231 -0
- jarvis/jarvis_code_agent/code_analyzer/languages/go_language.py +183 -0
- jarvis/jarvis_code_agent/code_analyzer/languages/python_language.py +219 -0
- jarvis/jarvis_code_agent/code_analyzer/languages/rust_language.py +209 -0
- jarvis/jarvis_code_agent/code_analyzer/llm_context_recommender.py +451 -0
- jarvis/jarvis_code_agent/code_analyzer/symbol_extractor.py +77 -0
- jarvis/jarvis_code_agent/code_analyzer/tree_sitter_extractor.py +48 -0
- jarvis/jarvis_code_agent/lint.py +270 -8
- jarvis/jarvis_code_agent/utils.py +142 -0
- jarvis/jarvis_code_analysis/code_review.py +483 -569
- jarvis/jarvis_data/config_schema.json +97 -8
- jarvis/jarvis_git_utils/git_commiter.py +38 -26
- jarvis/jarvis_mcp/sse_mcp_client.py +2 -2
- jarvis/jarvis_mcp/stdio_mcp_client.py +1 -1
- jarvis/jarvis_memory_organizer/memory_organizer.py +1 -1
- jarvis/jarvis_multi_agent/__init__.py +239 -25
- jarvis/jarvis_multi_agent/main.py +37 -1
- jarvis/jarvis_platform/base.py +103 -51
- jarvis/jarvis_platform/openai.py +26 -1
- jarvis/jarvis_platform/yuanbao.py +1 -1
- jarvis/jarvis_platform_manager/service.py +2 -2
- jarvis/jarvis_rag/cli.py +4 -4
- jarvis/jarvis_sec/__init__.py +3605 -0
- jarvis/jarvis_sec/checkers/__init__.py +32 -0
- jarvis/jarvis_sec/checkers/c_checker.py +2680 -0
- jarvis/jarvis_sec/checkers/rust_checker.py +1108 -0
- jarvis/jarvis_sec/cli.py +116 -0
- jarvis/jarvis_sec/report.py +257 -0
- jarvis/jarvis_sec/status.py +264 -0
- jarvis/jarvis_sec/types.py +20 -0
- jarvis/jarvis_sec/workflow.py +219 -0
- jarvis/jarvis_stats/cli.py +1 -1
- jarvis/jarvis_stats/stats.py +1 -1
- jarvis/jarvis_stats/visualizer.py +1 -1
- jarvis/jarvis_tools/cli/main.py +1 -0
- jarvis/jarvis_tools/execute_script.py +46 -9
- jarvis/jarvis_tools/generate_new_tool.py +3 -1
- jarvis/jarvis_tools/read_code.py +275 -12
- jarvis/jarvis_tools/read_symbols.py +141 -0
- jarvis/jarvis_tools/read_webpage.py +5 -3
- jarvis/jarvis_tools/registry.py +73 -35
- jarvis/jarvis_tools/search_web.py +15 -11
- jarvis/jarvis_tools/sub_agent.py +24 -42
- jarvis/jarvis_tools/sub_code_agent.py +14 -13
- jarvis/jarvis_tools/virtual_tty.py +1 -1
- jarvis/jarvis_utils/config.py +187 -35
- jarvis/jarvis_utils/embedding.py +3 -0
- jarvis/jarvis_utils/git_utils.py +181 -6
- jarvis/jarvis_utils/globals.py +3 -3
- jarvis/jarvis_utils/http.py +1 -1
- jarvis/jarvis_utils/input.py +78 -2
- jarvis/jarvis_utils/methodology.py +25 -19
- jarvis/jarvis_utils/utils.py +644 -359
- {jarvis_ai_assistant-0.3.30.dist-info → jarvis_ai_assistant-0.7.0.dist-info}/METADATA +85 -1
- jarvis_ai_assistant-0.7.0.dist-info/RECORD +192 -0
- {jarvis_ai_assistant-0.3.30.dist-info → jarvis_ai_assistant-0.7.0.dist-info}/entry_points.txt +4 -0
- jarvis/jarvis_agent/config.py +0 -92
- jarvis/jarvis_tools/edit_file.py +0 -179
- jarvis/jarvis_tools/rewrite_file.py +0 -191
- jarvis_ai_assistant-0.3.30.dist-info/RECORD +0 -137
- {jarvis_ai_assistant-0.3.30.dist-info → jarvis_ai_assistant-0.7.0.dist-info}/WHEEL +0 -0
- {jarvis_ai_assistant-0.3.30.dist-info → jarvis_ai_assistant-0.7.0.dist-info}/licenses/LICENSE +0 -0
- {jarvis_ai_assistant-0.3.30.dist-info → jarvis_ai_assistant-0.7.0.dist-info}/top_level.txt +0 -0
jarvis/__init__.py
CHANGED
jarvis/jarvis_agent/__init__.py
CHANGED
|
@@ -7,7 +7,8 @@ import re
|
|
|
7
7
|
import sys
|
|
8
8
|
from pathlib import Path
|
|
9
9
|
from enum import Enum
|
|
10
|
-
from typing import Any, Callable, Dict, List, Optional,
|
|
10
|
+
from typing import Any, Callable, Dict, List, Optional, Tuple, Union
|
|
11
|
+
|
|
11
12
|
|
|
12
13
|
# 第三方库导入
|
|
13
14
|
from rich.align import Align
|
|
@@ -24,16 +25,18 @@ from jarvis.jarvis_agent.tool_executor import execute_tool_call
|
|
|
24
25
|
from jarvis.jarvis_agent.memory_manager import MemoryManager
|
|
25
26
|
from jarvis.jarvis_memory_organizer.memory_organizer import MemoryOrganizer
|
|
26
27
|
from jarvis.jarvis_agent.task_analyzer import TaskAnalyzer
|
|
28
|
+
from jarvis.jarvis_agent.task_planner import TaskPlanner
|
|
27
29
|
from jarvis.jarvis_agent.file_methodology_manager import FileMethodologyManager
|
|
28
30
|
from jarvis.jarvis_agent.prompts import (
|
|
29
31
|
DEFAULT_SUMMARY_PROMPT,
|
|
30
32
|
SUMMARY_REQUEST_PROMPT,
|
|
31
|
-
TASK_ANALYSIS_PROMPT,
|
|
33
|
+
TASK_ANALYSIS_PROMPT as TASK_ANALYSIS_PROMPT,
|
|
32
34
|
)
|
|
33
35
|
from jarvis.jarvis_tools.registry import ToolRegistry
|
|
36
|
+
from jarvis.jarvis_agent.edit_file_handler import EditFileHandler
|
|
37
|
+
from jarvis.jarvis_agent.rewrite_file_handler import RewriteFileHandler
|
|
34
38
|
from jarvis.jarvis_agent.prompt_manager import PromptManager
|
|
35
39
|
from jarvis.jarvis_agent.event_bus import EventBus
|
|
36
|
-
from jarvis.jarvis_agent.config import AgentConfig
|
|
37
40
|
from jarvis.jarvis_agent.run_loop import AgentRunLoop
|
|
38
41
|
from jarvis.jarvis_agent.events import (
|
|
39
42
|
BEFORE_SUMMARY,
|
|
@@ -54,6 +57,9 @@ from jarvis.jarvis_agent.events import (
|
|
|
54
57
|
from jarvis.jarvis_agent.user_interaction import UserInteractionHandler
|
|
55
58
|
from jarvis.jarvis_agent.utils import join_prompts
|
|
56
59
|
from jarvis.jarvis_utils.methodology import _load_all_methodologies
|
|
60
|
+
from jarvis.jarvis_agent.shell_input_handler import shell_input_handler
|
|
61
|
+
from jarvis.jarvis_agent.file_context_handler import file_context_handler
|
|
62
|
+
from jarvis.jarvis_agent.builtin_input_handler import builtin_input_handler
|
|
57
63
|
|
|
58
64
|
# jarvis_platform 相关
|
|
59
65
|
from jarvis.jarvis_platform.base import BasePlatform
|
|
@@ -62,7 +68,6 @@ from jarvis.jarvis_platform.registry import PlatformRegistry
|
|
|
62
68
|
# jarvis_utils 相关
|
|
63
69
|
from jarvis.jarvis_utils.config import (
|
|
64
70
|
get_data_dir,
|
|
65
|
-
get_max_token_count,
|
|
66
71
|
get_normal_model_name,
|
|
67
72
|
get_normal_platform_name,
|
|
68
73
|
is_execute_tool_confirm,
|
|
@@ -71,6 +76,9 @@ from jarvis.jarvis_utils.config import (
|
|
|
71
76
|
is_use_methodology,
|
|
72
77
|
get_tool_filter_threshold,
|
|
73
78
|
get_after_tool_call_cb_dirs,
|
|
79
|
+
get_plan_max_depth,
|
|
80
|
+
is_plan_enabled,
|
|
81
|
+
get_addon_prompt_threshold,
|
|
74
82
|
)
|
|
75
83
|
from jarvis.jarvis_utils.embedding import get_context_token_count
|
|
76
84
|
from jarvis.jarvis_utils.globals import (
|
|
@@ -243,8 +251,25 @@ class Agent:
|
|
|
243
251
|
def clear_history(self):
|
|
244
252
|
"""
|
|
245
253
|
Clears the current conversation history by delegating to the session manager.
|
|
254
|
+
Emits BEFORE_HISTORY_CLEAR/AFTER_HISTORY_CLEAR and reapplies system prompt to preserve constraints.
|
|
246
255
|
"""
|
|
256
|
+
# 广播清理历史前事件(不影响主流程)
|
|
257
|
+
try:
|
|
258
|
+
self.event_bus.emit(BEFORE_HISTORY_CLEAR, agent=self)
|
|
259
|
+
except Exception:
|
|
260
|
+
pass
|
|
261
|
+
|
|
262
|
+
# 清理会话历史并重置模型状态
|
|
247
263
|
self.session.clear_history()
|
|
264
|
+
# 重置 addon_prompt 跳过轮数计数器
|
|
265
|
+
self._addon_prompt_skip_rounds = 0
|
|
266
|
+
|
|
267
|
+
# 重置后重新设置系统提示词,确保系统约束仍然生效
|
|
268
|
+
try:
|
|
269
|
+
self._setup_system_prompt()
|
|
270
|
+
except Exception:
|
|
271
|
+
pass
|
|
272
|
+
|
|
248
273
|
# 广播清理历史后的事件
|
|
249
274
|
try:
|
|
250
275
|
self.event_bus.emit(AFTER_HISTORY_CLEAR, agent=self)
|
|
@@ -264,6 +289,21 @@ class Agent:
|
|
|
264
289
|
"""获取工具使用提示"""
|
|
265
290
|
return build_action_prompt(self.output_handler) # type: ignore
|
|
266
291
|
|
|
292
|
+
def __new__(cls, *args, **kwargs):
|
|
293
|
+
if kwargs.get("agent_type") == "code":
|
|
294
|
+
try:
|
|
295
|
+
from jarvis.jarvis_code_agent.code_agent import CodeAgent
|
|
296
|
+
except ImportError as e:
|
|
297
|
+
raise RuntimeError(
|
|
298
|
+
"CodeAgent could not be imported. Please ensure jarvis_code_agent is installed correctly."
|
|
299
|
+
) from e
|
|
300
|
+
|
|
301
|
+
# 移除 agent_type 避免无限循环,并传递所有其他参数
|
|
302
|
+
kwargs.pop("agent_type", None)
|
|
303
|
+
return CodeAgent(**kwargs)
|
|
304
|
+
else:
|
|
305
|
+
return super().__new__(cls)
|
|
306
|
+
|
|
267
307
|
def __init__(
|
|
268
308
|
self,
|
|
269
309
|
system_prompt: str,
|
|
@@ -274,15 +314,23 @@ class Agent:
|
|
|
274
314
|
auto_complete: bool = False,
|
|
275
315
|
output_handler: Optional[List[OutputHandlerProtocol]] = None,
|
|
276
316
|
use_tools: Optional[List[str]] = None,
|
|
277
|
-
input_handler: Optional[List[Callable[[str, Any], Tuple[str, bool]]]] = None,
|
|
278
317
|
execute_tool_confirm: Optional[bool] = None,
|
|
279
318
|
need_summary: bool = True,
|
|
319
|
+
auto_summary_rounds: Optional[int] = None,
|
|
280
320
|
multiline_inputer: Optional[Callable[[str], str]] = None,
|
|
281
321
|
use_methodology: Optional[bool] = None,
|
|
282
322
|
use_analysis: Optional[bool] = None,
|
|
283
323
|
force_save_memory: Optional[bool] = None,
|
|
324
|
+
disable_file_edit: bool = False,
|
|
284
325
|
files: Optional[List[str]] = None,
|
|
285
326
|
confirm_callback: Optional[Callable[[str, bool], bool]] = None,
|
|
327
|
+
non_interactive: Optional[bool] = None,
|
|
328
|
+
in_multi_agent: Optional[bool] = None,
|
|
329
|
+
plan: Optional[bool] = None,
|
|
330
|
+
plan_max_depth: Optional[int] = None,
|
|
331
|
+
plan_depth: int = 0,
|
|
332
|
+
agent_type: str = "normal",
|
|
333
|
+
**kwargs,
|
|
286
334
|
):
|
|
287
335
|
"""初始化Jarvis Agent实例
|
|
288
336
|
|
|
@@ -293,8 +341,6 @@ class Agent:
|
|
|
293
341
|
|
|
294
342
|
summary_prompt: 任务总结提示模板
|
|
295
343
|
auto_complete: 是否自动完成任务
|
|
296
|
-
output_handler: 输出处理器列表
|
|
297
|
-
input_handler: 输入处理器列表
|
|
298
344
|
execute_tool_confirm: 执行工具前是否需要确认
|
|
299
345
|
need_summary: 是否需要生成总结
|
|
300
346
|
multiline_inputer: 多行输入处理器
|
|
@@ -302,21 +348,57 @@ class Agent:
|
|
|
302
348
|
use_analysis: 是否使用任务分析
|
|
303
349
|
force_save_memory: 是否强制保存记忆
|
|
304
350
|
confirm_callback: 用户确认回调函数,签名为 (tip: str, default: bool) -> bool;默认使用CLI的user_confirm
|
|
351
|
+
non_interactive: 是否以非交互模式运行(优先级最高,覆盖环境变量与配置)
|
|
352
|
+
plan: 是否启用任务规划与子任务拆分(默认从配置加载;启用后在进入主循环前评估是否需要将任务拆分为 <SUB_TASK> 列表,逐一由子Agent执行并汇总结果)
|
|
353
|
+
plan_max_depth: 任务规划的最大层数(默认3,可通过配置 JARVIS_PLAN_MAX_DEPTH 或入参覆盖)
|
|
354
|
+
plan_depth: 当前规划层数(内部用于递归控制,子Agent会在父基础上+1)
|
|
305
355
|
"""
|
|
306
|
-
#
|
|
307
|
-
|
|
356
|
+
# 基础属性初始化(仅根据入参设置原始值;实际生效的默认回退在 _init_config 中统一解析)
|
|
357
|
+
# 标识与描述
|
|
308
358
|
self.name = make_agent_name(name)
|
|
309
359
|
self.description = description
|
|
310
360
|
self.system_prompt = system_prompt
|
|
311
|
-
|
|
312
|
-
self.auto_complete = auto_complete
|
|
361
|
+
# 行为控制开关(原始入参值)
|
|
362
|
+
self.auto_complete = bool(auto_complete)
|
|
363
|
+
self.need_summary = bool(need_summary)
|
|
364
|
+
# 自动摘要轮次:None 表示使用配置文件中的默认值,由 AgentRunLoop 决定最终取值
|
|
365
|
+
self.auto_summary_rounds = auto_summary_rounds
|
|
366
|
+
self.use_methodology = use_methodology
|
|
367
|
+
self.use_analysis = use_analysis
|
|
368
|
+
self.execute_tool_confirm = execute_tool_confirm
|
|
369
|
+
self.summary_prompt = summary_prompt
|
|
370
|
+
self.force_save_memory = force_save_memory
|
|
371
|
+
self.disable_file_edit = bool(disable_file_edit)
|
|
372
|
+
# 资源与环境
|
|
373
|
+
self.model_group = model_group
|
|
374
|
+
self.files = files or []
|
|
375
|
+
self.use_tools = use_tools
|
|
376
|
+
self.non_interactive = non_interactive
|
|
377
|
+
# 多智能体运行标志:用于控制非交互模式下的自动完成行为
|
|
378
|
+
self.in_multi_agent = bool(in_multi_agent)
|
|
379
|
+
# 任务规划:优先使用入参,否则回退到配置
|
|
380
|
+
self.plan = bool(plan) if plan is not None else is_plan_enabled()
|
|
381
|
+
# 规划深度与上限
|
|
382
|
+
try:
|
|
383
|
+
self.plan_max_depth = (
|
|
384
|
+
int(plan_max_depth) if plan_max_depth is not None else int(get_plan_max_depth())
|
|
385
|
+
)
|
|
386
|
+
except Exception:
|
|
387
|
+
self.plan_max_depth = 2
|
|
388
|
+
try:
|
|
389
|
+
self.plan_depth = int(plan_depth)
|
|
390
|
+
except Exception:
|
|
391
|
+
self.plan_depth = 0
|
|
392
|
+
# 运行时状态
|
|
313
393
|
self.first = True
|
|
314
394
|
self.run_input_handlers_next_turn = False
|
|
315
395
|
self.user_data: Dict[str, Any] = {}
|
|
396
|
+
# 记录连续未添加 addon_prompt 的轮数
|
|
397
|
+
self._addon_prompt_skip_rounds: int = 0
|
|
316
398
|
|
|
317
399
|
|
|
318
400
|
# 用户确认回调:默认使用 CLI 的 user_confirm,可由外部注入以支持 TUI/GUI
|
|
319
|
-
self.
|
|
401
|
+
self.confirm_callback: Callable[[str, bool], bool] = (
|
|
320
402
|
confirm_callback or user_confirm # type: ignore[assignment]
|
|
321
403
|
)
|
|
322
404
|
|
|
@@ -326,25 +408,62 @@ class Agent:
|
|
|
326
408
|
|
|
327
409
|
# 初始化处理器
|
|
328
410
|
self._init_handlers(
|
|
329
|
-
output_handler or [],
|
|
330
|
-
input_handler,
|
|
331
411
|
multiline_inputer,
|
|
412
|
+
output_handler,
|
|
332
413
|
use_tools or [],
|
|
333
414
|
)
|
|
334
415
|
# 初始化用户交互封装,保持向后兼容
|
|
335
|
-
self.user_interaction = UserInteractionHandler(self.multiline_inputer, self.
|
|
416
|
+
self.user_interaction = UserInteractionHandler(self.multiline_inputer, self.confirm_callback)
|
|
336
417
|
# 将确认函数指向封装后的 confirm,保持既有调用不变
|
|
337
|
-
self.
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
418
|
+
self.confirm_callback = self.user_interaction.confirm # type: ignore[assignment]
|
|
419
|
+
# 非交互模式参数支持:允许通过构造参数显式控制,便于其他Agent调用时设置
|
|
420
|
+
try:
|
|
421
|
+
# 优先使用构造参数,其次回退到环境变量
|
|
422
|
+
self.non_interactive = (
|
|
423
|
+
bool(non_interactive)
|
|
424
|
+
if non_interactive is not None
|
|
425
|
+
else str(os.environ.get("JARVIS_NON_INTERACTIVE", "")).lower() in ("1", "true", "yes")
|
|
426
|
+
)
|
|
427
|
+
# 如果构造参数显式提供,则同步到环境变量与全局配置,供下游组件读取
|
|
428
|
+
if non_interactive is not None:
|
|
429
|
+
os.environ["JARVIS_NON_INTERACTIVE"] = "true" if self.non_interactive else "false"
|
|
430
|
+
|
|
431
|
+
except Exception:
|
|
432
|
+
# 防御式回退
|
|
433
|
+
self.non_interactive = False
|
|
434
|
+
|
|
435
|
+
# 初始化配置(直接解析,不再依赖 _init_config)
|
|
436
|
+
try:
|
|
437
|
+
resolved_use_methodology = bool(use_methodology if use_methodology is not None else is_use_methodology())
|
|
438
|
+
except Exception:
|
|
439
|
+
resolved_use_methodology = bool(use_methodology) if use_methodology is not None else True
|
|
440
|
+
|
|
441
|
+
try:
|
|
442
|
+
resolved_use_analysis = bool(use_analysis if use_analysis is not None else is_use_analysis())
|
|
443
|
+
except Exception:
|
|
444
|
+
resolved_use_analysis = bool(use_analysis) if use_analysis is not None else True
|
|
445
|
+
|
|
446
|
+
try:
|
|
447
|
+
resolved_execute_tool_confirm = bool(execute_tool_confirm if execute_tool_confirm is not None else is_execute_tool_confirm())
|
|
448
|
+
except Exception:
|
|
449
|
+
resolved_execute_tool_confirm = bool(execute_tool_confirm) if execute_tool_confirm is not None else False
|
|
450
|
+
|
|
451
|
+
try:
|
|
452
|
+
resolved_force_save_memory = bool(force_save_memory if force_save_memory is not None else is_force_save_memory())
|
|
453
|
+
except Exception:
|
|
454
|
+
resolved_force_save_memory = bool(force_save_memory) if force_save_memory is not None else False
|
|
455
|
+
|
|
456
|
+
self.use_methodology = resolved_use_methodology
|
|
457
|
+
self.use_analysis = resolved_use_analysis
|
|
458
|
+
self.execute_tool_confirm = resolved_execute_tool_confirm
|
|
459
|
+
self.summary_prompt = (summary_prompt or DEFAULT_SUMMARY_PROMPT)
|
|
460
|
+
self.force_save_memory = resolved_force_save_memory
|
|
461
|
+
# 多智能体模式下,默认不自动完成(即使是非交互),仅在明确传入 auto_complete=True 时开启
|
|
462
|
+
if self.in_multi_agent:
|
|
463
|
+
self.auto_complete = bool(self.auto_complete)
|
|
464
|
+
else:
|
|
465
|
+
# 非交互模式下默认自动完成;否则保持传入的 auto_complete 值
|
|
466
|
+
self.auto_complete = bool(self.auto_complete or (self.non_interactive or False))
|
|
348
467
|
|
|
349
468
|
# 初始化事件总线需先于管理器,以便管理器在构造中安全订阅事件
|
|
350
469
|
self.event_bus = EventBus()
|
|
@@ -353,6 +472,8 @@ class Agent:
|
|
|
353
472
|
self.task_analyzer = TaskAnalyzer(self)
|
|
354
473
|
self.file_methodology_manager = FileMethodologyManager(self)
|
|
355
474
|
self.prompt_manager = PromptManager(self)
|
|
475
|
+
# 任务规划器:封装规划与子任务调度逻辑
|
|
476
|
+
self.task_planner = TaskPlanner(self, plan_depth=self.plan_depth, plan_max_depth=self.plan_max_depth)
|
|
356
477
|
|
|
357
478
|
# 设置系统提示词
|
|
358
479
|
self._setup_system_prompt()
|
|
@@ -394,55 +515,26 @@ class Agent:
|
|
|
394
515
|
|
|
395
516
|
def _init_handlers(
|
|
396
517
|
self,
|
|
397
|
-
output_handler: List[OutputHandlerProtocol],
|
|
398
|
-
input_handler: Optional[List[Callable[[str, Any], Tuple[str, bool]]]],
|
|
399
518
|
multiline_inputer: Optional[Callable[[str], str]],
|
|
519
|
+
output_handler: Optional[List[OutputHandlerProtocol]],
|
|
400
520
|
use_tools: List[str],
|
|
401
521
|
):
|
|
402
522
|
"""初始化各种处理器"""
|
|
403
|
-
|
|
523
|
+
default_handlers: List[Any] = [ToolRegistry()]
|
|
524
|
+
if not getattr(self, "disable_file_edit", False):
|
|
525
|
+
default_handlers.extend([EditFileHandler(), RewriteFileHandler()])
|
|
526
|
+
handlers = output_handler or default_handlers
|
|
527
|
+
if getattr(self, "disable_file_edit", False):
|
|
528
|
+
handlers = [h for h in handlers if not isinstance(h, (EditFileHandler, RewriteFileHandler))]
|
|
529
|
+
self.output_handler = handlers
|
|
404
530
|
self.set_use_tools(use_tools)
|
|
405
|
-
self.input_handler =
|
|
531
|
+
self.input_handler = [
|
|
532
|
+
builtin_input_handler,
|
|
533
|
+
shell_input_handler,
|
|
534
|
+
file_context_handler,
|
|
535
|
+
]
|
|
406
536
|
self.multiline_inputer = multiline_inputer or get_multiline_input
|
|
407
537
|
|
|
408
|
-
def _init_config(
|
|
409
|
-
self,
|
|
410
|
-
use_methodology: Optional[bool],
|
|
411
|
-
use_analysis: Optional[bool],
|
|
412
|
-
execute_tool_confirm: Optional[bool],
|
|
413
|
-
summary_prompt: Optional[str],
|
|
414
|
-
model_group: Optional[str],
|
|
415
|
-
force_save_memory: Optional[bool],
|
|
416
|
-
):
|
|
417
|
-
"""初始化配置选项"""
|
|
418
|
-
# 使用集中配置解析,保持与原逻辑一致
|
|
419
|
-
cfg = AgentConfig(
|
|
420
|
-
system_prompt=self.system_prompt,
|
|
421
|
-
name=self.name,
|
|
422
|
-
description=self.description,
|
|
423
|
-
model_group=model_group,
|
|
424
|
-
auto_complete=self.auto_complete,
|
|
425
|
-
need_summary=self.need_summary,
|
|
426
|
-
summary_prompt=summary_prompt,
|
|
427
|
-
execute_tool_confirm=execute_tool_confirm,
|
|
428
|
-
use_methodology=use_methodology,
|
|
429
|
-
use_analysis=use_analysis,
|
|
430
|
-
force_save_memory=force_save_memory,
|
|
431
|
-
files=self.files,
|
|
432
|
-
max_token_count=None,
|
|
433
|
-
).resolve_defaults()
|
|
434
|
-
|
|
435
|
-
# 将解析结果回填到 Agent 实例属性,保持向后兼容
|
|
436
|
-
self.use_methodology = bool(cfg.use_methodology)
|
|
437
|
-
self.use_analysis = bool(cfg.use_analysis)
|
|
438
|
-
self.execute_tool_confirm = bool(cfg.execute_tool_confirm)
|
|
439
|
-
self.summary_prompt = cfg.summary_prompt or DEFAULT_SUMMARY_PROMPT
|
|
440
|
-
self.max_token_count = int(cfg.max_token_count or get_max_token_count(model_group))
|
|
441
|
-
self.force_save_memory = bool(cfg.force_save_memory)
|
|
442
|
-
|
|
443
|
-
# 聚合配置到 AgentConfig,作为后续单一事实来源(保持兼容,不改变既有属性使用)
|
|
444
|
-
self.config = cfg
|
|
445
|
-
|
|
446
538
|
def _setup_system_prompt(self):
|
|
447
539
|
"""设置系统提示词"""
|
|
448
540
|
try:
|
|
@@ -666,7 +758,13 @@ class Agent:
|
|
|
666
758
|
return message
|
|
667
759
|
|
|
668
760
|
def _add_addon_prompt(self, message: str, need_complete: bool) -> str:
|
|
669
|
-
"""添加附加提示到消息
|
|
761
|
+
"""添加附加提示到消息
|
|
762
|
+
|
|
763
|
+
规则:
|
|
764
|
+
1. 如果 session.addon_prompt 存在,优先使用它
|
|
765
|
+
2. 如果消息长度超过阈值,添加默认 addon_prompt
|
|
766
|
+
3. 如果连续10轮都没有添加过 addon_prompt,强制添加一次
|
|
767
|
+
"""
|
|
670
768
|
# 广播添加附加提示前事件(不影响主流程)
|
|
671
769
|
try:
|
|
672
770
|
self.event_bus.emit(
|
|
@@ -680,13 +778,32 @@ class Agent:
|
|
|
680
778
|
pass
|
|
681
779
|
|
|
682
780
|
addon_text = ""
|
|
781
|
+
should_add = False
|
|
782
|
+
|
|
683
783
|
if self.session.addon_prompt:
|
|
784
|
+
# 优先使用 session 中设置的 addon_prompt
|
|
684
785
|
addon_text = self.session.addon_prompt
|
|
685
786
|
message = join_prompts([message, addon_text])
|
|
686
787
|
self.session.addon_prompt = ""
|
|
788
|
+
should_add = True
|
|
687
789
|
else:
|
|
688
|
-
|
|
689
|
-
|
|
790
|
+
threshold = get_addon_prompt_threshold()
|
|
791
|
+
# 条件1:消息长度超过阈值
|
|
792
|
+
if len(message) > threshold:
|
|
793
|
+
addon_text = self.make_default_addon_prompt(need_complete)
|
|
794
|
+
message = join_prompts([message, addon_text])
|
|
795
|
+
should_add = True
|
|
796
|
+
# 条件2:连续10轮都没有添加过 addon_prompt,强制添加一次
|
|
797
|
+
elif self._addon_prompt_skip_rounds >= 10:
|
|
798
|
+
addon_text = self.make_default_addon_prompt(need_complete)
|
|
799
|
+
message = join_prompts([message, addon_text])
|
|
800
|
+
should_add = True
|
|
801
|
+
|
|
802
|
+
# 更新计数器:如果添加了 addon_prompt,重置计数器;否则递增
|
|
803
|
+
if should_add:
|
|
804
|
+
self._addon_prompt_skip_rounds = 0
|
|
805
|
+
else:
|
|
806
|
+
self._addon_prompt_skip_rounds += 1
|
|
690
807
|
|
|
691
808
|
# 广播添加附加提示后事件(不影响主流程)
|
|
692
809
|
try:
|
|
@@ -702,14 +819,9 @@ class Agent:
|
|
|
702
819
|
return message
|
|
703
820
|
|
|
704
821
|
def _manage_conversation_length(self, message: str) -> str:
|
|
705
|
-
"""
|
|
822
|
+
"""管理对话长度计数;摘要触发由轮次在 AgentRunLoop 中统一处理。"""
|
|
706
823
|
self.session.conversation_length += get_context_token_count(message)
|
|
707
824
|
|
|
708
|
-
if self.session.conversation_length > self.max_token_count:
|
|
709
|
-
summary = self._summarize_and_clear_history()
|
|
710
|
-
if summary:
|
|
711
|
-
message = join_prompts([summary, message])
|
|
712
|
-
self.session.conversation_length = get_context_token_count(message)
|
|
713
825
|
|
|
714
826
|
return message
|
|
715
827
|
|
|
@@ -729,7 +841,14 @@ class Agent:
|
|
|
729
841
|
pass
|
|
730
842
|
|
|
731
843
|
response = self.model.chat_until_success(message) # type: ignore
|
|
732
|
-
|
|
844
|
+
# 防御: 模型可能返回空响应(None或空字符串),统一为空字符串并告警
|
|
845
|
+
if not response:
|
|
846
|
+
try:
|
|
847
|
+
PrettyOutput.print("模型返回空响应,已使用空字符串回退。", OutputType.WARNING)
|
|
848
|
+
except Exception:
|
|
849
|
+
pass
|
|
850
|
+
response = ""
|
|
851
|
+
|
|
733
852
|
# 事件:模型调用后
|
|
734
853
|
try:
|
|
735
854
|
self.event_bus.emit(
|
|
@@ -758,10 +877,21 @@ class Agent:
|
|
|
758
877
|
try:
|
|
759
878
|
if not self.model:
|
|
760
879
|
raise RuntimeError("Model not initialized")
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
)
|
|
880
|
+
# 优先使用外部传入的 summary_prompt;如为空则回退到默认的会话摘要请求
|
|
881
|
+
safe_summary_prompt = self.summary_prompt or ""
|
|
882
|
+
if isinstance(safe_summary_prompt, str) and safe_summary_prompt.strip() != "":
|
|
883
|
+
prompt_to_use = safe_summary_prompt
|
|
884
|
+
else:
|
|
885
|
+
prompt_to_use = self.session.prompt + "\n" + SUMMARY_REQUEST_PROMPT
|
|
764
886
|
|
|
887
|
+
summary = self.model.chat_until_success(prompt_to_use) # type: ignore
|
|
888
|
+
# 防御: 可能返回空响应(None或空字符串),统一为空字符串并告警
|
|
889
|
+
if not summary:
|
|
890
|
+
try:
|
|
891
|
+
PrettyOutput.print("总结模型返回空响应,已使用空字符串回退。", OutputType.WARNING)
|
|
892
|
+
except Exception:
|
|
893
|
+
pass
|
|
894
|
+
summary = ""
|
|
765
895
|
return summary
|
|
766
896
|
except Exception:
|
|
767
897
|
PrettyOutput.print("总结对话历史失败", OutputType.ERROR)
|
|
@@ -820,6 +950,8 @@ class Agent:
|
|
|
820
950
|
self._setup_system_prompt()
|
|
821
951
|
# 重置会话
|
|
822
952
|
self.session.clear_history()
|
|
953
|
+
# 重置 addon_prompt 跳过轮数计数器
|
|
954
|
+
self._addon_prompt_skip_rounds = 0
|
|
823
955
|
# 广播清理历史后的事件
|
|
824
956
|
try:
|
|
825
957
|
self.event_bus.emit(AFTER_HISTORY_CLEAR, agent=self)
|
|
@@ -836,6 +968,8 @@ class Agent:
|
|
|
836
968
|
except Exception:
|
|
837
969
|
pass
|
|
838
970
|
result = self.file_methodology_manager.handle_history_with_file_upload()
|
|
971
|
+
# 重置 addon_prompt 跳过轮数计数器
|
|
972
|
+
self._addon_prompt_skip_rounds = 0
|
|
839
973
|
# 广播清理历史后的事件
|
|
840
974
|
try:
|
|
841
975
|
self.event_bus.emit(AFTER_HISTORY_CLEAR, agent=self)
|
|
@@ -882,13 +1016,17 @@ class Agent:
|
|
|
882
1016
|
|
|
883
1017
|
if self.need_summary:
|
|
884
1018
|
|
|
885
|
-
|
|
1019
|
+
# 确保总结提示词非空:若为None或仅空白,则回退到默认提示词
|
|
1020
|
+
safe_summary_prompt = self.summary_prompt or ""
|
|
1021
|
+
if isinstance(safe_summary_prompt, str) and safe_summary_prompt.strip() == "":
|
|
1022
|
+
safe_summary_prompt = DEFAULT_SUMMARY_PROMPT
|
|
1023
|
+
# 注意:不要写回 session.prompt,避免 BEFORE_SUMMARY 事件回调修改/清空后导致使用空prompt
|
|
886
1024
|
# 广播将要生成总结事件
|
|
887
1025
|
try:
|
|
888
1026
|
self.event_bus.emit(
|
|
889
1027
|
BEFORE_SUMMARY,
|
|
890
1028
|
agent=self,
|
|
891
|
-
prompt=
|
|
1029
|
+
prompt=safe_summary_prompt,
|
|
892
1030
|
auto_completed=auto_completed,
|
|
893
1031
|
need_summary=self.need_summary,
|
|
894
1032
|
)
|
|
@@ -897,7 +1035,15 @@ class Agent:
|
|
|
897
1035
|
|
|
898
1036
|
if not self.model:
|
|
899
1037
|
raise RuntimeError("Model not initialized")
|
|
900
|
-
|
|
1038
|
+
# 直接使用本地变量,避免受事件回调影响
|
|
1039
|
+
ret = self.model.chat_until_success(safe_summary_prompt) # type: ignore
|
|
1040
|
+
# 防御: 总结阶段模型可能返回空响应(None或空字符串),统一为空字符串并告警
|
|
1041
|
+
if not ret:
|
|
1042
|
+
try:
|
|
1043
|
+
PrettyOutput.print("总结阶段模型返回空响应,已使用空字符串回退。", OutputType.WARNING)
|
|
1044
|
+
except Exception:
|
|
1045
|
+
pass
|
|
1046
|
+
ret = ""
|
|
901
1047
|
result = ret
|
|
902
1048
|
|
|
903
1049
|
# 广播完成总结事件
|
|
@@ -957,7 +1103,6 @@ class Agent:
|
|
|
957
1103
|
{complete_prompt}
|
|
958
1104
|
如果没有完成,请进行下一步操作:
|
|
959
1105
|
- 仅包含一个操作
|
|
960
|
-
- 不要询问用户是否继续,直接继续执行直至完成
|
|
961
1106
|
- 如果信息不明确,请请求用户补充
|
|
962
1107
|
- 如果执行过程中连续失败5次,请使用ask_user询问用户操作
|
|
963
1108
|
- 操作列表:{action_handlers}{memory_prompts}
|
|
@@ -997,6 +1142,13 @@ class Agent:
|
|
|
997
1142
|
)
|
|
998
1143
|
except Exception:
|
|
999
1144
|
pass
|
|
1145
|
+
# 如启用规划模式,先判断是否需要拆分并调度子任务
|
|
1146
|
+
if self.plan:
|
|
1147
|
+
try:
|
|
1148
|
+
self._maybe_plan_and_dispatch(self.session.prompt)
|
|
1149
|
+
except Exception:
|
|
1150
|
+
# 防御式处理,规划失败不影响主流程
|
|
1151
|
+
pass
|
|
1000
1152
|
return self._main_loop()
|
|
1001
1153
|
except Exception as e:
|
|
1002
1154
|
PrettyOutput.print(f"任务失败: {str(e)}", OutputType.ERROR)
|
|
@@ -1041,7 +1193,7 @@ class Agent:
|
|
|
1041
1193
|
return self._complete_task(auto_completed=False)
|
|
1042
1194
|
|
|
1043
1195
|
if any(handler.can_handle(current_response) for handler in self.output_handler):
|
|
1044
|
-
if self.
|
|
1196
|
+
if self.confirm_callback("检测到有工具调用,是否继续处理工具调用?", True):
|
|
1045
1197
|
self.session.prompt = join_prompts([
|
|
1046
1198
|
f"被用户中断,用户补充信息为:{user_input}",
|
|
1047
1199
|
"用户同意继续工具调用。"
|
|
@@ -1104,6 +1256,56 @@ class Agent:
|
|
|
1104
1256
|
temp_model.set_system_prompt(system_prompt)
|
|
1105
1257
|
return temp_model
|
|
1106
1258
|
|
|
1259
|
+
def _build_child_agent_params(self, name: str, description: str) -> Dict[str, Any]:
|
|
1260
|
+
"""构建子Agent参数,尽量继承父Agent配置,并确保子Agent非交互自动完成。"""
|
|
1261
|
+
use_tools_param: Optional[List[str]] = None
|
|
1262
|
+
try:
|
|
1263
|
+
tr = self.get_tool_registry()
|
|
1264
|
+
if isinstance(tr, ToolRegistry):
|
|
1265
|
+
selected_tools = tr.get_all_tools()
|
|
1266
|
+
use_tools_param = [t["name"] for t in selected_tools]
|
|
1267
|
+
except Exception:
|
|
1268
|
+
use_tools_param = None
|
|
1269
|
+
|
|
1270
|
+
return {
|
|
1271
|
+
"system_prompt": origin_agent_system_prompt,
|
|
1272
|
+
"name": name,
|
|
1273
|
+
"description": description,
|
|
1274
|
+
"model_group": self.model_group,
|
|
1275
|
+
"summary_prompt": self.summary_prompt,
|
|
1276
|
+
"auto_complete": True,
|
|
1277
|
+
"use_tools": use_tools_param,
|
|
1278
|
+
"execute_tool_confirm": self.execute_tool_confirm,
|
|
1279
|
+
"need_summary": self.need_summary,
|
|
1280
|
+
"auto_summary_rounds": self.auto_summary_rounds,
|
|
1281
|
+
"multiline_inputer": self.multiline_inputer,
|
|
1282
|
+
"use_methodology": self.use_methodology,
|
|
1283
|
+
"use_analysis": self.use_analysis,
|
|
1284
|
+
"force_save_memory": self.force_save_memory,
|
|
1285
|
+
"disable_file_edit": self.disable_file_edit,
|
|
1286
|
+
"files": self.files,
|
|
1287
|
+
"confirm_callback": self.confirm_callback,
|
|
1288
|
+
"non_interactive": True,
|
|
1289
|
+
"in_multi_agent": True,
|
|
1290
|
+
"plan": self.plan, # 继承父Agent的规划开关
|
|
1291
|
+
"plan_depth": self.plan_depth + 1, # 子Agent层数+1
|
|
1292
|
+
"plan_max_depth": self.plan_max_depth, # 继承上限
|
|
1293
|
+
}
|
|
1294
|
+
|
|
1295
|
+
def _maybe_plan_and_dispatch(self, task_text: str) -> None:
|
|
1296
|
+
"""委托给 TaskPlanner 执行任务规划与子任务调度,保持向后兼容。"""
|
|
1297
|
+
try:
|
|
1298
|
+
if hasattr(self, "task_planner") and self.task_planner:
|
|
1299
|
+
# 优先使用初始化时注入的规划器
|
|
1300
|
+
self.task_planner.maybe_plan_and_dispatch(task_text) # type: ignore[attr-defined]
|
|
1301
|
+
else:
|
|
1302
|
+
# 防御式回退:临时创建规划器以避免因未初始化导致的崩溃
|
|
1303
|
+
from jarvis.jarvis_agent.task_planner import TaskPlanner
|
|
1304
|
+
TaskPlanner(self, plan_depth=self.plan_depth, plan_max_depth=self.plan_max_depth).maybe_plan_and_dispatch(task_text)
|
|
1305
|
+
except Exception:
|
|
1306
|
+
# 规划失败不影响主流程
|
|
1307
|
+
pass
|
|
1308
|
+
|
|
1107
1309
|
def _filter_tools_if_needed(self, task: str):
|
|
1108
1310
|
"""如果工具数量超过阈值,使用大模型筛选相关工具"""
|
|
1109
1311
|
tool_registry = self.get_tool_registry()
|
|
@@ -1268,7 +1470,7 @@ class Agent:
|
|
|
1268
1470
|
f"并且存在3个以上标签重叠的记忆。\n"
|
|
1269
1471
|
f"是否立即整理记忆库以优化性能和相关性?"
|
|
1270
1472
|
)
|
|
1271
|
-
if self.
|
|
1473
|
+
if self.confirm_callback(prompt, True):
|
|
1272
1474
|
PrettyOutput.print(
|
|
1273
1475
|
f"正在开始整理 '{scope_name}' ({memory_type}) 记忆库...",
|
|
1274
1476
|
OutputType.INFO,
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# -*- coding: utf-8 -*-
|
|
2
2
|
"""Agent管理器模块,负责Agent的初始化和任务执行"""
|
|
3
|
-
from typing import Optional
|
|
3
|
+
from typing import Optional, Callable
|
|
4
4
|
|
|
5
5
|
import typer
|
|
6
6
|
|
|
@@ -11,10 +11,8 @@ from jarvis.jarvis_agent import (
|
|
|
11
11
|
get_multiline_input,
|
|
12
12
|
origin_agent_system_prompt,
|
|
13
13
|
)
|
|
14
|
-
from jarvis.jarvis_agent.builtin_input_handler import builtin_input_handler
|
|
15
|
-
from jarvis.jarvis_agent.shell_input_handler import shell_input_handler
|
|
16
14
|
from jarvis.jarvis_agent.task_manager import TaskManager
|
|
17
|
-
from jarvis.
|
|
15
|
+
from jarvis.jarvis_utils.config import is_non_interactive, is_skip_predefined_tasks
|
|
18
16
|
|
|
19
17
|
|
|
20
18
|
class AgentManager:
|
|
@@ -27,6 +25,10 @@ class AgentManager:
|
|
|
27
25
|
restore_session: bool = False,
|
|
28
26
|
use_methodology: Optional[bool] = None,
|
|
29
27
|
use_analysis: Optional[bool] = None,
|
|
28
|
+
multiline_inputer: Optional[Callable[[str], str]] = None,
|
|
29
|
+
confirm_callback: Optional[Callable[[str, bool], bool]] = None,
|
|
30
|
+
non_interactive: Optional[bool] = None,
|
|
31
|
+
plan: Optional[bool] = None,
|
|
30
32
|
):
|
|
31
33
|
self.model_group = model_group
|
|
32
34
|
self.tool_group = tool_group
|
|
@@ -34,6 +36,11 @@ class AgentManager:
|
|
|
34
36
|
self.use_methodology = use_methodology
|
|
35
37
|
self.use_analysis = use_analysis
|
|
36
38
|
self.agent: Optional[Agent] = None
|
|
39
|
+
# 可选:注入输入与确认回调,用于Web模式等前端替代交互
|
|
40
|
+
self.multiline_inputer = multiline_inputer
|
|
41
|
+
self.confirm_callback = confirm_callback
|
|
42
|
+
self.non_interactive = non_interactive
|
|
43
|
+
self.plan = plan
|
|
37
44
|
|
|
38
45
|
def initialize(self) -> Agent:
|
|
39
46
|
"""初始化Agent"""
|
|
@@ -46,11 +53,13 @@ class AgentManager:
|
|
|
46
53
|
self.agent = Agent(
|
|
47
54
|
system_prompt=origin_agent_system_prompt,
|
|
48
55
|
model_group=self.model_group,
|
|
49
|
-
input_handler=[shell_input_handler, builtin_input_handler],
|
|
50
|
-
output_handler=[ToolRegistry()], # type: ignore
|
|
51
56
|
need_summary=False,
|
|
52
57
|
use_methodology=self.use_methodology,
|
|
53
58
|
use_analysis=self.use_analysis,
|
|
59
|
+
multiline_inputer=self.multiline_inputer,
|
|
60
|
+
confirm_callback=self.confirm_callback,
|
|
61
|
+
non_interactive=self.non_interactive,
|
|
62
|
+
plan=self.plan,
|
|
54
63
|
)
|
|
55
64
|
|
|
56
65
|
# 尝试恢复会话
|
|
@@ -72,8 +81,8 @@ class AgentManager:
|
|
|
72
81
|
self.agent.run(task_content)
|
|
73
82
|
raise typer.Exit(code=0)
|
|
74
83
|
|
|
75
|
-
#
|
|
76
|
-
if self.agent.first:
|
|
84
|
+
# 处理预定义任务(非交互模式下跳过;支持配置跳过加载)
|
|
85
|
+
if not is_non_interactive() and not is_skip_predefined_tasks() and self.agent.first:
|
|
77
86
|
task_manager = TaskManager()
|
|
78
87
|
tasks = task_manager.load_tasks()
|
|
79
88
|
if tasks and (selected_task := task_manager.select_task(tasks)):
|