auto-coder-web 0.1.116__py3-none-any.whl → 0.1.118__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.
@@ -32,7 +32,9 @@ from autocoder.auto_coder_runner import (
32
32
  completer,
33
33
  summon,
34
34
  get_memory,
35
- get_all_extensions
35
+ get_all_extensions,
36
+ start as start_engine,
37
+ stop as stop_engine
36
38
  )
37
39
 
38
40
  class AutoCoderRunnerWrapper:
@@ -41,6 +43,14 @@ class AutoCoderRunnerWrapper:
41
43
  self.product_mode = product_mode
42
44
  load_memory()
43
45
  load_tokenizer()
46
+
47
+
48
+ def start(self):
49
+ start_engine()
50
+
51
+ def stop(self):
52
+ stop_engine()
53
+
44
54
 
45
55
  def get_all_extensions_wrapper(self):
46
56
  return get_all_extensions(self.project_path)
auto_coder_web/proxy.py CHANGED
@@ -50,6 +50,7 @@ class ProxyServer:
50
50
 
51
51
  def _initialize(self):
52
52
  self.auto_coder_runner = AutoCoderRunnerWrapper(self.project_path, product_mode=self.product_mode)
53
+ self.auto_coder_runner.start()
53
54
  self.client = httpx.AsyncClient()
54
55
 
55
56
 
@@ -120,6 +121,8 @@ class ProxyServer:
120
121
 
121
122
  @self.app.on_event("shutdown")
122
123
  async def shutdown_event():
124
+ if self.auto_coder_runner:
125
+ self.auto_coder_runner.stop()
123
126
  await self.client.aclose()
124
127
 
125
128
  @self.app.websocket("/ws/terminal")
@@ -15,7 +15,11 @@ import platform
15
15
 
16
16
  # 为不同平台选择合适的终端库
17
17
  if platform.system() == 'Windows':
18
- import winpty
18
+ try:
19
+ import winpty
20
+ except ImportError:
21
+ print("Warning: winpty not found. Terminal functionality may not work on Windows.")
22
+ winpty = None
19
23
  else:
20
24
  import pty
21
25
  import fcntl
@@ -45,14 +49,21 @@ class TerminalSession:
45
49
  """Start the terminal session"""
46
50
  if self.platform == 'Windows':
47
51
  # Windows下使用winpty
52
+ if winpty is None:
53
+ raise RuntimeError("winpty is not available. Please install winpty: pip install winpty")
54
+
48
55
  try:
49
56
  self.pty = winpty.PTY(
50
57
  cols=80,
51
58
  rows=24
52
59
  )
53
- # 在Windows下,pid就是process.pid
54
- self.pid = self.pty.spawn(self.shell)
55
- self.fd = self.pty.fd # winpty提供了类似的文件描述符
60
+ # 在Windows下,spawn 返回的是process对象或进程ID
61
+ process_result = self.pty.spawn(self.shell)
62
+ if hasattr(process_result, 'pid'):
63
+ self.pid = process_result.pid
64
+ else:
65
+ self.pid = process_result # 假设直接返回的是 PID
66
+ self.fd = None # winpty 不使用传统的文件描述符
56
67
  self.running = True
57
68
  asyncio.create_task(self._handle_io())
58
69
  except Exception as e:
@@ -97,8 +108,21 @@ class TerminalSession:
97
108
  # Windows下使用winpty的读取方法
98
109
  if self.pty:
99
110
  try:
100
- data = self.pty.read(size)
101
- return data.encode('utf-8') if isinstance(data, str) else data
111
+ # winpty 可能有不同的读取方法
112
+ if hasattr(self.pty, 'read'):
113
+ data = self.pty.read(size)
114
+ elif hasattr(self.pty, 'read_blocking'):
115
+ data = self.pty.read_blocking(size, timeout=100) # 100ms超时
116
+ else:
117
+ # 如果没有直接的读取方法,返回空数据
118
+ return b''
119
+
120
+ if isinstance(data, str):
121
+ return data.encode('utf-8')
122
+ elif isinstance(data, bytes):
123
+ return data
124
+ else:
125
+ return b''
102
126
  except Exception as e:
103
127
  print(f"Error reading from winpty: {e}")
104
128
  return None
@@ -179,11 +203,17 @@ class TerminalSession:
179
203
  return
180
204
 
181
205
  try:
182
- encoded_data = data.encode('utf-8')
183
206
  if self.platform == 'Windows':
184
207
  if self.pty:
185
- self.pty.write(data) # winpty接受字符串输入
208
+ # winpty 可能有不同的写入方法
209
+ if hasattr(self.pty, 'write'):
210
+ self.pty.write(data) # winpty接受字符串输入
211
+ elif hasattr(self.pty, 'write_input'):
212
+ self.pty.write_input(data)
213
+ else:
214
+ print(f"Warning: winpty object has no write method")
186
215
  else:
216
+ encoded_data = data.encode('utf-8')
187
217
  if self.fd is not None:
188
218
  os.write(self.fd, encoded_data)
189
219
  except Exception as e:
@@ -197,9 +227,21 @@ class TerminalSession:
197
227
  if self.platform == 'Windows':
198
228
  if self.pty:
199
229
  try:
200
- self.pty.close()
230
+ # winpty.PTY 对象没有 close() 方法,使用进程终止
231
+ if self.pid:
232
+ try:
233
+ import psutil
234
+ process = psutil.Process(self.pid)
235
+ process.terminate()
236
+ process.wait(timeout=3)
237
+ except (psutil.NoSuchProcess, psutil.TimeoutExpired):
238
+ pass
239
+ except Exception as e:
240
+ print(f"Error terminating winpty process: {e}")
241
+ # 清空 pty 引用
242
+ self.pty = None
201
243
  except Exception as e:
202
- print(f"Error closing winpty: {e}")
244
+ print(f"Error cleaning up winpty: {e}")
203
245
  else:
204
246
  if self.pid:
205
247
  try:
@@ -234,6 +276,7 @@ class TerminalManager:
234
276
 
235
277
  async def handle_websocket(self, websocket: WebSocket, session_id: str):
236
278
  """Handle websocket connection for a terminal session"""
279
+ session = None
237
280
  try:
238
281
  await websocket.accept()
239
282
  session = await self.create_session(websocket, session_id)
@@ -265,14 +308,20 @@ class TerminalManager:
265
308
  session.write(data)
266
309
  except websockets.exceptions.ConnectionClosed:
267
310
  print("WebSocket closed normally during terminal session")
268
- pass
269
- finally:
270
- if session_id in self.sessions:
271
- await self.close_session(session_id)
311
+ except Exception as e:
312
+ # 检查是否是 WebSocket 断开连接相关的异常
313
+ if "1001" in str(e) or "ConnectionClosed" in str(e.__class__.__name__):
314
+ print("WebSocket disconnected during terminal session")
315
+ else:
316
+ print(f"Error in terminal websocket communication: {str(e)}")
317
+ raise
272
318
  except Exception as e:
273
319
  print(f"Error in terminal websocket: {str(e)}")
320
+ # 只在非预期的异常时重新抛出
321
+ if not ("1001" in str(e) or "ConnectionClosed" in str(e.__class__.__name__)):
322
+ raise
323
+ finally:
274
324
  if session_id in self.sessions:
275
325
  await self.close_session(session_id)
276
- raise
277
326
 
278
327
  terminal_manager = TerminalManager()
auto_coder_web/version.py CHANGED
@@ -1 +1 @@
1
- __version__ = "0.1.116"
1
+ __version__ = "0.1.118"