See llms.txt for all machine-readable content.
An n8n-first, durable FIFO gateway for a local OpenAI-compatible language model. It accepts ordinary Chat Completions requests, queues them in PostgreSQL, runs one inference at a time, and supports human retrieval commands, automatic waiting by shell-capable AI harnesses, and OpenAI-compatible SSE response framing.
/v1/chat/completions webhook secured with header authentication.stream: true is requested./v1/queue/tasks/:taskId webhook to return the durable status, queue position, and any stored error details for a specific task./v1/models webhook to return the configured comma-separated model identifiers without calling the upstream LLM.llm_queue_jobs table and indexes./v1/chat/completions, /v1/queue/tasks/:taskId, and /v1/models) and deploy behind TLS./v1/models.POST /v1/chat/completions
The body is the ordinary OpenAI Chat Completions request. Both stream: false and stream: true are accepted. The original body is stored in PostgreSQL; the dispatcher forces the upstream request to stream: false and removes stream_options so the result can be persisted reliably.
curl -sS "$OPENAI_BASE_URL/chat/completions" \
-H "Authorization: Bearer $OPENAI_API_KEY" \
-H 'Content-Type: application/json' \
-d '{
"model": "queued-local-model",
"messages": [{"role": "user", "content": "Explain transactional queues."}],
"stream": false,
"max_tokens": 800
}' | jq
For SSE-compatible mode:
curl -sS -N "$OPENAI_BASE_URL/chat/completions" \
-H "Authorization: Bearer $OPENAI_API_KEY" \
-H 'Content-Type: application/json' \
-d '{
"model": "queued-local-model",
"messages": [{"role": "user", "content": "Explain transactional queues."}],
"stream": true,
"stream_options": {"include_usage": true},
"max_tokens": 800
}'
When stream: true, successful Chat Completions responses use Content-Type: text/event-stream. The gateway converts its queue acknowledgement, synthetic waiting tool call, or stored completion into OpenAI chat.completion.chunk events and terminates the response with data: [DONE].
This is SSE protocol compatibility, not live GPU-token streaming. The initial request still returns promptly after enqueueing. After a shell-capable harness reports that waiting has completed, the stored answer is replayed as SSE chunks. If stream_options.include_usage is true, a final usage chunk with an empty choices array is emitted before [DONE].
GET /v1/queue/tasks/:taskId
curl -sS "$OPENAI_BASE_URL/queue/tasks/task_REPLACE_ME" \
-H "Authorization: Bearer $OPENAI_API_KEY" | jq
GET /v1/models
A normal prompt returns immediately:
Your request is queued as task_....
Check it with /result task_....
The following messages are handled by the gateway and do not use GPU tokens:
/result task_ID or /wait task_ID: retrieve status or the completed OpenAI response/cancel task_ID: cancel a task that is still queued/queue: list up to 50 active tasksIf the request advertises a supported function tool with a string command argument, the gateway returns an OpenAI-compatible synthetic tool call. Supported names are:
exec_commandrun_commandbashshellterminalexecSupported string arguments are cmd, command, and script.
The generated command:
curl and jq.When the harness posts the shell tool result back to Chat Completions, the gateway recognizes the reserved queue_wait_task_... tool-call ID and returns the stored model completion directly. It does not schedule a second inference.
The harness must expose the shell tool in the original request and must preserve the tool-call ID in its continuation. If it does not, the workflow falls back to the human command response.
created_at, id.running task is permitted.curl + jq being installed.