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

OpenAI Chat Completions

The Chat Completions API (POST {base_url}/chat/completions) with an API key. Works against OpenAI and any endpoint implementing that format: Ollama, vLLM, LM Studio, OpenRouter, Synthetic, LiteLLM.

This is not the legacy /v1/completions endpoint, which is a different protocol: a bare prompt string in, choices[].text out, no tool calling. Several of those same servers also expose it; meka does not implement it.

For the same key against OpenAI’s newer protocol, see openai-responses.

Configuration

SettingValue
Account backendopenai-chat-completions
Default base URLhttps://api.openai.com/v1
CredentialAPI key (sk-...) kept in the store
Auth methodBearer token (Authorization: Bearer <key>)

Quickest start

meka account add openai --backend openai-chat-completions
meka profile add work --account openai --model gpt-6-astra

meka account add prompts for your OpenAI API key, saves it to the store, and writes the [accounts.openai] table. To read the key from a pipe instead of prompting, pass --api-key-stdin. meka profile add then writes the profile that names the model.

Config file

The two commands write this for you (the key stays in the store, not here):

default_profile = "work"

[accounts.openai]
backend = "openai-chat-completions"

[profiles.work]
account = "openai"
model   = "gpt-6-astra"

Supported models

Any model reachable over the Chat Completions API that supports tool calling. For OpenAI’s current line-up, see OpenAI’s models overview; meka profile add suggests gpt-6-astra for a profile on an OpenAI account. Against a compatible endpoint the valid names are that server’s: whatever Ollama, vLLM, LM Studio or OpenRouter serves. meka forwards the model string verbatim and doesn’t gate which strings are valid.

Custom base URL

To use an OpenAI-compatible endpoint, set the account’s base_url when creating it:

# Ollama (no real key; pipe a placeholder)
printf 'unused' | meka account add ollama --backend openai-chat-completions \
    --base-url http://localhost:11434/v1 --api-key-stdin
meka profile add llama --account ollama --model llama3

# OpenRouter
meka account add openrouter --backend openai-chat-completions \
    --base-url https://openrouter.ai/api/v1
meka profile add sonnet --account openrouter --model anthropic/claude-sonnet-5.5

The resulting tables (the key, if any, lives in the store):

[accounts.ollama]
backend  = "openai-chat-completions"
base_url = "http://localhost:11434/v1"

[profiles.llama]
account = "ollama"
model   = "llama3"

API details

Endpoint: POST {base_url}/chat/completions

Tool format: Tools are sent as function definitions:

{
  "type": "function",
  "function": {
    "name": "file_read",
    "description": "Read the contents of a file at the given path.",
    "parameters": { "type": "object", "properties": { ... } }
  }
}

Tool results: Sent back as messages with role: "tool" and the corresponding tool_call_id.

Streaming: Uses Server-Sent Events (SSE) with data: {...} lines. The stream ends with data: [DONE].

Usage: a streamed request asks for its usage with stream_options.include_usage, which OpenAI’s own API needs before it reports any; an endpoint that refuses the field takes the account’s stream_usage set to false. The cached_tokens an endpoint reports under prompt_tokens_details count as cache reads in /status and the per-turn usage line.

Reasoning: the reasoning_content an endpoint streams (or reasoning, as vLLM and OpenRouter spell it) is shown as thinking, kept in the session, and sent back on every later request as the assistant message’s reasoning_content. DeepSeek’s thinking mode rejects a request with tools that omits an earlier turn’s reasoning; the other endpoints accept or ignore it. Reasoning another backend recorded is never sent here.