Repository navigation
Releases: trefeon/pi-freeflow
Release list
v1.41.0
Minor Changes
-
Add seven new free models β all keyless β for 37 in total (12 OpenCode Zen + 16 KiloCode Gateway + 1 Cline + 8 OVHcloud AI Endpoints).
New on OpenCode Zen:
minimax-m3.1-flash-free(MiniMax M3.1 Flash): 1M context, 524,288 output, vision. Effortlowthroughmax.flint-40b-free(Flint 40B): 262,144 context, 65,536 output, text-only. Effortlowthroughmax. Availability is bursty β an upstream 503 burst means retry, not that the model is gone.
New on KiloCode Gateway (OpenRouter-style reasoning, keyless):
minimax/minimax-m3.1-flash:free(MiniMax M3.1 Flash): 1M context, 524,288 output, vision. Reasoning is mandatory upstream and there are no reasoning deltas on tool turns.nvidia/nemotron-3.5-super-vl:free(Nemotron 3.5 Super VL): 1M context, 131,072 output, vision. NVIDIA's trial terms allow training on prompts, andmaxeffort can draw a transient 502/503 worth retrying.reflection/beam-free(Beam 1.0), aliasbeam-kilo: 1,048,576 context, 131,072 output, text-only. Reasoning is always on.recursive/flint-v1.0:free(Flint 40B), aliasflint-kilo: 262,144 context, 65,536 output, text-only. Thinking is mandatory and can consume a tight output budget.xingchen-agi/xing4.0-29b-a4b:free(Xing4.0 29B A4B), aliasxing4.0: 262,144 context, 235,929 output, text-only. Expect the shared upstream 429 quota often; that is a rate limit, not a dead model.
Short names:
minimax-m3.1-flashandflintstay on the Zen lane. The Kilo twins answer toflint-kiloandbeam-kilo, whilebeamandnemotron-3.5-super-vlkeep pointing at their existing Zen entries, so no saved selection changes lane.
Patch Changes
-
Protocol cleanup around reasoning effort, failover limits and tool definitions.
Three small drifts between what a lane accepted and what it advertised are settled. Unsupported reasoning-effort knobs are now clamped on the Chat Completions path exactly as the Responses path already clamped them, so a too-high or unsupported level keeps the turn on the same model instead of walking into an upstream refusal. Failover bodies headed to Kilo now clamp
max_completion_tokensalongsidemax_tokens, saving a wasted round trip. The user-facing tool definitions now carrystrictin the position the Chat Completions shape canonically uses, with both positions still accepted when reading a caller's tools back.The Anthropic-shaped messages lane no longer deletes Anthropic-native forced tool choices (
anyor a named tool) β it was documented to keep the caller's own choice semantics and now actually does; the chat and Responses lanes still normalize choices toauto-or-absent as upstream requires. -
Two OVH-hosted models no longer lose their answer to an upstream quirk, and an empty upstream stream now reports itself instead of looking like a blank reply.
Qwen3.8 27B on OVH answers a request carrying a thinking-effort knob with an empty stream; the proxy now drops that knob for this one model, so the turn produces the model's own reasoning and answer as usual. Mistral Small 3.2 24B requires tool-call ids of exactly nine letters and digits and discards the whole turn otherwise, so ids replayed from your session history are rewritten to that shape β consistently, so an assistant call and the tool result that answers it still match.
When OVH does return nothing at all, a non-streaming request now answers with a clear
502and "upstream returned an empty stream" instead of a fabricated empty completion. -
Retire Cline's
cline-free/muse-spark-1.3-contributorfrom the catalog.Cline stopped resolving the id: every request answers HTTP 404
model not foundwith the hintCline has no such model, while the sibling Cline model still resolves on the same account. The picker no longer offers Muse Spark 1.3. The id stays on the retired list, so a stale local cache or a refreshed upstream listing cannot bring it back.The Cline model that remains (
z-ai/glm-5.3-flash) still works once the signed-in account has free credit. Clients that already saved the retired model simply stop seeing it. -
Retire
exo-freefrom the catalog.The free endpoint answers HTTP 410 "Model exo-free has been deprecated" on every request path and the model is no longer on the service's model list, so the picker no longer offers it. The id stays on the retired list, which means a stale local cache or a refreshed upstream listing cannot put it back.
-
Parallel tool calls streamed through the proxy no longer corrupt each other.
Several free models label every parallel tool call with the same index while still giving each call its own id. On streamed turns the proxy merged calls by index alone, so the argument fragments of two parallel calls interleaved into one packet: one call could vanish entirely, or the arguments came through as glued-alongside JSON the host had to reject (which looked like the model failing at tool calling and the turn being retried). Streamed tool calls are now tracked the same way the assembled (non-streamed) ones always were β per call id, falling back to the wire index only when a call carries none β and a call whose index collides with another is renumbered so the host still sees two well-formed, re-executable calls. Streams with a single tool call are byte-for-byte unchanged.
-
Streamed tool calls now reach the client with the tool name exactly once.
One upstream (OpenCode Zen) streams a single tool call as two frames that BOTH carry the complete name: a name-only frame, then a frame repeating that name together with the arguments. The proxy appended every name it saw, so the assembled call came out named
get_weatherget_weatherβ a name no tool declaration matches. Streamed hosts bound the call by index and happened to tolerate it; anything reading the non-streamed aggregate, and any host that trusts the assembled packet, got a call it could not execute. A name that arrives alongside arguments is now treated as the authoritative whole name and replaces what was accumulated, while name-only deltas keep appending so ordinary piecewise-streamed names still reassemble. Both the streamed path and the assembled path apply the same rule. -
Failed and retried tool-call turns are now recorded locally so they can be diagnosed after the fact.
Every streamed turn that declared tools β and every non-streamed Chat Completions turn β leaves one line in
<data dir>/toolcall-audit.jsonldescribing how it ended: the caller's declared tool names, the calls the model actually made (name, argument size, whether the arguments parsed, whether the name was one the caller declared), the finish reason, and the classified failure. A turn where the model answered with plain text instead of calling a tool, or called a name the host never declared, now says so instead of vanishing into a generic red error. A Responses or Messages body served without an event stream is recorded as unclassifiable rather than counted against the model.Each upstream attempt abandoned in favour of another is recorded with its reason β rate limit, gateway timeout, payload limit, relay auth rejection, header timeout, socket fault β and, when the host re-sends the same conversation within ten minutes, the new turn carries the earlier one's request id and failure, so a failed first attempt and its host retry are attributable to one conversation.
The log records names, sizes, booleans and reasons only: message text, tool schemas and tool-argument values are never written. It is best-effort, never affects a request, stays empty for turns that declared no tools, and rotates to
.1at 5 MiB. Twojqone-liners in the architecture docs list failures by model and retried conversations.
Full Changelog: v1.40.1...v1.41.0
v1.40.1
Long streams are no longer cut at the five-minute ceiling mid-turn; a stalled relay is cut and re-fired instead.
Relay attempts carried a single deadline for the whole request. When a heavy reasoning turn ran past five minutes β big-pickle and long deepseek sessions routinely do β the deadline fired on live bytes, the proxy saw the dead stream as an upstream truncation, and silently re-fired the turn on another relay: on the screen the answer suddenly stopped and then continued as a fresh full generation, with the earlier partial content above it. The deadline now bounds only the header wait and is released the moment headers arrive, so a streaming body lives as long as bytes keep flowing β exactly like the other proxy paths that already cleared their timer on headers.
A body that stops flowing entirely is cut by a per-turn idle watchdog (120s of byte silence on a live socket is a wedged tunnel, not a thinking pause) and follows the existing one-refire truncation path, so a hung relay leg still hands the turn to a sibling instead of stalling until the host gives up.
Full Changelog: v1.40.0...v1.40.1
v1.40.0
Minor Changes
- Streaming turns now survive a relay rate limit: a 429 error frame that arrives before any tool call is held, the relay is cooled, and the same turn resumes once on a sibling relay. Pre-stream 429s still roll before any client bytes, and tool-call turns keep the authentic verdict to avoid duplicate execution.
Patch Changes
-
Reconcile the remaining free-model specs with the highest published twin values, keeping lane hard caps authoritative:
- Cat Jam now advertises its 1,048,576-token window: the endpoint refuses a 1.05M prompt with
context_length_exceeded(max 1,048,576), and a 900,337-token needle probe recalled correctly. - Nemotron 3 Ultra (both lanes) now declares the 1,000,000-token lane cap; larger prompts are refused.
- Nemotron 3.5 and Super now carry the highest published 235,929 output ceiling below the window.
- Thinking selectors now expose only the depths published by the free or paid twin's datasheet; unlisted rungs stay locked off. The 3.6/3.8 Qwens add
minimal, the other OVH reasoning rows exposemedium, Inkling Small addsmax, and Exo follows its paid twin'sminimal..xhighunion. - OVH output ceilings follow the highest published twin value below the window: 235,929 for the 397B and 3.8 Qwens, 65,536 for the 9B, 3.6 and both gpt-oss models, and 32,768 for Mistral and Llama.
- Remove Space Bunny: the free endpoint answers
410 ModelDeprecatedand points atminimax-m3.1-flash-free. - Declare only text and image inputs. The host catalog has no video or audio input type, so upstream video/audio/PDF support (MiMo, GLM 5.3 Flash, Nemotron Super VL, Nano Omni) is documented in the README instead of being advertised in the picker.
- Cat Jam now advertises its 1,048,576-token window: the endpoint refuses a 1.05M prompt with
-
Rate-limit rotation is now silent: a relay that answers 429 is cooled and deprioritized without a per-relay warning toast or per-relay WARN line while the pool still has a candidate. A pool-wide 429 burst alert still warns when many relays rate-limit in one minute. The rate-limit message appears only when no relay or direct fallback served the turn, including the existing 403-salvage path.
-
Model specs refreshed against the latest upstream catalogs. Free and paid variants of the same model now share the highest published context window, output ceiling, and input modalities, so a picker entry no longer understates what the model accepts.
-
Drop two Kilo models that stopped answering, so the picker only offers what is actually served:
nvidia/nemotron-3-super-120b-a12b:freeanswers404 Function ... Not found for account ...from its Nvidia provider, andthinkingmachines/inkling-small:freeanswers404 The requested model is currently unavailable. Both verdicts reproduce from two independent egress IPs while the sibling Nvidia ids answer200with the same request shape. The catalog is 32 models; both ids stay on the retired list so a stale cache cannot bring them back.
Full changelog: https://github.com/trefeon/pi-freeflow/blob/main/CHANGELOG.md
What's Changed
Full Changelog: v1.39.0...v1.40.0
v1.39.0
What's Changed
- chore(deps): bump typescript from 5.9.3 to 7.0.2 by @dependabot[bot] in #88
- feat(catalog): retire Muse Spark 1.2 contributor free model by @trefeon in #92
- chore(deps): bump js-yaml from 4.3.2 to 5.5.0 by @dependabot[bot] in #86
- ci: retry transient probe failures, pin actions, harden checkouts by @trefeon in #93
- chore(deps): bump @types/node from 22.20.1 to 22.20.5 in the dependencies group by @dependabot[bot] in #95
- ci(deps): bump pnpm/action-setup from 6.0.10 to 6.1.0 in the actions group by @dependabot[bot] in #94
- chore(deps): bump @changesets/cli from 2.31.1 to 3.0.3 by @dependabot[bot] in #96
- ci: give the model-health job a timeout that fits a hanging catalog by @trefeon in #97
- fix: close the October review findings (proxy auth, wire corruption, relay health, CLI, docs) by @trefeon in #98
New Contributors
- @dependabot[bot] made their first contribution in #88
Full Changelog: v1.38.5...v1.39.0
v1.38.5
Patch Changes
- Salvage relay rate-limit responses when direct fallback encounters network-level or abusive-IP 403 errors, preventing transient rate limits from locking up upstream models. Add the
/freeflow stickycommand to pin requests to one healthy relay until a rate limit or edge error occurs, preserving fresh pool relays. Recognize network-restricted and abusive-traffic 403 variants as free-tier gates so fresh sessions automatically fail over to healthy fallback models without interruption.
Full changelog: https://github.com/trefeon/pi-freeflow/blob/main/CHANGELOG.md
What's Changed
- ci: refresh action majors, gate CI by changed area, verify releases against npm by @trefeon in #84
- ci: gate the docs build on dependency changes and make the classifier testable by @trefeon in #89
- fix(relay): salvage relay rate-limit response on direct fallback 403 and add sticky command by @trefeon in #90
Full Changelog: v1.38.4...v1.38.5
v1.38.4
What's Changed
Full Changelog: v1.38.3...v1.38.4
v1.38.3
Patch Changes
- Absorb tool-call argument fragments arriving on terminal finish_reason chunks into buffered prefixes to prevent argument rotation and corrupted JSON loops. Add Reflection AI's Beam Free (1M context) to the OpenCode Zen lineup, and retire deprecated LL Alpha and Muse Spark 1.3 contributor free models.
Full changelog: https://github.com/trefeon/pi-freeflow/blob/main/CHANGELOG.md
Full Changelog: v1.38.2...v1.38.3
v1.38.2
Patch Changes
- Exo joins the OpenCode free tier β a live preview model with chat, tools, reasoning, and image input that the official free lineup lists.
- GLM-5.3 Flash and LL Alpha join the OpenCode free tier, and Step 5 Preview is retired β it is gone from the Zen lineup and demoted to paid on the Kilo lane, so those entries can no longer be selected.
- Documentation, the published model count (37), and the in-code notes are aligned with the live free lineup.
What's Changed
- fix(catalog): retire Step 5 Preview, add GLM-5.3 Flash and LL Alpha by @trefeon in #73
- fix(catalog): revive exo-free and align the docs with the 37-model catalog by @trefeon in #75
Full Changelog: v1.38.1...v1.38.2
v1.38.1
1.38.1
Patch Changes
- Add the Nemotron 3.5 Super VL free model and enable the max thinking level on Cat Jam β both live-verified through the proxy; align the README and docs with the shipped catalog.
- The first-run welcome now names the local proxy port actually in use instead of the default port.
- Streaming requests now pass through replies that arrive in a non-streaming format instead of dropping the answer, concurrent startups share a single connection attempt instead of racing, and a foreign process squatting the local proxy port is no longer mistaken for the daemon we own.
- Following logs now reads only the lines appended since the last tick instead of re-reading the whole log file every second, so
/freeflow logs --followstays light even on large logs. - Fix a batch of verified edge cases: non-ASCII streaming text is no longer corrupted when a character spans network chunks, assistant text stays visible on the responses path when it is served from a chat-only upstream, tool-argument repair also works on strict tool schemas, a relay that rejects our auth rolls to the next egress instead of being marked healthy, the update flow restarts the proxy it is actually attached to, and daemon/health state handling no longer loops or reads stale data.
Full changelog: https://github.com/trefeon/pi-freeflow/blob/main/CHANGELOG.md
What's Changed
- test: isolate daemon spawn in activation suites; fix first-run port message by @trefeon in #65
- fix(catalog): add Nemotron 3.5 Super VL, expose cat-jam max effort, align docs with the catalog by @trefeon in #66
- fix: verified review findings across streaming, tools, relay, and daemon paths by @trefeon in #67
- ci: harden watcher probes, alert lifecycle, and release guards by @trefeon in #64
- fix: pass non-SSE stream bodies through, single-flight daemon startup, validate port holders by @trefeon in #68
- perf(logs): incremental follow reads + test-quality cleanup batch by @trefeon in #69
- fix(logs): salvage the rotated tail when following logs by @trefeon in #70
- docs(logs): correct the follower's archive claim; re-scope the archive test by @trefeon in #72
Full Changelog: v1.38.0...v1.38.1
v1.38.0
What's Changed
- fix(daemon): start the proxy under Node from outside node_modules by @trefeon in #56
- pi coding agent dir by @jackusm in #57
- fix(config): stage daemon sources under the relocated agent dir by @trefeon in #58
- chore(scripts): align the live tool sweeps with the current catalog and rename rule by @trefeon in #59
- chore(scripts): scope the capability sweep and make its output budget configurable by @trefeon in #60
New Contributors
Full Changelog: v1.37.1...v1.38.0