unswallow (Python)
The 1:1 Python mirror of the unswallow TypeScript library: detect and recover tool calls trapped inside a model's reasoning channel — the reasoning-channel swallow bug class across vLLM, SGLang, and llama.cpp.
pip install unswallow
from unswallow import check_and_rescue
result = check_and_rescue(
raw_provider_response,
engine_hint="vllm",
engine_version="0.19.0",
tool_schemas=my_tools,
)
if result.recovered and result.recovered_response:
return result.recovered_response # tool_calls is populated, finish_reason is "tool_calls"
Same interface, same semantics, same bundled matrix data (synced from packages/matrix/data/engine-matrix.json), zero runtime dependencies, Python 3.9+.
Streaming
from unswallow import check_and_rescue_stream
result = await check_and_rescue_stream(
chunk_iterable, # AsyncIterable of OpenAI-compatible SSE chunks
engine_hint="vllm",
engine_version="0.19.0",
on_leak=logger.warning, # live pattern-C signal, optional
)
Or accumulate manually with StreamAccumulator (.push(chunk) / .end()).
History hygiene (Pattern D)
from unswallow import sanitize_history, strip_reasoning_tags
clean = sanitize_history(messages)
text = strip_reasoning_tags(assistant_text) # "< thinking>\nplan\n< response>\nanswer" -> "answer"
CLI
unswallow check # bundled self-test demo (vLLM #39056)
unswallow check --fixture response.json # captured raw response
unswallow check --endpoint http://localhost:8000/v1 --model Qwen/Qwen3.5-35B-A3B-FP8 --engine vllm --version 0.19.0
unswallow matrix
Exit codes for live probes: 0 = not affected, 1 = affected, 2 = error.
Development
cd packages/python
python -m unittest discover -s tests -v # stdlib-only test suite
The engine matrix is bundled as data — after editing packages/matrix/data/engine-matrix.json, run python packages/python/scripts/sync_matrix.py from the repo root. CI verifies the copies stay identical.
Everything else — patterns, confidence scoring, the false-positive guard, the benchmark corpus and the engine matrix — is documented in the repository root README.
Release files for unswallow 0.1.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| unswallow-0.1.0.tar.gz | 20.9 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| unswallow-0.1.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 41.2 kB
Release files / unswallow-0.1.0.tar.gz
| Download URL | unswallow-0.1.0.tar.gz |
|---|---|
| Size | 20.9 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
6321433b91131226dd9d4ca21bf0d988e954b05c030326322932a21a79c2663a
|
|
BLAKE2b-256 checksum How to use checksums |
aa5df2e11ce428ea73345d4e5988919c162e1a467f2518901d79596756646738
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.14.6
|
Release files / unswallow-0.1.0-py3-none-any.whl
| Download URL | unswallow-0.1.0-py3-none-any.whl |
|---|---|
| Size | 20.3 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
01b78abe0cc5539c74d30122d3f40d3bc7284ebc0a3de3251d7d2439577e7b2d
|
|
BLAKE2b-256 checksum How to use checksums |
2a33e2b6c8c6c0337d699bdfe1ecffe8d8b7f1f9a11d293050450c21d86563b2
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.14.6
|