Skip to content

0.7.0 - 2026-10-13

Choose a tag to compare

@github-actions github-actions released this 13 Oct 05:51

Release Notes

Added

  • max_tokens: sets the output ceiling of an Anthropic-dialect model. The
    key goes on a models: entry or an agents: entry, and the agent's wins
    over the model's, as for effort, temperature and top_p. It must be 1 or
    more (config max_tokens 0: want 1 or more). A new session and a /model
    switch evaluate it, the session records it in meta.json with where it came
    from, and iota resume restores what was recorded — the default included —
    whatever the config says today; a bot takes it from its config each start.
    Thinking counts toward it. There is no /model tab or flag for it, and a
    hand-edited max_tokens: 0 in a session is ignored. On any
    other provider type the key does nothing and says so
    (Warning: `max_tokens` does not apply to provider type … (ignored)).
  • A chat can move to another provider from /model. A row on another
    endpoint used to be refused with "start a new session there". Before the
    first reply, picking it now moves the chat there. After a reply, iota first
    saves the chat, then tells you how many earlier replies carry
    provider-specific payload (reasoning, provider-side tool state) the target
    does not replay, that iota resume <id> continues on the new model
    afterwards, and that picking the old row moves it back — and asks
    Move this chat to <provider>:<model>? before anything changes. Your
    settings come along as they do on a -M resume (below). A chat that is not
    saved is told to /save first, a model of another kind (an image model for
    a chat) is still refused, and a bot never moves: its config does.

Changed

  • The Anthropic dialect asks for up to 32000 output tokens, not 4096. A
    thinking model could spend all of 4096 thinking and be cut off before it
    wrote a word. The ceiling is a bound, not a charge: tokens are billed as
    they are produced. An endpoint that caps lower answers a too-large value
    with an error, so set a smaller max_tokens: for such a model.
  • An output the ceiling cut off is an error, never the answer. On the
    Anthropic dialect (stop_reason: max_tokens) and on the Responses dialect
    (response.incomplete: max_output_tokens), the chat shows a red
    Output truncated block: what cut it, the tool call it was composing if
    any (dropped, by name — it does not run), and what to do. On Anthropic
    that is where to raise max_tokens:, and that the edit reaches this
    session only after a restart, a resume and a /model switch away and
    back, while a lower effort in /model applies at once; the Responses
    dialect has no such setting, so there it is to lower the effort in
    /model or ask for a shorter reply. Text the model did write is kept,
    marked incomplete; with no text or completed tool rounds to keep, the turn
    is rolled back, though what the request cost still counts in the session
    totals. A cut is not retried — the same request would hit the same
    ceiling. A half-finished thought is no longer
    shown, saved or sent back to the model as the reply. With -m, a cut fails
    the run (exit 1, Error: output truncated — …, nothing saved), a cut-off
    compaction summary fails instead of replacing the history with a fragment,
    and a cut-off title leaves the placeholder title.
  • Sessions record their provider by name, and resume there. A session now
    stores the providers: name it runs on (session format v2) instead of a
    provider type and a URL, and iota resume — and /session — opens that
    provider from the config, as if -M <provider>:<model> had been typed. A
    name the config no longer defines is an error that says how to resume it
    elsewhere (… which the config does not define; resume it elsewhere with -M <provider>:<model>), never a quiet fall back to another endpoint, and
    a missing key on the agent's own endpoint no longer stops a session that
    runs on another. Resuming replies another dialect wrote says how many carry
    payload this one does not replay. Sessions written by earlier versions
    (format v1) are no longer read: opening one is an error that names
    scripts/session-v1-to-v2.py, which converts them once. The script only
    reports what it would change until you add --write; it rewrites
    meta.json alone, leaving the transcript and attachments as they are. It
    picks the provider by the endpoint the session recorded: the one entry of
    that type whose url: is that URL, or the type's built-in provider when
    the session ran on the default endpoint. When that does not settle it (no
    entry matches, two do, or another type's entry has taken the built-in's
    name), it reports the bundle and leaves it as it is for --map TYPE=NAME
    to decide.
  • iota resume <id> -M moves the session for good. -M on a resume used
    to change only that run; the session now records the new provider and
    model, so the next plain iota resume continues there. What you set by
    hand — effort, temperature, top_p, the output ceiling — comes along unless
    the config there sets it; what the old endpoint's config supplied stays
    behind. The warning says so.
  • /model rows read the same wherever the chat is. A row is
    provider:model, or just the model when every choice is on one provider,
    followed by the models: entries that name it in brackets
    (relay:vendor/fast [fast]). What picking it does is an annotation beside
    it, like (current): (moves the chat), or (needs a new session) in a
    bot.
  • Anthropic calls without tools stream too. A -m run with no tools, the
    compaction summary and the title used a non-streaming request, which sends
    nothing until the whole output exists and could outlast the 120 s wait for
    a response. They now use the stream the chat uses, so an
    Anthropic-compatible endpoint that cannot stream now fails there instead of
    answering.

Fixed

  • An Anthropic stream that stops early is an error, not an answer. A
    response that ended before the message did — no message_stop, no stop
    reason — was taken as complete, so -m and a compaction could succeed on a
    fragment.
  • A failing request without tools is sent 11 times, not 121. A turn
    that offered the model no tools retried inside a retry, so one failing
    request (a 5xx, a dropped connection) could go out up to 121 times with
    minutes of backoff. Every model call now has one set of ten retries.
  • Typing a choice's name in /model picks that choice. Typing fast, the
    name of a models: entry, sent fast to the provider as a model id; the
    field now reads typed text as -M does, and provider:* picks nothing.

Install iota 0.7.0

Install prebuilt binaries via shell script

curl --proto '=https' --tlsv1.2 -LsSf https://github.com/iotash/iota/releases/download/v0.7.0/iota-installer.sh | sh

Install prebuilt binaries via powershell script

powershell -ExecutionPolicy Bypass -c "irm https://github.com/iotash/iota/releases/download/v0.7.0/iota-installer.ps1 | iex"

Install prebuilt binaries via Homebrew

brew install iotash/tap/iota

Download iota 0.7.0

File Platform Checksum
iota-aarch64-apple-darwin.tar.xz Apple Silicon macOS checksum
iota-x86_64-apple-darwin.tar.xz Intel macOS checksum
iota-x86_64-pc-windows-msvc.zip x64 Windows checksum
iota-aarch64-unknown-linux-gnu.tar.xz ARM64 Linux checksum
iota-x86_64-unknown-linux-gnu.tar.xz x64 Linux checksum