janito 1.9.0__py3-none-any.whl → 1.10.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.
- janito/__init__.py +1 -1
- janito/agent/api_exceptions.py +4 -0
- janito/agent/config.py +1 -1
- janito/agent/config_defaults.py +2 -26
- janito/agent/conversation.py +163 -122
- janito/agent/conversation_api.py +149 -159
- janito/agent/{conversation_history.py → llm_conversation_history.py} +18 -1
- janito/agent/openai_client.py +38 -23
- janito/agent/openai_schema_generator.py +162 -129
- janito/agent/platform_discovery.py +134 -77
- janito/agent/profile_manager.py +5 -5
- janito/agent/rich_message_handler.py +80 -31
- janito/agent/templates/profiles/system_prompt_template_base.txt.j2 +5 -4
- janito/agent/test_openai_schema_generator.py +93 -0
- janito/agent/tool_base.py +7 -2
- janito/agent/tool_executor.py +54 -49
- janito/agent/tool_registry.py +5 -2
- janito/agent/tool_use_tracker.py +26 -5
- janito/agent/tools/__init__.py +6 -3
- janito/agent/tools/create_directory.py +3 -1
- janito/agent/tools/create_file.py +7 -1
- janito/agent/tools/fetch_url.py +40 -3
- janito/agent/tools/find_files.py +3 -1
- janito/agent/tools/get_file_outline/core.py +6 -7
- janito/agent/tools/get_file_outline/search_outline.py +3 -1
- janito/agent/tools/get_lines.py +7 -2
- janito/agent/tools/move_file.py +3 -1
- janito/agent/tools/present_choices.py +3 -1
- janito/agent/tools/python_command_runner.py +150 -0
- janito/agent/tools/python_file_runner.py +148 -0
- janito/agent/tools/python_stdin_runner.py +154 -0
- janito/agent/tools/remove_directory.py +3 -1
- janito/agent/tools/remove_file.py +5 -1
- janito/agent/tools/replace_file.py +12 -2
- janito/agent/tools/replace_text_in_file.py +4 -2
- janito/agent/tools/run_bash_command.py +30 -69
- janito/agent/tools/run_powershell_command.py +134 -105
- janito/agent/tools/search_text.py +172 -122
- janito/agent/tools/validate_file_syntax/core.py +3 -1
- janito/agent/tools_utils/action_type.py +7 -0
- janito/agent/tools_utils/dir_walk_utils.py +3 -2
- janito/agent/tools_utils/formatting.py +47 -21
- janito/agent/tools_utils/gitignore_utils.py +66 -40
- janito/agent/tools_utils/test_gitignore_utils.py +46 -0
- janito/cli/_print_config.py +63 -61
- janito/cli/arg_parser.py +13 -12
- janito/cli/cli_main.py +137 -147
- janito/cli/main.py +152 -174
- janito/cli/one_shot.py +40 -26
- janito/i18n/__init__.py +1 -1
- janito/rich_utils.py +46 -8
- janito/shell/commands/__init__.py +2 -4
- janito/shell/commands/conversation_restart.py +3 -1
- janito/shell/commands/edit.py +3 -0
- janito/shell/commands/history_view.py +3 -3
- janito/shell/commands/lang.py +3 -0
- janito/shell/commands/livelogs.py +5 -3
- janito/shell/commands/prompt.py +6 -0
- janito/shell/commands/session.py +3 -0
- janito/shell/commands/session_control.py +3 -0
- janito/shell/commands/termweb_log.py +8 -0
- janito/shell/commands/tools.py +3 -0
- janito/shell/commands/track.py +36 -0
- janito/shell/commands/utility.py +13 -18
- janito/shell/commands/verbose.py +3 -4
- janito/shell/input_history.py +62 -0
- janito/shell/main.py +117 -181
- janito/shell/session/manager.py +0 -21
- janito/shell/ui/interactive.py +0 -2
- janito/termweb/static/editor.css +0 -4
- janito/tests/test_rich_utils.py +44 -0
- janito/web/app.py +0 -75
- {janito-1.9.0.dist-info → janito-1.10.0.dist-info}/METADATA +61 -42
- {janito-1.9.0.dist-info → janito-1.10.0.dist-info}/RECORD +78 -71
- {janito-1.9.0.dist-info → janito-1.10.0.dist-info}/WHEEL +1 -1
- janito/agent/providers.py +0 -77
- janito/agent/tools/run_python_command.py +0 -161
- janito/shell/commands/sum.py +0 -49
- {janito-1.9.0.dist-info → janito-1.10.0.dist-info}/entry_points.txt +0 -0
- {janito-1.9.0.dist-info → janito-1.10.0.dist-info}/licenses/LICENSE +0 -0
- {janito-1.9.0.dist-info → janito-1.10.0.dist-info}/top_level.txt +0 -0
@@ -1,4 +1,5 @@
|
|
1
1
|
from janito.agent.tool_base import ToolBase
|
2
|
+
from janito.agent.tools_utils.action_type import ActionType
|
2
3
|
from janito.agent.tool_registry import register_tool
|
3
4
|
from janito.i18n import tr
|
4
5
|
|
@@ -32,7 +33,7 @@ class ReplaceTextInFileTool(ToolBase):
|
|
32
33
|
from janito.agent.tools_utils.utils import display_path
|
33
34
|
|
34
35
|
disp_path = display_path(file_path)
|
35
|
-
action = "(all)" if replace_all else "
|
36
|
+
action = "(all)" if replace_all else ""
|
36
37
|
search_lines = len(search_text.splitlines())
|
37
38
|
replace_lines = len(replacement_text.splitlines())
|
38
39
|
if replace_lines == 0:
|
@@ -67,7 +68,8 @@ class ReplaceTextInFileTool(ToolBase):
|
|
67
68
|
action=action,
|
68
69
|
)
|
69
70
|
self.report_info(
|
70
|
-
|
71
|
+
ActionType.WRITE,
|
72
|
+
info_msg + (" ..." if not info_msg.rstrip().endswith("...") else ""),
|
71
73
|
)
|
72
74
|
try:
|
73
75
|
with open(file_path, "r", encoding="utf-8", errors="replace") as f:
|
@@ -1,4 +1,5 @@
|
|
1
1
|
from janito.agent.tool_base import ToolBase
|
2
|
+
from janito.agent.tools_utils.action_type import ActionType
|
2
3
|
from janito.agent.tool_registry import register_tool
|
3
4
|
from janito.i18n import tr
|
4
5
|
import subprocess
|
@@ -16,7 +17,7 @@ class RunBashCommandTool(ToolBase):
|
|
16
17
|
command (str): The bash command to execute.
|
17
18
|
timeout (int, optional): Timeout in seconds for the command. Defaults to 60.
|
18
19
|
require_confirmation (bool, optional): If True, require user confirmation before running. Defaults to False.
|
19
|
-
|
20
|
+
requires_user_input (bool, optional): If True, warns that the command may require user input and might hang. Defaults to False. Non-interactive commands are preferred for automation and reliability.
|
20
21
|
Returns:
|
21
22
|
str: File paths and line counts for stdout and stderr.
|
22
23
|
"""
|
@@ -26,16 +27,19 @@ class RunBashCommandTool(ToolBase):
|
|
26
27
|
command: str,
|
27
28
|
timeout: int = 60,
|
28
29
|
require_confirmation: bool = False,
|
29
|
-
|
30
|
+
requires_user_input: bool = False,
|
30
31
|
) -> str:
|
31
32
|
if not command.strip():
|
32
|
-
self.report_warning(tr("
|
33
|
+
self.report_warning(tr("\u2139\ufe0f Empty command provided."))
|
33
34
|
return tr("Warning: Empty command provided. Operation skipped.")
|
34
|
-
self.report_info(
|
35
|
-
|
35
|
+
self.report_info(
|
36
|
+
ActionType.EXECUTE,
|
37
|
+
tr("🖥️ Running bash command: {command} ...\n", command=command),
|
38
|
+
)
|
39
|
+
if requires_user_input:
|
36
40
|
self.report_warning(
|
37
41
|
tr(
|
38
|
-
"
|
42
|
+
"\u26a0\ufe0f Warning: This command might be interactive, require user input, and might hang."
|
39
43
|
)
|
40
44
|
)
|
41
45
|
sys.stdout.flush()
|
@@ -61,88 +65,45 @@ class RunBashCommandTool(ToolBase):
|
|
61
65
|
bufsize=1,
|
62
66
|
env=env,
|
63
67
|
)
|
64
|
-
stdout_lines = 0
|
65
|
-
stderr_lines = 0
|
66
|
-
stdout_content = []
|
67
|
-
stderr_content = []
|
68
|
-
max_lines = 100
|
69
|
-
import threading
|
70
|
-
|
71
|
-
def stream_reader(
|
72
|
-
stream, file_handle, report_func, content_list, line_counter
|
73
|
-
):
|
74
|
-
for line in iter(stream.readline, ""):
|
75
|
-
file_handle.write(line)
|
76
|
-
file_handle.flush()
|
77
|
-
report_func(line)
|
78
|
-
content_list.append(line)
|
79
|
-
line_counter[0] += 1
|
80
|
-
stream.close()
|
81
|
-
|
82
|
-
stdout_counter = [0]
|
83
|
-
stderr_counter = [0]
|
84
|
-
stdout_thread = threading.Thread(
|
85
|
-
target=stream_reader,
|
86
|
-
args=(
|
87
|
-
process.stdout,
|
88
|
-
stdout_file,
|
89
|
-
self.report_stdout,
|
90
|
-
stdout_content,
|
91
|
-
stdout_counter,
|
92
|
-
),
|
93
|
-
)
|
94
|
-
stderr_thread = threading.Thread(
|
95
|
-
target=stream_reader,
|
96
|
-
args=(
|
97
|
-
process.stderr,
|
98
|
-
stderr_file,
|
99
|
-
self.report_stderr,
|
100
|
-
stderr_content,
|
101
|
-
stderr_counter,
|
102
|
-
),
|
103
|
-
)
|
104
|
-
stdout_thread.start()
|
105
|
-
stderr_thread.start()
|
106
68
|
try:
|
107
|
-
process.
|
69
|
+
stdout_content, stderr_content = process.communicate(
|
70
|
+
timeout=timeout
|
71
|
+
)
|
108
72
|
except subprocess.TimeoutExpired:
|
109
73
|
process.kill()
|
110
74
|
self.report_error(
|
111
|
-
tr(
|
75
|
+
tr(
|
76
|
+
" \u274c Timed out after {timeout} seconds.",
|
77
|
+
timeout=timeout,
|
78
|
+
)
|
112
79
|
)
|
113
80
|
return tr(
|
114
81
|
"Command timed out after {timeout} seconds.", timeout=timeout
|
115
82
|
)
|
116
|
-
stdout_thread.join()
|
117
|
-
stderr_thread.join()
|
118
|
-
stdout_lines = stdout_counter[0]
|
119
|
-
stderr_lines = stderr_counter[0]
|
120
83
|
self.report_success(
|
121
|
-
tr(
|
84
|
+
tr(
|
85
|
+
" \u2705 return code {return_code}",
|
86
|
+
return_code=process.returncode,
|
87
|
+
)
|
122
88
|
)
|
123
89
|
warning_msg = ""
|
124
|
-
if
|
90
|
+
if requires_user_input:
|
125
91
|
warning_msg = tr(
|
126
|
-
"
|
92
|
+
"\u26a0\ufe0f Warning: This command might be interactive, require user input, and might hang.\n"
|
127
93
|
)
|
94
|
+
max_lines = 100
|
95
|
+
stdout_lines = stdout_content.count("\n")
|
96
|
+
stderr_lines = stderr_content.count("\n")
|
128
97
|
if stdout_lines <= max_lines and stderr_lines <= max_lines:
|
129
|
-
with open(
|
130
|
-
stdout_file.name, "r", encoding="utf-8", errors="replace"
|
131
|
-
) as out_f:
|
132
|
-
stdout_content_str = out_f.read()
|
133
|
-
with open(
|
134
|
-
stderr_file.name, "r", encoding="utf-8", errors="replace"
|
135
|
-
) as err_f:
|
136
|
-
stderr_content_str = err_f.read()
|
137
98
|
result = warning_msg + tr(
|
138
99
|
"Return code: {return_code}\n--- STDOUT ---\n{stdout_content}",
|
139
100
|
return_code=process.returncode,
|
140
|
-
stdout_content=
|
101
|
+
stdout_content=stdout_content,
|
141
102
|
)
|
142
|
-
if
|
103
|
+
if stderr_content.strip():
|
143
104
|
result += tr(
|
144
105
|
"\n--- STDERR ---\n{stderr_content}",
|
145
|
-
stderr_content=
|
106
|
+
stderr_content=stderr_content,
|
146
107
|
)
|
147
108
|
return result
|
148
109
|
else:
|
@@ -163,5 +124,5 @@ class RunBashCommandTool(ToolBase):
|
|
163
124
|
)
|
164
125
|
return result
|
165
126
|
except Exception as e:
|
166
|
-
self.report_error(tr("
|
127
|
+
self.report_error(tr(" \u274c Error: {error}", error=e))
|
167
128
|
return tr("Error running command: {error}", error=e)
|
@@ -1,4 +1,5 @@
|
|
1
1
|
from janito.agent.tool_base import ToolBase
|
2
|
+
from janito.agent.tools_utils.action_type import ActionType
|
2
3
|
from janito.agent.tool_registry import register_tool
|
3
4
|
from janito.i18n import tr
|
4
5
|
import subprocess
|
@@ -18,30 +19,16 @@ class RunPowerShellCommandTool(ToolBase):
|
|
18
19
|
command (str): The PowerShell command to execute. This string is passed directly to PowerShell using the --Command argument (not as a script file).
|
19
20
|
timeout (int, optional): Timeout in seconds for the command. Defaults to 60.
|
20
21
|
require_confirmation (bool, optional): If True, require user confirmation before running. Defaults to False.
|
21
|
-
|
22
|
+
requires_user_input (bool, optional): If True, warns that the command may require user input and might hang. Defaults to False. Non-interactive commands are preferred for automation and reliability.
|
22
23
|
Returns:
|
23
24
|
str: Output and status message, or file paths/line counts if output is large.
|
24
25
|
"""
|
25
26
|
|
26
|
-
def
|
27
|
-
|
28
|
-
command: str,
|
29
|
-
timeout: int = 60,
|
30
|
-
require_confirmation: bool = False,
|
31
|
-
interactive: bool = False,
|
32
|
-
) -> str:
|
33
|
-
if not command.strip():
|
34
|
-
self.report_warning(tr("ℹ️ Empty command provided."))
|
35
|
-
return tr("Warning: Empty command provided. Operation skipped.")
|
36
|
-
encoding_prefix = "$OutputEncoding = [Console]::OutputEncoding = [System.Text.Encoding]::UTF8; "
|
37
|
-
command_with_encoding = encoding_prefix + command
|
38
|
-
self.report_info(
|
39
|
-
tr("🖥️ Running PowerShell command: {command} ...\n", command=command)
|
40
|
-
)
|
41
|
-
if interactive:
|
27
|
+
def _confirm_and_warn(self, command, require_confirmation, requires_user_input):
|
28
|
+
if requires_user_input:
|
42
29
|
self.report_warning(
|
43
30
|
tr(
|
44
|
-
"
|
31
|
+
"\u26a0\ufe0f Warning: This command might be interactive, require user input, and might hang."
|
45
32
|
)
|
46
33
|
)
|
47
34
|
if require_confirmation:
|
@@ -52,11 +39,109 @@ class RunPowerShellCommandTool(ToolBase):
|
|
52
39
|
)
|
53
40
|
)
|
54
41
|
if not confirmed:
|
55
|
-
self.report_warning(tr("
|
56
|
-
return
|
57
|
-
|
42
|
+
self.report_warning(tr("\u26a0\ufe0f Execution cancelled by user."))
|
43
|
+
return False
|
44
|
+
return True
|
58
45
|
|
59
|
-
|
46
|
+
def _launch_process(self, shell_exe, command_with_encoding):
|
47
|
+
return subprocess.Popen(
|
48
|
+
[
|
49
|
+
shell_exe,
|
50
|
+
"-NoProfile",
|
51
|
+
"-ExecutionPolicy",
|
52
|
+
"Bypass",
|
53
|
+
"-Command",
|
54
|
+
command_with_encoding,
|
55
|
+
],
|
56
|
+
stdout=subprocess.PIPE,
|
57
|
+
stderr=subprocess.PIPE,
|
58
|
+
text=True,
|
59
|
+
bufsize=1,
|
60
|
+
universal_newlines=True,
|
61
|
+
encoding="utf-8",
|
62
|
+
)
|
63
|
+
|
64
|
+
def _stream_output(self, stream, file_obj, report_func, count_func, counter):
|
65
|
+
for line in stream:
|
66
|
+
file_obj.write(line)
|
67
|
+
file_obj.flush()
|
68
|
+
report_func(line)
|
69
|
+
if count_func == "stdout":
|
70
|
+
counter["stdout"] += 1
|
71
|
+
else:
|
72
|
+
counter["stderr"] += 1
|
73
|
+
|
74
|
+
def _format_result(
|
75
|
+
self, requires_user_input, return_code, stdout_file, stderr_file, max_lines=100
|
76
|
+
):
|
77
|
+
warning_msg = ""
|
78
|
+
if requires_user_input:
|
79
|
+
warning_msg = tr(
|
80
|
+
"\u26a0\ufe0f Warning: This command might be interactive, require user input, and might hang.\n"
|
81
|
+
)
|
82
|
+
with open(stdout_file.name, "r", encoding="utf-8", errors="replace") as out_f:
|
83
|
+
stdout_content = out_f.read()
|
84
|
+
with open(stderr_file.name, "r", encoding="utf-8", errors="replace") as err_f:
|
85
|
+
stderr_content = err_f.read()
|
86
|
+
stdout_lines = stdout_content.count("\n")
|
87
|
+
stderr_lines = stderr_content.count("\n")
|
88
|
+
if stdout_lines <= max_lines and stderr_lines <= max_lines:
|
89
|
+
result = warning_msg + tr(
|
90
|
+
"Return code: {return_code}\n--- STDOUT ---\n{stdout_content}",
|
91
|
+
return_code=return_code,
|
92
|
+
stdout_content=stdout_content,
|
93
|
+
)
|
94
|
+
if stderr_content.strip():
|
95
|
+
result += tr(
|
96
|
+
"\n--- STDERR ---\n{stderr_content}",
|
97
|
+
stderr_content=stderr_content,
|
98
|
+
)
|
99
|
+
return result
|
100
|
+
else:
|
101
|
+
result = warning_msg + tr(
|
102
|
+
"stdout_file: {stdout_file} (lines: {stdout_lines})\n",
|
103
|
+
stdout_file=stdout_file.name,
|
104
|
+
stdout_lines=stdout_lines,
|
105
|
+
)
|
106
|
+
if stderr_lines > 0 and stderr_content.strip():
|
107
|
+
result += tr(
|
108
|
+
"stderr_file: {stderr_file} (lines: {stderr_lines})\n",
|
109
|
+
stderr_file=stderr_file.name,
|
110
|
+
stderr_lines=stderr_lines,
|
111
|
+
)
|
112
|
+
result += tr(
|
113
|
+
"returncode: {return_code}\nUse the get_lines tool to inspect the contents of these files when needed.",
|
114
|
+
return_code=return_code,
|
115
|
+
)
|
116
|
+
return result
|
117
|
+
|
118
|
+
def run(
|
119
|
+
self,
|
120
|
+
command: str,
|
121
|
+
timeout: int = 60,
|
122
|
+
require_confirmation: bool = False,
|
123
|
+
requires_user_input: bool = False,
|
124
|
+
) -> str:
|
125
|
+
if not command.strip():
|
126
|
+
self.report_warning(tr("\u2139\ufe0f Empty command provided."))
|
127
|
+
return tr("Warning: Empty command provided. Operation skipped.")
|
128
|
+
encoding_prefix = "$OutputEncoding = [Console]::OutputEncoding = [System.Text.Encoding]::UTF8; "
|
129
|
+
command_with_encoding = encoding_prefix + command
|
130
|
+
self.report_info(
|
131
|
+
ActionType.EXECUTE,
|
132
|
+
tr(
|
133
|
+
"\U0001f5a5\ufe0f Running PowerShell command: {command} ...\n",
|
134
|
+
command=command,
|
135
|
+
),
|
136
|
+
)
|
137
|
+
if not self._confirm_and_warn(
|
138
|
+
command, require_confirmation, requires_user_input
|
139
|
+
):
|
140
|
+
return tr("\u274c Command execution cancelled by user.")
|
141
|
+
from janito.agent.platform_discovery import PlatformDiscovery
|
142
|
+
|
143
|
+
pd = PlatformDiscovery()
|
144
|
+
shell_exe = "powershell.exe" if pd.is_windows() else "pwsh"
|
60
145
|
try:
|
61
146
|
with (
|
62
147
|
tempfile.NamedTemporaryFile(
|
@@ -72,44 +157,27 @@ class RunPowerShellCommandTool(ToolBase):
|
|
72
157
|
encoding="utf-8",
|
73
158
|
) as stderr_file,
|
74
159
|
):
|
75
|
-
process =
|
76
|
-
|
77
|
-
shell_exe,
|
78
|
-
"-NoProfile",
|
79
|
-
"-ExecutionPolicy",
|
80
|
-
"Bypass",
|
81
|
-
"-Command",
|
82
|
-
command_with_encoding,
|
83
|
-
],
|
84
|
-
stdout=subprocess.PIPE,
|
85
|
-
stderr=subprocess.PIPE,
|
86
|
-
text=True,
|
87
|
-
bufsize=1,
|
88
|
-
universal_newlines=True,
|
89
|
-
encoding="utf-8",
|
90
|
-
)
|
91
|
-
|
92
|
-
stdout_lines = 0
|
93
|
-
stderr_lines = 0
|
94
|
-
|
95
|
-
def stream_output(stream, file_obj, report_func, count_func):
|
96
|
-
nonlocal stdout_lines, stderr_lines
|
97
|
-
for line in stream:
|
98
|
-
file_obj.write(line)
|
99
|
-
file_obj.flush()
|
100
|
-
report_func(line)
|
101
|
-
if count_func == "stdout":
|
102
|
-
stdout_lines += 1
|
103
|
-
else:
|
104
|
-
stderr_lines += 1
|
105
|
-
|
160
|
+
process = self._launch_process(shell_exe, command_with_encoding)
|
161
|
+
counter = {"stdout": 0, "stderr": 0}
|
106
162
|
stdout_thread = threading.Thread(
|
107
|
-
target=
|
108
|
-
args=(
|
163
|
+
target=self._stream_output,
|
164
|
+
args=(
|
165
|
+
process.stdout,
|
166
|
+
stdout_file,
|
167
|
+
self.report_stdout,
|
168
|
+
"stdout",
|
169
|
+
counter,
|
170
|
+
),
|
109
171
|
)
|
110
172
|
stderr_thread = threading.Thread(
|
111
|
-
target=
|
112
|
-
args=(
|
173
|
+
target=self._stream_output,
|
174
|
+
args=(
|
175
|
+
process.stderr,
|
176
|
+
stderr_file,
|
177
|
+
self.report_stderr,
|
178
|
+
"stderr",
|
179
|
+
counter,
|
180
|
+
),
|
113
181
|
)
|
114
182
|
stdout_thread.start()
|
115
183
|
stderr_thread.start()
|
@@ -118,7 +186,10 @@ class RunPowerShellCommandTool(ToolBase):
|
|
118
186
|
except subprocess.TimeoutExpired:
|
119
187
|
process.kill()
|
120
188
|
self.report_error(
|
121
|
-
tr(
|
189
|
+
tr(
|
190
|
+
" \u274c Timed out after {timeout} seconds.",
|
191
|
+
timeout=timeout,
|
192
|
+
)
|
122
193
|
)
|
123
194
|
return tr(
|
124
195
|
"Command timed out after {timeout} seconds.", timeout=timeout
|
@@ -127,54 +198,12 @@ class RunPowerShellCommandTool(ToolBase):
|
|
127
198
|
stderr_thread.join()
|
128
199
|
stdout_file.flush()
|
129
200
|
stderr_file.flush()
|
130
|
-
|
131
201
|
self.report_success(
|
132
|
-
tr("
|
202
|
+
tr(" \u2705 return code {return_code}", return_code=return_code)
|
203
|
+
)
|
204
|
+
return self._format_result(
|
205
|
+
requires_user_input, return_code, stdout_file, stderr_file
|
133
206
|
)
|
134
|
-
warning_msg = ""
|
135
|
-
if interactive:
|
136
|
-
warning_msg = tr(
|
137
|
-
"⚠️ Warning: This command might be interactive, require user input, and might hang.\n"
|
138
|
-
)
|
139
|
-
# Read back the content for summary if not too large
|
140
|
-
with open(
|
141
|
-
stdout_file.name, "r", encoding="utf-8", errors="replace"
|
142
|
-
) as out_f:
|
143
|
-
stdout_content = out_f.read()
|
144
|
-
with open(
|
145
|
-
stderr_file.name, "r", encoding="utf-8", errors="replace"
|
146
|
-
) as err_f:
|
147
|
-
stderr_content = err_f.read()
|
148
|
-
max_lines = 100
|
149
|
-
if stdout_lines <= max_lines and stderr_lines <= max_lines:
|
150
|
-
result = warning_msg + tr(
|
151
|
-
"Return code: {return_code}\n--- STDOUT ---\n{stdout_content}",
|
152
|
-
return_code=return_code,
|
153
|
-
stdout_content=stdout_content,
|
154
|
-
)
|
155
|
-
if stderr_content.strip():
|
156
|
-
result += tr(
|
157
|
-
"\n--- STDERR ---\n{stderr_content}",
|
158
|
-
stderr_content=stderr_content,
|
159
|
-
)
|
160
|
-
return result
|
161
|
-
else:
|
162
|
-
result = warning_msg + tr(
|
163
|
-
"stdout_file: {stdout_file} (lines: {stdout_lines})\n",
|
164
|
-
stdout_file=stdout_file.name,
|
165
|
-
stdout_lines=stdout_lines,
|
166
|
-
)
|
167
|
-
if stderr_lines > 0 and stderr_content.strip():
|
168
|
-
result += tr(
|
169
|
-
"stderr_file: {stderr_file} (lines: {stderr_lines})\n",
|
170
|
-
stderr_file=stderr_file.name,
|
171
|
-
stderr_lines=stderr_lines,
|
172
|
-
)
|
173
|
-
result += tr(
|
174
|
-
"returncode: {return_code}\nUse the get_lines tool to inspect the contents of these files when needed.",
|
175
|
-
return_code=return_code,
|
176
|
-
)
|
177
|
-
return result
|
178
207
|
except Exception as e:
|
179
|
-
self.report_error(tr("
|
208
|
+
self.report_error(tr(" \u274c Error: {error}", error=e))
|
180
209
|
return tr("Error running command: {error}", error=e)
|