quantalogic 0.2.29__py3-none-any.whl → 0.2.30__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.
quantalogic/main.py CHANGED
@@ -23,9 +23,52 @@ from quantalogic.agent_config import ( # noqa: E402
23
23
  )
24
24
  from quantalogic.task_runner import task_runner # noqa: E402
25
25
 
26
+ # Platform-specific imports
27
+ try:
28
+ if sys.platform == 'win32':
29
+ import msvcrt # Built-in Windows module
30
+ else:
31
+ import termios
32
+ import tty
33
+ except ImportError as e:
34
+ logger.warning(f"Could not import platform-specific module: {e}")
35
+ # Fall back to basic terminal handling if imports fail
36
+ msvcrt = None
37
+ termios = None
38
+ tty = None
39
+
26
40
  AGENT_MODES = ["code", "basic", "interpreter", "full", "code-basic", "search", "search-full"]
27
41
 
28
42
 
43
+ def setup_terminal():
44
+ """Configure terminal settings based on platform."""
45
+ if sys.platform == 'win32':
46
+ if msvcrt:
47
+ return None # Windows terminal is already configured
48
+ logger.warning("msvcrt module not available on Windows")
49
+ return None
50
+ else:
51
+ if termios and tty:
52
+ try:
53
+ fd = sys.stdin.fileno()
54
+ old_settings = termios.tcgetattr(fd)
55
+ tty.setraw(fd)
56
+ return old_settings
57
+ except (termios.error, AttributeError) as e:
58
+ logger.warning(f"Failed to configure terminal: {e}")
59
+ return None
60
+ return None
61
+
62
+
63
+ def restore_terminal(old_settings):
64
+ """Restore terminal settings based on platform."""
65
+ if sys.platform != 'win32' and termios and old_settings:
66
+ try:
67
+ termios.tcsetattr(sys.stdin.fileno(), termios.TCSADRAIN, old_settings)
68
+ except (termios.error, AttributeError) as e:
69
+ logger.warning(f"Failed to restore terminal settings: {e}")
70
+
71
+
29
72
  @click.group(invoke_without_command=True)
30
73
  @click.option(
31
74
  "--compact-every-n-iteration",
@@ -181,8 +224,12 @@ def task(
181
224
 
182
225
 
183
226
  def main():
184
- """Main Entry point"""
185
- cli()
227
+ """Main entry point."""
228
+ old_settings = setup_terminal()
229
+ try:
230
+ cli() # type: ignore
231
+ finally:
232
+ restore_terminal(old_settings)
186
233
 
187
234
 
188
235
  if __name__ == "__main__":
@@ -1,13 +1,22 @@
1
1
  """Tool for executing bash commands with interactive input support."""
2
2
 
3
3
  import os
4
- import pty
5
4
  import select
6
5
  import signal
7
6
  import subprocess
8
7
  import sys
9
8
  from typing import Dict, Optional, Union
10
9
 
10
+ from loguru import logger
11
+
12
+ # Platform-specific imports
13
+ try:
14
+ if sys.platform != 'win32':
15
+ import pty
16
+ except ImportError as e:
17
+ logger.warning(f"Could not import platform-specific module: {e}")
18
+ pty = None
19
+
11
20
  from quantalogic.tools.tool import Tool, ToolArgument
12
21
 
13
22
 
@@ -41,20 +50,58 @@ class ExecuteBashCommandTool(Tool):
41
50
  ),
42
51
  ]
43
52
 
