c065a2dea7
provider.Request.ResponseFormat was being silently dropped by the openai translation layer (translate.go:translateRequest). The upstream provider type and the openai-go SDK both supported it; the adapter just never propagated it. This is why Move 1 (set ResponseFormat=ResponseJSON in the SLM classifier) produced zero observable change: the field made it from the classifier into provider.Request but stopped at the OpenAI translation step. The ollama backend (used via the OpenAI-compatible endpoint) therefore never received format=json_object and kept emitting free-form prose, which the classifier's downstream JSON parser duly rejected — 50 fallbacks in a row across two model swaps. Translate provider.ResponseJSON to oai.ResponseFormatJSONObjectParam and provider.ResponseText to oai.ResponseFormatTextParam; leave the union zero-valued when the caller didn't set ResponseFormat so the SDK omits the field per its omitzero tag. Three table cases cover the json / text / unset paths. Affects ollama, llama.cpp, llamafile, and any other backend reached via openaicompat — all run through openai.translateRequest.