Files
scriptorium/docs/integrations/openai-compatible-chat.md

4.4 KiB

OpenAI-Compatible Chat Integration

This is the outbound wire contract for Scriptorium's OpenAI-compatible chat-completions client.

Endpoint And Method

Scriptorium uses the request endpoint override when present; otherwise it uses the configured client base URL. It removes a trailing slash and sends POST /chat/completions.

For example, http://localhost:8000/v1 becomes http://localhost:8000/v1/chat/completions.

Request Payload

The payload always contains model and rendered messages. It additionally contains these fields when applicable:

Field Inclusion
session_id Non-empty rendered prompt session ID.
temperature Non-zero effective value or an explicit zero override.
max_tokens Non-zero effective value or an explicit zero override.
top_p Non-zero effective value or an explicit zero override.
service_tier Any non-empty configured value.
reasoning_effort Any non-empty configured value.
response_format Structured output is requested.
provider-specific fields Flattened from extra_params.

service_tier and reasoning_effort are forwarded without a provider value catalog; the selected backend decides which values it supports.

extra_params are top-level JSON fields, not a nested object. Keys cannot be empty or collide with model, session_id, messages, temperature, max_tokens, top_p, service_tier, reasoning_effort, or response_format. Values must be JSON-serializable.

A rendered session_id is sent as a top-level JSON field, not as a header. Empty values are omitted. The maximum length is 256 Unicode code points.

Messages without cache control use string content. A message with cache control uses one text block:

{
  "role": "system",
  "content": [{
    "type": "text",
    "text": "rendered text",
    "cache_control": {"type": "ephemeral", "ttl": "1h"}
  }]
}

When the prompt omits cache-control ttl, the payload omits ttl. Structured JSON Schema output is sent as:

{
  "response_format": {
    "type": "json_schema",
    "json_schema": {
      "name": "schema name",
      "strict": true,
      "schema": {"type": "object"}
    }
  }
}

Authentication And Timeout

When a direct request API key is present, Scriptorium sends Authorization: Bearer <key> and does not read api_key_env. Otherwise, it resolves the configured non-empty api_key_env at request time and sends the same header. If neither mechanism supplies a key, it sends no Authorization header.

The transport-wide safety cap is chosen at client construction. A positive timeout on a supplied http.Client takes precedence over a positive Config.Timeout; if neither is positive, the internal ten-minute default is used. The supplied client is cloned, and zero or negative timeout values are treated as unset.

Separately, a positive effective timeout_seconds creates a deadline for each outbound generation call. Its value follows the execution-setting hierarchy: an explicit request override, then a non-zero profile value, then the 600-second framework default. An explicit request override of zero disables only this generation deadline. Negative values are rejected before a request is sent.

The complete observable rule is that the earliest caller-context deadline, transport cap, or positive generation deadline terminates the call. Transport and cancellation failures retain the generation-error classification.

Response Subset And Failures

A successful provider response must supply non-empty choices[0].message.content. Scriptorium reads these optional or required usage fields when present:

  • usage.prompt_tokens
  • usage.completion_tokens
  • usage.total_tokens
  • usage.prompt_tokens_details.cached_tokens
  • usage.cache_write_tokens

Missing cache usage is reported as zero. Invalid JSON, an empty choices array, or empty first-choice content is a malformed provider response. Network and request-construction failures, non-2xx responses, and malformed responses fail the outbound call. Provider response bodies are not exposed by this client.

The client does not implement built-in retries, tool calls, top-level cache_control, or multi-request payload modes.

Prompt schema preparation and runner orchestration are described in runner internals. Prompt and profile configuration is defined by the configuration reference.