ServicesAI Services

/chat/completions Endpoint

Auto-passthrough mechanism, format conversion, SSE event mapping, and calling methods.

POST /v1/ai/chat/completions is the OpenAI-compatible endpoint.

How It Works

POST /v1/ai/chat/completions
  { model, messages, stream }


       resolve(mode: "openai")

    ┌─────────┴──────────┐
    │                    │
  Has openai handler  No openai handler
  (non-OpenAI format) (OpenAI-compatible)
    │                    │
    ▼                    ▼
  Custom conversion    Auto passthrough
    │                    │
    ▼                    ▼
  Response            Response

Auto Passthrough

When a provider has baseURL + envKey but no openai handler, AIService auto-generates a passthrough:

async (ctx) => {
  const apiKey = ctx.env(envKey);
  return fetch(`${baseURL}/chat/completions`, {
    headers: { Authorization: `Bearer ${apiKey}` },
    body: JSON.stringify(ctx.input),  // forward as-is
  });
};

No ai-sdk. No type conversion. Fully transparent.

Format Conversion

For OpenAI-compatible providers with custom upstream requirements, the openai handler can do bidirectional conversion.

SSE Event Mapping (Custom Upstream → OpenAI)

Upstream SSE EventOpenAI SSE Chunk
message_startdelta: { role: "assistant" }
content_block_delta (text_delta)delta: { content: "..." }
content_block_delta (input_json_delta)delta: { tool_calls: [...] }
message_deltafinish_reason: "stop" + usage
message_stopdata: [DONE]

stop_reason Mapping

UpstreamOpenAI
end_turnstop
max_tokenslength
tool_usetool_calls

Calling

# curl streaming
curl http://127.0.0.1:43127/v1/ai/chat/completions \
  -H "Authorization: Bearer ub_xxx" \
  -d '{"model":"deepseek-v4-flash","messages":[{"role":"user","content":"hello"}],"stream":true}'
// OpenAI SDK
const openai = new OpenAI({
  baseURL: "http://127.0.0.1:43127/v1/ai",
  apiKey: "ub_xxx",
});
await openai.chat.completions.create({
  model: "deepseek-v4-flash",
  messages: [{ role: "user", content: "hello" }],
  stream: true,
});