Skip to content

Request normalization

The same OpenAI-style parameter can behave differently across open-model serving stacks: one honors it, one ignores it, one rejects it with its own error. Keln normalizes requests and responses per model, so one request shape works everywhere and tool calls and reasoning fields behave the same on every provider.

Parameters

Keln honors standard parameters or translates them per model. Support for some parameters varies by provider (seed, n, logprobs, logit_bias, the frequency/presence penalties, stop). A request that uses one goes to a provider that supports it, and tools, JSON modes, and image input route the same way. When no provider serving the model can honor a hard requirement, Keln returns a 400 naming the parameter.

Keln passes open-model extensions (top_k, min_p, repetition_penalty) through where the serving stack supports them, and names any field it accepts but does not act on in the x-keln-inert-params response header.

Message shapes

  • developer role is treated as system.
  • Content can be a string or a text-part array.
  • A replayed reasoning field folds into reasoning_content, and replayed reasoning_content is preserved, so multi-turn tool calling keeps the trace (reasoning).
  • cache_control blocks are ignored (caching is automatic).
  • Unknown fields are ignored.

Repairs while the response streams

Keln normalizes every response to the spec shape:

  • Streamed tool-call fragments arrive with dense, 0-based indices.
  • A <think> block that a provider left inside content is moved to reasoning_content.
  • If a provider ignores max_tokens, Keln cuts the output at your cap.
  • Keln handles stop-sequence differences between providers so you never see them.

Rejected before billing

Keln counts each request with the model's tokenizer against its context window (context_length in /v1/models) and returns 400 context_length_exceeded for an oversized request before billing any tokens.

Stripped before dispatch

Keln removes end-user identifiers (user, safety_identifier), storage and metadata flags, and provider-steering fields before a request leaves Keln, as part of zero data retention. It also detects and removes system prompts that a provider injects, so the model sees only your messages.

Full per-parameter behavior: Chat completions reference ↗