Every LLM call this package makes is a bounded, structured-extraction task
over text already given in the prompt (classify a file, extract a
variable's label, list the scales named in ~30 sentences, group files by
study) – pattern-matching over given material, not multi-step reasoning
(no arithmetic, no multi-hop inference, no planning). A "thinking"/
"reasoning" model spending extra tokens re-deriving what the prompt already
states is close to pure overhead here: it inflates cost/latency and eats
into the same max_tokens budget as the visible answer, which is a
confirmed real cause of truncated structured responses on gpt-oss models
via Groq. Minimal reasoning effort is the right DEFAULT for what this
package does, not a tradeoff against quality.
Details
There is no single universal "reasoning" switch across providers – this is genuinely per model family, each verified rather than assumed:
openai/gpt-oss-*(Groq or any OpenAI-compatible host): thereasoning_effortchat-completion parameter, accepting"low","medium", or"high"–"low"is the minimum; there is no full-off option for this family (verified against Groq's own docs).qwen3*-family models: alsoreasoning_effort, but accepting"none"or"default"–"none"fully disables reasoning tokens, unlike gpt-oss.Mistral's reasoning-capable models (
mistral-small-latest,mistral-medium-3-5): alsoreasoning_effort, but with only TWO values,"high"(full thinking chunk) or"none"(thinking chunk omitted) – verified against Mistral's own docs, a third distinct shape from both gpt-oss and qwen3.Ollama-hosted reasoning models (DeepSeek-R1, Qwen3, ...): the native API's boolean
think(llm()already sends this as a/nothinksystem-prompt prefix over Ollama's native/api/chatendpoint whenthink = FALSE, since Ollama's OpenAI-compatible/v1/endpoint ignores it) – a genuinely different mechanism (a flag on the request, not a graded effort level), sollm_reasoning()'s"low"/"none"both map tothink = FALSEfor this family; there is no Ollama equivalent of"medium"/"high"to request.
A model family with none of the above (a plain non-reasoning model, or one
not yet covered here) is left untouched: llm_reasoning() never forces an
unsupported parameter onto a call, since providers vary in whether an
unrecognised parameter is silently ignored or rejected outright.
