janito 1.12.2__py3-none-any.whl → 1.13.1__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.
@@ -6,6 +6,8 @@ import subprocess
6
6
  import tempfile
7
7
  import sys
8
8
  import os
9
+ import threading
10
+ from janito.agent.runtime_config import runtime_config
9
11
 
10
12
 
11
13
  @register_tool(name="run_bash_command")
@@ -22,6 +24,156 @@ class RunBashCommandTool(ToolBase):
22
24
  str: File paths and line counts for stdout and stderr.
23
25
  """
24
26
 
27
+ def _stream_output(
28
+ self,
29
+ stream,
30
+ report_func,
31
+ accum=None,
32
+ file_obj=None,
33
+ count_func=None,
34
+ counter=None,
35
+ ):
36
+ for line in stream:
37
+ if accum is not None:
38
+ accum.append(line)
39
+ if file_obj is not None:
40
+ file_obj.write(line)
41
+ file_obj.flush()
42
+ report_func(line)
43
+ if counter is not None and count_func is not None:
44
+ counter[count_func] += 1
45
+
46
+ def _handle_all_out(self, process, timeout):
47
+ stdout_accum = []
48
+ stderr_accum = []
49
+ stdout_thread = threading.Thread(
50
+ target=self._stream_output,
51
+ args=(process.stdout, self.report_stdout, stdout_accum),
52
+ )
53
+ stderr_thread = threading.Thread(
54
+ target=self._stream_output,
55
+ args=(process.stderr, self.report_stderr, stderr_accum),
56
+ )
57
+ stdout_thread.start()
58
+ stderr_thread.start()
59
+ try:
60
+ return_code = process.wait(timeout=timeout)
61
+ except subprocess.TimeoutExpired:
62
+ process.kill()
63
+ self.report_error(
64
+ tr(" ❌ Timed out after {timeout} seconds.", timeout=timeout)
65
+ )
66
+ return tr("Command timed out after {timeout} seconds.", timeout=timeout)
67
+ stdout_thread.join()
68
+ stderr_thread.join()
69
+ self.report_success(
70
+ tr(" ✅ return code {return_code}", return_code=return_code)
71
+ )
72
+ stdout_content = "".join(stdout_accum)
73
+ stderr_content = "".join(stderr_accum)
74
+ result = tr(
75
+ "Return code: {return_code}\n--- STDOUT ---\n{stdout_content}",
76
+ return_code=return_code,
77
+ stdout_content=stdout_content,
78
+ )
79
+ if stderr_content.strip():
80
+ result += tr(
81
+ "\n--- STDERR ---\n{stderr_content}", stderr_content=stderr_content
82
+ )
83
+ return result
84
+
85
+ def _handle_file_out(self, process, timeout):
86
+ max_lines = 100
87
+ with (
88
+ tempfile.NamedTemporaryFile(
89
+ mode="w+",
90
+ prefix="run_bash_stdout_",
91
+ delete=False,
92
+ encoding="utf-8",
93
+ ) as stdout_file,
94
+ tempfile.NamedTemporaryFile(
95
+ mode="w+",
96
+ prefix="run_bash_stderr_",
97
+ delete=False,
98
+ encoding="utf-8",
99
+ ) as stderr_file,
100
+ ):
101
+ counter = {"stdout": 0, "stderr": 0}
102
+ stdout_thread = threading.Thread(
103
+ target=self._stream_output,
104
+ args=(
105
+ process.stdout,
106
+ self.report_stdout,
107
+ None,
108
+ stdout_file,
109
+ "stdout",
110
+ counter,
111
+ ),
112
+ )
113
+ stderr_thread = threading.Thread(
114
+ target=self._stream_output,
115
+ args=(
116
+ process.stderr,
117
+ self.report_stderr,
118
+ None,
119
+ stderr_file,
120
+ "stderr",
121
+ counter,
122
+ ),
123
+ )
124
+ stdout_thread.start()
125
+ stderr_thread.start()
126
+ try:
127
+ return_code = process.wait(timeout=timeout)
128
+ except subprocess.TimeoutExpired:
129
+ process.kill()
130
+ self.report_error(
131
+ tr(" ❌ Timed out after {timeout} seconds.", timeout=timeout)
132
+ )
133
+ return tr("Command timed out after {timeout} seconds.", timeout=timeout)
134
+ stdout_thread.join()
135
+ stderr_thread.join()
136
+ stdout_file.flush()
137
+ stderr_file.flush()
138
+ self.report_success(
139
+ tr(" ✅ return code {return_code}", return_code=return_code)
140
+ )
141
+ stdout_file.seek(0)
142
+ stderr_file.seek(0)
143
+ stdout_content = stdout_file.read()
144
+ stderr_content = stderr_file.read()
145
+ stdout_lines = stdout_content.count("\n")
146
+ stderr_lines = stderr_content.count("\n")
147
+ if stdout_lines <= max_lines and stderr_lines <= max_lines:
148
+ result = tr(
149
+ "Return code: {return_code}\n--- STDOUT ---\n{stdout_content}",
150
+ return_code=return_code,
151
+ stdout_content=stdout_content,
152
+ )
153
+ if stderr_content.strip():
154
+ result += tr(
155
+ "\n--- STDERR ---\n{stderr_content}",
156
+ stderr_content=stderr_content,
157
+ )
158
+ return result
159
+ else:
160
+ result = tr(
161
+ "[LARGE OUTPUT]\nstdout_file: {stdout_file} (lines: {stdout_lines})\n",
162
+ stdout_file=stdout_file.name,
163
+ stdout_lines=stdout_lines,
164
+ )
165
+ if stderr_lines > 0:
166
+ result += tr(
167
+ "stderr_file: {stderr_file} (lines: {stderr_lines})\n",
168
+ stderr_file=stderr_file.name,
169
+ stderr_lines=stderr_lines,
170
+ )
171
+ result += tr(
172
+ "returncode: {return_code}\nUse the get_lines tool to inspect the contents of these files when needed.",
173
+ return_code=return_code,
174
+ )
175
+ return result
176
+
25
177
  def run(
26
178
  self,
27
179
  command: str,
@@ -30,7 +182,7 @@ class RunBashCommandTool(ToolBase):
30
182
  requires_user_input: bool = False,
31
183
  ) -> str:
32
184
  if not command.strip():
33
- self.report_warning(tr("\u2139\ufe0f Empty command provided."))
185
+ self.report_warning(tr("ℹ️ Empty command provided."))
34
186
  return tr("Warning: Empty command provided. Operation skipped.")
35
187
  self.report_info(
36
188
  ActionType.EXECUTE,
@@ -39,90 +191,28 @@ class RunBashCommandTool(ToolBase):
39
191
  if requires_user_input:
40
192
  self.report_warning(
41
193
  tr(
42
- "\u26a0\ufe0f Warning: This command might be interactive, require user input, and might hang."
194
+ "⚠️ Warning: This command might be interactive, require user input, and might hang."
43
195
  )
44
196
  )
45
197
  sys.stdout.flush()
46
198
  try:
47
- with (
48
- tempfile.NamedTemporaryFile(
49
- mode="w+", prefix="run_bash_stdout_", delete=False, encoding="utf-8"
50
- ) as stdout_file,
51
- tempfile.NamedTemporaryFile(
52
- mode="w+", prefix="run_bash_stderr_", delete=False, encoding="utf-8"
53
- ) as stderr_file,
54
- ):
55
- env = os.environ.copy()
56
- env["PYTHONIOENCODING"] = "utf-8"
57
- env["LC_ALL"] = "C.UTF-8"
58
- env["LANG"] = "C.UTF-8"
59
- process = subprocess.Popen(
60
- ["bash", "-c", command],
61
- stdout=subprocess.PIPE,
62
- stderr=subprocess.PIPE,
63
- text=True,
64
- encoding="utf-8",
65
- bufsize=1,
66
- env=env,
67
- )
68
- try:
69
- stdout_content, stderr_content = process.communicate(
70
- timeout=timeout
71
- )
72
- except subprocess.TimeoutExpired:
73
- process.kill()
74
- self.report_error(
75
- tr(
76
- " \u274c Timed out after {timeout} seconds.",
77
- timeout=timeout,
78
- )
79
- )
80
- return tr(
81
- "Command timed out after {timeout} seconds.", timeout=timeout
82
- )
83
- self.report_success(
84
- tr(
85
- " \u2705 return code {return_code}",
86
- return_code=process.returncode,
87
- )
88
- )
89
- warning_msg = ""
90
- if requires_user_input:
91
- warning_msg = tr(
92
- "\u26a0\ufe0f Warning: This command might be interactive, require user input, and might hang.\n"
93
- )
94
- max_lines = 100
95
- stdout_lines = stdout_content.count("\n")
96
- stderr_lines = stderr_content.count("\n")
97
- if stdout_lines <= max_lines and stderr_lines <= max_lines:
98
- result = warning_msg + tr(
99
- "Return code: {return_code}\n--- STDOUT ---\n{stdout_content}",
100
- return_code=process.returncode,
101
- stdout_content=stdout_content,
102
- )
103
- if stderr_content.strip():
104
- result += tr(
105
- "\n--- STDERR ---\n{stderr_content}",
106
- stderr_content=stderr_content,
107
- )
108
- return result
109
- else:
110
- result = warning_msg + tr(
111
- "[LARGE OUTPUT]\nstdout_file: {stdout_file} (lines: {stdout_lines})\n",
112
- stdout_file=stdout_file.name,
113
- stdout_lines=stdout_lines,
114
- )
115
- if stderr_lines > 0:
116
- result += tr(
117
- "stderr_file: {stderr_file} (lines: {stderr_lines})\n",
118
- stderr_file=stderr_file.name,
119
- stderr_lines=stderr_lines,
120
- )
121
- result += tr(
122
- "returncode: {return_code}\nUse the get_lines tool to inspect the contents of these files when needed.",
123
- return_code=process.returncode,
124
- )
125
- return result
199
+ env = os.environ.copy()
200
+ env["PYTHONIOENCODING"] = "utf-8"
201
+ env["LC_ALL"] = "C.UTF-8"
202
+ env["LANG"] = "C.UTF-8"
203
+ process = subprocess.Popen(
204
+ ["bash", "-c", command],
205
+ stdout=subprocess.PIPE,
206
+ stderr=subprocess.PIPE,
207
+ text=True,
208
+ encoding="utf-8",
209
+ bufsize=1,
210
+ env=env,
211
+ )
212
+ if runtime_config.get("all_out"):
213
+ return self._handle_all_out(process, timeout)
214
+ else:
215
+ return self._handle_file_out(process, timeout)
126
216
  except Exception as e:
127
- self.report_error(tr(" \u274c Error: {error}", error=e))
217
+ self.report_error(tr(" Error: {error}", error=e))
128
218
  return tr("Error running command: {error}", error=e)
@@ -6,6 +6,7 @@ import subprocess
6
6
  import os
7
7
  import tempfile
8
8
  import threading
9
+ from janito.agent.runtime_config import runtime_config
9
10
 
10
11
 
11
12
  @register_tool(name="run_powershell_command")
@@ -29,7 +30,7 @@ class RunPowerShellCommandTool(ToolBase):
29
30
  if requires_user_input:
30
31
  self.report_warning(
31
32
  tr(
32
- "\u26a0\ufe0f Warning: This command might be interactive, require user input, and might hang."
33
+ "⚠️ Warning: This command might be interactive, require user input, and might hang."
33
34
  )
34
35
  )
35
36
  if require_confirmation:
@@ -40,7 +41,7 @@ class RunPowerShellCommandTool(ToolBase):
40
41
  )
41
42
  )
42
43
  if not confirmed:
43
- self.report_warning(tr("\u26a0\ufe0f Execution cancelled by user."))
44
+ self.report_warning(tr("⚠️ Execution cancelled by user."))
44
45
  return False
45
46
  return True
46
47
 
@@ -65,59 +66,114 @@ class RunPowerShellCommandTool(ToolBase):
65
66
  env=env,
66
67
  )
67
68
 
68
- def _stream_output(self, stream, file_obj, report_func, count_func, counter):
69
+ def _stream_output(
70
+ self,
71
+ stream,
72
+ report_func,
73
+ accum=None,
74
+ file_obj=None,
75
+ count_func=None,
76
+ counter=None,
77
+ ):
69
78
  for line in stream:
70
- file_obj.write(line)
71
- file_obj.flush()
79
+ if accum is not None:
80
+ accum.append(line)
81
+ if file_obj is not None:
82
+ file_obj.write(line)
83
+ file_obj.flush()
72
84
  report_func(line)
73
- if count_func == "stdout":
74
- counter["stdout"] += 1
75
- else:
76
- counter["stderr"] += 1
85
+ if counter is not None and count_func is not None:
86
+ counter[count_func] += 1
77
87
 
78
- def _format_result(
79
- self, requires_user_input, return_code, stdout_file, stderr_file, max_lines=100
80
- ):
81
- warning_msg = ""
82
- if requires_user_input:
83
- warning_msg = tr(
84
- "\u26a0\ufe0f Warning: This command might be interactive, require user input, and might hang.\n"
88
+ def _handle_all_out(self, process, timeout):
89
+ stdout_accum = []
90
+ stderr_accum = []
91
+ stdout_thread = threading.Thread(
92
+ target=self._stream_output,
93
+ args=(process.stdout, self.report_stdout, stdout_accum),
94
+ )
95
+ stderr_thread = threading.Thread(
96
+ target=self._stream_output,
97
+ args=(process.stderr, self.report_stderr, stderr_accum),
98
+ )
99
+ stdout_thread.start()
100
+ stderr_thread.start()
101
+ try:
102
+ return_code = process.wait(timeout=timeout)
103
+ except subprocess.TimeoutExpired:
104
+ process.kill()
105
+ self.report_error(
106
+ tr(" ❌ Timed out after {timeout} seconds.", timeout=timeout)
85
107
  )
86
- with open(stdout_file.name, "r", encoding="utf-8", errors="replace") as out_f:
87
- stdout_content = out_f.read()
88
- with open(stderr_file.name, "r", encoding="utf-8", errors="replace") as err_f:
89
- stderr_content = err_f.read()
90
- stdout_lines = stdout_content.count("\n")
91
- stderr_lines = stderr_content.count("\n")
92
- if stdout_lines <= max_lines and stderr_lines <= max_lines:
93
- result = warning_msg + tr(
94
- "Return code: {return_code}\n--- STDOUT ---\n{stdout_content}",
95
- return_code=return_code,
96
- stdout_content=stdout_content,
108
+ return tr("Command timed out after {timeout} seconds.", timeout=timeout)
109
+ stdout_thread.join()
110
+ stderr_thread.join()
111
+ self.report_success(
112
+ tr(" return code {return_code}", return_code=return_code)
113
+ )
114
+ stdout = "".join(stdout_accum)
115
+ stderr = "".join(stderr_accum)
116
+ result = f"Return code: {return_code}\n--- STDOUT ---\n{stdout}"
117
+ if stderr and stderr.strip():
118
+ result += f"\n--- STDERR ---\n{stderr}"
119
+ return result
120
+
121
+ def _handle_file_out(self, process, timeout):
122
+ with (
123
+ tempfile.NamedTemporaryFile(
124
+ mode="w+",
125
+ prefix="run_powershell_stdout_",
126
+ delete=False,
127
+ encoding="utf-8",
128
+ ) as stdout_file,
129
+ tempfile.NamedTemporaryFile(
130
+ mode="w+",
131
+ prefix="run_powershell_stderr_",
132
+ delete=False,
133
+ encoding="utf-8",
134
+ ) as stderr_file,
135
+ ):
136
+ counter = {"stdout": 0, "stderr": 0}
137
+ stdout_thread = threading.Thread(
138
+ target=self._stream_output,
139
+ args=(
140
+ process.stdout,
141
+ self.report_stdout,
142
+ None,
143
+ stdout_file,
144
+ "stdout",
145
+ counter,
146
+ ),
97
147
  )
98
- if stderr_content.strip():
99
- result += tr(
100
- "\n--- STDERR ---\n{stderr_content}",
101
- stderr_content=stderr_content,
102
- )
103
- return result
104
- else:
105
- result = warning_msg + tr(
106
- "stdout_file: {stdout_file} (lines: {stdout_lines})\n",
107
- stdout_file=stdout_file.name,
108
- stdout_lines=stdout_lines,
148
+ stderr_thread = threading.Thread(
149
+ target=self._stream_output,
150
+ args=(
151
+ process.stderr,
152
+ self.report_stderr,
153
+ None,
154
+ stderr_file,
155
+ "stderr",
156
+ counter,
157
+ ),
109
158
  )
110
- if stderr_lines > 0 and stderr_content.strip():
111
- result += tr(
112
- "stderr_file: {stderr_file} (lines: {stderr_lines})\n",
113
- stderr_file=stderr_file.name,
114
- stderr_lines=stderr_lines,
159
+ stdout_thread.start()
160
+ stderr_thread.start()
161
+ try:
162
+ return_code = process.wait(timeout=timeout)
163
+ except subprocess.TimeoutExpired:
164
+ process.kill()
165
+ self.report_error(
166
+ tr(" ❌ Timed out after {timeout} seconds.", timeout=timeout)
115
167
  )
116
- result += tr(
117
- "returncode: {return_code}\nUse the get_lines tool to inspect the contents of these files when needed.",
118
- return_code=return_code,
168
+ return tr("Command timed out after {timeout} seconds.", timeout=timeout)
169
+ stdout_thread.join()
170
+ stderr_thread.join()
171
+ stdout_file.flush()
172
+ stderr_file.flush()
173
+ self.report_success(
174
+ tr(" ✅ return code {return_code}", return_code=return_code)
119
175
  )
120
- return result
176
+ return self._format_result(stdout_file.name, stderr_file.name, return_code)
121
177
 
122
178
  def run(
123
179
  self,
@@ -127,87 +183,69 @@ class RunPowerShellCommandTool(ToolBase):
127
183
  requires_user_input: bool = False,
128
184
  ) -> str:
129
185
  if not command.strip():
130
- self.report_warning(tr("\u2139\ufe0f Empty command provided."))
186
+ self.report_warning(tr("ℹ️ Empty command provided."))
131
187
  return tr("Warning: Empty command provided. Operation skipped.")
132
188
  encoding_prefix = "$OutputEncoding = [Console]::OutputEncoding = [System.Text.Encoding]::UTF8; "
133
189
  command_with_encoding = encoding_prefix + command
134
190
  self.report_info(
135
191
  ActionType.EXECUTE,
136
192
  tr(
137
- "\U0001f5a5\ufe0f Running PowerShell command: {command} ...\n",
193
+ "🖥️ Running PowerShell command: {command} ...\n",
138
194
  command=command,
139
195
  ),
140
196
  )
141
197
  if not self._confirm_and_warn(
142
198
  command, require_confirmation, requires_user_input
143
199
  ):
144
- return tr("\u274c Command execution cancelled by user.")
200
+ return tr(" Command execution cancelled by user.")
145
201
  from janito.agent.platform_discovery import PlatformDiscovery
146
202
 
147
203
  pd = PlatformDiscovery()
148
204
  shell_exe = "powershell.exe" if pd.is_windows() else "pwsh"
149
205
  try:
150
- with (
151
- tempfile.NamedTemporaryFile(
152
- mode="w+",
153
- prefix="run_powershell_stdout_",
154
- delete=False,
155
- encoding="utf-8",
156
- ) as stdout_file,
157
- tempfile.NamedTemporaryFile(
158
- mode="w+",
159
- prefix="run_powershell_stderr_",
160
- delete=False,
161
- encoding="utf-8",
162
- ) as stderr_file,
163
- ):
206
+ if runtime_config.get("all_out"):
164
207
  process = self._launch_process(shell_exe, command_with_encoding)
165
- counter = {"stdout": 0, "stderr": 0}
166
- stdout_thread = threading.Thread(
167
- target=self._stream_output,
168
- args=(
169
- process.stdout,
170
- stdout_file,
171
- self.report_stdout,
172
- "stdout",
173
- counter,
174
- ),
175
- )
176
- stderr_thread = threading.Thread(
177
- target=self._stream_output,
178
- args=(
179
- process.stderr,
180
- stderr_file,
181
- self.report_stderr,
182
- "stderr",
183
- counter,
184
- ),
185
- )
186
- stdout_thread.start()
187
- stderr_thread.start()
188
- try:
189
- return_code = process.wait(timeout=timeout)
190
- except subprocess.TimeoutExpired:
191
- process.kill()
192
- self.report_error(
193
- tr(
194
- " \u274c Timed out after {timeout} seconds.",
195
- timeout=timeout,
196
- )
197
- )
198
- return tr(
199
- "Command timed out after {timeout} seconds.", timeout=timeout
200
- )
201
- stdout_thread.join()
202
- stderr_thread.join()
203
- stdout_file.flush()
204
- stderr_file.flush()
205
- self.report_success(
206
- tr(" \u2705 return code {return_code}", return_code=return_code)
207
- )
208
- return self._format_result(
209
- requires_user_input, return_code, stdout_file, stderr_file
210
- )
208
+ return self._handle_all_out(process, timeout)
209
+ else:
210
+ process = self._launch_process(shell_exe, command_with_encoding)
211
+ return self._handle_file_out(process, timeout)
211
212
  except Exception as e:
212
- self.report_error(tr(" \u274c Error: {error}", error=e))
213
+ self.report_error(tr(" Error: {error}", error=e))
213
214
  return tr("Error running command: {error}", error=e)
215
+
216
+ def _format_result(self, stdout_file_name, stderr_file_name, return_code):
217
+ with open(stdout_file_name, "r", encoding="utf-8", errors="replace") as out_f:
218
+ stdout_content = out_f.read()
219
+ with open(stderr_file_name, "r", encoding="utf-8", errors="replace") as err_f:
220
+ stderr_content = err_f.read()
221
+ max_lines = 100
222
+ stdout_lines = stdout_content.count("\n")
223
+ stderr_lines = stderr_content.count("\n")
224
+
225
+ def head_tail(text, n=10):
226
+ lines = text.splitlines()
227
+ if len(lines) <= 2 * n:
228
+ return "\n".join(lines)
229
+ return "\n".join(
230
+ lines[:n]
231
+ + ["... ({} lines omitted) ...".format(len(lines) - 2 * n)]
232
+ + lines[-n:]
233
+ )
234
+
235
+ if stdout_lines <= max_lines and stderr_lines <= max_lines:
236
+ result = f"Return code: {return_code}\n--- STDOUT ---\n{stdout_content}"
237
+ if stderr_content.strip():
238
+ result += f"\n--- STDERR ---\n{stderr_content}"
239
+ return result
240
+ else:
241
+ result = f"stdout_file: {stdout_file_name} (lines: {stdout_lines})\n"
242
+ if stderr_lines > 0 and stderr_content.strip():
243
+ result += f"stderr_file: {stderr_file_name} (lines: {stderr_lines})\n"
244
+ result += f"returncode: {return_code}\n"
245
+ result += "--- STDOUT (head/tail) ---\n" + head_tail(stdout_content) + "\n"
246
+ if stderr_content.strip():
247
+ result += (
248
+ "--- STDERR (head/tail) ---\n" + head_tail(stderr_content) + "\n"
249
+ )
250
+ result += "Use the get_lines tool to inspect the contents of these files when needed."
251
+ return result
@@ -125,7 +125,7 @@ class SearchTextTool(ToolBase):
125
125
  file_word = pluralize("match", count)
126
126
  self.report_success(
127
127
  tr(
128
- " \u2705 {count} {file_word}{max_flag}",
128
+ " {count} {file_word}{max_flag}",
129
129
  count=count,
130
130
  file_word=file_word,
131
131
  max_flag=" (max)" if dir_limit_reached else "",
@@ -18,7 +18,7 @@ def prepare_pattern(pattern, is_regex, report_error, report_warning):
18
18
  regex = re.compile(pattern)
19
19
  use_regex = True
20
20
  except re.error as e:
21
- report_warning(tr("\u26a0\ufe0f Invalid regex pattern."))
21
+ report_warning(tr("⚠️ Invalid regex pattern."))
22
22
  return (
23
23
  None,
24
24
  False,
@@ -36,7 +36,7 @@ def _get_validator(ext):
36
36
 
37
37
 
38
38
  def _handle_validation_error(e, report_warning):
39
- msg = tr("\u26a0\ufe0f Warning: Syntax error: {error}", error=e)
39
+ msg = tr("⚠️ Warning: Syntax error: {error}", error=e)
40
40
  if report_warning:
41
41
  report_warning(msg)
42
42
  return msg
@@ -51,7 +51,7 @@ def validate_file_syntax(
51
51
  if validator:
52
52
  return validator(file_path)
53
53
  else:
54
- msg = tr("\u26a0\ufe0f Warning: Unsupported file extension: {ext}", ext=ext)
54
+ msg = tr("⚠️ Warning: Unsupported file extension: {ext}", ext=ext)
55
55
  if report_warning:
56
56
  report_warning(msg)
57
57
  return msg
@@ -78,9 +78,9 @@ class ValidateFileSyntaxTool(ToolBase):
78
78
  file_path (str): Path to the file to validate.
79
79
  Returns:
80
80
  str: Validation status message. Example:
81
- - "\u2705 Syntax OK"
82
- - "\u26a0\ufe0f Warning: Syntax error: <error message>"
83
- - "\u26a0\ufe0f Warning: Unsupported file extension: <ext>"
81
+ - " Syntax OK"
82
+ - "⚠️ Warning: Syntax error: <error message>"
83
+ - "⚠️ Warning: Unsupported file extension: <ext>"
84
84
  """
85
85
 
86
86
  def run(self, file_path: str) -> str:
@@ -98,8 +98,8 @@ class ValidateFileSyntaxTool(ToolBase):
98
98
  report_warning=self.report_warning,
99
99
  report_success=self.report_success,
100
100
  )
101
- if result.startswith("\u2705"):
101
+ if result.startswith(""):
102
102
  self.report_success(result)
103
- elif result.startswith("\u26a0\ufe0f"):
104
- self.report_warning(tr("\u26a0\ufe0f ") + result.lstrip("\u26a0\ufe0f "))
103
+ elif result.startswith("⚠️"):
104
+ self.report_warning(tr("⚠️ ") + result.lstrip("⚠️ "))
105
105
  return result
@@ -102,8 +102,8 @@ def _check_unclosed_inline_code(content):
102
102
  def _build_markdown_result(errors):
103
103
  if errors:
104
104
  msg = tr(
105
- "\u26a0\ufe0f Warning: Markdown syntax issues found:\n{errors}",
105
+ "⚠️ Warning: Markdown syntax issues found:\n{errors}",
106
106
  errors="\n".join(errors),
107
107
  )
108
108
  return msg
109
- return "\u2705 Syntax valid"
109
+ return " Syntax valid"