mikehostetler

mikehostetler

ReqLLM – Composable LLM client built on Req

ReqLLM v1.27.0

I’m especially excited about this release because it brings the OpenAI Decisions API into ReqLLM through the new ReqLLM.evaluate/4 function.

I also want to highlight ReqLLM’s callback-based Model Routing API. It lets an application select a model at request time without putting a fixed routing policy inside ReqLLM.

OPENAI DECISIONS API

Use an evaluation-capable model to ask named boolean, choice, and score questions about text or JSON-compatible state.

questions = %{
  queue: %{
    type: :choice,
    instructions: "Which team should handle this?",
    criteria: %{
      billing: "Billing and refunds",
      support: "Technical help"
    }
  },
  urgent: %{
    type: :boolean,
    instructions: "Does this need immediate action?"
  }
}

{:ok, decision} =
  ReqLLM.evaluate(
    "openai:gpt-6-luna",
    %{ticket: "Refund me today"},
    questions,
    provider_options: [openai: [safety_identifier: "tenant-123"]]
  )

decision.object["queue"]["choice"]
decision.object["urgent"]["probability"]

The safety_identifier option is optional. Answers remain keyed by question name. The full provider response remains available in decision.provider_meta.raw_response.

LLMDB is the source for model eligibility. ReqLLM.evaluation_models/0 lists the evaluation models that ReqLLM can call.

CALLBACK MODEL ROUTING

Pass a router struct to a normal ReqLLM generation function. ReqLLM normalizes the request, calls resolve/2 once, and continues through the selected model’s standard provider path.

defmodule MyApp.ModelRouter do
  @behaviour ReqLLM.Router

  defstruct fast: "openai:gpt-6-luna",
            deep: "openai:gpt-6-sol"

  @impl true
  def resolve(router, %ReqLLM.Router.Request{routing_context: context}) do
    model = if context[:depth] == :deep, do: router.deep, else: router.fast
    ReqLLM.model(model)
  end
end

router = struct(MyApp.ModelRouter)

{:ok, response} =
  ReqLLM.generate_text(
    router,
    "Explain OTP supervision",
    routing_context: %{depth: :deep}
  )

ReqLLM.Response.text(response)

The application owns the routing policy. The callback can use local rules, an evaluation model, or another service. ReqLLM passes routing_context through unchanged.

The same routing contract works with generate_text, stream_text, generate_object, and stream_object.

OTHER CHANGES

  • Azure Chat Completions log-probability support
  • Gemini 3 object output when tools are present
  • A bounded JSON Schema validator cache with FIFO by default and optional LRU or custom eviction
  • Safer redaction of unknown provider reasoning payloads
  • Correct OpenAI anonymous authentication and exact streaming model identity
  • Responses API refusals decoded as text with a content_filter finish reason
  • A fix for non-streaming connection-pool timeouts
  • Contract hardening for streaming, tools, telemetry, usage, billing, URL selection, and timeout cleanup

Thanks to Arton Ragsdale, mvanhorn, Wu Shuwen, Justin Smestad, and Nickjgniklu for their work in this release.

LINKS

Where Next? Top

Trending in News & Updates Top

Jskalc
LiveVue v1.0 released After four release candidates and a lot of community feedback, LiveVue 1.0 is stable :tada: I’ve built a dedicated...
New
zachdaniel
Your standard application generally only tracks what is true right now. Updates overwrite previous data, and asking questions about the p...
New
woylie
<span class="hashtag-icon-placeholder"></span>let-me 3.0.4 has been released. Changed Log the policy module and the check module in the...
New
woylie
Flop Phoenix 0.27.0 has been released. Changed Require Flop 0.29.0, which turns Flop.Schema from a protocol into a behaviour. Determin...
New
webofbits
Aludel 0.8.0 is now available on GitHub and Hex. This release adds typed_judge assertions for evaluations that need deterministic, struc...
New
kyroco
VitalAIze 0.3.0 is out. It puts your other machines on your team on the board, live. I changed the architecture and am using gRPC to stre...
New
woylie
Flop 0.29.0 has been released. Added Add Flop.allowed_fields/2, which returns the fields that may be filtered or sorted for the given ...
New

Other Trending Topics Top

GenericJam
Edit: 2026 May 15 - This post is archived. Mob is alive!! Main docs: mob v0.7.11 — Documentation A bit of explanation for the slightly c...
New
garrison
Hobbes is a low-level distributed database for the Elixir programming language. Hobbes provides a simple, safe, and scalable storage lay...
New
budgie
A little off-topic, but I feel like people here have a good head on their shoulders. I used to be quite good at making software. Was luc...
New
KristerV
Hey. Is there anyone here who creates agents in their apps? Not talking about using agents, but creating them. I’m finding it pretty diff...
New
mudasobwa
I fully migrated to my own harness from Anthropic/Gemini and I think it’s time to share it. Welcome DSH, the DeepSeek Harness, fully writ...
New
mcass19
ExRatatui lets you cook up rich terminal UIs in Elixir, powered by Rust’s ratatui via Rustler NIFs. Build interactive terminal applicatio...
New

We're in Beta

About us Mission Statement

Options

Thread Display Mode




Thread Preview

Skip Thread Previews