motif64

m64_04b2a07e4eac / AGENT.md

75 lines, 2.9 KBraw

deepseek-flash-openrouter-gb10

An OpenAI-compatible chat endpoint for DeepSeek V4.1 Flash (OpenRouter model deepseek/deepseek-v4.1-flash). It only provides the model: run opencode (or any OpenAI-compatible client) on your own machine and point it here. Your files and tools stay on your machine; only the model calls come to this capsule.

No GPU. The container's only egress is openrouter.ai:443, through the m64 gate, which adds the OpenRouter key: the capsule never holds it.

Routes

All paths are relative to the capsule's URL (e.g. http://<tailnet-ip>:<port>).

Method Path What
POST /v1/chat/completions OpenAI chat completions, streaming or not
GET /v1/models one model: deepseek-v4.1-flash
GET /status phase (ready when usable)
GET /agent this document plus live status
GET /human/ landing page: opencode setup and a quick-test chat

POST /v1/chat/completions

Body: application/json only (415 otherwise). Accepted fields:

  • messages (required), tools, tool_choice, response_format, max_tokens, stream, capsule;
  • model, user, stream_options are accepted and ignored or passed on; n must be 1. The model is always DeepSeek V4.1 Flash, whatever model says.

Any other field (e.g. temperature, top_p) is refused with 400 naming the field.

stream: true returns Server-Sent Events (data: {...} chunks, ending with data: [DONE]), relayed as OpenRouter sends them. OpenRouter may interleave SSE comment lines (: OPENROUTER PROCESSING) while the model thinks; SSE clients ignore them. Non-streaming responses are OpenRouter's JSON, plus params_used.

Errors from OpenRouter (rate limits, upstream failures) keep their status and body.

curl -s $URL/v1/chat/completions -H 'Content-Type: application/json' \
  -d '{"messages":[{"role":"user","content":"Say hi"}],"max_tokens":50}'

curl -N $URL/v1/chat/completions -H 'Content-Type: application/json' \
  -d '{"messages":[{"role":"user","content":"Count to 5"}],"stream":true}'

opencode on your machine

~/.config/opencode/opencode.json (global) or opencode.json in the project root:

{
  "$schema": "https://opencode.ai/config.json",
  "provider": {
    "dsflash": {
      "npm": "@ai-sdk/openai-compatible",
      "name": "DeepSeek V4.1 Flash (capsule)",
      "options": { "baseURL": "<capsule URL>/v1" },
      "models": { "deepseek-v4.1-flash": { "name": "DeepSeek V4.1 Flash", "tool_call": true } }
    }
  },
  "model": "dsflash/deepseek-v4.1-flash"
}

Or, on a machine with m64: m64 deepseek-flash-openrouter-gb10 --ui opencode serves the capsule and starts opencode with a generated config pointing at it.

Access

On the tailnet (the default bind) there is no token: anyone on the tailnet can use the endpoint and so spend the OpenRouter key. With a token (--host 0.0.0.0 etc.), send Authorization: Bearer <token> (opencode: "apiKey": "<token>" in the provider options).