44
- def execute(
53
+ def _execute_windows(
45
54
  self,
46
55
  command: str,
47
- working_dir: Optional[str] = None,
48
- timeout: Union[int, str, None] = 60,
49
- env: Optional[Dict[str, str]] = None,
56
+ cwd: str,
57
+ timeout_seconds: int,
58
+ env_vars: Dict[str, str],
50
59
  ) -> str:
51
- """Executes a bash command with interactive input handling."""
52
- timeout_seconds = int(timeout) if timeout else 60
53
- cwd = working_dir or os.getcwd()
54
- env_vars = os.environ.copy()
55
- if env:
56
- env_vars.update(env)
60
+ """Execute command on Windows platform."""
61
+ try:
62
+ # On Windows, use subprocess with pipes
63
+ process = subprocess.Popen(
64
+ command,
65
+ shell=True,
66
+ stdin=subprocess.PIPE,
67
+ stdout=subprocess.PIPE,
68
+ stderr=subprocess.PIPE,
69
+ cwd=cwd,
70
+ env=env_vars,
71
+ text=True,
72
+ encoding='utf-8'
73
+ )
74
+
75
+ try:
76
+ stdout, stderr = process.communicate(timeout=timeout_seconds)
77
+ return_code = process.returncode
78
+
79
+ if return_code != 0 and stderr:
80
+ logger.warning(f"Command failed with error: {stderr}")
81
+
82
+ formatted_result = (
83
+ "<command_output>"
84
+ f" <stdout>{stdout.strip()}</stdout>"
85
+ f" <returncode>{return_code}</returncode>"
86
+ f"</command_output>"
87
+ )
88
+ return formatted_result
89
+
90
+ except subprocess.TimeoutExpired:
91
+ process.kill()
92
+ return f"Command timed out after {timeout_seconds} seconds."
93
+
94
+ except Exception as e:
95
+ return f"Unexpected error executing command: {str(e)}"
57
96
 
97
+ def _execute_unix(
98
+ self,
99
+ command: str,
100
+ cwd: str,
101
+ timeout_seconds: int,
102
+ env_vars: Dict[str, str],
103
+ ) -> str:
104
+ """Execute command on Unix platform."""
58
105
  try:
59
106
  master, slave = pty.openpty()
60
107
  proc = subprocess.Popen(
@@ -94,9 +141,7 @@ class ExecuteBashCommandTool(Tool):
94
141
  user_input = os.read(sys.stdin.fileno(), 1024)
95
142
  os.write(master, user_input)
96
143
 
97
- # Check if process completed or EOF received
98
144
  if break_loop or proc.poll() is not None:
99
- # Read any remaining output
100
145
  while True:
101
146
  data = os.read(master, 1024).decode()
102
147
  if not data:
@@ -127,6 +172,28 @@ class ExecuteBashCommandTool(Tool):
127
172
  except Exception as e:
128
173
  return f"Unexpected error executing command: {str(e)}"
129
174
 
175
+ def execute(
176
+ self,
177
+ command: str,
178
+ working_dir: Optional[str] = None,
179
+ timeout: Union[int, str, None] = 60,
180
+ env: Optional[Dict[str, str]] = None,
181
+ ) -> str:
182
+ """Executes a bash command with interactive input handling."""
183
+ timeout_seconds = int(timeout) if timeout else 60
184
+ cwd = working_dir or os.getcwd()
185
+ env_vars = os.environ.copy()
186
+ if env:
187
+ env_vars.update(env)
188
+
189
+ if sys.platform == 'win32':
190
+ return self._execute_windows(command, cwd, timeout_seconds, env_vars)
191
+ else:
192
+ if not pty:
193
+ logger.warning("PTY module not available, falling back to Windows-style execution")
194
+ return self._execute_windows(command, cwd, timeout_seconds, env_vars)
195
+ return self._execute_unix(command, cwd, timeout_seconds, env_vars)
196
+
130
197
 
131
198
  if __name__ == "__main__":
132
199
  tool = ExecuteBashCommandTool()
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: quantalogic
3
- Version: 0.2.29
3
+ Version: 0.2.30
4
4
  Summary: QuantaLogic ReAct Agents
5
5
  Author: Raphaël MANSUY
6
6
  Author-email: raphael.mansuy@gmail.com
@@ -10,7 +10,7 @@ quantalogic/event_emitter.py,sha256=jqot2g4JRXc88K6PW837Oqxbf7shZfO-xdPaUWmzupk,
10
10
  quantalogic/generative_model.py,sha256=az_kqWdEBQRROvvYZu6d68JQ4nzDbQG23gADeHLMypc,16761
11
11
  quantalogic/get_model_info.py,sha256=YCBZ8qynlq_iLUc--xBrQxacFZL9RHZPv5cdVwjukcw,602
12
12
  quantalogic/interactive_text_editor.py,sha256=_pNPnUG3Y3_YX0R9-kx0vcaUWU0AAC350jpJ5UjrTuE,6986
13
- quantalogic/main.py,sha256=YYP0DSnzlLpbyQPlQxbq-ZKIoA5ezv0kjy5LsQlT6bI,5227
13
+ quantalogic/main.py,sha256=A0ruAGy1ptYH46VHrhIFZeVUQajrIK18Zvri0Itcmi0,6765
14
14
  quantalogic/memory.py,sha256=zbtRuM05jaS2lJll-92dt5JfYVLERnF_m_9xqp2x-k0,6304
15
15
  quantalogic/model_names.py,sha256=UZlz25zG9B2dpfwdw_e1Gw5qFsKQ7iME9FJh9Ts4u6s,938
16
16
  quantalogic/prompts.py,sha256=CW4CRgW1hTpXeWdeJNbPaRPUeUm-xKuGHJrT8mOtvkw,3602
@@ -33,7 +33,7 @@ quantalogic/tools/download_http_file_tool.py,sha256=wTfanbXjIRi5-qrbluuLvNmDNhvm
33
33
  quantalogic/tools/duckduckgo_search_tool.py,sha256=xVaEb_SUK5NL3lwMQXj1rGQYYvNT-td-qaB9QCes27Q,7014
34
34
  quantalogic/tools/edit_whole_content_tool.py,sha256=nXmpAvojvqvAcqNMy1kUKZ1ocboky_ZcnCR4SNCSPgw,2360
35
35
  quantalogic/tools/elixir_tool.py,sha256=fzPPtAW-Koy9KB0r5k2zV1f1U0WphL-LXPPOBkeNkug,7652
36
- quantalogic/tools/execute_bash_command_tool.py,sha256=0JGeJobY1QC6mx8HZYTqNAUg5cNc5Xn8a26J45XaDRE,4693
36
+ quantalogic/tools/execute_bash_command_tool.py,sha256=kl3RSOZCOc-U52dwd0h6BxXvjMlAX7D0Bo2-HkCOcxo,6908
37
37
  quantalogic/tools/generate_database_report_tool.py,sha256=QbZjtmegGEOEZAIa-CSeBo5O9dYBZTk_PWrumyFUg1Q,1890
38
38
  quantalogic/tools/grep_app_tool.py,sha256=BDxygwx7WCbqbiP2jmSRnIsoIUVYG5A4SKzId524ys4,19957
39
39
  quantalogic/tools/input_question_tool.py,sha256=UoTlNhdmdr-eyiVtVCG2qJe_R4bU_ag-DzstSdmYkvM,1848
@@ -85,8 +85,8 @@ quantalogic/version_check.py,sha256=cttR1lR3OienGLl7NrK1Te1fhDkqSjCci7HC1vFUTSY,
85
85
  quantalogic/welcome_message.py,sha256=IXMhem8h7srzNUwvw8G_lmEkHU8PFfote021E_BXmVk,3039
86
86
  quantalogic/xml_parser.py,sha256=uMLQNHTRCg116FwcjRoquZmSwVtE4LEH-6V2E3RD-dA,11466
87
87
  quantalogic/xml_tool_parser.py,sha256=Vz4LEgDbelJynD1siLOVkJ3gLlfHsUk65_gCwbYJyGc,3784
88
- quantalogic-0.2.29.dist-info/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
89
- quantalogic-0.2.29.dist-info/METADATA,sha256=Nnd_JEcVXdVip81fApVj5t3pRLvF4boV1TXteHwKB5k,20534
90
- quantalogic-0.2.29.dist-info/WHEEL,sha256=Nq82e9rUAnEjt98J6MlVmMCZb-t9cYE2Ir1kpBmnWfs,88
91
- quantalogic-0.2.29.dist-info/entry_points.txt,sha256=h74O_Q3qBRCrDR99qvwB4BpBGzASPUIjCfxHq6Qnups,183
92
- quantalogic-0.2.29.dist-info/RECORD,,
88
+ quantalogic-0.2.30.dist-info/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
89
+ quantalogic-0.2.30.dist-info/METADATA,sha256=hjKqynOMQvyUjApchHNiYJDF5i0owdznI2gmo3TmKrs,20534
90
+ quantalogic-0.2.30.dist-info/WHEEL,sha256=Nq82e9rUAnEjt98J6MlVmMCZb-t9cYE2Ir1kpBmnWfs,88
91
+ quantalogic-0.2.30.dist-info/entry_points.txt,sha256=h74O_Q3qBRCrDR99qvwB4BpBGzASPUIjCfxHq6Qnups,183
92
+ quantalogic-0.2.30.dist-info/RECORD,,