unsloth/studio/backend
Roland Tannous 5cedd9a5b2 Fix httpcore asyncgen cleanup in /v1/messages and /v1/completions
The earlier fix in 985e92a9 was incomplete: it closed aiter_lines()
explicitly but still used `async with httpx.AsyncClient()` /
`async with client.stream()` inside the generator. When the generator
is orphaned (e.g. client disconnects mid-stream and Starlette drops
the StreamingResponse iterator without explicitly calling aclose()),
Python's asyncgen finalizer runs the cleanup in a DIFFERENT task than
the one that originally entered the httpx context managers. The
`async with` exits then trigger httpcore's HTTP11ConnectionByteStream
.aclose(), which enters anyio.CancelScope.__exit__ with a mismatched
task and raises RuntimeError("Attempted to exit cancel scope in a
different task"). That error escapes any user-owned try/except
because it happens during GC finalization.

Replace `async with` with manual client/response lifecycle in both
/v1/messages passthrough and /v1/completions proxy. Close the
response and client in a finally block wrapped in
`try: ... except Exception: pass`. This suppresses RuntimeError (and
other Exception subclasses) from the anyio cleanup noise while
letting GeneratorExit (a BaseException, not Exception) propagate
cleanly so the generator terminates as Python expects.

Traceback observed in user report:
  File ".../httpcore/_async/connection_pool.py", line 404, in __aiter__
      yield part
  RuntimeError: async generator ignored GeneratorExit
...
  File ".../anyio/_backends/_asyncio.py", line 455, in __exit__
      raise RuntimeError(
  RuntimeError: Attempted to exit cancel scope in a different task
2026-04-13 12:09:46 +04:00
..
assets Add Gemma 4 model sampling defaults (#4838) 2026-04-03 13:57:15 -07:00
auth [pre-commit.ci] auto fixes from pre-commit.com hooks 2026-04-10 13:33:51 +00:00
core Studio: add Anthropic-compatible /v1/messages endpoint (#4981) 2026-04-13 11:07:42 +04:00
loggers Final cleanup 2026-03-12 18:28:04 +00:00
models Studio: add Anthropic-compatible /v1/messages endpoint (#4981) 2026-04-13 11:07:42 +04:00
plugins Bump Data Designer to 0.5.4 (removes litellm dependency) (#4569) 2026-03-25 02:01:43 -07:00
requirements Pin transformers and huggingface-hub in main Studio venv (#4788) 2026-04-02 09:21:30 -07:00
routes Fix httpcore asyncgen cleanup in /v1/messages and /v1/completions 2026-04-13 12:09:46 +04:00
state Final cleanup 2026-03-12 18:28:04 +00:00
storage feat: custom scan folders for GGUF model discovery (#4723) 2026-03-31 06:40:31 -07:00
tests Studio: add Anthropic-compatible /v1/messages endpoint (#4981) 2026-04-13 11:07:42 +04:00
utils Add AMD ROCm/HIP support across installer and hardware detection (#4720) 2026-04-10 01:56:12 -07:00
__init__.py Final cleanup 2026-03-12 18:28:04 +00:00
_platform_compat.py Fix Studio crash on Anaconda/conda-forge Python (#4484) 2026-03-22 05:36:55 -07:00
colab.py Fix/studio colab button message: Add fallback message for Colab Studio button when proxy URL fails (#4866) 2026-04-05 21:57:45 -07:00
main.py Add AMD ROCm/HIP support across installer and hardware detection (#4720) 2026-04-10 01:56:12 -07:00
run.py Add /v1/completions, /v1/embeddings, /v1/responses endpoints and --parallel support 2026-04-10 14:44:22 +00:00
startup_banner.py studio: unify Windows installer/setup logging style, verbosity controls, and startup messaging (#4651) 2026-03-30 00:53:23 -07:00