jarvis-ai-assistant 0.3.27__py3-none-any.whl → 0.3.29__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 +73 -29
- jarvis/jarvis_agent/agent_manager.py +6 -0
- jarvis/jarvis_agent/config_editor.py +1 -1
- jarvis/jarvis_agent/event_bus.py +2 -2
- jarvis/jarvis_agent/events.py +157 -0
- jarvis/jarvis_agent/file_methodology_manager.py +18 -7
- jarvis/jarvis_agent/jarvis.py +11 -4
- jarvis/jarvis_agent/memory_manager.py +4 -4
- jarvis/jarvis_agent/prompts.py +2 -2
- jarvis/jarvis_agent/protocols.py +4 -1
- jarvis/jarvis_agent/run_loop.py +9 -24
- jarvis/jarvis_agent/shell_input_handler.py +7 -2
- jarvis/jarvis_agent/task_analyzer.py +19 -15
- jarvis/jarvis_agent/task_manager.py +6 -4
- jarvis/jarvis_agent/user_interaction.py +1 -1
- jarvis/jarvis_agent/utils.py +50 -0
- jarvis/jarvis_code_agent/code_agent.py +2 -2
- jarvis/jarvis_code_analysis/code_review.py +0 -1
- jarvis/jarvis_git_utils/git_commiter.py +13 -4
- jarvis/jarvis_mcp/sse_mcp_client.py +1 -1
- jarvis/jarvis_mcp/stdio_mcp_client.py +1 -1
- jarvis/jarvis_memory_organizer/memory_organizer.py +6 -9
- jarvis/jarvis_methodology/main.py +0 -2
- jarvis/jarvis_multi_agent/__init__.py +3 -3
- jarvis/jarvis_platform/base.py +1 -1
- jarvis/jarvis_platform/kimi.py +1 -1
- jarvis/jarvis_platform/registry.py +1 -1
- jarvis/jarvis_platform/tongyi.py +1 -1
- jarvis/jarvis_platform/yuanbao.py +1 -2
- jarvis/jarvis_platform_manager/service.py +1 -1
- jarvis/jarvis_rag/cli.py +1 -1
- jarvis/jarvis_rag/embedding_manager.py +0 -1
- jarvis/jarvis_rag/llm_interface.py +0 -3
- jarvis/jarvis_rag/retriever.py +3 -3
- jarvis/jarvis_smart_shell/main.py +0 -1
- jarvis/jarvis_stats/cli.py +2 -3
- jarvis/jarvis_stats/stats.py +3 -4
- jarvis/jarvis_stats/storage.py +3 -3
- jarvis/jarvis_tools/clear_memory.py +1 -3
- jarvis/jarvis_tools/cli/main.py +0 -1
- jarvis/jarvis_tools/edit_file.py +3 -4
- jarvis/jarvis_tools/execute_script.py +2 -2
- jarvis/jarvis_tools/generate_new_tool.py +3 -5
- jarvis/jarvis_tools/registry.py +2 -3
- jarvis/jarvis_tools/retrieve_memory.py +2 -3
- jarvis/jarvis_tools/save_memory.py +3 -3
- jarvis/jarvis_tools/search_web.py +2 -2
- jarvis/jarvis_tools/sub_agent.py +21 -2
- jarvis/jarvis_tools/sub_code_agent.py +18 -2
- jarvis/jarvis_tools/virtual_tty.py +3 -14
- jarvis/jarvis_utils/builtin_replace_map.py +4 -4
- jarvis/jarvis_utils/config.py +32 -17
- jarvis/jarvis_utils/fzf.py +4 -3
- jarvis/jarvis_utils/git_utils.py +1 -1
- jarvis/jarvis_utils/globals.py +1 -2
- jarvis/jarvis_utils/input.py +5 -5
- jarvis/jarvis_utils/methodology.py +3 -5
- jarvis/jarvis_utils/output.py +1 -1
- jarvis/jarvis_utils/utils.py +160 -31
- {jarvis_ai_assistant-0.3.27.dist-info → jarvis_ai_assistant-0.3.29.dist-info}/METADATA +1 -1
- {jarvis_ai_assistant-0.3.27.dist-info → jarvis_ai_assistant-0.3.29.dist-info}/RECORD +66 -64
- {jarvis_ai_assistant-0.3.27.dist-info → jarvis_ai_assistant-0.3.29.dist-info}/WHEEL +0 -0
- {jarvis_ai_assistant-0.3.27.dist-info → jarvis_ai_assistant-0.3.29.dist-info}/entry_points.txt +0 -0
- {jarvis_ai_assistant-0.3.27.dist-info → jarvis_ai_assistant-0.3.29.dist-info}/licenses/LICENSE +0 -0
- {jarvis_ai_assistant-0.3.27.dist-info → jarvis_ai_assistant-0.3.29.dist-info}/top_level.txt +0 -0
jarvis/jarvis_agent/protocols.py
CHANGED
@@ -1,7 +1,8 @@
|
|
1
1
|
# -*- coding: utf-8 -*-
|
2
|
-
from typing import Any, Protocol, Tuple
|
2
|
+
from typing import Any, Protocol, Tuple, runtime_checkable
|
3
3
|
|
4
4
|
|
5
|
+
@runtime_checkable
|
5
6
|
class OutputHandlerProtocol(Protocol):
|
6
7
|
"""
|
7
8
|
Defines the interface for an output handler, which is responsible for
|
@@ -28,3 +29,5 @@ class OutputHandlerProtocol(Protocol):
|
|
28
29
|
A tuple containing a boolean (whether to return) and the result.
|
29
30
|
"""
|
30
31
|
...
|
32
|
+
|
33
|
+
__all__ = ["OutputHandlerProtocol"]
|
jarvis/jarvis_agent/run_loop.py
CHANGED
@@ -11,7 +11,8 @@ from enum import Enum
|
|
11
11
|
from typing import Any, TYPE_CHECKING
|
12
12
|
|
13
13
|
from jarvis.jarvis_utils.output import OutputType, PrettyOutput
|
14
|
-
from jarvis.
|
14
|
+
from jarvis.jarvis_agent.events import BEFORE_TOOL_CALL, AFTER_TOOL_CALL
|
15
|
+
from jarvis.jarvis_agent.utils import join_prompts, is_auto_complete, normalize_next_action
|
15
16
|
|
16
17
|
if TYPE_CHECKING:
|
17
18
|
# 仅用于类型标注,避免运行时循环依赖
|
@@ -63,7 +64,7 @@ class AgentRunLoop:
|
|
63
64
|
# 广播工具调用前事件(不影响主流程)
|
64
65
|
try:
|
65
66
|
ag.event_bus.emit(
|
66
|
-
|
67
|
+
BEFORE_TOOL_CALL,
|
67
68
|
agent=ag,
|
68
69
|
current_response=current_response,
|
69
70
|
)
|
@@ -72,12 +73,7 @@ class AgentRunLoop:
|
|
72
73
|
need_return, tool_prompt = ag._call_tools(current_response)
|
73
74
|
|
74
75
|
# 将上一个提示和工具提示安全地拼接起来
|
75
|
-
|
76
|
-
if ag.session.prompt:
|
77
|
-
prompt_parts.append(ag.session.prompt)
|
78
|
-
if tool_prompt:
|
79
|
-
prompt_parts.append(tool_prompt)
|
80
|
-
ag.session.prompt = "\n\n".join(prompt_parts)
|
76
|
+
ag.session.prompt = join_prompts([ag.session.prompt, tool_prompt])
|
81
77
|
|
82
78
|
if need_return:
|
83
79
|
return ag.session.prompt
|
@@ -88,7 +84,7 @@ class AgentRunLoop:
|
|
88
84
|
# 广播工具调用后的事件(不影响主流程)
|
89
85
|
try:
|
90
86
|
ag.event_bus.emit(
|
91
|
-
|
87
|
+
AFTER_TOOL_CALL,
|
92
88
|
agent=ag,
|
93
89
|
current_response=current_response,
|
94
90
|
need_return=need_return,
|
@@ -102,27 +98,16 @@ class AgentRunLoop:
|
|
102
98
|
continue
|
103
99
|
|
104
100
|
# 检查自动完成
|
105
|
-
if ag.auto_complete and
|
101
|
+
if ag.auto_complete and is_auto_complete(current_response):
|
106
102
|
return ag._complete_task(auto_completed=True)
|
107
103
|
|
108
104
|
# 获取下一步用户输入
|
109
105
|
next_action = ag._get_next_user_action()
|
110
|
-
|
111
|
-
|
112
|
-
or (
|
113
|
-
isinstance(next_action, Enum)
|
114
|
-
and getattr(next_action, "value", None) == "continue"
|
115
|
-
)
|
116
|
-
):
|
106
|
+
action = normalize_next_action(next_action)
|
107
|
+
if action == "continue":
|
117
108
|
run_input_handlers = True
|
118
109
|
continue
|
119
|
-
elif
|
120
|
-
next_action == "complete"
|
121
|
-
or (
|
122
|
-
isinstance(next_action, Enum)
|
123
|
-
and getattr(next_action, "value", None) == "complete"
|
124
|
-
)
|
125
|
-
):
|
110
|
+
elif action == "complete":
|
126
111
|
return ag._complete_task(auto_completed=False)
|
127
112
|
|
128
113
|
except Exception as e:
|
@@ -3,6 +3,7 @@ from typing import Any, Tuple
|
|
3
3
|
|
4
4
|
from jarvis.jarvis_utils.output import OutputType, PrettyOutput
|
5
5
|
from jarvis.jarvis_utils.input import user_confirm
|
6
|
+
from jarvis.jarvis_agent.utils import join_prompts
|
6
7
|
|
7
8
|
|
8
9
|
def shell_input_handler(user_input: str, agent: Any) -> Tuple[str, bool]:
|
@@ -28,7 +29,7 @@ def shell_input_handler(user_input: str, agent: Any) -> Tuple[str, bool]:
|
|
28
29
|
# If any line contains the no-confirm marker, skip the pre-execution confirmation
|
29
30
|
no_confirm = any(marker in c for c in cmdline)
|
30
31
|
|
31
|
-
if no_confirm or user_confirm(
|
32
|
+
if no_confirm or user_confirm("是否要执行以上shell脚本?", default=True):
|
32
33
|
from jarvis.jarvis_tools.registry import ToolRegistry
|
33
34
|
|
34
35
|
output = ToolRegistry().handle_tool_calls(
|
@@ -41,7 +42,11 @@ def shell_input_handler(user_input: str, agent: Any) -> Tuple[str, bool]:
|
|
41
42
|
)
|
42
43
|
if user_confirm("是否将执行结果反馈给Agent?", default=True):
|
43
44
|
return (
|
44
|
-
|
45
|
+
join_prompts([
|
46
|
+
user_input,
|
47
|
+
f"用户执行以下脚本:\n{script}",
|
48
|
+
f"执行结果:\n{output}",
|
49
|
+
]),
|
45
50
|
False,
|
46
51
|
)
|
47
52
|
return "", True
|
@@ -3,12 +3,13 @@
|
|
3
3
|
任务分析器模块
|
4
4
|
负责处理任务分析和方法论生成功能
|
5
5
|
"""
|
6
|
-
from typing import Optional
|
7
6
|
|
8
7
|
from jarvis.jarvis_utils.globals import get_interrupt, set_interrupt
|
9
8
|
|
10
9
|
from jarvis.jarvis_agent.prompts import TASK_ANALYSIS_PROMPT
|
11
10
|
from jarvis.jarvis_utils.output import OutputType, PrettyOutput
|
11
|
+
from jarvis.jarvis_agent.utils import join_prompts
|
12
|
+
from jarvis.jarvis_agent.events import BEFORE_TOOL_CALL, AFTER_TOOL_CALL, BEFORE_SUMMARY, TASK_COMPLETED
|
12
13
|
|
13
14
|
|
14
15
|
class TaskAnalyzer:
|
@@ -44,7 +45,7 @@ class TaskAnalyzer:
|
|
44
45
|
# 循环处理工具调用,直到没有工具调用为止
|
45
46
|
self._process_analysis_loop()
|
46
47
|
|
47
|
-
except Exception
|
48
|
+
except Exception:
|
48
49
|
PrettyOutput.print("分析失败", OutputType.ERROR)
|
49
50
|
finally:
|
50
51
|
# 标记已完成一次分析,避免事件回调重复执行
|
@@ -56,10 +57,7 @@ class TaskAnalyzer:
|
|
56
57
|
|
57
58
|
def _prepare_analysis_prompt(self, satisfaction_feedback: str) -> str:
|
58
59
|
"""准备分析提示"""
|
59
|
-
|
60
|
-
if satisfaction_feedback:
|
61
|
-
analysis_prompt += satisfaction_feedback
|
62
|
-
return analysis_prompt
|
60
|
+
return join_prompts([TASK_ANALYSIS_PROMPT, satisfaction_feedback])
|
63
61
|
|
64
62
|
def _process_analysis_loop(self):
|
65
63
|
"""处理分析循环"""
|
@@ -75,7 +73,7 @@ class TaskAnalyzer:
|
|
75
73
|
# 执行工具调用(补充事件:before_tool_call/after_tool_call)
|
76
74
|
try:
|
77
75
|
self.agent.event_bus.emit(
|
78
|
-
|
76
|
+
BEFORE_TOOL_CALL,
|
79
77
|
agent=self.agent,
|
80
78
|
current_response=response,
|
81
79
|
)
|
@@ -85,7 +83,7 @@ class TaskAnalyzer:
|
|
85
83
|
self.agent.session.prompt = tool_prompt
|
86
84
|
try:
|
87
85
|
self.agent.event_bus.emit(
|
88
|
-
|
86
|
+
AFTER_TOOL_CALL,
|
89
87
|
agent=self.agent,
|
90
88
|
current_response=response,
|
91
89
|
need_return=need_return,
|
@@ -131,9 +129,15 @@ class TaskAnalyzer:
|
|
131
129
|
def _handle_interrupt_with_tool_calls(self, user_input: str) -> str:
|
132
130
|
"""处理有工具调用时的中断"""
|
133
131
|
if self.agent.user_confirm("检测到有工具调用,是否继续处理工具调用?", True):
|
134
|
-
return
|
132
|
+
return join_prompts([
|
133
|
+
f"被用户中断,用户补充信息为:{user_input}",
|
134
|
+
"用户同意继续工具调用。"
|
135
|
+
])
|
135
136
|
else:
|
136
|
-
return
|
137
|
+
return join_prompts([
|
138
|
+
f"被用户中断,用户补充信息为:{user_input}",
|
139
|
+
"检测到有工具调用,但被用户拒绝执行。请根据用户的补充信息重新考虑下一步操作。"
|
140
|
+
])
|
137
141
|
|
138
142
|
def collect_satisfaction_feedback(self, auto_completed: bool) -> str:
|
139
143
|
"""收集满意度反馈"""
|
@@ -141,18 +145,18 @@ class TaskAnalyzer:
|
|
141
145
|
|
142
146
|
if not auto_completed and self.agent.use_analysis:
|
143
147
|
if self.agent.user_confirm("您对本次任务的完成是否满意?", True):
|
144
|
-
satisfaction_feedback = "
|
148
|
+
satisfaction_feedback = "用户对本次任务的完成表示满意。"
|
145
149
|
else:
|
146
150
|
feedback = self.agent._multiline_input(
|
147
151
|
"请提供您的反馈意见(可留空直接回车):", False
|
148
152
|
)
|
149
153
|
if feedback:
|
150
154
|
satisfaction_feedback = (
|
151
|
-
f"
|
155
|
+
f"用户对本次任务的完成不满意,反馈意见如下:\n{feedback}"
|
152
156
|
)
|
153
157
|
else:
|
154
158
|
satisfaction_feedback = (
|
155
|
-
"
|
159
|
+
"用户对本次任务的完成不满意,未提供具体反馈意见。"
|
156
160
|
)
|
157
161
|
|
158
162
|
return satisfaction_feedback
|
@@ -163,9 +167,9 @@ class TaskAnalyzer:
|
|
163
167
|
def _subscribe_events(self) -> None:
|
164
168
|
bus = self.agent.get_event_bus() # type: ignore[attr-defined]
|
165
169
|
# 在生成总结前触发(保持与原顺序一致)
|
166
|
-
bus.subscribe(
|
170
|
+
bus.subscribe(BEFORE_SUMMARY, self._on_before_summary)
|
167
171
|
# 当无需总结时,作为兜底触发分析
|
168
|
-
bus.subscribe(
|
172
|
+
bus.subscribe(TASK_COMPLETED, self._on_task_completed)
|
169
173
|
|
170
174
|
def _on_before_summary(self, **payload) -> None:
|
171
175
|
if self._analysis_done:
|
@@ -14,6 +14,7 @@ from jarvis.jarvis_agent import (
|
|
14
14
|
get_multiline_input,
|
15
15
|
user_confirm,
|
16
16
|
)
|
17
|
+
from jarvis.jarvis_agent.utils import join_prompts
|
17
18
|
from jarvis.jarvis_utils.config import get_data_dir
|
18
19
|
from jarvis.jarvis_utils.fzf import fzf_select
|
19
20
|
|
@@ -109,7 +110,7 @@ class TaskManager:
|
|
109
110
|
if need_additional:
|
110
111
|
additional_input = get_multiline_input("请输入补充信息:")
|
111
112
|
if additional_input:
|
112
|
-
selected_task = f"
|
113
|
+
selected_task = join_prompts([selected_task, f"补充信息:\n{additional_input}"])
|
113
114
|
return selected_task
|
114
115
|
except Exception:
|
115
116
|
# 如果解析失败,则回退到手动输入
|
@@ -138,9 +139,10 @@ class TaskManager:
|
|
138
139
|
if need_additional:
|
139
140
|
additional_input = get_multiline_input("请输入补充信息:")
|
140
141
|
if additional_input:
|
141
|
-
selected_task = (
|
142
|
-
|
143
|
-
|
142
|
+
selected_task = join_prompts([
|
143
|
+
selected_task,
|
144
|
+
f"补充信息:\n{additional_input}"
|
145
|
+
])
|
144
146
|
return selected_task
|
145
147
|
PrettyOutput.print(
|
146
148
|
"无效的选择。请选择列表中的一个号码。", OutputType.WARNING
|
@@ -0,0 +1,50 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
"""
|
3
|
+
工具函数(jarvis_agent.utils)
|
4
|
+
|
5
|
+
- join_prompts: 统一的提示拼接策略(仅拼接非空段落,使用双换行)
|
6
|
+
- is_auto_complete: 统一的自动完成标记检测
|
7
|
+
"""
|
8
|
+
from typing import Iterable, List, Any
|
9
|
+
from enum import Enum
|
10
|
+
from jarvis.jarvis_utils.tag import ot
|
11
|
+
|
12
|
+
def join_prompts(parts: Iterable[str]) -> str:
|
13
|
+
"""
|
14
|
+
将多个提示片段按统一规则拼接:
|
15
|
+
- 过滤掉空字符串
|
16
|
+
- 使用两个换行分隔
|
17
|
+
- 不进行额外 strip,保持调用方原样语义
|
18
|
+
"""
|
19
|
+
non_empty: List[str] = [p for p in parts if p]
|
20
|
+
return "\n\n".join(non_empty)
|
21
|
+
|
22
|
+
def is_auto_complete(response: str) -> bool:
|
23
|
+
"""
|
24
|
+
检测是否包含自动完成标记。
|
25
|
+
当前实现:包含 ot('!!!COMPLETE!!!') 即视为自动完成。
|
26
|
+
"""
|
27
|
+
try:
|
28
|
+
return ot("!!!COMPLETE!!!") in response
|
29
|
+
except Exception:
|
30
|
+
# 防御性处理:即使 ot 出现异常,也不阻塞主流程
|
31
|
+
return "!!!COMPLETE!!!" in response
|
32
|
+
|
33
|
+
def normalize_next_action(next_action: Any) -> str:
|
34
|
+
"""
|
35
|
+
规范化下一步动作为字符串:
|
36
|
+
- 如果是 Enum, 返回其 value(若为字符串)
|
37
|
+
- 如果是 str, 原样返回
|
38
|
+
- 其他情况返回空字符串
|
39
|
+
"""
|
40
|
+
try:
|
41
|
+
if isinstance(next_action, Enum):
|
42
|
+
value = getattr(next_action, "value", None)
|
43
|
+
return value if isinstance(value, str) else ""
|
44
|
+
if isinstance(next_action, str):
|
45
|
+
return next_action
|
46
|
+
return ""
|
47
|
+
except Exception:
|
48
|
+
return ""
|
49
|
+
|
50
|
+
__all__ = ["join_prompts", "is_auto_complete", "normalize_next_action"]
|
@@ -262,7 +262,7 @@ class CodeAgent:
|
|
262
262
|
if has_uncommitted_changes():
|
263
263
|
|
264
264
|
git_commiter = GitCommitTool()
|
265
|
-
git_commiter.execute({"prefix": prefix, "suffix": suffix, "agent": self.agent})
|
265
|
+
git_commiter.execute({"prefix": prefix, "suffix": suffix, "agent": self.agent, "model_group": getattr(self.agent.model, "model_group", None)})
|
266
266
|
|
267
267
|
def _init_env(self, prefix: str, suffix: str) -> None:
|
268
268
|
"""初始化环境,组合以下功能:
|
@@ -522,7 +522,7 @@ class CodeAgent:
|
|
522
522
|
check=True,
|
523
523
|
)
|
524
524
|
git_commiter = GitCommitTool()
|
525
|
-
git_commiter.execute({"prefix": prefix, "suffix": suffix, "agent": self.agent})
|
525
|
+
git_commiter.execute({"prefix": prefix, "suffix": suffix, "agent": self.agent, "model_group": getattr(self.agent.model, "model_group", None)})
|
526
526
|
|
527
527
|
# 在用户接受commit后,根据配置决定是否保存记忆
|
528
528
|
if self.agent.force_save_memory:
|
@@ -2,7 +2,6 @@
|
|
2
2
|
import os
|
3
3
|
import re
|
4
4
|
import subprocess
|
5
|
-
import sys
|
6
5
|
import tempfile
|
7
6
|
from typing import Any, Dict, Optional
|
8
7
|
|
@@ -138,7 +137,7 @@ class GitCommitTool:
|
|
138
137
|
base_prompt = (
|
139
138
|
custom_prompt
|
140
139
|
if custom_prompt
|
141
|
-
else
|
140
|
+
else """根据代码差异生成提交信息:
|
142
141
|
提交信息应使用中文书写
|
143
142
|
# 格式模板
|
144
143
|
必须使用以下格式:
|
@@ -219,11 +218,21 @@ commit信息
|
|
219
218
|
platform = PlatformRegistry().create_platform(platform_name)
|
220
219
|
if platform and model_name:
|
221
220
|
platform.set_model_name(model_name)
|
222
|
-
|
223
|
-
|
221
|
+
if platform and model_group:
|
222
|
+
try:
|
223
|
+
platform.set_model_group(model_group)
|
224
|
+
except Exception:
|
225
|
+
# 兼容早期实现
|
226
|
+
platform.model_group = model_group # type: ignore
|
224
227
|
else:
|
225
228
|
platform = PlatformRegistry().get_normal_platform()
|
226
229
|
|
230
|
+
# 跳过模型可用性校验:
|
231
|
+
# 为避免某些平台/代理不支持 get_model_list 接口导致的噪音日志(如 404),
|
232
|
+
# 这里默认不调用 platform.get_model_list() 进行模型可用性校验。
|
233
|
+
# 如果未来需要恢复校验,可参考被移除的逻辑。
|
234
|
+
# no-op
|
235
|
+
|
227
236
|
# Ensure platform is not None
|
228
237
|
if not platform:
|
229
238
|
return {
|
@@ -7,14 +7,11 @@
|
|
7
7
|
"""
|
8
8
|
|
9
9
|
import json
|
10
|
-
import sys
|
11
10
|
from collections import defaultdict
|
12
|
-
from itertools import combinations
|
13
11
|
from pathlib import Path
|
14
|
-
from typing import Dict, List, Set,
|
12
|
+
from typing import Dict, List, Set, Any, Optional
|
15
13
|
|
16
14
|
import typer
|
17
|
-
import yaml
|
18
15
|
|
19
16
|
from jarvis.jarvis_utils.config import (
|
20
17
|
get_data_dir,
|
@@ -66,7 +63,7 @@ class MemoryOrganizer:
|
|
66
63
|
"""加载指定类型的所有记忆"""
|
67
64
|
memories = []
|
68
65
|
memory_files = self._get_memory_files(memory_type)
|
69
|
-
error_lines:
|
66
|
+
error_lines: List[str] = []
|
70
67
|
|
71
68
|
for memory_file in memory_files:
|
72
69
|
try:
|
@@ -311,7 +308,7 @@ tags:
|
|
311
308
|
group_memories = [memories[i] for i in original_indices]
|
312
309
|
|
313
310
|
# 显示将要合并的记忆(先拼接后统一打印,避免循环逐条输出)
|
314
|
-
lines = [
|
311
|
+
lines = ["", f"准备合并 {len(group_memories)} 个记忆:"]
|
315
312
|
for mem in group_memories:
|
316
313
|
lines.append(
|
317
314
|
f" - ID: {mem.get('id', '未知')}, "
|
@@ -391,8 +388,8 @@ tags:
|
|
391
388
|
)
|
392
389
|
|
393
390
|
# 删除原始记忆文件(先汇总日志,最后统一打印)
|
394
|
-
info_lines:
|
395
|
-
warn_lines:
|
391
|
+
info_lines: List[str] = []
|
392
|
+
warn_lines: List[str] = []
|
396
393
|
for orig_memory in original_memories:
|
397
394
|
if "file_path" in orig_memory:
|
398
395
|
try:
|
@@ -431,7 +428,7 @@ tags:
|
|
431
428
|
导出的记忆数量
|
432
429
|
"""
|
433
430
|
all_memories = []
|
434
|
-
progress_lines:
|
431
|
+
progress_lines: List[str] = []
|
435
432
|
|
436
433
|
for memory_type in memory_types:
|
437
434
|
progress_lines.append(f"正在导出 {memory_type} 类型的记忆...")
|
@@ -73,7 +73,7 @@ content: |2
|
|
73
73
|
if len(send_messages) > 1:
|
74
74
|
return (
|
75
75
|
False,
|
76
|
-
|
76
|
+
"Send multiple messages, please only send one message at a time.",
|
77
77
|
)
|
78
78
|
if len(send_messages) == 0:
|
79
79
|
return False, ""
|
@@ -100,7 +100,7 @@ content: |2
|
|
100
100
|
msg = yaml.safe_load(item)
|
101
101
|
if "to" in msg and "content" in msg:
|
102
102
|
ret.append(msg)
|
103
|
-
except Exception
|
103
|
+
except Exception:
|
104
104
|
continue
|
105
105
|
return ret
|
106
106
|
|
@@ -161,7 +161,7 @@ content: {msg['content']}
|
|
161
161
|
"""
|
162
162
|
to_agent_name = msg.get("to")
|
163
163
|
if not to_agent_name:
|
164
|
-
return
|
164
|
+
return "消息中未指定 `to` 字段"
|
165
165
|
|
166
166
|
if to_agent_name not in self.agents_config_map:
|
167
167
|
PrettyOutput.print(
|
jarvis/jarvis_platform/base.py
CHANGED
@@ -88,7 +88,7 @@ class BasePlatform(ABC):
|
|
88
88
|
PrettyOutput.print(
|
89
89
|
f"长上下文,分批提交,共{len(inputs)}部分...", OutputType.INFO
|
90
90
|
)
|
91
|
-
prefix_prompt =
|
91
|
+
prefix_prompt = """
|
92
92
|
我将分多次提供大量内容,在我明确告诉你内容已经全部提供完毕之前,每次仅需要输出"已收到",明白请输出"开始接收输入"。
|
93
93
|
"""
|
94
94
|
while_true(lambda: while_success(lambda: self._chat(prefix_prompt), 5), 5)
|
jarvis/jarvis_platform/kimi.py
CHANGED
@@ -194,7 +194,7 @@ class KimiModel(BasePlatform):
|
|
194
194
|
uploaded_files = []
|
195
195
|
for index, file_path in enumerate(file_list, 1):
|
196
196
|
file_name = os.path.basename(file_path)
|
197
|
-
log_lines:
|
197
|
+
log_lines: List[str] = [f"处理文件 [{index}/{len(file_list)}]: {file_name}"]
|
198
198
|
try:
|
199
199
|
mime_type, _ = mimetypes.guess_type(file_path)
|
200
200
|
action = (
|
jarvis/jarvis_platform/tongyi.py
CHANGED
@@ -276,7 +276,7 @@ class TongyiPlatform(BasePlatform):
|
|
276
276
|
|
277
277
|
for file_path in file_list:
|
278
278
|
file_name = os.path.basename(file_path)
|
279
|
-
log_lines:
|
279
|
+
log_lines: List[str] = []
|
280
280
|
log_lines.append(f"上传文件 {file_name}")
|
281
281
|
try:
|
282
282
|
if not os.path.exists(file_path):
|
@@ -69,7 +69,6 @@ class YuanbaoPlatform(BasePlatform):
|
|
69
69
|
"X-Requested-With": "XMLHttpRequest",
|
70
70
|
"chat_version": "v1",
|
71
71
|
"X-Instance-ID": "5",
|
72
|
-
"X-Requested-With": "XMLHttpRequest",
|
73
72
|
"Accept": "application/json, text/plain, */*",
|
74
73
|
"Content-Type": "application/json",
|
75
74
|
"sec-ch-ua-mobile": "?0",
|
@@ -134,7 +133,7 @@ class YuanbaoPlatform(BasePlatform):
|
|
134
133
|
|
135
134
|
for file_path in file_list:
|
136
135
|
file_name = os.path.basename(file_path)
|
137
|
-
log_lines:
|
136
|
+
log_lines: List[str] = []
|
138
137
|
log_lines.append(f"上传文件 {file_name}")
|
139
138
|
try:
|
140
139
|
# 1. Prepare the file information
|
jarvis/jarvis_rag/cli.py
CHANGED
jarvis/jarvis_rag/retriever.py
CHANGED
@@ -185,7 +185,7 @@ class ChromaRetriever:
|
|
185
185
|
if not changed and not deleted:
|
186
186
|
return
|
187
187
|
# 为避免在循环中逐条打印,先拼接后统一打印
|
188
|
-
lines:
|
188
|
+
lines: List[str] = []
|
189
189
|
if changed:
|
190
190
|
lines.append(
|
191
191
|
f"检测到 {len(changed)} 个已索引文件发生变化,建议重新索引以保证检索准确性。"
|
@@ -247,7 +247,7 @@ class ChromaRetriever:
|
|
247
247
|
return
|
248
248
|
|
249
249
|
# 先处理删除
|
250
|
-
delete_errors:
|
250
|
+
delete_errors: List[str] = []
|
251
251
|
for src in deleted:
|
252
252
|
try:
|
253
253
|
self.collection.delete(where={"source": src}) # type: ignore[arg-type]
|
@@ -258,7 +258,7 @@ class ChromaRetriever:
|
|
258
258
|
|
259
259
|
# 再处理变更(重建)
|
260
260
|
docs_to_add: List[Document] = []
|
261
|
-
rebuild_errors:
|
261
|
+
rebuild_errors: List[str] = []
|
262
262
|
for src in changed:
|
263
263
|
try:
|
264
264
|
# 删除旧条目
|
jarvis/jarvis_stats/cli.py
CHANGED
@@ -16,7 +16,6 @@ from pathlib import Path
|
|
16
16
|
from .stats import StatsManager
|
17
17
|
from jarvis.jarvis_utils.utils import init_env
|
18
18
|
from jarvis.jarvis_utils.config import get_data_dir
|
19
|
-
from jarvis.jarvis_utils.output import OutputType, PrettyOutput
|
20
19
|
|
21
20
|
app = typer.Typer(help="Jarvis 统计模块命令行工具")
|
22
21
|
console = Console()
|
@@ -310,7 +309,7 @@ def remove(
|
|
310
309
|
unit = info.get("unit", "-")
|
311
310
|
last_updated = info.get("last_updated", "-")
|
312
311
|
|
313
|
-
rprint(
|
312
|
+
rprint("\n[yellow]准备删除指标:[/yellow]")
|
314
313
|
rprint(f" 名称: {metric}")
|
315
314
|
rprint(f" 单位: {unit}")
|
316
315
|
rprint(f" 最后更新: {last_updated}")
|
@@ -340,7 +339,7 @@ def demo():
|
|
340
339
|
stats = StatsManager(_get_stats_dir())
|
341
340
|
|
342
341
|
# 添加演示数据
|
343
|
-
with console.status("[bold green]正在生成演示数据...")
|
342
|
+
with console.status("[bold green]正在生成演示数据..."):
|
344
343
|
# API响应时间
|
345
344
|
for i in range(20):
|
346
345
|
response_time = random.uniform(0.1, 2.0)
|