mship-engine 0.7.12__tar.gz

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.
Files changed (81) hide show
  1. mship_engine-0.7.12/PKG-INFO +312 -0
  2. mship_engine-0.7.12/README.md +217 -0
  3. mship_engine-0.7.12/modelship/__init__.py +0 -0
  4. mship_engine-0.7.12/modelship/deploy/__init__.py +0 -0
  5. mship_engine-0.7.12/modelship/deploy/actor_options.py +178 -0
  6. mship_engine-0.7.12/modelship/deploy/capabilities.py +84 -0
  7. mship_engine-0.7.12/modelship/deploy/config.py +131 -0
  8. mship_engine-0.7.12/modelship/deploy/effective_config.py +131 -0
  9. mship_engine-0.7.12/modelship/deploy/serve_utils.py +484 -0
  10. mship_engine-0.7.12/modelship/deploy/strategy.py +243 -0
  11. mship_engine-0.7.12/modelship/driver.py +377 -0
  12. mship_engine-0.7.12/modelship/infer/base_infer.py +473 -0
  13. mship_engine-0.7.12/modelship/infer/base_serving.py +21 -0
  14. mship_engine-0.7.12/modelship/infer/deploy_coordinator.py +204 -0
  15. mship_engine-0.7.12/modelship/infer/diffusers/diffusers_infer.py +171 -0
  16. mship_engine-0.7.12/modelship/infer/diffusers/openai/serving_image.py +230 -0
  17. mship_engine-0.7.12/modelship/infer/image_serving_common.py +83 -0
  18. mship_engine-0.7.12/modelship/infer/infer_config.py +649 -0
  19. mship_engine-0.7.12/modelship/infer/llama_server/llama_server_infer.py +885 -0
  20. mship_engine-0.7.12/modelship/infer/model_deployment.py +459 -0
  21. mship_engine-0.7.12/modelship/infer/model_resolver.py +271 -0
  22. mship_engine-0.7.12/modelship/infer/replica_coordinator.py +170 -0
  23. mship_engine-0.7.12/modelship/infer/sherpa_onnx/bundle.py +76 -0
  24. mship_engine-0.7.12/modelship/infer/sherpa_onnx/registry.py +138 -0
  25. mship_engine-0.7.12/modelship/infer/sherpa_onnx/sherpa_onnx_infer.py +154 -0
  26. mship_engine-0.7.12/modelship/infer/stable_diffusion_cpp/openai/serving_image.py +181 -0
  27. mship_engine-0.7.12/modelship/infer/stable_diffusion_cpp/stable_diffusion_cpp_infer.py +138 -0
  28. mship_engine-0.7.12/modelship/infer/vllm/capabilities.py +20 -0
  29. mship_engine-0.7.12/modelship/infer/vllm/engine_ops.py +646 -0
  30. mship_engine-0.7.12/modelship/infer/vllm/openai/serving_speech.py +6 -0
  31. mship_engine-0.7.12/modelship/infer/vllm/parsing/__init__.py +6 -0
  32. mship_engine-0.7.12/modelship/infer/vllm/parsing/detect.py +252 -0
  33. mship_engine-0.7.12/modelship/infer/vllm/vllm_infer.py +884 -0
  34. mship_engine-0.7.12/modelship/infer/whispercpp/whispercpp_infer.py +322 -0
  35. mship_engine-0.7.12/modelship/launcher.py +114 -0
  36. mship_engine-0.7.12/modelship/logging.py +243 -0
  37. mship_engine-0.7.12/modelship/metrics.py +409 -0
  38. mship_engine-0.7.12/modelship/openai/api.py +1151 -0
  39. mship_engine-0.7.12/modelship/openai/auth.py +186 -0
  40. mship_engine-0.7.12/modelship/openai/compaction_crypto.py +99 -0
  41. mship_engine-0.7.12/modelship/openai/mcp/__init__.py +5 -0
  42. mship_engine-0.7.12/modelship/openai/mcp/client.py +108 -0
  43. mship_engine-0.7.12/modelship/openai/mcp/egress.py +60 -0
  44. mship_engine-0.7.12/modelship/openai/mcp/loop.py +706 -0
  45. mship_engine-0.7.12/modelship/openai/mcp/spec.py +199 -0
  46. mship_engine-0.7.12/modelship/openai/protocol/__init__.py +163 -0
  47. mship_engine-0.7.12/modelship/openai/protocol/audio.py +170 -0
  48. mship_engine-0.7.12/modelship/openai/protocol/base.py +21 -0
  49. mship_engine-0.7.12/modelship/openai/protocol/chat.py +194 -0
  50. mship_engine-0.7.12/modelship/openai/protocol/embeddings.py +43 -0
  51. mship_engine-0.7.12/modelship/openai/protocol/error.py +67 -0
  52. mship_engine-0.7.12/modelship/openai/protocol/images.py +115 -0
  53. mship_engine-0.7.12/modelship/openai/protocol/responses/__init__.py +83 -0
  54. mship_engine-0.7.12/modelship/openai/protocol/responses/adapter.py +452 -0
  55. mship_engine-0.7.12/modelship/openai/protocol/responses/schemas.py +275 -0
  56. mship_engine-0.7.12/modelship/openai/protocol/responses/streaming.py +395 -0
  57. mship_engine-0.7.12/modelship/openai/protocol/usage.py +26 -0
  58. mship_engine-0.7.12/modelship/openai/state/__init__.py +22 -0
  59. mship_engine-0.7.12/modelship/openai/state/responses.py +322 -0
  60. mship_engine-0.7.12/modelship/openai/utils/__init__.py +4 -0
  61. mship_engine-0.7.12/modelship/openai/utils/audio.py +16 -0
  62. mship_engine-0.7.12/modelship/openai/utils/chat.py +293 -0
  63. mship_engine-0.7.12/modelship/openai/utils/responses.py +691 -0
  64. mship_engine-0.7.12/modelship/preflight/__init__.py +42 -0
  65. mship_engine-0.7.12/modelship/preflight/base.py +584 -0
  66. mship_engine-0.7.12/modelship/preflight/llama_cpp.py +536 -0
  67. mship_engine-0.7.12/modelship/preflight/stable_diffusion_cpp.py +42 -0
  68. mship_engine-0.7.12/modelship/preflight/vllm.py +822 -0
  69. mship_engine-0.7.12/modelship/state/__init__.py +169 -0
  70. mship_engine-0.7.12/modelship/state/base.py +97 -0
  71. mship_engine-0.7.12/modelship/state/memory.py +254 -0
  72. mship_engine-0.7.12/modelship/state/redis.py +154 -0
  73. mship_engine-0.7.12/modelship/utils/__init__.py +157 -0
  74. mship_engine-0.7.12/modelship/utils/accelerator.py +46 -0
  75. mship_engine-0.7.12/modelship/utils/audio.py +69 -0
  76. mship_engine-0.7.12/modelship/utils/cache.py +18 -0
  77. mship_engine-0.7.12/modelship/utils/cli.py +250 -0
  78. mship_engine-0.7.12/modelship/utils/ray_auth.py +25 -0
  79. mship_engine-0.7.12/modelship/utils/request_id.py +23 -0
  80. mship_engine-0.7.12/pyproject.toml +248 -0
  81. mship_engine-0.7.12/pyproject.toml.orig +218 -0
