Skip to content

Release 0.7.0 - #256

Merged
deepfates merged 4 commits into
mainfrom
claude/release-0.7.0
Sep 29, 2026
Merged

deepfates merged 4 commits into
mainfrom
claude/release-0.7.0

Conversation

@deepfates

@deepfates deepfates commented Sep 29, 2026 •

Copy link
Copy Markdown
Owner

The 0.7.0 release change. Nothing is tagged, published or merged; the owner tags v0.7.0 and runs mix hex.publish.

It is 0.7.0, not 0.6.1, under the semver ruling in decisions.md (a release that changes what a caller receives bumps the minor): cost is nil where it was ReqLLM's estimate (#253), an incomplete stream returns an error where it returned the text that had arrived (#255), the model recorded for a streamed call, and the Imp.Usage key for some clients, change (#255), and ReActV2's :last_request_note history entry carries empty tool_calls and tool_call_results (#260).

What changed

  • mix.exs @version "0.7.0"; priv/public_api.json package_version (regenerated with mix imp.public_api; only that line changed); test/package_contract_test.exs asserts "0.7.0".
  • {:imp, "~> 0.7"} in README, docs/getting-started/setting-up.md, docs/production.md, docs/coming-from-dspy.md, the five livebooks, and examples/deployment (mix.exs, README.md). The tree/v0.6.0 and blob/v0.6.0 links now point to v0.7.0; they 404 until the tag exists. README: "Imp 0.7 is experimental". The {:req, "~> 0.6"} lines are Req's version and are unchanged.
  • CHANGELOG.md: ## Unreleased is ## 0.7.0 — 2026-09-28.
  • RELEASE_NOTES.md: rewritten for 0.7.0: why minor, install, headline changes, Upgrading from 0.6 (five steps), Known limits.

Update: fact-check corrections

The fact-check ran the uncertain claims on v0.6.0 and 0.7.0, and commit "Release notes: apply the fact-check corrections" applies its text changes to RELEASE_NOTES.md, the 0.7.0 CHANGELOG section and one sentence of the Imp.Clients.ReqLLM moduledoc. No code changed.

  • A streamed call records the configured model id without its provider prefix. ReqLLM 1.24 never passes a streamed response's reported model through, so the claim that it records the model the provider reported is gone. In 0.6.0 a real streamed call had no Imp.Usage entry at all.
  • A failed stream's usage is recorded on the failed :model_response event only. Imp.Usage does not see streamed calls, which run in a separate process; this is a new Known limit.
  • OpenRouter's charge: 0.6.0 read it only for models ReqLLM's catalog does not price.
  • Effort translation: Anthropic and Google get a thinking budget; OpenAI, OpenRouter, Groq and xAI receive the effort as written. This replaces "maps or clamps", in the CHANGELOG and the moduledoc.
  • Both tuple shapes are named, "Using that filler/text for history is Imp's" replaces the earlier wording, Upgrading 6 notes that a reloaded history holds %{tool_calls: []}, and the CHANGELOG note entry gives the conversion.

Checks after this commit: format exit 0, compile --warnings-as-errors exit 0, docs --warnings-as-errors exit 0, imp.public_api --check current, the contract tests plus test/req_llm_client_test.exs 207 tests, 0 failures (1 excluded). mix check was not re-run, since only docs text changed.

Update: #260 merged in

origin/main (99ef8cd, #260) is merged into this branch as a merge commit, with no rebase or force-push. Its two Unreleased > Changed entries sit at the end of 0.7.0's Changed section, word for word; there is no Unreleased heading left. The RELEASE_NOTES edits for #260 are in the same merge commit (c95a832).

  • The why-minor paragraph now names four caller-visible changes, the note's history shape among them.
  • Headline changes gain two bullets: the note renders as a user message with no invented reply (in the last request and on replay), and the written-mode replay of a step that recorded no call and no other output.
  • Upgrading step 6: a host that stores returned ReActV2 histories and recognises the note by its exact shape must accept tool_calls and tool_call_results, or match the note by its key or text. A note stored by an earlier version keeps the input-only shape and, passed back, still renders with the "Not supplied" reply. It can be converted by adding tool_calls: %Imp.Adapter.Types.ToolCalls{tool_calls: []} and tool_call_results: [] to it; for a dumped history, Imp.History.load!/1, add the fields, and dump again. I checked the conversion with a throwaway test (since deleted), in native and written tool modes: an old-shape entry passed back as history: produces the filler in the request, and the converted entry does not. The dumped form carries __imp_type__ tags, which is why the step says to load and re-dump rather than edit the JSON.
  • The "Not supplied for this conversation history message." filler: the release notes say it is Imp's own and that DSPy 3.2.1 renders a missing history output as None. I found no text in the notes, CHANGELOG, docs or lib that calls it DSPy's. Two nearby texts are not changed here: the comment above append_user_turn/2 in lib/imp/predict/react_v2.ex calls an input-only entry "a DSPy History entry", which names the structure, not the filler; and the message of commit 67297cd says "keep DSPy's rendering", which history can't change. The divergence itself is History entries with missing outputs: Imp invents a filler DSPy doesn't; native replay drops answers #261 and is not in this release.

Judgement calls in the CHANGELOG

  1. Two Streamed ReqLLM calls record the usage and cost the provider reported #255 entries moved from Fixed to Changed and are now marked "Breaking:" with a migration, as Release 0.6.0 (draft: version pending owner) #246 did for unmarked breaking changes:
    • a stream that did not complete ends in {:error, %Imp.LMError{}} instead of a completion of the text that arrived;
    • the model a streamed call records. The Streamed ReqLLM calls record the usage and cost the provider reported #255 entry said only that the Imp.Usage key changes. In 0.6.0 a ReqLLM stream carried no usage, so it had no Imp.Usage entry at all; the change a host can see is the req_llm metadata model on the :model_response event (openai:gpt-test becomes gpt-test, or the model the provider reported). The entry now says that.
  2. An addition to that entry, which no merged entry mentioned: provider_name/1 now goes through model_identity/1, so a non-streamed call to a client built from a string-keyed spec map or a {provider, opts} / {provider, model, opts} tuple records its provider, where 0.6.0's provider_name/1 matched only an atom-keyed :provider map or a "provider:model" string and gave nil. Its Imp.Usage key goes from "m" to "openai/m". At main I checked the keys with a throwaway test ({:openai, id: "m"}, %{"provider" => "openai", "id" => "m"} and "openai:m" each give ["openai/m"]) and that Imp.req_llm/2 keeps the spec as given. The 0.6.0 side comes from reading git show v0.6.0:lib/imp/clients/req_llm.ex; I did not run it.
  3. The cost entry adds that estimated_cost is nil for a streamed call, as the Imp.Core.LMResponse and Imp.LM moduledocs say.

Judgement calls in RELEASE_NOTES

  1. Carried-forward Known limits, each checked against main. None of the modules they describe changed between v0.6.0 and main (git diff --stat v0.6.0..origin/main touches only req_llm.ex, core.ex, lm.ex, saving.ex, streaming/execution.ex, exceptions.ex and a benchmark task), and mix.lock is unchanged:
    • mint/Finch: mix.lock holds mint 1.10.1 and Finch 0.23.0. Hex's newest Finch is still 0.23.0, and Close abandoned HTTP/1 connections after request errors sneako/finch#397 is still open and unmerged. The limit stays word for word.
    • The flat pair divergence, checkpoints as sensitive state, ReActV2 prose that quotes field names, ReqLLM's warning log with headers, the Bearer length in command output, and the GEPA full-validation checkpoint all stay.
    • The Install section's cowlib/Cowboy and mint paragraphs are still true: cowboy 2.19.0 and cowlib 2.20.0 are the newest on Hex, mint 1.11.0 is the newest mint, and mix.exs still declares {:mint, "~> 1.8"}.
  2. Two new Known limits:
    • The usage map (:usage on the event, Imp.Usage, get_lm_usage/1) is ReqLLM's, so for a non-streamed call its :cost/:total_cost are the catalog estimate (ReqLLM.Usage.Cost.merge/3 puts them there, and sanitize_usage/1 keeps them). A model call's cost is the provider's reported charge; the catalog price is estimated_cost #253 changed the cost field but not this map, so a host reading usage[:cost] still gets the estimate.
    • A provider error sent inside a stream has status nil and retryable: true (stream_failure/2 passes true; Imp.LMError's moduledoc gives the reason).
  3. Upgrading step 5 (spend totals grow) is a behaviour change, not a breaking one: 0.6.0 recorded no usage for a ReqLLM stream, and now records usage for streams, including failed ones.

Dependabot

GitHub reports open alerts for accelerate and nltk. They come from benchmarks/requirements-ifbench-parity.txt, the Python environment for a benchmark, not the Hex package. mix hex.build --unpack of this branch contains no benchmarks/ directory and no .txt file (top level: CHANGELOG.md, LICENSE, NOTICE, README.md, RELEASE_NOTES.md, assets, docs, examples, hex_metadata.config, lib, ...). This PR does not change that file.

Checks on this branch (merge commit c95a832)

  • mix format --check-formatted: exit 0
  • mix compile --warnings-as-errors --force: exit 0 (427 files)
  • mix docs --warnings-as-errors: exit 0
  • mix dialyzer.check: "Total errors: 142, Skipped: 142, Unnecessary Skips: 0", "done (passed successfully)"
  • mix imp.public_api --check: "Public API manifest is current: priv/public_api.json"
  • documentation_contract, documented_paths, public_api_manifest, public_surface, package_contract, deployment_reference, livebook_contract: 106 tests, 0 failures (1 excluded)
  • MIX_ENV=test mix package.check: "clean-room package proof passed: tmp/package-clean-room"
  • mix check (1-minute load 1.7, no other test VM): exit 0, "59 doctests, 9 properties, 3562 tests, 0 failures, 13 skipped (221 excluded)"

No test was added, so there was nothing to falsify by reverting. The release only moves version strings and documents changes that are already merged.

@Version 0.7.0, CHANGELOG Unreleased becomes 0.7.0, RELEASE_NOTES for
0.7.0, and {:imp, "~> 0.7"} and v0.7.0 links in the README, docs,
livebooks and deployment example. The streamed-call model change and the
incomplete-stream error are marked Breaking with their migrations.
A streamed call records the configured model id; Imp.Usage does not see
streamed calls, so failed-stream spend is on the :model_response event
only (new Known limit); OpenRouter's charge was read in 0.6.0 only for
uncatalogued models; how ReqLLM's providers take an effort, here and in
the Imp.Clients.ReqLLM moduledoc; both tuple shapes; using the filler for
history is Imp's; the reloaded note's tool_calls is a plain map; and the
CHANGELOG note entry says how to convert an old note.
@deepfates
deepfates merged commit 7e9eb76 into main Sep 29, 2026
10 checks passed
@deepfates
deepfates deleted the claude/release-0.7.0 branch September 29, 2026 03:32
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant