13 Commits

Author SHA1 Message Date
Test User
958dc05b7f
fix: replace atexit with BackgroundTask for temp zip cleanup
Using atexit to clean up temporary zip files is unreliable because
atexit handlers only run when the process exits, not after each
download. This means temp files accumulate on disk, one per download,
until the server restarts.

Replace with Starlette's BackgroundTask which runs cleanup after
the response is fully sent, ensuring temp files are deleted promptly.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-14 20:17:09 +08:00
voidborne-d
511d05e545 fix: use run_coroutine_threadsafe in send_message_sync to prevent cross-loop crash
WebSocketManager.send_message_sync is called from background worker threads
(via asyncio.get_event_loop().run_in_executor) during workflow execution — by
WebSocketLogger, ArtifactDispatcher, and WebPromptChannel.

Previous implementation:
  try:
      loop = asyncio.get_running_loop()
      if loop.is_running():
          asyncio.create_task(...)          # path only reachable from main thread
      else:
          asyncio.run(...)                  # creates a NEW event loop
  except RuntimeError:
      asyncio.run(...)                      # also creates a new event loop

The problem: WebSocket objects are bound to the *main* uvicorn event loop.
asyncio.run() spins up a separate event loop and calls websocket.send_text()
there, which in Python 3.12 raises:

  RuntimeError: Task got Future attached to a different loop

...causing all log/artifact/prompt messages emitted from workflow threads to be
silently dropped or to crash the worker thread.

Fix:
- Store the event loop that created the first WebSocket connection as
  self._owner_loop (captured in connect(), which always runs on the main loop).
- send_message_sync schedules the coroutine on that loop via
  asyncio.run_coroutine_threadsafe(), then waits with a 10 s timeout.
- Calling from the main thread still works (run_coroutine_threadsafe is safe
  when called from any thread, including the loop thread itself).

Added 7 tests covering:
- send from main thread
- send from worker thread (verifies send_text runs on the owner loop thread)
- 8 concurrent workers with no lost messages
- send after disconnect does not crash
- send before connect (no owner loop) does not crash
- owner loop captured on first connect
- owner loop stable across multiple connects
2026-04-02 16:01:46 +00:00
NA-Wen
5099636757 add tool list routes 2026-03-11 12:11:06 +08:00
NA-Wen
d48e82f17e add tool list routes 2026-03-11 12:06:33 +08:00
NA-Wen
e5587203ba remove replicated mcp server 2026-03-11 11:58:10 +08:00
NA-Wen
55f565d53f update readme & solve frontend efficiency 2026-03-11 11:35:33 +08:00
NA-Wen
54ad9a57ee fix frontend error 2026-03-11 11:22:18 +08:00
NA-Wen
9381abd96f [feat] add server endpoint 2026-03-11 10:49:52 +08:00
Petar Zivkovic
06a601359c fix: removed duplicate CORS middleware 2026-02-09 16:57:50 +01:00
Shu Yao
b0ccc228b4 fix: websocket disconnect problem
upgrade: allow set not log_output to avoid log every node output
2026-02-05 18:11:06 +08:00
swugi
c4d6dd4aec fix: erronous graph rename mechanism 2026-01-13 16:55:46 +08:00
Shu Yao
7bb72f56e6 add: batch execution API added 2026-01-10 22:35:32 +08:00
NA-Wen
f0db945ed3 initial commit of chatdev 2.0 2026-01-07 16:24:01 +08:00