jarvis-ai-assistant 0.1.138__py3-none-any.whl → 0.1.141__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 +62 -14
- jarvis/jarvis_agent/builtin_input_handler.py +4 -14
- jarvis/jarvis_agent/main.py +1 -1
- jarvis/jarvis_agent/patch.py +37 -40
- jarvis/jarvis_agent/shell_input_handler.py +2 -3
- jarvis/jarvis_code_agent/code_agent.py +23 -30
- jarvis/jarvis_code_analysis/checklists/__init__.py +3 -0
- jarvis/jarvis_code_analysis/checklists/c_cpp.py +50 -0
- jarvis/jarvis_code_analysis/checklists/csharp.py +75 -0
- jarvis/jarvis_code_analysis/checklists/data_format.py +82 -0
- jarvis/jarvis_code_analysis/checklists/devops.py +107 -0
- jarvis/jarvis_code_analysis/checklists/docs.py +87 -0
- jarvis/jarvis_code_analysis/checklists/go.py +52 -0
- jarvis/jarvis_code_analysis/checklists/infrastructure.py +98 -0
- jarvis/jarvis_code_analysis/checklists/java.py +66 -0
- jarvis/jarvis_code_analysis/checklists/javascript.py +73 -0
- jarvis/jarvis_code_analysis/checklists/kotlin.py +107 -0
- jarvis/jarvis_code_analysis/checklists/loader.py +76 -0
- jarvis/jarvis_code_analysis/checklists/php.py +77 -0
- jarvis/jarvis_code_analysis/checklists/python.py +56 -0
- jarvis/jarvis_code_analysis/checklists/ruby.py +107 -0
- jarvis/jarvis_code_analysis/checklists/rust.py +58 -0
- jarvis/jarvis_code_analysis/checklists/shell.py +75 -0
- jarvis/jarvis_code_analysis/checklists/sql.py +72 -0
- jarvis/jarvis_code_analysis/checklists/swift.py +77 -0
- jarvis/jarvis_code_analysis/checklists/web.py +97 -0
- jarvis/jarvis_code_analysis/code_review.py +660 -0
- jarvis/jarvis_dev/main.py +61 -88
- jarvis/jarvis_git_squash/main.py +3 -3
- jarvis/jarvis_git_utils/git_commiter.py +242 -0
- jarvis/jarvis_init/main.py +62 -0
- jarvis/jarvis_platform/base.py +4 -0
- jarvis/jarvis_platform/kimi.py +173 -5
- jarvis/jarvis_platform/openai.py +3 -0
- jarvis/jarvis_platform/registry.py +1 -0
- jarvis/jarvis_platform/yuanbao.py +275 -5
- jarvis/jarvis_tools/ask_codebase.py +6 -9
- jarvis/jarvis_tools/ask_user.py +17 -5
- jarvis/jarvis_tools/base.py +3 -1
- jarvis/jarvis_tools/chdir.py +1 -0
- jarvis/jarvis_tools/create_code_agent.py +4 -3
- jarvis/jarvis_tools/create_sub_agent.py +1 -0
- jarvis/jarvis_tools/execute_script.py +170 -0
- jarvis/jarvis_tools/file_analyzer.py +90 -239
- jarvis/jarvis_tools/file_operation.py +99 -31
- jarvis/jarvis_tools/{find_methodolopy.py → find_methodology.py} +2 -1
- jarvis/jarvis_tools/lsp_get_diagnostics.py +2 -0
- jarvis/jarvis_tools/methodology.py +11 -11
- jarvis/jarvis_tools/read_code.py +2 -0
- jarvis/jarvis_tools/read_webpage.py +33 -196
- jarvis/jarvis_tools/registry.py +68 -131
- jarvis/jarvis_tools/search_web.py +14 -6
- jarvis/jarvis_tools/virtual_tty.py +399 -0
- jarvis/jarvis_utils/config.py +29 -3
- jarvis/jarvis_utils/embedding.py +0 -317
- jarvis/jarvis_utils/file_processors.py +343 -0
- jarvis/jarvis_utils/input.py +0 -1
- jarvis/jarvis_utils/methodology.py +94 -435
- jarvis/jarvis_utils/utils.py +207 -9
- {jarvis_ai_assistant-0.1.138.dist-info → jarvis_ai_assistant-0.1.141.dist-info}/METADATA +4 -4
- jarvis_ai_assistant-0.1.141.dist-info/RECORD +94 -0
- {jarvis_ai_assistant-0.1.138.dist-info → jarvis_ai_assistant-0.1.141.dist-info}/entry_points.txt +4 -4
- jarvis/jarvis_code_agent/file_select.py +0 -202
- jarvis/jarvis_platform/ai8.py +0 -268
- jarvis/jarvis_platform/ollama.py +0 -137
- jarvis/jarvis_platform/oyi.py +0 -307
- jarvis/jarvis_rag/file_processors.py +0 -138
- jarvis/jarvis_rag/main.py +0 -1734
- jarvis/jarvis_tools/code_review.py +0 -333
- jarvis/jarvis_tools/execute_python_script.py +0 -58
- jarvis/jarvis_tools/execute_shell.py +0 -97
- jarvis/jarvis_tools/execute_shell_script.py +0 -58
- jarvis/jarvis_tools/find_caller.py +0 -278
- jarvis/jarvis_tools/find_symbol.py +0 -295
- jarvis/jarvis_tools/function_analyzer.py +0 -331
- jarvis/jarvis_tools/git_commiter.py +0 -167
- jarvis/jarvis_tools/project_analyzer.py +0 -304
- jarvis/jarvis_tools/rag.py +0 -143
- jarvis/jarvis_tools/tool_generator.py +0 -221
- jarvis_ai_assistant-0.1.138.dist-info/RECORD +0 -85
- /jarvis/{jarvis_rag → jarvis_init}/__init__.py +0 -0
- {jarvis_ai_assistant-0.1.138.dist-info → jarvis_ai_assistant-0.1.141.dist-info}/LICENSE +0 -0
- {jarvis_ai_assistant-0.1.138.dist-info → jarvis_ai_assistant-0.1.141.dist-info}/WHEEL +0 -0
- {jarvis_ai_assistant-0.1.138.dist-info → jarvis_ai_assistant-0.1.141.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,399 @@
|
|
|
1
|
+
from typing import Dict, Any
|
|
2
|
+
import os
|
|
3
|
+
import time
|
|
4
|
+
import pty
|
|
5
|
+
import fcntl
|
|
6
|
+
import signal
|
|
7
|
+
import select
|
|
8
|
+
|
|
9
|
+
class VirtualTTYTool:
|
|
10
|
+
name = "virtual_tty"
|
|
11
|
+
description = "控制虚拟终端执行各种操作,如启动终端、输入命令、获取输出等。与execute_script不同,此工具会创建一个持久的虚拟终端会话,可以连续执行多个命令,并保持终端状态。适用于需要交互式操作的场景,如运行需要用户输入的交互式程序。"
|
|
12
|
+
labels = ['terminal', 'system', 'interactive']
|
|
13
|
+
parameters = {
|
|
14
|
+
"type": "object",
|
|
15
|
+
"properties": {
|
|
16
|
+
"action": {
|
|
17
|
+
"type": "string",
|
|
18
|
+
"description": "要执行的终端操作,可选值: 'launch', 'send_keys', 'output', 'close', 'get_screen'"
|
|
19
|
+
},
|
|
20
|
+
"keys": {
|
|
21
|
+
"type": "string",
|
|
22
|
+
"description": "要发送的按键序列(用于send_keys操作)。"
|
|
23
|
+
},
|
|
24
|
+
"add_enter": {
|
|
25
|
+
"type": "boolean",
|
|
26
|
+
"description": "是否在按键序列末尾添加回车符(\\n),默认为false"
|
|
27
|
+
},
|
|
28
|
+
"timeout": {
|
|
29
|
+
"type": "number",
|
|
30
|
+
"description": "等待输出的超时时间(秒),用于send_keys和output操作"
|
|
31
|
+
},
|
|
32
|
+
"tty_id": {
|
|
33
|
+
"type": "string",
|
|
34
|
+
"description": "虚拟终端的唯一标识符,用于区分多个TTY会话。如果未提供,默认为'default'"
|
|
35
|
+
}
|
|
36
|
+
},
|
|
37
|
+
"required": ["action"]
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
def execute(self, args: Dict[str, Any]) -> Dict[str, Any]:
|
|
41
|
+
"""执行终端操作
|
|
42
|
+
|
|
43
|
+
参数:
|
|
44
|
+
args: 包含操作参数的字典,包括agent属性
|
|
45
|
+
|
|
46
|
+
返回:
|
|
47
|
+
字典,包含以下内容:
|
|
48
|
+
- success: 布尔值,表示操作状态
|
|
49
|
+
- stdout: 成功消息或操作结果
|
|
50
|
+
- stderr: 错误消息或空字符串
|
|
51
|
+
"""
|
|
52
|
+
# 获取agent对象
|
|
53
|
+
agent = args.get("agent")
|
|
54
|
+
if agent is None:
|
|
55
|
+
return {
|
|
56
|
+
"success": False,
|
|
57
|
+
"stdout": "",
|
|
58
|
+
"stderr": "未提供agent对象"
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
# 获取TTY ID,默认为"default"
|
|
62
|
+
tty_id = args.get("tty_id", "default")
|
|
63
|
+
|
|
64
|
+
# 确保agent有tty_sessions字典
|
|
65
|
+
if not hasattr(agent, "tty_sessions"):
|
|
66
|
+
agent.tty_sessions = {}
|
|
67
|
+
|
|
68
|
+
# 如果指定的tty_id不存在,为其创建一个新的tty_data
|
|
69
|
+
if tty_id not in agent.tty_sessions:
|
|
70
|
+
agent.tty_sessions[tty_id] = {
|
|
71
|
+
"master_fd": None,
|
|
72
|
+
"pid": None,
|
|
73
|
+
"shell": "/bin/bash"
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
action = args.get("action", "").strip().lower()
|
|
77
|
+
|
|
78
|
+
# 验证操作类型
|
|
79
|
+
valid_actions = ['launch', 'send_keys', 'output', 'close', 'get_screen', 'list']
|
|
80
|
+
if action not in valid_actions:
|
|
81
|
+
return {
|
|
82
|
+
"success": False,
|
|
83
|
+
"stdout": "",
|
|
84
|
+
"stderr": f"不支持的操作: {action}。有效操作: {', '.join(valid_actions)}"
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
try:
|
|
88
|
+
if action == "launch":
|
|
89
|
+
print(f"🚀 正在启动虚拟终端 [{tty_id}]...")
|
|
90
|
+
result = self._launch_tty(agent, tty_id)
|
|
91
|
+
if result["success"]:
|
|
92
|
+
print(f"✅ 启动虚拟终端 [{tty_id}] 成功")
|
|
93
|
+
else:
|
|
94
|
+
print(f"❌ 启动虚拟终端 [{tty_id}] 失败")
|
|
95
|
+
return result
|
|
96
|
+
elif action == "send_keys":
|
|
97
|
+
keys = args.get("keys", "").strip()
|
|
98
|
+
add_enter = args.get("add_enter", False)
|
|
99
|
+
timeout = args.get("timeout", 5.0) # 默认5秒超时
|
|
100
|
+
print(f"⌨️ 正在向终端 [{tty_id}] 发送按键序列: {keys}...")
|
|
101
|
+
result = self._input_command(agent, tty_id, keys, timeout, add_enter)
|
|
102
|
+
if result["success"]:
|
|
103
|
+
print(f"✅ 发送按键序列到终端 [{tty_id}] 成功")
|
|
104
|
+
else:
|
|
105
|
+
print(f"❌ 发送按键序列到终端 [{tty_id}] 失败")
|
|
106
|
+
return result
|
|
107
|
+
elif action == "output":
|
|
108
|
+
timeout = args.get("timeout", 5.0) # 默认5秒超时
|
|
109
|
+
print(f"📥 正在获取终端 [{tty_id}] 输出...")
|
|
110
|
+
result = self._get_output(agent, tty_id, timeout)
|
|
111
|
+
if result["success"]:
|
|
112
|
+
print(f"✅ 获取终端 [{tty_id}] 输出成功")
|
|
113
|
+
else:
|
|
114
|
+
print(f"❌ 获取终端 [{tty_id}] 输出失败")
|
|
115
|
+
return result
|
|
116
|
+
elif action == "close":
|
|
117
|
+
print(f"🔒 正在关闭虚拟终端 [{tty_id}]...")
|
|
118
|
+
result = self._close_tty(agent, tty_id)
|
|
119
|
+
if result["success"]:
|
|
120
|
+
print(f"✅ 关闭虚拟终端 [{tty_id}] 成功")
|
|
121
|
+
else:
|
|
122
|
+
print(f"❌ 关闭虚拟终端 [{tty_id}] 失败")
|
|
123
|
+
return result
|
|
124
|
+
elif action == "get_screen":
|
|
125
|
+
print(f"🖥️ 正在获取终端 [{tty_id}] 屏幕内容...")
|
|
126
|
+
result = self._get_screen(agent, tty_id)
|
|
127
|
+
if result["success"]:
|
|
128
|
+
print(f"✅ 获取终端 [{tty_id}] 屏幕内容成功")
|
|
129
|
+
else:
|
|
130
|
+
print(f"❌ 获取终端 [{tty_id}] 屏幕内容失败")
|
|
131
|
+
return result
|
|
132
|
+
elif action == "list":
|
|
133
|
+
print("📋 正在获取所有虚拟终端列表...")
|
|
134
|
+
result = self._list_ttys(agent)
|
|
135
|
+
if result["success"]:
|
|
136
|
+
print("✅ 获取虚拟终端列表成功")
|
|
137
|
+
else:
|
|
138
|
+
print("❌ 获取虚拟终端列表失败")
|
|
139
|
+
return result
|
|
140
|
+
return {
|
|
141
|
+
"success": False,
|
|
142
|
+
"stdout": "",
|
|
143
|
+
"stderr": "不支持的操作"
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
except Exception as e:
|
|
147
|
+
return {
|
|
148
|
+
"success": False,
|
|
149
|
+
"stdout": "",
|
|
150
|
+
"stderr": f"执行终端操作出错: {str(e)}"
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
def _launch_tty(self, agent: Any, tty_id: str) -> Dict[str, Any]:
|
|
154
|
+
"""启动虚拟终端"""
|
|
155
|
+
try:
|
|
156
|
+
# 如果该ID的终端已经启动,先关闭它
|
|
157
|
+
if agent.tty_sessions[tty_id]["master_fd"] is not None:
|
|
158
|
+
self._close_tty(agent, tty_id)
|
|
159
|
+
|
|
160
|
+
# 创建伪终端
|
|
161
|
+
pid, master_fd = pty.fork()
|
|
162
|
+
|
|
163
|
+
if pid == 0: # 子进程
|
|
164
|
+
# 执行shell
|
|
165
|
+
os.execvp(agent.tty_sessions[tty_id]["shell"], [agent.tty_sessions[tty_id]["shell"]])
|
|
166
|
+
else: # 父进程
|
|
167
|
+
# 设置非阻塞模式
|
|
168
|
+
fcntl.fcntl(master_fd, fcntl.F_SETFL, os.O_NONBLOCK)
|
|
169
|
+
|
|
170
|
+
# 保存终端状态
|
|
171
|
+
agent.tty_sessions[tty_id]["master_fd"] = master_fd
|
|
172
|
+
agent.tty_sessions[tty_id]["pid"] = pid
|
|
173
|
+
|
|
174
|
+
# 读取初始输出
|
|
175
|
+
output = ""
|
|
176
|
+
start_time = time.time()
|
|
177
|
+
while time.time() - start_time < 2.0: # 最多等待2秒
|
|
178
|
+
try:
|
|
179
|
+
r, _, _ = select.select([master_fd], [], [], 0.1)
|
|
180
|
+
if r:
|
|
181
|
+
data = os.read(master_fd, 1024)
|
|
182
|
+
if data:
|
|
183
|
+
output += data.decode()
|
|
184
|
+
except BlockingIOError:
|
|
185
|
+
continue
|
|
186
|
+
|
|
187
|
+
if output:
|
|
188
|
+
print(f"📤 终端 [{tty_id}]: {output}")
|
|
189
|
+
|
|
190
|
+
return {
|
|
191
|
+
"success": True,
|
|
192
|
+
"stdout": output,
|
|
193
|
+
"stderr": ""
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
except Exception as e:
|
|
197
|
+
return {
|
|
198
|
+
"success": False,
|
|
199
|
+
"stdout": "",
|
|
200
|
+
"stderr": f"启动虚拟终端 [{tty_id}] 失败: {str(e)}"
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
def _input_command(self, agent: Any, tty_id: str, command: str, timeout: float, add_enter: bool = False) -> Dict[str, Any]:
|
|
204
|
+
"""输入命令并等待输出"""
|
|
205
|
+
if agent.tty_sessions[tty_id]["master_fd"] is None:
|
|
206
|
+
return {
|
|
207
|
+
"success": False,
|
|
208
|
+
"stdout": "",
|
|
209
|
+
"stderr": f"虚拟终端 [{tty_id}] 未启动"
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
try:
|
|
213
|
+
# 根据add_enter参数决定是否添加换行符
|
|
214
|
+
if add_enter:
|
|
215
|
+
command = command + "\n"
|
|
216
|
+
|
|
217
|
+
# 发送按键序列
|
|
218
|
+
os.write(agent.tty_sessions[tty_id]["master_fd"], command.encode())
|
|
219
|
+
|
|
220
|
+
# 等待输出
|
|
221
|
+
output = ""
|
|
222
|
+
start_time = time.time()
|
|
223
|
+
|
|
224
|
+
while time.time() - start_time < timeout:
|
|
225
|
+
try:
|
|
226
|
+
# 使用select等待数据可读
|
|
227
|
+
r, _, _ = select.select([agent.tty_sessions[tty_id]["master_fd"]], [], [], 0.1)
|
|
228
|
+
if r:
|
|
229
|
+
data = os.read(agent.tty_sessions[tty_id]["master_fd"], 1024)
|
|
230
|
+
if data:
|
|
231
|
+
output += data.decode()
|
|
232
|
+
except BlockingIOError:
|
|
233
|
+
continue
|
|
234
|
+
print(f"📤 终端 [{tty_id}]: {output}")
|
|
235
|
+
return {
|
|
236
|
+
"success": True,
|
|
237
|
+
"stdout": output,
|
|
238
|
+
"stderr": ""
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
except Exception as e:
|
|
242
|
+
return {
|
|
243
|
+
"success": False,
|
|
244
|
+
"stdout": "",
|
|
245
|
+
"stderr": f"在终端 [{tty_id}] 执行命令失败: {str(e)}"
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
def _get_output(self, agent: Any, tty_id: str, timeout: float = 5.0) -> Dict[str, Any]:
|
|
249
|
+
"""获取终端输出"""
|
|
250
|
+
if agent.tty_sessions[tty_id]["master_fd"] is None:
|
|
251
|
+
return {
|
|
252
|
+
"success": False,
|
|
253
|
+
"stdout": "",
|
|
254
|
+
"stderr": f"虚拟终端 [{tty_id}] 未启动"
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
try:
|
|
258
|
+
output = ""
|
|
259
|
+
start_time = time.time()
|
|
260
|
+
|
|
261
|
+
while time.time() - start_time < timeout:
|
|
262
|
+
# 使用select等待数据可读
|
|
263
|
+
r, _, _ = select.select([agent.tty_sessions[tty_id]["master_fd"]], [], [], 0.1)
|
|
264
|
+
if r:
|
|
265
|
+
while True:
|
|
266
|
+
try:
|
|
267
|
+
data = os.read(agent.tty_sessions[tty_id]["master_fd"], 1024)
|
|
268
|
+
if data:
|
|
269
|
+
output += data.decode()
|
|
270
|
+
else:
|
|
271
|
+
break
|
|
272
|
+
except BlockingIOError:
|
|
273
|
+
break
|
|
274
|
+
print(f"📤 终端 [{tty_id}]: {output}")
|
|
275
|
+
|
|
276
|
+
return {
|
|
277
|
+
"success": True,
|
|
278
|
+
"stdout": output,
|
|
279
|
+
"stderr": ""
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
except Exception as e:
|
|
283
|
+
return {
|
|
284
|
+
"success": False,
|
|
285
|
+
"stdout": "",
|
|
286
|
+
"stderr": f"获取终端 [{tty_id}] 输出失败: {str(e)}"
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
def _close_tty(self, agent: Any, tty_id: str) -> Dict[str, Any]:
|
|
290
|
+
"""关闭虚拟终端"""
|
|
291
|
+
if agent.tty_sessions[tty_id]["master_fd"] is None:
|
|
292
|
+
return {
|
|
293
|
+
"success": True,
|
|
294
|
+
"stdout": f"没有正在运行的虚拟终端 [{tty_id}]",
|
|
295
|
+
"stderr": ""
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
try:
|
|
299
|
+
# 关闭主文件描述符
|
|
300
|
+
os.close(agent.tty_sessions[tty_id]["master_fd"])
|
|
301
|
+
|
|
302
|
+
# 终止子进程
|
|
303
|
+
if agent.tty_sessions[tty_id]["pid"]:
|
|
304
|
+
os.kill(agent.tty_sessions[tty_id]["pid"], signal.SIGTERM)
|
|
305
|
+
|
|
306
|
+
# 重置终端数据
|
|
307
|
+
agent.tty_sessions[tty_id] = {
|
|
308
|
+
"master_fd": None,
|
|
309
|
+
"pid": None,
|
|
310
|
+
"shell": "/bin/bash"
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
return {
|
|
314
|
+
"success": True,
|
|
315
|
+
"stdout": f"虚拟终端 [{tty_id}] 已关闭",
|
|
316
|
+
"stderr": ""
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
except Exception as e:
|
|
320
|
+
return {
|
|
321
|
+
"success": False,
|
|
322
|
+
"stdout": "",
|
|
323
|
+
"stderr": f"关闭虚拟终端 [{tty_id}] 失败: {str(e)}"
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
def _get_screen(self, agent: Any, tty_id: str) -> Dict[str, Any]:
|
|
327
|
+
"""获取当前终端屏幕内容"""
|
|
328
|
+
if agent.tty_sessions[tty_id]["master_fd"] is None:
|
|
329
|
+
return {
|
|
330
|
+
"success": False,
|
|
331
|
+
"stdout": "",
|
|
332
|
+
"stderr": f"虚拟终端 [{tty_id}] 未启动"
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
try:
|
|
336
|
+
# 发送控制序列获取屏幕内容
|
|
337
|
+
os.write(agent.tty_sessions[tty_id]["master_fd"], b"\x1b[2J\x1b[H\x1b[999;999H\x1b[6n")
|
|
338
|
+
|
|
339
|
+
# 读取响应
|
|
340
|
+
output = ""
|
|
341
|
+
start_time = time.time()
|
|
342
|
+
while time.time() - start_time < 2.0: # 最多等待2秒
|
|
343
|
+
try:
|
|
344
|
+
r, _, _ = select.select([agent.tty_sessions[tty_id]["master_fd"]], [], [], 0.1)
|
|
345
|
+
if r:
|
|
346
|
+
data = os.read(agent.tty_sessions[tty_id]["master_fd"], 1024)
|
|
347
|
+
if data:
|
|
348
|
+
output += data.decode()
|
|
349
|
+
except BlockingIOError:
|
|
350
|
+
continue
|
|
351
|
+
|
|
352
|
+
# 清理控制字符
|
|
353
|
+
output = output.replace("\x1b[2J", "").replace("\x1b[H", "").replace("\x1b[999;999H", "").replace("\x1b[6n", "")
|
|
354
|
+
|
|
355
|
+
return {
|
|
356
|
+
"success": True,
|
|
357
|
+
"stdout": output.strip(),
|
|
358
|
+
"stderr": ""
|
|
359
|
+
}
|
|
360
|
+
|
|
361
|
+
except Exception as e:
|
|
362
|
+
return {
|
|
363
|
+
"success": False,
|
|
364
|
+
"stdout": "",
|
|
365
|
+
"stderr": f"获取终端 [{tty_id}] 屏幕内容失败: {str(e)}"
|
|
366
|
+
}
|
|
367
|
+
|
|
368
|
+
def _list_ttys(self, agent: Any) -> Dict[str, Any]:
|
|
369
|
+
"""列出所有虚拟终端"""
|
|
370
|
+
try:
|
|
371
|
+
active_ttys = []
|
|
372
|
+
|
|
373
|
+
for tty_id, tty_data in agent.tty_sessions.items():
|
|
374
|
+
status = "活动" if tty_data["master_fd"] is not None else "关闭"
|
|
375
|
+
active_ttys.append({
|
|
376
|
+
"id": tty_id,
|
|
377
|
+
"status": status,
|
|
378
|
+
"pid": tty_data["pid"] if tty_data["pid"] else None,
|
|
379
|
+
"shell": tty_data["shell"]
|
|
380
|
+
})
|
|
381
|
+
|
|
382
|
+
# 格式化输出
|
|
383
|
+
output = "虚拟终端列表:\n"
|
|
384
|
+
for tty in active_ttys:
|
|
385
|
+
output += f"ID: {tty['id']}, 状态: {tty['status']}, PID: {tty['pid']}, Shell: {tty['shell']}\n"
|
|
386
|
+
|
|
387
|
+
return {
|
|
388
|
+
"success": True,
|
|
389
|
+
"stdout": output,
|
|
390
|
+
"stderr": "",
|
|
391
|
+
"tty_list": active_ttys # 返回原始数据,方便程序处理
|
|
392
|
+
}
|
|
393
|
+
|
|
394
|
+
except Exception as e:
|
|
395
|
+
return {
|
|
396
|
+
"success": False,
|
|
397
|
+
"stdout": "",
|
|
398
|
+
"stderr": f"获取虚拟终端列表失败: {str(e)}"
|
|
399
|
+
}
|
jarvis/jarvis_utils/config.py
CHANGED
|
@@ -16,7 +16,16 @@ def get_max_token_count() -> int:
|
|
|
16
16
|
返回:
|
|
17
17
|
int: 模型能处理的最大token数量。
|
|
18
18
|
"""
|
|
19
|
-
return int(os.getenv('JARVIS_MAX_TOKEN_COUNT', '
|
|
19
|
+
return int(os.getenv('JARVIS_MAX_TOKEN_COUNT', '102400000'))
|
|
20
|
+
|
|
21
|
+
def get_max_input_token_count() -> int:
|
|
22
|
+
"""
|
|
23
|
+
获取模型允许的最大输入token数量。
|
|
24
|
+
|
|
25
|
+
返回:
|
|
26
|
+
int: 模型能处理的最大输入token数量。
|
|
27
|
+
"""
|
|
28
|
+
return int(os.getenv('JARVIS_MAX_INPUT_TOKEN_COUNT', '32000'))
|
|
20
29
|
|
|
21
30
|
def get_thread_count() -> int:
|
|
22
31
|
"""
|
|
@@ -111,7 +120,7 @@ def is_confirm_before_apply_patch() -> bool:
|
|
|
111
120
|
返回:
|
|
112
121
|
bool: 如果需要确认则返回True,默认为False
|
|
113
122
|
"""
|
|
114
|
-
return os.getenv('JARVIS_CONFIRM_BEFORE_APPLY_PATCH', '
|
|
123
|
+
return os.getenv('JARVIS_CONFIRM_BEFORE_APPLY_PATCH', 'true') == 'true'
|
|
115
124
|
|
|
116
125
|
def get_rag_ignored_paths() -> list:
|
|
117
126
|
"""
|
|
@@ -155,7 +164,6 @@ def get_rag_ignored_paths() -> list:
|
|
|
155
164
|
'*.png',
|
|
156
165
|
'*.gif',
|
|
157
166
|
'*.tiff',
|
|
158
|
-
'*.pdf',
|
|
159
167
|
'*.zip',
|
|
160
168
|
'*.tar',
|
|
161
169
|
'*.tar.gz',
|
|
@@ -176,3 +184,21 @@ def get_rag_ignored_paths() -> list:
|
|
|
176
184
|
pass
|
|
177
185
|
|
|
178
186
|
return default_ignored
|
|
187
|
+
|
|
188
|
+
def get_browser_headless() -> bool:
|
|
189
|
+
"""
|
|
190
|
+
获取浏览器是否在无头模式下运行。
|
|
191
|
+
|
|
192
|
+
返回:
|
|
193
|
+
bool: 如果浏览器在无头模式下运行则返回True,否则返回False
|
|
194
|
+
"""
|
|
195
|
+
return os.getenv('JARVIS_BROWSER_HEADLESS', 'true') == 'true'
|
|
196
|
+
|
|
197
|
+
def get_max_tool_call_count() -> int:
|
|
198
|
+
"""
|
|
199
|
+
获取最大工具调用次数。
|
|
200
|
+
|
|
201
|
+
返回:
|
|
202
|
+
int: 最大连续工具调用次数,默认为20
|
|
203
|
+
"""
|
|
204
|
+
return int(os.getenv('JARVIS_MAX_TOOL_CALL_COUNT', '20'))
|