[REL] v0.4.0 — Integrator ergonomics
Breaking changes:
ALLM.Tool.new/1(and__from_tagged__/1) now recursively normalize atom-keyed:schemamaps to string keys for deterministic adapter wire shape; callers depending on atom keys on%Tool{}.schemawill see strings insteadALLM.Providers.Fakestreaming{:usage, map}script entries now fold onto:message_completed.metadata.usageinstead of emitting a:raw_chunkevent; tests asserting the prior:raw_chunkshape should pass{:raw_chunk, {:usage, _}}directly
Other changes:
- Add
ALLM.Sandbox— Mox-styleset_engine/1/get_engine/0/with_engine/2honouring$callersso engines set in a parent test process are visible toTask.async/1/Task.async_stream/3workers - Add
ALLM.unwrap/1— fold the three-clausegenerate/3return (:stop/:error/{:error, _}) into{:ok, text} | {:error, _} - Add
ALLM.Providers.Fakeadapter_opts[:usage](Usage struct or keyword; populatesresponse.usageon every call) andadapter_opts[:record](sends{:allm_fake_record, request, opts}to a pid before script interpretation) - Add
ALLM.Image.from_data_uri/1— parsedata:<mime>;base64,...strings into a{:base64, _}-source%Image{}that round-trips throughto_data_uri/1 - Add
ALLM.JsonSchema.normalize/1— shared atom-to-string key normalizer called by bothTool.new/1andALLM.json_schema/3 - Carry structured detail for
Validate.message/1's{:content, :invalid_part_type}error in%ValidationError{}.metadata(machine-readable) plus a human-readableException.message/1—errorslist shape unchanged - Document the arity-2
:handlercontext keys (:context | :session_id | :tool_call | :engine | :request_id) inALLM.Tool's@typedoc - Document
chat(engine, thread, response_format: schema, structured_finalize: true)inguides/tools.md— the existing tool-loop + structured coda flow was previously undiscoverable - Add
guides/fakes.md— consolidated Fake testing patterns (script vocabulary, cursor disambiguation,:usage/:record, halt-cleanup observation, retry simulation, Sandbox cross-process injection) - Extend
guides/getting_started.mdwith the three-clause finish-reason fold pattern and the engine-no-:api_keyclarification - Extend
guides/tools.mdwith handler-context keys and an "Adapter-call cadence" subsection (tool-loop turns consume 2 adapter calls each) - Extend
guides/vision.mdto point atImage.from_data_uri/1for data-URI inputs
[REL] v0.4.1 — Streaming HTTP timeout forwarding
Other changes:
- Forward
:receive_timeout,:request_timeout, and:pool_timeoutfromoptstoFinch.async_request/3in the streaming codepath ofALLM.Providers.OpenAI,ALLM.Providers.Anthropic, andALLM.Providers.Gemini. Previously these opts were dropped on the streaming arm — onlygenerate/2's non-streamingReq-based path honoured them — so callers passingrequest_timeout:to long-running streaming requests fell back to Finch's defaults (≈20s receive), causing premature:timeoutfailures on slow-first-token requests. Eachstream/2's@docnow documents the new opts and clarifies that:stream_timeout(inter-message) and:receive_timeout(HTTP-level) are distinct timers - Extend
ALLM.Test.FinchStubwithcaptured_opts/1so tests can assert which Finch-level options the adapter forwarded - Fix
scripts/release.exsmanglingmix.exs@versionwhen the new version starts with a digit (e.g.0.4.0). The replacement used\1back-references which Erlang'sreparsed as\10followed by literal text — producing.4.0"instead of@version "0.4.0". Switch to unambiguous\g{N}back-refs
[REL] v0.3.1 — Documentation rebuild
Other changes:
- Rewrite every
@moduledocand public@docso prose is self-contained — no internal phase, spec-section, or design-decision references - Add eight ExDoc guides under
guides/(Getting Started, Streaming, Tools, Sessions, Vision, Image Generation, Errors & Retries, Multi-Tenant Keys), shipped to both hexdocs and the source tarball - Restructure README around a 5-minute on-ramp and cross-link the guides instead of duplicating their content
- Drop the alpha warning in favor of a concrete stability statement (semver promise within v0.x)
- Add
scripts/audit_user_docs.exs(banned-token gate) andscripts/check_lib_diff_non_doc.exs(docstring-vs-body classifier) - Fix an
async: trueflake inanthropic_stream_wire_testby passing the stub key per-call instead of through the globalALLM.Keys.Storeagent - Clean up the release script — drop the redundant
finalizestep
[REL] v0.3.0 — Initial public release
First public release of ALLM — a provider-neutral, streaming-first LLM execution library for Elixir. The package is alpha: public APIs and on-disk session shapes may shift between releases until v1.0.
Other changes:
- Layer A serializable data:
Message,Thread,ToolCall,Request,Response,Session,StepResult,ChatResult,Event,Usage— round-trip through:erlang.term_to_binary/1and JSON - Stateless execution facade:
ALLM.generate/3,stream_generate/3,step/3,stream_step/3,chat/3,stream/3 - Stateful continuation via
ALLM.Sessionwith auto and per-tool manual orchestration modes and{:ask_user, ...}suspension - Streaming as the primitive — synchronous calls are reducers over a
closed
ALLM.Eventtagged-tuple union viaALLM.StreamCollector - Bundled adapters for OpenAI (Chat Completions + Responses), Anthropic Messages, and Google Gemini, all live-validated
- Vision input across all three providers via
ALLM.TextPart/ALLM.ImagePart - Image generation/edit/variation behaviour with an OpenAI Images adapter
- Telemetry events, retry policy, capability pre-flight, and BYOK key
resolution through
ALLM.Keys - Conformance harnesses (
ALLM.Test.AdapterConformance,ImageAdapterConformance) and a deterministicALLM.Providers.Faketest vehicle - Provider-neutral example scripts under
examples/runnable viaALLM_PROVIDER=<name> mix run examples/run_all.exs