v1.1.4
[1.1.4] — 2026-06-19
Provider-translation correctness release. Tool/function calling, sampling parameters, completion-token limits, finish-reason normalization, multimodal input, and streaming fidelity are now correctly translated across native and OpenAI-compatible providers. Bundles an 11-bump dependency sweep and an internal shared-helper refactor (~1,800 lines of duplication removed) with no public API breaks. Fixes every issue labelled release-1.1.4: #139, #140, #141, #142, #143, #144, and #145.
Fixed
- Tool / function calling dropped on native non-OpenAI providers (issue #139, PR #214): Anthropic, Gemini, Bedrock (Claude), and Cohere now forward
tools/tool_choicein each provider's native shape, parsetool_use/tool_callsresponses (JSON-object arguments → JSON string), assemble streaming tool-call deltas with index remapping, and handle multi-turn tool round-trips. OpenAI-compatible providers preserve streamedtool_callsdeltas via a shared decoder. - Sampling / output params silently dropped (issue #140): a shared
internal/openaicompatrequest builder forwards the full OpenAI-shaped body (top_p,stop,seed, penalties,response_format,n, …); native providers translate to upstream field names and warn-and-drop only what an API cannot express. max_completion_tokensignored by non-OpenAI providers (issue #141, PR #213): the limit is normalized at the gateway seam so every provider honors it, and OpenAI / Azure o-series reasoning models receivemax_completion_tokensinstead of the rejectedmax_tokens.finish_reasonnot normalized to OpenAI values (issue #142): Anthropic / Bedrock / Cohere native stop reasons now map tostop | length | tool_calls | content_filter, so clients can detect truncation and tool use.- Anthropic multimodal images dropped and tool-role messages malformed (issue #143): image content maps to Anthropic content blocks (vision no longer degrades to text-only) and tool results emit
tool_resultblocks inside a user turn instead of a bare{"role":"tool"}object the API rejects. - Gemini system prompt prepended to the user message (issue #144): routed through the dedicated top-level
systemInstructionfield (Gemini 1.5+) instead of being smuggled into the first user turn, and no longer lost when a system message has no following user turn. - Streaming and per-provider translation fidelity (issue #145): Anthropic streaming usage is parsed (non-zero token / cost metrics); DeepSeek
reasoning_contentand prompt-cache tokens are surfaced; Cohere embeddingsinput_typeis configurable (defaults tosearch_document).
Changed
- Dependency sweep (11 bumps): aws-sdk-go-v2 (config / credentials / bedrockruntime), OpenTelemetry (otel + otlptracegrpc), go-chi/chi v5, modernc.org/sqlite, lib/pq, codecov-action, and upload-artifact, plus SA1019 deprecation fixes surfaced by the bumps.
- Internal shared-helper refactor:
openaicompat.StreamSSE/PostChat/PostStreamcollapse ~23 OpenAI-compatible providers' duplicated request and stream plumbing; newcore.NormalizeToolChoice/NormalizeFinishReason/Ptrhelpers and a sharedanthropicwiretool mapper;interface{}→anymodernization. ~1,800 net lines removed with no behavior change beyond unifying SSE decode-error handling.
Contributors
Thanks to everyone who shipped this release:
- Provider-translation correctness + dependency sweep (#205) — @MitulShah1
- Tool/function calling across providers (#214) and
max_completion_tokensfallback (#213) — @Rachit-Gandhi
Full changelog: https://github.com/ferro-labs/ai-gateway/blob/v1.1.4/CHANGELOG.md