Tools
ClawDuctor
An OpenClaw plugin that manages LM Studio model loading, request concurrency, queuing, and provider synchronization.
Install
npm install
npm
Configuration Example
{
"plugins": {
"allow": ["clawductor"],
"entries": {
"clawductor": {
"enabled": true,
"config": {
"lmsCommand": "lms",
"maxLoadedLlms": 1,
"defaultParallel": 1,
"syncModels": "once",
"switchTimeoutMs": 300000,
"pollIntervalMs": 250,
"modelOverrides": {
"qwen/qwen3.6-35b-a3b": {
"parallel": 1,
"contextLength": 262144
}
},
"managedEmbeddings": [
{
"modelId": "text-embedding-google_embeddinggemma-300m-qat",
"identifier": "text-embedding-google_embeddinggemma-300m-qat",
"contextLength": 2048
}
]
}
}
}
}
}
README
# Clawductor
Clawductor is an OpenClaw provider plugin that manages LM Studio model loading
before inference.
## Requirements
- OpenClaw `2026.7.1-2` or a compatible later 2026 release.
- Node.js `22.22.3`, `24.15.0`, `25.9.0`, or a newer compatible release in
those supported major lines.
- LM Studio CLI available as `lms`, or configured with an absolute path to
`lms.exe`.
## What Clawductor does
- Reuses the existing `models.providers.lmstudio.models` catalog.
- Ensures a configured `models.providers.clawductor` mirror exists so the
OpenClaw allowlist and model picker recognize Clawductor models.
- Resolves each configured model ID against `lms ls --json` before loading it,
including case-insensitive `_` versus `/` separator differences.
- Exposes the same models as `clawductor/<model-id>`.
- Routes Clawductor LLM and embedding requests through one shared queue.
- Exposes a Gateway-authenticated, loopback-only non-streaming inference route
for separate local processes.
- Waits for active LLM and embedding inference to finish.
- Unloads managed embeddings during an LLM switch.
- Loads the requested LLM first with explicit context length and `--parallel`.
- Reloads managed embeddings only after the LLM-first state is verified.
- Verifies model IDs, identifiers, context lengths, parallelism, idle state,
and the complete loaded-model set before inference.
- Stops the request if loading or verification fails.
Same-model requests can run concurrently up to that model's configured
`parallel` value. A request for a different model waits until all active
requests finish.
## Local inference route
Clawductor registers this exact route on the OpenClaw Gateway:
```text
POST /clawductor/v1/chat/completions
```
The Gateway must authenticate the request. Clawductor then independently
requires the network client and any browser `Origin` header to be loopback,
requires `Content-Type: application/json`, and requires `stream` to be
`false`. The requested model must exist in the live
`models.providers.clawductor.models` catalog. The LM Studio base URL is read
from that same live provider configuration when inference begins.
The request body is limited to 2 MiB and must arrive within 30 seconds. The
upstream response is limited to 8 MiB. Inference has a 30-minute response
deadline, but a deadline response does not release the lease early: the
in-flight LM Studio operation continues to hold the shared queue until it
actually settles.
Queue waiting itself has no timeout. Requests are non-replaceable by default.
A caller may explicitly make a request replaceable by sending both headers:
```text
X-Clawductor-Queue-Mode: replaceable
X-Clawductor-Caller-Id: <stable-caller-id>
```
When a newer replaceable request from the same caller arrives, an older one
that is still waiting is rejected and the newer request keeps its queue
position. If model preparation already began, Clawductor finishes preparation
to a verified safe state before rejecting the older request. Once inference
has acquired a lease, replacement never cancels it.
The route never forwards the Gateway authorization header to LM Studio and
never logs request bodies, response bodies, prompts, credentials, or model
output.
## Configured-provider synchronization
OpenClaw 2026.7.1-2 does not treat a provider registered only by a plugin as a
configured provider when it builds the model allowlist. On full plugin
activation, Clawductor uses OpenClaw's supported transactional config mutation
API to create `models.providers.clawductor` from
`models.providers.lmstudio`.
Before a change, Clawductor writes a timestamped backup next to
`openclaw.json`. OpenClaw also validates the source and result, performs the
write atomically, maintains its own rotating backups, and plans the hot reload.
The next activation is a no-op, so the reload cannot loop.
Clawductor never changes or deletes an existing provider or model entry:
- `syncModels: "once"` (default) creates the provider only when absent.
- `syncModels: "always"` also appends models that exist in `lmstudio` but are
missing from `clawductor`. Existing entries are never modified.
If `models.providers.lmstudio` does not exist, activation logs an informational
message and continues without writing.
Configured model IDs are intentionally preserved. Resolution changes only the
key passed to `lms load`; it never silently rewrites a user's config.
## Configuration
```json
{
"plugins": {
"allow": ["clawductor"],
"entries": {
"clawductor": {
"enabled": true,
"config": {
"lmsCommand": "lms",
"maxLoadedLlms": 1,
"defaultParallel": 1,
"syncModels": "once",
"switchTimeoutMs": 300000,
"pollIntervalMs": 250,
"modelOverrides": {
"qwen/qwen3.6-35b-a3b": {
"parallel": 1,
"contextLength": 262144
}
},
"managedEmbeddings": [
{
"modelId": "text-embedding-google_embeddinggemma-300m-qat",
"identifier": "text-embedding-google_embeddinggemma-300m-qat",
"contextLength": 2048
}
]
}
}
}
}
}
```
An absolute Windows command path is also supported:
```json
{
"lmsCommand": "C:\\Users\\YourName\\.lmstudio\\bin\\lms.exe"
}
```
Keep model definitions under `models.providers.lmstudio.models`. Change
selectable/default/agent model references from `lmstudio/<model-id>` to
`clawductor/<model-id>` only after the plugin is installed and inspected.
## Pre-flight diagnostic
Run:
```powershell
openclaw clawductor doctor
```
The diagnostic prints every configured Clawductor model, its resolved LMS load
key, and whether the key exists locally. Unresolved models include near
matches, exit with a non-zero status, and retain their original ID at runtime
instead of guessing. Use `--json` for machine-readable output.
## Local installation
Back up `openclaw.json`, then install the archive:
```powershell
openclaw plugins install .\clawductor-0.4.0.tgz
openclaw plugins inspect clawductor --runtime --json
openclaw clawductor doctor
```
Do not change model references until inspection reports `status: "loaded"` and
an empty diagnostics array.
## Boundary
- Exactly one LLM may be loaded.
- Every LM Studio embedding that may be loaded must appear in
`managedEmbeddings`.
- Unmanaged loaded models cause a fail-closed error and are never unloaded.
- `lmstudio/...` requests bypass Clawductor.
- Embedding requests not routed through `memorySearch.provider = "clawductor"`
bypass the shared scheduler.
- Managing two simultaneously loaded LLMs is a later scheduler extension.
LM Studio's UI Parallel badge and `lms ps --json` report the requested value,
not the allocated slot count. Verify actual slot allocation in the LM Studio
Developer Logs (`srv load_model: initializing, n_slots = ...`) or by comparing
single-request and concurrent-request wall times.
## Development
```powershell
npm install
npm run check
npm test
npm run pack:check
```
Target: OpenClaw `2026.7.1-2`.
tools
Comments
Sign in to leave a comment