@@ -0,0 +1,312 @@
1
+ Metadata-Version: 2.3
2
+ Name: mship-engine
3
+ Version: 0.7.12
4
+ Summary: The production backend for self-hosted agents — the OpenAI Responses API with server-side conversation state (durable with Redis), universal tool calling, and reasoning, alongside embeddings, speech, and image generation, behind one OpenAI-compatible endpoint. Built on Ray Serve.
5
+ Keywords: ai,inference,vllm,ray,ray-serve,openai,llm,agentic,tool-calling,reasoning,responses-api,multimodal,tts,stt,embeddings,image-generation,diffusers,self-hosted
6
+ Author: Alex Margarit
7
+ License: Apache-2.0
8
+ Classifier: Development Status :: 3 - Alpha
9
+ Classifier: License :: OSI Approved :: Apache Software License
10
+ Classifier: Programming Language :: Python :: 3.12
11
+ Classifier: Topic :: Home Automation
12
+ Classifier: Topic :: Multimedia :: Sound/Audio :: Speech
13
+ Requires-Dist: argparse>=1.4.0
14
+ Requires-Dist: asyncio>=4.0.0
15
+ Requires-Dist: cryptography>=43.0.0
16
+ Requires-Dist: fastapi>=0.116.1,<0.136.0
17
+ Requires-Dist: httpx>=0.28.1
18
+ Requires-Dist: httpx2>=2.9.1
19
+ Requires-Dist: huggingface-hub>=1.12.0
20
+ Requires-Dist: numpy>=2.2.6
21
+ Requires-Dist: pydantic>=2.12.0
22
+ Requires-Dist: pydantic-yaml>=1.6.0
23
+ Requires-Dist: python-multipart>=0.0.20
24
+ Requires-Dist: ray[data,default,serve-grpc]>=2.54.0,<2.55.0
25
+ Requires-Dist: requests>=2.32.5
26
+ Requires-Dist: psutil>=5.9
27
+ Requires-Dist: gguf>=0.18.0
28
+ Requires-Dist: redis>=8.0.0
29
+ Requires-Dist: protobuf<7.0.0
30
+ Requires-Dist: mcp>=2,<3
31
+ Requires-Dist: stable-diffusion-cpp-python>=0.4.7 ; extra == 'cpu'
32
+ Requires-Dist: onnxruntime>=1.28.0 ; extra == 'cpu'
33
+ Requires-Dist: librosa>=0.11.0 ; extra == 'cpu'
34
+ Requires-Dist: numba>=0.61.0 ; extra == 'cpu'
35
+ Requires-Dist: scipy>=1.16.1 ; extra == 'cpu'
36
+ Requires-Dist: soundfile>=0.13.0 ; extra == 'cpu'
37
+ Requires-Dist: pywhispercpp>=1.5.0 ; extra == 'cpu'
38
+ Requires-Dist: sherpa-onnx>=1.13.4 ; extra == 'cpu'
39
+ Requires-Dist: sherpa-onnx-core==1.13.4 ; extra == 'cpu'
40
+ Requires-Dist: torch>=2.10.0 ; extra == 'cuda'
41
+ Requires-Dist: torchvision>=0.25.0 ; extra == 'cuda'
42
+ Requires-Dist: transformers>=5.5.3 ; extra == 'cuda'
43
+ Requires-Dist: flashinfer-python>=0.6.1 ; extra == 'cuda'
44
+ Requires-Dist: vllm==0.26.0 ; extra == 'cuda'
45
+ Requires-Dist: vllm[audio]==0.26.0 ; extra == 'cuda'
46
+ Requires-Dist: bitsandbytes>=0.49.0 ; extra == 'cuda'
47
+ Requires-Dist: diffusers>=0.31.0 ; extra == 'cuda'
48
+ Requires-Dist: stable-diffusion-cpp-python>=0.4.7 ; extra == 'cuda'
49
+ Requires-Dist: onnxruntime-gpu>=1.28.0 ; extra == 'cuda'
50
+ Requires-Dist: nvidia-ml-py ; extra == 'cuda'
51
+ Requires-Dist: librosa>=0.11.0 ; extra == 'cuda'
52
+ Requires-Dist: numba>=0.61.0 ; extra == 'cuda'
53
+ Requires-Dist: scipy>=1.16.1 ; extra == 'cuda'
54
+ Requires-Dist: soundfile>=0.13.0 ; extra == 'cuda'
55
+ Requires-Dist: pywhispercpp>=1.5.0 ; extra == 'cuda'
56
+ Requires-Dist: sherpa-onnx>=1.13.4 ; extra == 'cuda'
57
+ Requires-Dist: sherpa-onnx-core==1.13.4 ; extra == 'cuda'
58
+ Requires-Dist: ruff>=0.11.0 ; extra == 'dev'
59
+ Requires-Dist: pyright>=1.1.400 ; extra == 'dev'
60
+ Requires-Dist: pytest>=8.0.0 ; extra == 'dev'
61
+ Requires-Dist: pytest-asyncio>=0.25.0 ; extra == 'dev'
62
+ Requires-Dist: pre-commit>=4.0.0 ; extra == 'dev'
63
+ Requires-Dist: fakeredis>=2.36.2 ; extra == 'dev'
64
+ Requires-Dist: mkdocs-material>=9.6.0 ; extra == 'docs'
65
+ Requires-Dist: librosa>=0.11.0 ; extra == 'metal'
66
+ Requires-Dist: numba>=0.61.0 ; extra == 'metal'
67
+ Requires-Dist: scipy>=1.16.1 ; extra == 'metal'
68
+ Requires-Dist: soundfile>=0.13.0 ; extra == 'metal'
69
+ Requires-Dist: onnxruntime>=1.28.0 ; extra == 'metal'
70
+ Requires-Dist: stable-diffusion-cpp-python>=0.4.7 ; extra == 'metal'
71
+ Requires-Dist: pywhispercpp>=1.5.0 ; extra == 'metal'
72
+ Requires-Dist: sherpa-onnx>=1.13.4 ; extra == 'metal'
73
+ Requires-Dist: sherpa-onnx-core==1.13.4 ; extra == 'metal'
74
+ Requires-Dist: opentelemetry-sdk>=1.20.0 ; extra == 'otel'
75
+ Requires-Dist: opentelemetry-exporter-otlp>=1.20.0 ; extra == 'otel'
76
+ Requires-Dist: torch==2.11.0+cpu ; sys_platform == 'linux' and extra == 'vllm-cpu'
77
+ Requires-Dist: torchvision==0.26.0+cpu ; sys_platform == 'linux' and extra == 'vllm-cpu'
78
+ Requires-Dist: transformers>=5.5.3 ; extra == 'vllm-cpu'
79
+ Requires-Dist: vllm==0.26.0+cpu ; sys_platform == 'linux' and extra == 'vllm-cpu'
80
+ Requires-Dist: vllm[audio]==0.26.0+cpu ; sys_platform == 'linux' and extra == 'vllm-cpu'
81
+ Requires-Python: ==3.12.10
82
+ Project-URL: Homepage, https://github.com/modelship-ai/modelship
83
+ Project-URL: Documentation, https://docs.model-ship.ai/
84
+ Project-URL: Issues, https://github.com/modelship-ai/modelship/issues
85
+ Project-URL: Changelog, https://github.com/modelship-ai/modelship/blob/main/CHANGELOG.md
86
+ Provides-Extra: cpu
87
+ Provides-Extra: cuda
88
+ Provides-Extra: dev
89
+ Provides-Extra: docs
90
+ Provides-Extra: metal
91
+ Provides-Extra: otel
92
+ Provides-Extra: thin
93
+ Provides-Extra: vllm-cpu
94
+ Description-Content-Type: text/markdown
95
+
96
+ <div align="center">
97
+ <picture>
98
+ <source media="(prefers-color-scheme: dark)" srcset="https://raw.githubusercontent.com/modelship-ai/modelship/main/docs/assets/logo-dark.svg">
99
+ <source media="(prefers-color-scheme: light)" srcset="https://raw.githubusercontent.com/modelship-ai/modelship/main/docs/assets/logo-light.svg">
100
+ <img alt="Modelship" src="https://raw.githubusercontent.com/modelship-ai/modelship/main/docs/assets/logo-light.svg" width="160">
101
+ </picture>
102
+ </div>
103
+
104
+ # Modelship
105
+
106
+ [![CI](https://github.com/modelship-ai/modelship/actions/workflows/ci.yml/badge.svg)](https://github.com/modelship-ai/modelship/actions/workflows/ci.yml)
107
+ [![License: Apache 2.0](https://img.shields.io/badge/License-Apache_2.0-blue.svg)](https://opensource.org/licenses/Apache-2.0)
108
+ [![Python 3.12+](https://img.shields.io/badge/python-3.12+-blue.svg)](https://www.python.org/downloads/)
109
+ [![Docs](https://img.shields.io/badge/docs-docs.model--ship.ai-0E7C86.svg)](https://docs.model-ship.ai/)
110
+
111
+ Modelship runs the AI stack your agents call — chat, the **Responses API** with server-side conversation state (durable with Redis), universal **tool calling**, and **reasoning**, alongside embeddings, speech, and image generation — behind one OpenAI-compatible endpoint on your own GPUs (or CPU). Built on [Ray Serve](https://docs.ray.io/en/latest/serve/index.html): state is shared across gateway replicas, deploys are declarative, and everything is observable. Point the OpenAI SDK at it and your agent runs unchanged — private, with no per-token bill.
112
+
113
+ ## Why Modelship?
114
+
115
+ - **Agent state that isn't siloed per replica** — the `/v1/responses` API with reasoning, universal tool/function calling, and server-side conversation state (`previous_response_id`) live in one pluggable store shared by every gateway replica — in-memory by default, or Redis for durability across restarts and node failure. Works across both the vLLM and llama.cpp (`llama_server`) loaders.
116
+ - **Everything an agent app calls, one endpoint** — chat, embeddings for RAG, speech-to-text, text-to-speech, and image generation, all behind a single OpenAI-compatible `/v1` surface. No juggling separate services for each modality.
117
+ - **Drop-in OpenAI, on your hardware** — any OpenAI SDK client works out of the box. Point it at Modelship instead of the OpenAI API and your agent code doesn't change — it just runs privately, on infrastructure you control.
118
+ - **GPU memory control** — allocate exact GPU fractions per model (e.g. 70% for the LLM, 5% for TTS) so a full stack fits on hardware you already own
119
+ - **Mix and match backends** — vLLM for high-throughput GPU or CPU inference, llama.cpp for efficient quantized GGUF models, Diffusers for images, sherpa-onnx for TTS, and whisper.cpp for STT — in the same deployment
120
+
121
+ ## Architecture
122
+
123
+ <picture>
124
+ <source media="(prefers-color-scheme: dark)" srcset="docs/assets/architecture-dark.svg">
125
+ <source media="(prefers-color-scheme: light)" srcset="docs/assets/architecture-light.svg">
126
+ <img alt="Modelship architecture: an agent app calls the Modelship gateway's OpenAI-compatible API, which exposes chat, embeddings, audio, and image endpoints plus a Responses API backed by a shared conversation-state store, routing round-robin to Ray Serve deployments across GPU and CPU cluster nodes." src="docs/assets/architecture-light.svg">
127
+ </picture>
128
+
129
+ Each model runs as an isolated [Ray Serve](https://docs.ray.io/en/latest/serve/index.html) deployment with its own lifecycle, health checks, and resource budget. Several inference backends are available:
130
+
131
+ | Backend | Best for | GPU required |
132
+ |---|---|---|
133
+ | **vLLM** | High-throughput chat, embeddings, transcription | No — installs on GPU or CPU |
134
+ | **llama.cpp** (`llama_server`) | High-efficiency quantized GGUF models (chat, embeddings, vision) | No |
135
+ | **Diffusers** | Image generation | Yes |
136
+ | **sherpa-onnx** | TTS (Kokoro) | No |
137
+ | **whisper.cpp** | STT | No |
138
+
139
+ Models can be deployed across multiple GPUs, run on CPU-only, or both — multiple deployments of the same model (e.g. one on GPU via vLLM, one on CPU via vLLM or llama.cpp) are load-balanced with round-robin routing. Each deployment can also scale horizontally with `num_replicas`.
140
+
141
+ ## Requirements
142
+
143
+ - **Docker** (or Python 3.12+ with `uv` for local development)
144
+ - **NVIDIA GPU** (optional) — 16 GB+ VRAM recommended for a full stack (LLM + TTS + STT + embeddings) via vLLM; 8 GB is sufficient for lighter setups. Not required when using the vLLM or llama.cpp backends on CPU
145
+ - **[NVIDIA Container Toolkit](https://docs.nvidia.com/datacenter/cloud-native/container-toolkit/install-guide.html)** — required only when running GPU models in Docker
146
+ - **HuggingFace token** for gated models
147
+
148
+ ## Features
149
+
150
+ - **Multi-model, multi-GPU** — run chat, embedding, STT, TTS, and image generation models simultaneously across one or more GPUs with tunable per-model GPU memory allocation
151
+ - **CPU-only support** — run models without a GPU using the vLLM or llama.cpp (`llama_server`) backends (chat, embeddings, transcription, vision). Useful for development, testing, or small models that don't need GPU acceleration
152
+ - **Multiple inference backends** — vLLM for high-throughput GPU or CPU inference, llama.cpp for efficient quantized GGUF models on CPU or GPU, Diffusers for image generation, sherpa-onnx for TTS, and whisper.cpp for STT
153
+ - **Zero-downtime hot-reloads** — modify your `models.yaml` and run a cluster reconcile; changes are applied incrementally without interrupting the API gateway or unchanged models
154
+ - **Advanced agentic capabilities** — native support for DeepSeek-style reasoning (`<think>` blocks parsed into `reasoning_content`) and universal tool/function calling across the vLLM and GGUF (`llama_server`) backends
155
+ - **Server-side MCP tool execution** — point `/v1/responses` at any self-hosted MCP server (`tools: [{"type": "mcp", ...}]`) and the gateway discovers its tools, calls them, and loops — with an approval flow (`require_approval`) client-driven tool calling doesn't have
156
+ - **Per-model isolated deployments** — each model runs in its own Ray Serve deployment with independent lifecycle, health checks, failure isolation, and configurable replica count
157
+ - **OpenAI-compatible API** — drop-in replacement for any OpenAI SDK client
158
+ - **Streaming** — SSE streaming for chat completions and TTS audio
159
+ - **Multi-GPU & hybrid routing** — assign models to specific GPUs or run them on CPU-only; deploy the same model on both GPU and CPU and requests are load-balanced via round-robin; full tensor parallelism support for large models spanning multiple GPUs
160
+ - **Client disconnect detection** — cancels in-flight inference when the client disconnects, freeing GPU resources immediately
161
+ - **Security** — gateway API-key authentication (`MSHIP_API_KEYS`), Ray cluster token auth (`--ray-auth=token`), and configurable request payload/concurrency limits
162
+ - **Built-in observability** — Prometheus metrics, custom `modelship:*` metrics, vLLM engine stats, Ray cluster metrics, structured JSON logging, and OpenTelemetry log export; pre-built Grafana dashboard and alerting rules included
163
+
164
+ ## Supported OpenAI Endpoints
165
+
166
+ | Endpoint | Usecase |
167
+ |---|---|
168
+ | `POST /v1/chat/completions` | Chat / text generation (streaming and non-streaming) |
169
+ | `POST /v1/responses` | Responses API — text, reasoning, client-driven tool calls, server-side MCP tool execution, and stored conversations (streaming and non-streaming) |
170
+ | `GET`/`DELETE /v1/responses/{id}` | Fetch or drop a stored response (`/input_items` lists its input); `background: true` on create + `POST .../cancel` for queued/pollable runs |
171
+ | `POST /v1/embeddings` | Text embeddings |
172
+ | `POST /v1/audio/transcriptions` | Speech-to-text |
173
+ | `POST /v1/audio/translations` | Audio translation |
174
+ | `POST /v1/audio/speech` | Text-to-speech (SSE streaming or single-response) |
175
+ | `POST /v1/images/generations` | Image generation |
176
+ | `GET /v1/models` | List available models |
177
+
178
+ ## Quick Start
179
+
180
+ The fastest way to try Modelship: run a tiny reasoning model on a laptop — no GPU required. Copy-paste this block and you'll have an OpenAI-compatible API on `http://localhost:8000` in a few minutes.
181
+
182
+ ```bash
183
+ mkdir -p models-cache && cat > models.yaml <<'EOF'
184
+ models:
185
+ - name: reasoning-qwen
186
+ model: "lmstudio-community/Qwen3-0.6B-GGUF:*Q4_K_M.gguf"
187
+ usecase: generate
188
+ loader: llama_server
189
+ num_cpus: 3
190
+ llama_server_config:
191
+ n_ctx: 4096 # Give reasoning space to think
192
+ EOF
193
+
194
+ docker run --rm --shm-size=8g \
195
+ -v ./models.yaml:/modelship/config/models.yaml \
196
+ -v ./models-cache:/.cache \
197
+ -p 8000:8000 \
198
+ ghcr.io/modelship-ai/modelship:latest-cpu
199
+ ```
200
+
201
+ Images are multi-arch (amd64 + arm64), so this works on Apple Silicon and ARM Linux hosts too.
202
+
203
+ Once the server is up (look for `Deployed app 'modelship api' successfully`), call the **Responses API** and watch the model think:
204
+
205
+ ```bash
206
+ curl http://localhost:8000/v1/responses \
207
+ -H "Content-Type: application/json" \
208
+ -d '{
209
+ "model": "reasoning-qwen",
210
+ "input": "Which is larger, 9.11 or 9.9?"
211
+ }'
212
+ ```
213
+
214
+ The response includes both `output_text` and a first-class `reasoning` output item — the same server-side conversation state (`previous_response_id`) and tool-calling support work here as they do on GPU-backed models. `/v1/chat/completions` remains available too, if that's what your client speaks.
215
+
216
+ ### Native install (no Docker)
217
+
218
+ One install command everywhere, then pick the node's role at run time:
219
+
220
+ ```bash
221
+ pipx install mship # or: uv tool install mship / pip install mship
222
+
223
+ mship deploy --cuda --config models.yaml # NVIDIA GPU node
224
+ mship deploy --cpu --config models.yaml # CPU node (includes vLLM CPU)
225
+ mship deploy --metal --config models.yaml # Apple Silicon
226
+ mship deploy --thin --config models.yaml # coordinator/head only, no capacity
227
+ ```
228
+
229
+ Nothing to pin and nothing to match across machines. The first run of a variant sets itself up; after that it starts straight through. Every node lands on the same footing, so a new one joins the cluster by running the same command.
230
+
231
+ Platform prerequisites still apply: Xcode Command Line Tools on macOS, `build-essential`/`cmake` on Linux, plus `ninja-build` and NVIDIA's `nvcc` for `--cuda`. Alpine and other musl distros are unsupported. See [docs/installation.md](docs/installation.md) for the full list.
232
+
233
+ ### GPU (vLLM, Diffusers)
234
+
235
+ For high-throughput GPU inference, use the `-cuda` image and add `--gpus all`. You'll also need the [NVIDIA Container Toolkit](https://docs.nvidia.com/datacenter/cloud-native/container-toolkit/install-guide.html) and an `HF_TOKEN` for gated models. Example `models.yaml` entries for vLLM, Diffusers, and multi-GPU setups live in [docs/model-configuration.md](docs/model-configuration.md); ready-to-run configs are in [config/examples/](config/examples/).
236
+
237
+ ```bash
238
+ docker run --rm --shm-size=8g --gpus all \
239
+ -e HF_TOKEN=your_token_here \
240
+ -v ./models.yaml:/modelship/config/models.yaml \
241
+ -v ./models-cache:/.cache \
242
+ -p 8000:8000 \
243
+ ghcr.io/modelship-ai/modelship:latest-cuda
244
+ ```
245
+
246
+ > [!NOTE]
247
+ > `ghcr.io/modelship-ai/modelship:latest` (bare tag, no suffix) is the **thin** control/coordinator image — no torch/vllm, for a driver/head role only. It cannot serve models by itself; always use `-cuda` or `-cpu` to actually run inference. See [docs/development.md](docs/development.md) for the full three-image breakdown.
248
+
249
+ > [!TIP]
250
+ > Always set `--shm-size=8g` (or higher) when running the docker container to prevent PyTorch from hitting shared memory limits during multi-process operations.
251
+
252
+ Hitting an error? Check [docs/troubleshooting.md](docs/troubleshooting.md).
253
+
254
+ ## Documentation
255
+
256
+ Full docs are hosted at **[docs.model-ship.ai](https://docs.model-ship.ai/)**. The same source files are also browsable directly in this repo:
257
+
258
+ - [Development](docs/development.md) — dev environment setup, building, and running locally
259
+ - [Model Configuration](docs/model-configuration.md) — full `models.yaml` reference, GPU pinning, environment variables
260
+ - [Multi-node without Kubernetes](docs/multi-node-docker.md) — join VMs into one Ray cluster with plain `docker run`, no orchestrator
261
+ - [Architecture](docs/architecture.md) — system design, request lifecycle, loaders
262
+ - [Monitoring & Logging](docs/monitoring.md) — Prometheus metrics, Grafana dashboard, structured logging, health checks
263
+ - [Troubleshooting](docs/troubleshooting.md) — common first-run errors and fixes
264
+
265
+ ## Monitoring
266
+
267
+ Modelship exposes Prometheus metrics (Ray cluster, Ray Serve, vLLM, and custom `modelship:*` metrics) through a single scrape endpoint on port 8079. Metrics are **enabled by default** — set `MSHIP_METRICS=false` to disable. A pre-built [Grafana dashboard](docs/grafana-dashboard.json) and [Prometheus alerting rules](docs/prometheus-alerts.yml) are included in the repository.
268
+
269
+ Logging supports structured JSON output (`MSHIP_LOG_FORMAT=json`) and request ID correlation across Ray actor boundaries. Logs can be shipped to a remote syslog server (`--log-target syslog://host:514`) or an OpenTelemetry collector (`--otel-endpoint http://collector:4317`). Set `MSHIP_LOG_LEVEL` to `TRACE` for full request/response payloads, or `DEBUG` for detailed diagnostics without payloads.
270
+
271
+ See [Monitoring & Logging](docs/monitoring.md) for full details.
272
+
273
+ ## Production Readiness
274
+
275
+ Modelship is actively used and designed for stability in multi-tenant setups. Key guarantees include:
276
+
277
+ - **Mutex-backed deployments:** A cluster-wide deploy coordinator prevents VRAM exhaustion by ensuring models are never loaded concurrently if resources are tight.
278
+ - **Comprehensive HTTP-level tests:** The `tests/test_*_integration.py` suites validate chat, reasoning, tool-calling, and streaming across all loaders using real (small) models.
279
+ - **Security:** Gateway API-key auth, opt-in Ray cluster token auth, and payload/concurrency limits (`MSHIP_MAX_REQUEST_BODY_BYTES`) guard against unauthenticated or oversized requests.
280
+ - **Observability:** Deep integration with Prometheus, OpenTelemetry, and structured logging, with a pre-built Grafana dashboard and Prometheus alerting rules included.
281
+
282
+ We are currently hardening the Kubernetes/KubeRay path (a Helm chart ships in [`helm/`](helm/modelship/); GPU-aware probes and gateway-level rate-limiting are next). See the full [Production Readiness Plan](docs/production-readiness.md) for the scorecard and roadmap.
283
+
284
+ ## Open Responses Conformance
285
+
286
+ `/v1/responses` is also tested against the independent [Open Responses](https://github.com/openresponses/openresponses) compliance suite (`bun run test:compliance`), which exercises the endpoint over real HTTP against a live deployment rather than mocks.
287
+
288
+ **Latest result: 17/17** (`Qwen3-VL-8B-Instruct` AWQ, vLLM, 2026-07-24), including the full WebSocket transport suite:
289
+
290
+ | Test | Category | Status |
291
+ |---|---|---|
292
+ | Basic Text Response | Core | ✅ Pass |
293
+ | Assistant Message Phase | Core | ✅ Pass |
294
+ | Response Output Phase Schema | Core | ✅ Pass |
295
+ | Streaming Response | Core | ✅ Pass |
296
+ | System Prompt | Core | ✅ Pass |
297
+ | Multi-turn Conversation | Core | ✅ Pass |
298
+ | Tool Calling | Core | ✅ Pass |
299
+ | Compaction Endpoint | `/v1/responses/compact` | ✅ Pass |
300
+ | Compaction Missing Required Model | `/v1/responses/compact` | ✅ Pass |
301
+ | Image Input | Vision | ✅ Pass |
302
+ | WebSocket Response | WebSocket | ✅ Pass |
303
+ | WebSocket Sequential Responses | WebSocket | ✅ Pass |
304
+ | WebSocket Continuation | WebSocket | ✅ Pass |
305
+ | WebSocket Store False Reconnect Recovery | WebSocket | ✅ Pass |
306
+ | WebSocket Missing Previous Response | WebSocket | ✅ Pass |
307
+ | WebSocket Failed Continuation Evicts Cache | WebSocket | ✅ Pass |
308
+ | WebSocket Compact New Chain | WebSocket | ✅ Pass |
309
+
310
+ ## Contributing
311
+
312
+ See [CONTRIBUTING.md](CONTRIBUTING.md) for guidelines on setting up the dev environment, code style, and submitting pull requests.
@@ -0,0 +1,217 @@
1
+ <div align="center">
2
+ <picture>
3
+ <source media="(prefers-color-scheme: dark)" srcset="https://raw.githubusercontent.com/modelship-ai/modelship/main/docs/assets/logo-dark.svg">
4
+ <source media="(prefers-color-scheme: light)" srcset="https://raw.githubusercontent.com/modelship-ai/modelship/main/docs/assets/logo-light.svg">
5
+ <img alt="Modelship" src="https://raw.githubusercontent.com/modelship-ai/modelship/main/docs/assets/logo-light.svg" width="160">
6
+ </picture>
7
+ </div>
8
+
9
+ # Modelship
10
+
11
+ [![CI](https://github.com/modelship-ai/modelship/actions/workflows/ci.yml/badge.svg)](https://github.com/modelship-ai/modelship/actions/workflows/ci.yml)
12
+ [![License: Apache 2.0](https://img.shields.io/badge/License-Apache_2.0-blue.svg)](https://opensource.org/licenses/Apache-2.0)
13
+ [![Python 3.12+](https://img.shields.io/badge/python-3.12+-blue.svg)](https://www.python.org/downloads/)
14
+ [![Docs](https://img.shields.io/badge/docs-docs.model--ship.ai-0E7C86.svg)](https://docs.model-ship.ai/)
15
+
16
+ Modelship runs the AI stack your agents call — chat, the **Responses API** with server-side conversation state (durable with Redis), universal **tool calling**, and **reasoning**, alongside embeddings, speech, and image generation — behind one OpenAI-compatible endpoint on your own GPUs (or CPU). Built on [Ray Serve](https://docs.ray.io/en/latest/serve/index.html): state is shared across gateway replicas, deploys are declarative, and everything is observable. Point the OpenAI SDK at it and your agent runs unchanged — private, with no per-token bill.
17
+
18
+ ## Why Modelship?
19
+
20
+ - **Agent state that isn't siloed per replica** — the `/v1/responses` API with reasoning, universal tool/function calling, and server-side conversation state (`previous_response_id`) live in one pluggable store shared by every gateway replica — in-memory by default, or Redis for durability across restarts and node failure. Works across both the vLLM and llama.cpp (`llama_server`) loaders.
21
+ - **Everything an agent app calls, one endpoint** — chat, embeddings for RAG, speech-to-text, text-to-speech, and image generation, all behind a single OpenAI-compatible `/v1` surface. No juggling separate services for each modality.
22
+ - **Drop-in OpenAI, on your hardware** — any OpenAI SDK client works out of the box. Point it at Modelship instead of the OpenAI API and your agent code doesn't change — it just runs privately, on infrastructure you control.
23
+ - **GPU memory control** — allocate exact GPU fractions per model (e.g. 70% for the LLM, 5% for TTS) so a full stack fits on hardware you already own
24
+ - **Mix and match backends** — vLLM for high-throughput GPU or CPU inference, llama.cpp for efficient quantized GGUF models, Diffusers for images, sherpa-onnx for TTS, and whisper.cpp for STT — in the same deployment
25
+
26
+ ## Architecture
27
+
28
+ <picture>
29
+ <source media="(prefers-color-scheme: dark)" srcset="docs/assets/architecture-dark.svg">
30
+ <source media="(prefers-color-scheme: light)" srcset="docs/assets/architecture-light.svg">
31
+ <img alt="Modelship architecture: an agent app calls the Modelship gateway's OpenAI-compatible API, which exposes chat, embeddings, audio, and image endpoints plus a Responses API backed by a shared conversation-state store, routing round-robin to Ray Serve deployments across GPU and CPU cluster nodes." src="docs/assets/architecture-light.svg">
32
+ </picture>
33
+
34
+ Each model runs as an isolated [Ray Serve](https://docs.ray.io/en/latest/serve/index.html) deployment with its own lifecycle, health checks, and resource budget. Several inference backends are available:
35
+
36
+ | Backend | Best for | GPU required |
37
+ |---|---|---|
38
+ | **vLLM** | High-throughput chat, embeddings, transcription | No — installs on GPU or CPU |
39
+ | **llama.cpp** (`llama_server`) | High-efficiency quantized GGUF models (chat, embeddings, vision) | No |
40
+ | **Diffusers** | Image generation | Yes |
41
+ | **sherpa-onnx** | TTS (Kokoro) | No |
42
+ | **whisper.cpp** | STT | No |
43
+
44
+ Models can be deployed across multiple GPUs, run on CPU-only, or both — multiple deployments of the same model (e.g. one on GPU via vLLM, one on CPU via vLLM or llama.cpp) are load-balanced with round-robin routing. Each deployment can also scale horizontally with `num_replicas`.
45
+
46
+ ## Requirements
47
+
48
+ - **Docker** (or Python 3.12+ with `uv` for local development)
49
+ - **NVIDIA GPU** (optional) — 16 GB+ VRAM recommended for a full stack (LLM + TTS + STT + embeddings) via vLLM; 8 GB is sufficient for lighter setups. Not required when using the vLLM or llama.cpp backends on CPU
50
+ - **[NVIDIA Container Toolkit](https://docs.nvidia.com/datacenter/cloud-native/container-toolkit/install-guide.html)** — required only when running GPU models in Docker
51
+ - **HuggingFace token** for gated models
52
+
53
+ ## Features
54
+
55
+ - **Multi-model, multi-GPU** — run chat, embedding, STT, TTS, and image generation models simultaneously across one or more GPUs with tunable per-model GPU memory allocation
56
+ - **CPU-only support** — run models without a GPU using the vLLM or llama.cpp (`llama_server`) backends (chat, embeddings, transcription, vision). Useful for development, testing, or small models that don't need GPU acceleration
57
+ - **Multiple inference backends** — vLLM for high-throughput GPU or CPU inference, llama.cpp for efficient quantized GGUF models on CPU or GPU, Diffusers for image generation, sherpa-onnx for TTS, and whisper.cpp for STT
58
+ - **Zero-downtime hot-reloads** — modify your `models.yaml` and run a cluster reconcile; changes are applied incrementally without interrupting the API gateway or unchanged models
59
+ - **Advanced agentic capabilities** — native support for DeepSeek-style reasoning (`<think>` blocks parsed into `reasoning_content`) and universal tool/function calling across the vLLM and GGUF (`llama_server`) backends
60
+ - **Server-side MCP tool execution** — point `/v1/responses` at any self-hosted MCP server (`tools: [{"type": "mcp", ...}]`) and the gateway discovers its tools, calls them, and loops — with an approval flow (`require_approval`) client-driven tool calling doesn't have
61
+ - **Per-model isolated deployments** — each model runs in its own Ray Serve deployment with independent lifecycle, health checks, failure isolation, and configurable replica count
62
+ - **OpenAI-compatible API** — drop-in replacement for any OpenAI SDK client
63
+ - **Streaming** — SSE streaming for chat completions and TTS audio
64
+ - **Multi-GPU & hybrid routing** — assign models to specific GPUs or run them on CPU-only; deploy the same model on both GPU and CPU and requests are load-balanced via round-robin; full tensor parallelism support for large models spanning multiple GPUs
65
+ - **Client disconnect detection** — cancels in-flight inference when the client disconnects, freeing GPU resources immediately
66
+ - **Security** — gateway API-key authentication (`MSHIP_API_KEYS`), Ray cluster token auth (`--ray-auth=token`), and configurable request payload/concurrency limits
67
+ - **Built-in observability** — Prometheus metrics, custom `modelship:*` metrics, vLLM engine stats, Ray cluster metrics, structured JSON logging, and OpenTelemetry log export; pre-built Grafana dashboard and alerting rules included
68
+
69
+ ## Supported OpenAI Endpoints
70
+
71
+ | Endpoint | Usecase |
72
+ |---|---|
73
+ | `POST /v1/chat/completions` | Chat / text generation (streaming and non-streaming) |
74
+ | `POST /v1/responses` | Responses API — text, reasoning, client-driven tool calls, server-side MCP tool execution, and stored conversations (streaming and non-streaming) |
75
+ | `GET`/`DELETE /v1/responses/{id}` | Fetch or drop a stored response (`/input_items` lists its input); `background: true` on create + `POST .../cancel` for queued/pollable runs |
76
+ | `POST /v1/embeddings` | Text embeddings |
77
+ | `POST /v1/audio/transcriptions` | Speech-to-text |
78
+ | `POST /v1/audio/translations` | Audio translation |
79
+ | `POST /v1/audio/speech` | Text-to-speech (SSE streaming or single-response) |
80
+ | `POST /v1/images/generations` | Image generation |
81
+ | `GET /v1/models` | List available models |
82
+
83
+ ## Quick Start
84
+
85
+ The fastest way to try Modelship: run a tiny reasoning model on a laptop — no GPU required. Copy-paste this block and you'll have an OpenAI-compatible API on `http://localhost:8000` in a few minutes.
86
+
87
+ ```bash
88
+ mkdir -p models-cache && cat > models.yaml <<'EOF'
89
+ models:
90
+ - name: reasoning-qwen
91
+ model: "lmstudio-community/Qwen3-0.6B-GGUF:*Q4_K_M.gguf"
92
+ usecase: generate
93
+ loader: llama_server
94
+ num_cpus: 3
95
+ llama_server_config:
96
+ n_ctx: 4096 # Give reasoning space to think
97
+ EOF
98
+
99
+ docker run --rm --shm-size=8g \
100
+ -v ./models.yaml:/modelship/config/models.yaml \
101
+ -v ./models-cache:/.cache \
102
+ -p 8000:8000 \
103
+ ghcr.io/modelship-ai/modelship:latest-cpu
104
+ ```
105
+
106
+ Images are multi-arch (amd64 + arm64), so this works on Apple Silicon and ARM Linux hosts too.
107
+
108
+ Once the server is up (look for `Deployed app 'modelship api' successfully`), call the **Responses API** and watch the model think:
109
+
110
+ ```bash
111
+ curl http://localhost:8000/v1/responses \
112
+ -H "Content-Type: application/json" \
113
+ -d '{
114
+ "model": "reasoning-qwen",
115
+ "input": "Which is larger, 9.11 or 9.9?"
116
+ }'
117
+ ```
118
+
119
+ The response includes both `output_text` and a first-class `reasoning` output item — the same server-side conversation state (`previous_response_id`) and tool-calling support work here as they do on GPU-backed models. `/v1/chat/completions` remains available too, if that's what your client speaks.
120
+
121
+ ### Native install (no Docker)
122
+
123
+ One install command everywhere, then pick the node's role at run time:
124
+
125
+ ```bash
126
+ pipx install mship # or: uv tool install mship / pip install mship
127
+
128
+ mship deploy --cuda --config models.yaml # NVIDIA GPU node
129
+ mship deploy --cpu --config models.yaml # CPU node (includes vLLM CPU)
130
+ mship deploy --metal --config models.yaml # Apple Silicon
131
+ mship deploy --thin --config models.yaml # coordinator/head only, no capacity
132
+ ```
133
+
134
+ Nothing to pin and nothing to match across machines. The first run of a variant sets itself up; after that it starts straight through. Every node lands on the same footing, so a new one joins the cluster by running the same command.
135
+
136
+ Platform prerequisites still apply: Xcode Command Line Tools on macOS, `build-essential`/`cmake` on Linux, plus `ninja-build` and NVIDIA's `nvcc` for `--cuda`. Alpine and other musl distros are unsupported. See [docs/installation.md](docs/installation.md) for the full list.
137
+
138
+ ### GPU (vLLM, Diffusers)
139
+
140
+ For high-throughput GPU inference, use the `-cuda` image and add `--gpus all`. You'll also need the [NVIDIA Container Toolkit](https://docs.nvidia.com/datacenter/cloud-native/container-toolkit/install-guide.html) and an `HF_TOKEN` for gated models. Example `models.yaml` entries for vLLM, Diffusers, and multi-GPU setups live in [docs/model-configuration.md](docs/model-configuration.md); ready-to-run configs are in [config/examples/](config/examples/).
141
+
142
+ ```bash
143
+ docker run --rm --shm-size=8g --gpus all \
144
+ -e HF_TOKEN=your_token_here \
145
+ -v ./models.yaml:/modelship/config/models.yaml \
146
+ -v ./models-cache:/.cache \
147
+ -p 8000:8000 \
148
+ ghcr.io/modelship-ai/modelship:latest-cuda
149
+ ```
150
+
151
+ > [!NOTE]
152
+ > `ghcr.io/modelship-ai/modelship:latest` (bare tag, no suffix) is the **thin** control/coordinator image — no torch/vllm, for a driver/head role only. It cannot serve models by itself; always use `-cuda` or `-cpu` to actually run inference. See [docs/development.md](docs/development.md) for the full three-image breakdown.
153
+
154
+ > [!TIP]
155
+ > Always set `--shm-size=8g` (or higher) when running the docker container to prevent PyTorch from hitting shared memory limits during multi-process operations.
156
+
157
+ Hitting an error? Check [docs/troubleshooting.md](docs/troubleshooting.md).
158
+
159
+ ## Documentation
160
+
161
+ Full docs are hosted at **[docs.model-ship.ai](https://docs.model-ship.ai/)**. The same source files are also browsable directly in this repo:
162
+
163
+ - [Development](docs/development.md) — dev environment setup, building, and running locally
164
+ - [Model Configuration](docs/model-configuration.md) — full `models.yaml` reference, GPU pinning, environment variables
165
+ - [Multi-node without Kubernetes](docs/multi-node-docker.md) — join VMs into one Ray cluster with plain `docker run`, no orchestrator
166
+ - [Architecture](docs/architecture.md) — system design, request lifecycle, loaders
167
+ - [Monitoring & Logging](docs/monitoring.md) — Prometheus metrics, Grafana dashboard, structured logging, health checks
168
+ - [Troubleshooting](docs/troubleshooting.md) — common first-run errors and fixes
169
+
170
+ ## Monitoring
171
+
172
+ Modelship exposes Prometheus metrics (Ray cluster, Ray Serve, vLLM, and custom `modelship:*` metrics) through a single scrape endpoint on port 8079. Metrics are **enabled by default** — set `MSHIP_METRICS=false` to disable. A pre-built [Grafana dashboard](docs/grafana-dashboard.json) and [Prometheus alerting rules](docs/prometheus-alerts.yml) are included in the repository.
173
+
174
+ Logging supports structured JSON output (`MSHIP_LOG_FORMAT=json`) and request ID correlation across Ray actor boundaries. Logs can be shipped to a remote syslog server (`--log-target syslog://host:514`) or an OpenTelemetry collector (`--otel-endpoint http://collector:4317`). Set `MSHIP_LOG_LEVEL` to `TRACE` for full request/response payloads, or `DEBUG` for detailed diagnostics without payloads.
175
+
176
+ See [Monitoring & Logging](docs/monitoring.md) for full details.
177
+
178
+ ## Production Readiness
179
+
180
+ Modelship is actively used and designed for stability in multi-tenant setups. Key guarantees include:
181
+
182
+ - **Mutex-backed deployments:** A cluster-wide deploy coordinator prevents VRAM exhaustion by ensuring models are never loaded concurrently if resources are tight.
183
+ - **Comprehensive HTTP-level tests:** The `tests/test_*_integration.py` suites validate chat, reasoning, tool-calling, and streaming across all loaders using real (small) models.
184
+ - **Security:** Gateway API-key auth, opt-in Ray cluster token auth, and payload/concurrency limits (`MSHIP_MAX_REQUEST_BODY_BYTES`) guard against unauthenticated or oversized requests.
185
+ - **Observability:** Deep integration with Prometheus, OpenTelemetry, and structured logging, with a pre-built Grafana dashboard and Prometheus alerting rules included.
186
+
187
+ We are currently hardening the Kubernetes/KubeRay path (a Helm chart ships in [`helm/`](helm/modelship/); GPU-aware probes and gateway-level rate-limiting are next). See the full [Production Readiness Plan](docs/production-readiness.md) for the scorecard and roadmap.
188
+
189
+ ## Open Responses Conformance
190
+
191
+ `/v1/responses` is also tested against the independent [Open Responses](https://github.com/openresponses/openresponses) compliance suite (`bun run test:compliance`), which exercises the endpoint over real HTTP against a live deployment rather than mocks.
192
+
193
+ **Latest result: 17/17** (`Qwen3-VL-8B-Instruct` AWQ, vLLM, 2026-07-24), including the full WebSocket transport suite:
194
+
195
+ | Test | Category | Status |
196
+ |---|---|---|
197
+ | Basic Text Response | Core | ✅ Pass |
198
+ | Assistant Message Phase | Core | ✅ Pass |
199
+ | Response Output Phase Schema | Core | ✅ Pass |
200
+ | Streaming Response | Core | ✅ Pass |
201
+ | System Prompt | Core | ✅ Pass |
202
+ | Multi-turn Conversation | Core | ✅ Pass |
203
+ | Tool Calling | Core | ✅ Pass |
204
+ | Compaction Endpoint | `/v1/responses/compact` | ✅ Pass |
205
+ | Compaction Missing Required Model | `/v1/responses/compact` | ✅ Pass |
206
+ | Image Input | Vision | ✅ Pass |
207
+ | WebSocket Response | WebSocket | ✅ Pass |
208
+ | WebSocket Sequential Responses | WebSocket | ✅ Pass |
209
+ | WebSocket Continuation | WebSocket | ✅ Pass |
210
+ | WebSocket Store False Reconnect Recovery | WebSocket | ✅ Pass |
211
+ | WebSocket Missing Previous Response | WebSocket | ✅ Pass |
212
+ | WebSocket Failed Continuation Evicts Cache | WebSocket | ✅ Pass |
213
+ | WebSocket Compact New Chain | WebSocket | ✅ Pass |
214
+
215
+ ## Contributing
216
+
217
+ See [CONTRIBUTING.md](CONTRIBUTING.md) for guidelines on setting up the dev environment, code style, and submitting pull requests.
File without changes
File without changes