llm 0.37 Adds Multimodal Embeddings and a Cheaper Default — What That Means for Local Audio Pipelines Simon Willison released llm 0.37 on 2 November, adding the gpt-6.1-sol and gpt-6.1-terra models, an `llm openai endpoint add` command for arbitrary OpenAI-compatible endpoints, and a switch of the default model to gpt-6-luna at half the previous default's price. The release also lets the library accept different content-types for binary payloads, enabling multimodal embedding models such as Gemini Embedding 2 to embed text, audio, images and video through one API. The writeup argues the change matters mainly for offline or post-turn retrieval work, since embedding calls measured in hundreds of milliseconds should stay off the hot path of live audio pipelines. Simon Willison shipped llm 0.37 https://simonwillison.net/2026/Nov/2/llm/ on 2 November. The release adds gpt-6.1-sol and gpt-6.1-terra , a new llm openai endpoint add command for arbitrary OpenAI-compatible endpoints, and switches the default model to gpt-6-luna half the price of the previous default . The more interesting line for people who actually ship tools is the embeddings change: the library now accepts different content-types for binary payloads, which is required for models like Gemini Embedding 2 that can embed text, audio, images, and video in one API. That is a small API surface change. It is also the exact seam where most local real-time systems still fall over. An embedding call that accepts raw audio is useful for retrieval, speaker clustering, or “find the similar turn” later. It is almost never the thing you want on the hot path of a live call. Latency budgets for a dual-track interview or call assistant look roughly like this: A multimodal embedding model, even a fast one, is usually measured in hundreds of milliseconds once you count serialization, network or GPU queue , and the fact that you rarely want to embed every 200 ms chunk. You embed the finalized turn, or you embed offline. The streaming path stays lean. The practical pattern is the same one that shows up in any real agent loop once tool count or payload size leaves the toy regime: keep the expensive representation out of the critical path until you actually need it. None of the new embedding APIs change the fact that a Windows call has two independent audio streams that must stay separate: Mixing them early destroys speaker labels and forces the recognizer to handle two languages or two accents in one beam. The correct architecture is two independent pipelines that only meet at the UI or the final transcript store. On Windows the loopback path is still “open an input stream on a render device” via WASAPI. In Rust with cpal it looks like this: // Simplified — real code also handles format negotiation and device changes use cpal::traits::{DeviceTrait, HostTrait, StreamTrait}; fn open loopback host: &cpal::Host, device name: &str - Result