Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

HTTP proxy quickstart

The proxy puts a network boundary around the Rust engine. Use it from any language that can send JSON over HTTP.

Availability: Rust: engine inside the server · CLI: starts the server · HTTP: compact llmshim API · Clients: connect to this API

The proxy has its own compact contract. It is not an OpenAI-compatible proxy.

1. Install a proxy-enabled binary

The proxy is behind the crate's proxy feature when building from source:

cargo install llmshim --features proxy

The Homebrew binary also includes the proxy:

brew install sanjay920/tap/llmshim

Configure at least one provider before starting it:

llmshim configure

2. Start the server

llmshim proxy

The default bind address is 0.0.0.0:3000. Override it for the process with LLMSHIM_HOST and LLMSHIM_PORT:

LLMSHIM_HOST=127.0.0.1 LLMSHIM_PORT=8080 llmshim proxy

The examples below assume the default port and use localhost to reach it.

3. Send a chat request

curl http://localhost:3000/v1/chat \
  -H 'Content-Type: application/json' \
  -d '{
    "model": "openai/gpt-6-sol",
    "messages": [
      {"role": "user", "content": "What is Rust in one sentence?"}
    ],
    "config": {
      "max_tokens": 128
    },
    "provider_config": {
      "x-anthropic": {
        "disable_1m_context": true
      }
    }
  }'

config contains portable controls. provider_config is optional and merges provider-specific fields into the core request; omit it when you do not need a native control.

The non-streaming response uses llmshim's compact ChatResponse:

{
  "id": "msg_...",
  "model": "gpt-6-sol",
  "provider": "openai",
  "message": {
    "role": "assistant",
    "content": "Rust is a systems programming language..."
  },
  "usage": {
    "input_tokens": 15,
    "output_tokens": 12,
    "total_tokens": 27
  },
  "latency_ms": 640
}

IDs, text, token counts, and timing vary by request. reasoning and message.tool_calls appear only when the provider returns them.

Set top-level "stream": true on the same request to receive typed SSE events instead of a JSON response. POST /v1/chat/stream is the always-streaming equivalent.

See the HTTP API for the full contract.

Do not expose the bare proxy publicly

The server has permissive CORS and provides no authentication or TLS. For local use, bind it to 127.0.0.1. For a public deployment, put it behind an external gateway that supplies authentication and TLS. The supported topology and deployment checklist are covered in Deploy the proxy safely.

Stateless Responses requests

POST /v1/responses accepts a Responses request with a configured model route:

curl http://localhost:3000/v1/responses \
  -H 'Content-Type: application/json' \
  -d '{"model":"openai/gpt-6-astra","input":"Hello","store":false}'

This endpoint supports JSON and streaming requests: string input or message items with text/image parts, instructions, function tools and tool-call/result items, tool_choice, max_output_tokens, temperature, top_p, reasoning.effort, and text.format (text, JSON object, or JSON Schema). Function arguments and tool outputs are strings. Send the full history on every request; call_id links a function call to its output. Images require image_url, with optional detail (auto, low, or high). File inputs and file-backed images are unsupported.

The result has object: "response", message/output-text or refusal items, function-call items, provider-supplied reasoning summaries, and input/output, cached, and reasoning token details. Token exhaustion returns status: "incomplete" and incomplete_details.reason: "max_output_tokens". The proxy and gateway share their existing admission, logging, error status, Retry-After, and credential behavior with this route.

Set stream: true for Responses SSE events with contiguous sequence numbers and a terminal response containing output and usage. Reasoning items returned by an earlier request can be included unchanged in input; scoped receipts preserve provider provenance. Unsupported or unissued reasoning is dropped with reasons in metadata.reasoning_dropped. Use include: ["reasoning.encrypted_content"] for encrypted output where supported.

previous_response_id, conversation, store: true, and hosted tools return a named 400. Unknown top-level fields are refused. See native APIs for the stream and replay contract.