Skip to content

v0.16.0 — Measured, and a web client

Latest

Choose a tag to compare

@DusanCar-sudo DusanCar-sudo released this 28 Aug 07:24
· 1 commit to master since this release

Four bugs users were hitting on 0.15.5, the provider routing they came out of,
and a graphical client for people who would rather not live in a terminal.

Roadmap note. The 0.15.5 notes put Windows and macOS computer use in 0.16.0
and 0.16.5. That work ran into problems that took longer to sort out than
expected, and the defects fixed below were affecting live runs — so those went
first. Windows and macOS computer use is definitely still coming, in one of the
next few releases. No version number against it this time, given what the last
estimate turned out to be worth.

Fixed — defects that were affecting real runs

  • Gemini 2.5 model ids no longer work and were still being shipped. Google
    keeps listing them, but generateContent answers 404 "no longer available to
    new users". A listing is not an entitlement. Anyone who picked Gemini in the
    wizard had a configuration that could not work. Replaced with the 3.x line,
    every id confirmed against a live call rather than a catalogue, and the
    pricing table follows.

  • BytePlus and FPT models were being sent to DeepSeek. Both resell other
    vendors' models under their own gateway, so their catalogue ids are bare
    vendor names — deepseek-v4-flash-ga-260813, DeepSeek-V4-Flash. Neither had
    a routing prefix, so choosing one produced an id that routed to DeepSeek's own
    API with a DeepSeek key: wrong endpoint, wrong bill, and an error blaming the
    wrong provider.

  • deepseek/deepseek-v4-pro ran against a 128k context instead of its real
    1M.
    The routing prefix was missing from the strip regex, so the registry
    lookup failed and every caller fell back to a 128k default — compacting about
    eight times earlier than necessary. The bare id was unaffected, which is why
    it stayed hidden.

  • The setup wizard told people to retype a valid key. Every connection
    failure offered "re-enter API key". OpenAI answers an unpaid account with 429
    "exceeded your current quota", OpenCode Zen with 401 "Insufficient balance", a
    retired model with 500 — none of which a different key can fix. Failures are
    now classified (auth, billing, rate, model, server, network) and each leads
    with the remedy that can actually help, saying plainly when the key is not the
    problem.

  • Pasted text and mouse reports could land in the model picker's filter. A
    paste arrives wrapped in bracketed-paste markers and a mouse report as
    \x1b[<b;x;yM; both decode to keypresses whose text is printable, so their
    bytes were typed into the filter box.

Changed — one provider table instead of five

factory.ts described the same providers five separate times: the strip regex,
the API key resolver, the family resolver, the reverse base-URL map, and a
~320-line chain of construction branches. Nothing forced them to agree, and two
of the bugs above are what that drift looks like from the outside.

There is now one descriptor table, and all five views derive from it. Adding a
provider is a single entry. createProvider drops from ~320 lines to 47.

Two tests hold it together: one asserts the five structures agree with each
other, the other that the user-facing catalogue agrees with routing at all —
every model of all 31 routing targets resolves to its own provider's key.

Added — a web client

aura serve already spoke the full protocol over its WebSocket; what was
missing was a client. React, building to dist/web, served by the same command.

Streaming turns, markdown with copyable code, stop and regenerate, a
conversation sidebar, inline tool calls and approval prompts, a provider picker
across 28 providers with an API-key field when one is missing, tool toggles that
actually reach the engine, live token and cost, dark and light, and a layout
that works on a phone over --lan or --tailscale.

Seven languages — English, Serbian (Cyrillic), French, Italian, Spanish, Arabic,
Russian — with Arabic driving real right-to-left through logical properties
rather than a transform.

The design mirrors the TUI: every colour is taken from the terminal palette.

Commands beginning with : run rather than reaching the model. Fourteen work in
the client; the rest are reported by name as terminal-only rather than silently
sent to the agent as a question.

Security

  • Plugin install, plugin removal and API-key changes are off by default.
    aura serve exposed them to anything holding the pairing token. Installing a
    plugin downloads and runs code with the server's full privileges and no
    sandbox, so under --lan or --tailscale that turned any paired device into
    remote code execution. All three now require aura serve --allow-plugin-install; listing what is installed stays open.
  • A proven pairing token becomes an httpOnly; SameSite=Strict cookie, so
    the page's own asset requests authenticate. Without it every subresource 401'd
    and the page rendered blank.
  • Model output is sanitised before rendering. The client renders markdown as
    HTML, and on the agent path that output carries whatever a tool read off disk.
    Raw HTML is disabled at the renderer and the result is scrubbed anyway, tested
    against the actual vectors.

Added — measurement

  • The escalation benchmark had never run. It was excluded from npm test
    correctly, being slow and live, but pinned to an account that later lapsed —
    so it self-skipped, and a benchmark that skips is indistinguishable from one
    that passes. First live result: 6.7% missed escalation, 0% false
    escalation
    over 30 cases. Both misses are design-mode; retrieval was 15/15.
  • A Gazelle blind eval, because 26x fewer tokens was a cost measurement with
    no quality number beside it. Blind-scored, labels stripped: 114x fewer
    tokens
    , correctness a wash on conversational prompts and +2.89 on
    questions needing tools, where the coder path ran out of room and answered
    anyway. The judge saturated on helpfulness, so that half is reported as
    unmeasured rather than as a result.
  • The cost ledger no longer counts an unbilled call as a measured zero. A
    provider error or an exhausted balance is not evidence that the large model
    would have cost nothing, and counting it that way reported the gate as a total
    loss.
  • Recorded provider fixtures, one per wire format rather than one per
    vendor: there are four formats behind thirty-one routing targets.

Also

  • The verifier can run on a separate provider, so it stops marking its own
    homework.
  • It now sees the evidence an answer is actually about — identifiers, paths,
    line refs — rather than a flat 300-character head of each tool result, which
    on a real file read was about 6% of the evidence, chosen without reference to
    what was being checked.
  • A second training path writes direct correction pairs from escalation
    episodes; every row carries its provenance so the two sources can be ablated
    separately. Neither path runs automatically.
  • docs/SANDBOX-DESIGN.md — a design for --sandboxed, a real out-of-process
    boundary, with the mechanism verified but not yet implemented. The default
    path remains a guardrail, and SECURITY.md still says so.