pi-freeflow 1.11.2 → 1.12.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,379 +1,384 @@
1
- # pi-freeflow 🌊
2
-
3
- > **24 free models. Up to 1M context. Zero API keys. Infinite scale via your own relay pool.**
4
-
5
- Thin by design: model list + dumb relay + log. Host `pi-ai` owns thinking, normalization & provider magic. We just make it free, fast, and unbreakable.
6
-
7
- [![npm version](https://img.shields.io/npm/v/pi-freeflow?style=flat-square&color=00E5FF)](https://www.npmjs.com/package/pi-freeflow)
8
- [![npm downloads](https://img.shields.io/npm/dm/pi-freeflow?style=flat-square)](https://www.npmjs.com/package/pi-freeflow)
9
- [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg?style=flat-square)](https://opensource.org/licenses/MIT)
10
- [![Pi](https://img.shields.io/badge/Powered%20by-Pi-7c3aed?style=flat-square)](https://github.com/badlogic/pi-ai)
11
- [![Oh My Pi](https://img.shields.io/badge/Compatible-OMP-black?style=flat-square)](https://github.com/coder/oh-my-pi)
12
-
13
- Join devs bypassing rate limits with their own relay pools. BYO, add as many as you need.
14
-
15
- ---
16
-
17
- ### Features at a Glance
18
-
19
- | Feature | Description | Value | Cost |
20
- | :--- | :--- | :--- | :--- |
21
- | **24 Curated Free Models** | 7 OpenCode Zen + 17 KiloCode Gateway models, up to 1M context & 512K output | Ceiling Unlocked | **$0** |
22
- | **BYO Relay Pool** | Round-robin load balancing across your Cloudflare Workers & Vercel Edges | Zero Rate Limits | **$0** (your free tiers) |
23
- | **Adaptive Health & Error Detection** | Auto-cooldown on 429 rate limits, 504 timeouts, and socket drops | 0ms Wasted Latency | **$0** |
24
- | **Stream Truncation Resilience** | Stateful SSE terminal tracking (`response.failed` / `response.incomplete` injection) | Zero Host Crashes | **$0** |
25
- | **Smart Model Aliasing** | Clean slash-free & colon-free CLI model names compatible with thinking selectors | DX Optimized | **$0** |
26
- | **Auto-Enabled on Session** | Relay stays enabled in `auto` mode on session start and model switch | Zero Friction | **$0** |
27
- | **Interactive CLI Management** | 10+ `/freeflow` subcommands (`status`, `list`, `use`, `add`, `label`, `remove`, `deploy`, `logs`, `debug`) | Full Control | **$0** |
28
- | **Dumb Proxy That Never Breaks** | `127.0.0.1:28180`, host-normalized, pathname-guarded `/v1/models` | 100% Uptime | **$0** |
29
- | **Observable Real Logs** | `~/.pi/agent/pi-freeflow.log`, 10MB auto-rotation, real-time debug toggle | Observable | **$0** |
30
-
31
- Philosophy: **Thin by design.** We only ship model list + relay proxy + log. Host owns thinking & normalization.
32
-
33
- ---
34
-
35
- ### 24 Curated Models, One Command
36
-
37
- ```bash
38
- /model → freeflow → pick
39
- ```
40
-
41
- #### OpenCode Zen (7 Models), Responses & Chat API
42
- Optimized for deep reasoning, long-horizon coding & autonomous agentic workflows.
43
-
44
- | Model ID | Creator / Lab | Context | Max Output | Thinking | Vision |
45
- | :--- | :--- | :--- | :--- | :--- | :--- |
46
- | `muse-spark-1.2-contributor-free` | Meta Superintelligence Labs | **1M** (1.048.576) | **131K** (131.072) | `minimal … xhigh` | ✅ |
47
- | `muse-spark-1.3-contributor-free` | Meta Superintelligence Labs | **1M** (1.048.576) | **131K** (131.072) | `minimal … xhigh` | ✅ |
48
- | `mimo-v2.5-free` | Xiaomi MiMo | **1M** (1.048.576) | **131K** (131.072) | `minimal … xhigh`\* | ✅ |
49
- | `nemotron-3.5-lightning-free` | NVIDIA | **1M** (1.000.000) | **262K** (262.144) | `minimal … xhigh` | ❌ |
50
- | `nemotron-3-ultra-free` | NVIDIA | **1M** (1.000.000) | **128K** (128.000) | `minimal … xhigh` | ❌ |
51
- | `big-pickle` | Big Pickle | **200K** (200.000) | **32K** (32.000) | `high / max` | ❌ |
52
- | `ling-3.0-flash-fin-free` | Inclusion AI | **262K** (262.144) | **131K** (131.072) | `minimal … xhigh` | ❌ |
53
-
54
- #### KiloCode Gateway (17 Models), OpenRouter Compatible
55
- Keyless access with `Bearer kilo-free`. Clean slash-free and colon-free CLI aliases supported.
56
-
57
- | Model ID | Creator / Lab | Context | Max Output | Thinking | Vision |
58
- | :--- | :--- | :--- | :--- | :--- | :--- |
59
- | `dots-3-note-preview` (`dots-studio/...:free`) | Dots Studio | **512K** (512.000) | **512K** (512.000) | `minimal…xhigh`\* | ✅ |
60
- | `step-3.7-flash` (`stepfun/...:free`) | StepFun | **262K** (262.144) | **262K** (262.144) | `minimal…xhigh`\* | ✅ |
61
- | `nemotron-3-nano-omni` (`nvidia/...:free`) | NVIDIA | **256K** (256.000) | **131K** (131.072) | `minimal…xhigh`\* | ✅ |
62
- | `nemotron-3-ultra-550b` (`nvidia/...:free`) | NVIDIA | **1M** (1.000.000) | **128K** (128.000) | `minimal…xhigh`\* | ❌ |
63
- | `nvidia/nemotron-3.5-lightning:free` | NVIDIA | **1M** (1.000.000) | **262K** (262.144) | `minimal…xhigh`\* | ❌ |
64
- | `nemotron-3-super` (`nvidia/...:free`) | NVIDIA | **262K** (262.144) | **262K** (262.144) | `minimal…xhigh`\* | ❌ |
65
- | `north-mini-code` (`cohere/...:free`) | Cohere | **256K** (256.000) | **64K** (64.000) | `minimal…xhigh`\* | ❌ |
66
- | `laguna-s-2.1:free` (`poolside/...:free`) | Poolside | **262K** (262.144) | **32K** (32.768) | `minimal…xhigh`\* | ❌ |
67
- | `laguna-xs-2.1:free` (`poolside/...:free`) | Poolside | **262K** (262.144) | **32K** (32.768) | `minimal…xhigh`\* | ❌ |
68
- | `lfm-2.5` (`liquid/lfm-2.5-2.6b:free`) | Liquid AI | **65K** (65.536) | **32K** (32.768) | `minimal…xhigh`\* | ❌ |
69
- | `kilo-auto` (`kilo-auto/free`) | Kilo Gateway Auto | **256K** (256.000) | **10K** (10.000) | `minimal…xhigh`\* | ❌ |
70
- | `openrouter` (`openrouter/free`) | OpenRouter Free | **200K** (200.000) | **65K** (65.536) | `minimal…xhigh`\* | ✅ |
71
- | `content-safety` (`nvidia/...:free`) | NVIDIA | **128K** (128.000) | **8K** (8.192) | ❌ *(non-thinking)* | ✅ |
72
- | `ling-3.0-flash-fin` (`inclusionai/ling-3.0-flash-fin:free`) | Inclusion AI | **262K** (262.144) | **32K** (32.768) | `minimal…xhigh`\* | ❌ |
73
- | `inkling` (`thinkingmachines/inkling:free`) | Thinking Machines | **1M** (1.048.576) | **262K** (262.144) | `minimal…xhigh`\* | ✅ |
74
- | `ling-3.0-flash-sante` (`inclusionai/ling-3.0-flash-sante:free`) | Inclusion AI | **262K** (262.144) | **32K** (32.768) | `minimal…xhigh`\* | ❌ |
75
- | `inkling-small` (`thinkingmachines/inkling-small:free`) | Thinking Machines | **1M** (1.048.576) | **262K** (262.144) | `minimal…xhigh`\* | ✅ |
76
-
77
- \* Levels are forwarded as-is through the OpenRouter-style nested `reasoning` parameter; effort mapping is decided by each model. MiMo collapses `minimal→low` and `xhigh→high` upstream, so its selector shows 5 labels but only 3 distinct effort values.
78
-
79
- ---
80
-
81
- ### How It Works: BYO Relays, Zero Rate Limits
82
-
83
- ```
84
- You → 127.0.0.1:28180 (dumb proxy, host-normalized) → x-relay-target → N egress IPs (your pool) → opencode.ai / api.kilo.ai
85
- ↑ host already normalized thinking → proxy just forwards
86
- ```
87
-
88
- 1. **Per-Request Round-Robin**: 10 parallel subagents hit N different egress IPs (your pool size). No thundering herd.
89
- 2. **Adaptive Health & Error Cooldown**: Relays hitting 429, 504, or socket disconnects enter temporary cooldown (30-90s) and automatically move behind healthy candidates. Healthy relays handle traffic with 0ms wasted delay.
90
- 3. **Seamless 429 Roll**: `429 / 408 / 502 / 503 / 504 / 520-530` → instant roll to next relay, never 429 to agent.
91
- 4. **Stream Truncation Resilience**: Stateful SSE terminal tracking prevents fatal unhandled stream closed errors when connections drop.
92
- 5. **Direct Fallback Safety Net**: If all relays in the pool are exhausted, transparent direct fetch to upstream.
93
- 6. **Zero Subagent Connect Errors**: 24h `DISK_CACHE_ONLY` model catalog avoids subagents hammering remote catalogs.
94
-
95
- You bring the relays (free tiers). We bring the rolling.
96
-
97
- ---
98
-
99
- ### Interactive Commands Reference (`/freeflow`)
100
-
101
- Manage your relay pool directly from the OMP / Pi terminal:
102
-
103
- ```bash
104
- /freeflow status # View active relay, pool status, and candidates
105
- /freeflow list # List all relays with real-time health badges (✓ / ⚠️ [cooling])
106
- /freeflow use <url|index|label> # Switch active relay
107
- /freeflow url <url> # Set the active relay URL directly
108
- /freeflow add <url> [label] # Add new relay to the pool
109
- /freeflow label <index|url> <name># Assign a friendly label to a relay
110
- /freeflow remove <index|url|label># Remove a relay from the pool
111
- /freeflow test <index|url|label> # Probe a relay for reachability (HTTP 200 + latency)
112
- /freeflow on | off | auto # Toggle relay mode (auto = enabled for freeflow)
113
- /freeflow deploy <platform> # Guided relay deploy: vercel|cloudflare|deno — token in-memory, auto-adds (Vercel 1M/mo recommended)
114
- /freeflow logs [lines] # Inspect recent proxy logs
115
- /freeflow trace [req-id] # Tail logs filtered by request correlation ID
116
- /freeflow refresh # Reload the model catalog from live upstreams
117
- /freeflow update # Check for and install a package update
118
- /freeflow debug on | off # Toggle full HTTP lifecycle debug logging
119
- /freeflow kill # Stop the shared proxy daemon now (restarts on next use)
120
- ```
121
-
122
- ---
123
-
124
- ### Quick Start in 30 Seconds
125
-
126
- **On Oh My Pi (OMP):**
127
- ```bash
128
- omp plugin install pi-freeflow
129
- # or local dev (repo checkout)
130
- omp plugin link /path/to/pi-freeflow
131
- ```
132
-
133
- **On Pi:**
134
- ```bash
135
- pi install npm:pi-freeflow
136
- ```
137
-
138
- > Both commands fetch the **same npm package** from the registry — pi-freeflow
139
- > is an extension loaded by the host, not a standalone CLI. It works on **OMP
140
- > and Pi only** (they share the extension API).
141
-
142
- #### 2. Pick a Model
143
-
144
- **OMP — interactive:**
145
- ```bash
146
- omp
147
- /model → freeflow → muse-spark-1.2-contributor-free (1M) → max
148
- ```
149
-
150
- **OMP — one-shot CLI:**
151
- ```bash
152
- omp -p --model freeflow/muse-spark-1.2-contributor-free "build me a SaaS"
153
- omp -p --model freeflow/step-3.7-flash:high "solve this bug" # alias + thinking level
154
- ```
155
-
156
- **Pi — interactive:**
157
- ```bash
158
- pi
159
- /model → freeflow → pick
160
- ```
161
-
162
- **Pi — one-shot CLI:**
163
- ```bash
164
- pi -p --model freeflow/step-3.7-flash:high "solve this bug"
165
- ```
166
-
167
- > Model IDs accept a full canonical ID, a short alias (see the tables above),
168
- > and an optional `:effort` suffix (`:minimal` … `:xhigh`, `:max` where
169
- > supported). The host resolves the rest — you only type `freeflow/<name>`.
170
-
171
- #### 3. Manage Your Relay Pool (OMP & Pi both)
172
-
173
- ```bash
174
- /freeflow status # active relay, pool status, candidates
175
- /freeflow list # relays with health badges
176
- /freeflow add <url> [label]
177
- /freeflow deploy # guided deploy: vercel|cloudflare|deno
178
- /freeflow logs [n] # tail proxy logs
179
- ```
180
-
181
- These slash commands work **identically in OMP and Pi** — the extension
182
- registers the same `/freeflow` command set in both hosts.
183
- #### 4. Add Your Free Relays (Scale Infinitely)
184
-
185
- Default ships direct. Add relays via `/freeflow add <url> [label]`.
186
-
187
- **Zero setup?** Run `/freeflow deploy cloudflare` (or `deno`, `vercel`), paste your platform token once, and the relay is created and activated for you. Manual snippets below.
188
-
189
- **Option A: Cloudflare Workers (100k req/day, no 25s timeout) — Auto Deploy**
190
- ```bash
191
- /freeflow deploy cloudflare # prompts token in-memory, auto-adds to pool
192
- ```
193
- *Manual fallback:* `dash.cloudflare.com` → Workers → Create → Deploy → Edit code → paste the canonical worker source (see "Canonical worker source" below) → Deploy → `/freeflow add https://your.workers.dev cf-worker-1`
194
-
195
- **Option B: Vercel Edge Relay (1M req/mo) — Auto Deploy**
196
- ```bash
197
- /freeflow deploy vercel # prompts token in-memory, auto-adds to pool
198
- # or shorthand: /freeflow deploy
199
- ```
200
- *Manual fallback:* Push 2 files (`api/relay.js` + `vercel.json`) to GitHub $\to$ Import on `vercel.com` $\to$ `/freeflow add https://your.vercel.app vercel-relay-1`
201
-
202
- For `api/relay.js`, use the canonical worker source (see below); `vercel.json` stays:
203
-
204
- ```json
205
- { "rewrites": [{ "source": "/(.*)", "destination": "/api/relay" }] }
206
- ```
207
-
208
- **Option C: Deno Deploy (100k req/day) — Auto Deploy**
209
- ```bash
210
- /freeflow deploy deno # prompts token in-memory, auto-adds to pool
211
- ```
212
- *Manual fallback:* `dash.deno.com` → New Project → Playground → paste the canonical worker source (see below) → Deploy → `/freeflow add https://your-project.deno.dev deno-relay-1`
213
-
214
- **Canonical worker source (all platforms)**
215
-
216
- The relay worker template is generated per deployment by `/freeflow deploy` and lives in [`src/deploy.ts`](src/deploy.ts): one hardened core plus thin Vercel / Cloudflare / Deno wrappers. Deployed relays are public by default for seamless migration across proxy tools (such as 9router), while enforcing the target allowlist (`https://opencode.ai`, `https://api.kilo.ai`), SSRF/private-host guard, relay-path validation, and a header denylist.
217
-
218
- ```js
219
- // Minimal Cloudflare illustration. Prefer /freeflow deploy: the generated
220
- // worker (src/deploy.ts) is the signed/hardened source for all three
221
- // platforms. This example omits the SSRF guard, path validation, and auth.
222
- const ALLOWED_TARGETS = ["https://opencode.ai", "https://api.kilo.ai"];
223
- export default {
224
- async fetch(req) {
225
- const target = req.headers.get("x-relay-target");
226
- const relayPath = req.headers.get("x-relay-path") || "/";
227
- if (!target || !ALLOWED_TARGETS.includes(target.replace(/\/$/, ""))) {
228
- return new Response(JSON.stringify({ error: "Forbidden target" }), { status: 403 });
229
- }
230
- const headers = new Headers(req.headers);
231
- headers.delete("x-relay-target"); headers.delete("x-relay-path"); headers.delete("host");
232
- return fetch(target.replace(/\/$/, "") + relayPath, { method: req.method, headers, body: req.method !== "GET" && req.method !== "HEAD" ? req.body : undefined });
233
- },
234
- };
235
- ```
236
-
237
- **Verify your pool:**
238
- ```bash
239
- /freeflow status # relay-A 1/N (ON) → candidates:N
240
- /freeflow list # lists all relays with health status
241
- /freeflow logs # tail -25
242
- cat ~/.pi/agent/pi-freeflow.log | tail -n 20
243
- ```
244
-
245
- ---
246
-
247
- ### Logs & Debugging
248
-
249
- ```bash
250
- /freeflow logs
251
- cat ~/.pi/agent/pi-freeflow.log | tail -n 50
252
-
253
- # debug toggle (full debug is on by default for complete error reports; `off` restores info)
254
- /freeflow debug on
255
- ```
256
-
257
- Log rotation at 10MB. Clean, parseable, real-time HTTP lifecycle tracking.
258
-
259
- ---
260
-
261
- ### Design
262
-
263
- This package stays thin. It ships three things: a model catalog, a relay proxy, and a log. There is no build step. Zero runtime dependencies — uses native Node.js global fetch. Thinking and prompt normalization stay with the host (`pi-ai`).
264
-
265
- Current size: about 11.3k lines including tests. The full suite (sandboxed, mocked network) and typecheck pass before every release — see CHANGELOG.md.
266
-
267
- ---
268
-
269
- ### FAQ
270
-
271
- **Do I need API keys?**
272
- No. Kilo uses `Bearer kilo-free`, OpenCode free models are anonymous (no header needed).
273
-
274
- **What if all relays are 429?**
275
- Proxy tries direct. If that is also 429, Pi shows the rate limit. That number is the global upstream cap; without relays you would hit the same wall.
276
-
277
- **Can I use without relays?**
278
- Yes. `/freeflow off` → direct. Add relays later to scale.
279
-
280
- **What happens when I update to a new version?**
281
- The local proxy daemon is shared across sessions on port 28180. On upgrade, the new extension
282
- detects a stale daemon (mismatched internal version) and replaces it automatically — no manual
283
- kill, no restart of other sessions required. Replacement only happens when the running daemon is
284
- idle: sessions with in-flight requests are never interrupted (busy or newer daemons are reused
285
- with a log note instead). If a daemon cannot be replaced (e.g. port held by an unrelated process),
286
- it falls back to reusing it with a warning. To disable replacement entirely, set the no-kill env
287
- to `1` before starting a session.
288
-
289
- **What happens when I close a session?**
290
- Nothing visible to your other sessions. The proxy daemon is a separate background
291
- process shared by every OMP/Pi session on the machine. Closing one session just
292
- unregisters it; the daemon keeps serving the rest and retires itself automatically
293
- once the last client disconnects and no client re-attaches within a short grace window.
294
- To stop it manually, run `/freeflow kill` — the next freeflow use starts it again.
295
-
296
- **Where's the normalizer?**
297
- Deleted in 1.3.0. If zai/qwen/deepseek thinking broke before, it's fixed now because host handles it.
298
-
299
- **Why is context free?**
300
- We use OpenCode Zen & Kilo free tiers. You pay only with your own Cloudflare/Vercel free tiers for egress.
301
- **Why is it installed via npm?**
302
- The npm package is the **distribution channel** only — both hosts resolve it internally:
303
- `omp plugin install pi-freeflow` and `pi install npm:pi-freeflow` install the same
304
- package from the npm registry. pi-freeflow is an **extension, not a standalone CLI** —
305
- the host (OMP or Pi) loads and runs it. A plain `npm install` just downloads the
306
- files; it is not a supported way to run the extension.
307
-
308
- **Which hosts can use it?**
309
- Oh My Pi (OMP) and Pi only. They share the same extension API
310
- (`extensions/index.ts` declares both `omp` and `pi` extension entries), so one
311
- package serves both. Other AI agents (OpenCode, KiloCode, Cursor, ...) have their
312
- own plugin systems and do not load this extension.
313
-
314
- ---
315
-
316
- ### Contributing
317
-
318
- Contributions welcome — bug fixes, new relay platforms, model additions, docs improvements.
319
-
320
- #### Prerequisites
321
-
322
- - **Node.js ≥ 22.19.0** (uses `--experimental-strip-types`, no build step)
323
- - **pnpm** (package manager)
324
-
325
- #### Setup & Verify
326
-
327
- ```bash
328
- git clone https://github.com/trefeon/pi-freeflow
329
- cd pi-freeflow
330
- pnpm install
331
-
332
- # run all three before opening a PR
333
- pnpm test # full suite; sandboxed + network-mocked
334
- pnpm typecheck # tsc --noEmit, must pass clean
335
- pnpm smoke # verifies extensions/index.ts loads without crashing
336
- ```
337
-
338
- #### Project Structure
339
-
340
- ```
341
- src/
342
- ├── index.ts # extension entry, lifecycle hooks
343
- ├── models.ts # 24-model catalog definitions
344
- ├── catalog.ts # model catalog cache (24h disk)
345
- ├── proxy.ts # local proxy server (127.0.0.1:28180)
346
- ├── relay.ts # relay selection & round-robin
347
- ├── relay-state.ts # relay pool state, health tracking
348
- ├── stream-pipe.ts # SSE stream piping & truncation resilience
349
- ├── commands.ts # /freeflow CLI subcommands
350
- ├── deploy.ts # guided relay deploy (vercel/cloudflare/deno)
351
- ├── config.ts # constants, whitelists, paths, and runtime settings
352
- ├── logger.ts # file logger with 10MB rotation
353
- └── types.ts # shared type definitions
354
- extensions/
355
- └── index.ts # OMP/Pi extension manifest
356
- test/
357
- └── *.test.ts # mirrors src/, node:test runner
358
- ```
359
-
360
- #### Guidelines
361
-
362
- - **Stay thin.** Zero runtime dependencies, no build step. If it belongs in the host (`pi-ai`), don't add it here.
363
- - **Test what you touch.** Every `src/*.ts` has a matching `test/*.test.ts`. Add or update tests for your change.
364
- - **Keep model IDs clean.** Slash-free, colon-free aliases for CLI compatibility. See existing patterns in `models.ts`.
365
- - **One concern per PR.** Bug fix? One PR. New relay platform? Separate PR. Easier to review, faster to merge.
366
-
367
- #### Reporting Issues
368
-
369
- Found a bug or want a feature? [Open an issue](https://github.com/trefeon/pi-freeflow/issues) with:
370
- - What happened vs what you expected
371
- - Your relay setup (`/freeflow status` output helps)
372
- - Relevant logs (`/freeflow logs` or `~/.pi/agent/pi-freeflow.log`)
373
-
374
- ---
375
-
376
- ### License
377
-
378
- MIT © trefeon
379
-
1
+ # pi-freeflow 🌊
2
+
3
+ > **26 free models. Up to 1M context. Zero API keys. Infinite scale via your own relay pool.**
4
+
5
+ Thin by design: model list + dumb relay + log. Host `pi-ai` owns thinking, normalization & provider magic. We just make it free, fast, and unbreakable.
6
+
7
+ [![npm version](https://img.shields.io/npm/v/pi-freeflow?style=flat-square&color=00E5FF)](https://www.npmjs.com/package/pi-freeflow)
8
+ [![npm downloads](https://img.shields.io/npm/dm/pi-freeflow?style=flat-square)](https://www.npmjs.com/package/pi-freeflow)
9
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg?style=flat-square)](https://opensource.org/licenses/MIT)
10
+ [![Pi](https://img.shields.io/badge/Powered%20by-Pi-7c3aed?style=flat-square)](https://github.com/badlogic/pi-ai)
11
+ [![Oh My Pi](https://img.shields.io/badge/Compatible-OMP-black?style=flat-square)](https://github.com/coder/oh-my-pi)
12
+
13
+ Join devs bypassing rate limits with their own relay pools. BYO, add as many as you need.
14
+
15
+ ---
16
+
17
+ ### Features at a Glance
18
+
19
+ | Feature | Description | Value | Cost |
20
+ | :--- | :--- | :--- | :--- |
21
+ | **26 Curated Free Models** | 7 OpenCode Zen + 19 KiloCode Gateway models, up to 1M context & 512K output | Ceiling Unlocked | **$0** |
22
+ | **BYO Relay Pool** | Round-robin load balancing across your Cloudflare Workers & Vercel Edges | Zero Rate Limits | **$0** (your free tiers) |
23
+ | **Adaptive Health & Error Detection** | Auto-cooldown on 429 rate limits, 504 timeouts, and socket drops | 0ms Wasted Latency | **$0** |
24
+ | **Stream Truncation Resilience** | Stateful SSE terminal tracking (`response.failed` / `response.incomplete` injection) | Zero Host Crashes | **$0** |
25
+ | **Smart Model Aliasing** | Clean slash-free & colon-free CLI model names compatible with thinking selectors | DX Optimized | **$0** |
26
+ | **Auto-Enabled on Session** | Relay stays enabled in `auto` mode on session start and model switch | Zero Friction | **$0** |
27
+ | **Interactive CLI Management** | 10+ `/freeflow` subcommands (`status`, `list`, `use`, `add`, `label`, `remove`, `deploy`, `logs`, `debug`) | Full Control | **$0** |
28
+ | **Dumb Proxy That Never Breaks** | `127.0.0.1:28180`, host-normalized, pathname-guarded `/v1/models` | 100% Uptime | **$0** |
29
+ | **Observable Real Logs** | `~/.pi/agent/pi-freeflow.log`, 10MB auto-rotation, real-time debug toggle | Observable | **$0** |
30
+
31
+ Philosophy: **Thin by design.** We only ship model list + relay proxy + log. Host owns thinking & normalization.
32
+
33
+ ---
34
+
35
+ ### 26 Curated Models, One Command
36
+
37
+ ```bash
38
+ /model → freeflow → pick
39
+ ```
40
+
41
+ #### OpenCode Zen (7 Models), Responses & Chat API
42
+ Optimized for deep reasoning, long-horizon coding & autonomous agentic workflows.
43
+
44
+ | Model ID | Creator / Lab | Context | Max Output | Thinking | Vision |
45
+ | :--- | :--- | :--- | :--- | :--- | :--- |
46
+ | `muse-spark-1.2-contributor-free` | Meta Superintelligence Labs | **1M** (1.048.576) | **131K** (131.072) | `minimal … xhigh` | ✅ |
47
+ | `muse-spark-1.3-contributor-free` | Meta Superintelligence Labs | **1M** (1.048.576) | **131K** (131.072) | `minimal … xhigh` | ✅ |
48
+ | `mimo-v2.5-free` | Xiaomi MiMo | **1M** (1.048.576) | **131K** (131.072) | `minimal … xhigh`\* | ✅ |
49
+ | `nemotron-3.5-lightning-free` | NVIDIA | **1M** (1.000.000) | **262K** (262.144) | `minimal … xhigh` | ❌ |
50
+ | `nemotron-3-ultra-free` | NVIDIA | **1M** (1.000.000) | **128K** (128.000) | `minimal … xhigh` | ❌ |
51
+ | `big-pickle` | Big Pickle | **200K** (200.000) | **32K** (32.000) | `high / max` | ❌ |
52
+ | `ling-3.0-flash-fin-free` | Inclusion AI | **262K** (262.144) | **131K** (131.072) | `minimal … xhigh` | ❌ |
53
+
54
+ #### KiloCode Gateway (19 Models), OpenRouter Compatible
55
+ Keyless access with `Bearer kilo-free`. Clean slash-free and colon-free CLI aliases supported.
56
+
57
+ | Model ID | Creator / Lab | Context | Max Output | Thinking | Vision |
58
+ | :--- | :--- | :--- | :--- | :--- | :--- |
59
+ | `dots-3-note-preview` (`dots-studio/...:free`) | Dots Studio | **512K** (512.000) | **512K** (512.000) | `minimal…xhigh`\* | ✅ |
60
+ | `step-3.7-flash` (`stepfun/...:free`) | StepFun | **262K** (262.144) | **262K** (262.144) | `minimal…xhigh`\* | ✅ |
61
+ | `nemotron-3-nano-omni` (`nvidia/...:free`) | NVIDIA | **256K** (256.000) | **131K** (131.072) | `minimal…xhigh`\* | ✅ |
62
+ | `nemotron-3-ultra-550b` (`nvidia/...:free`) | NVIDIA | **1M** (1.000.000) | **128K** (128.000) | `minimal…xhigh`\* | ❌ |
63
+ | `nvidia/nemotron-3.5-lightning:free` | NVIDIA | **1M** (1.000.000) | **262K** (262.144) | `minimal…xhigh`\* | ❌ |
64
+ | `nemotron-3-super` (`nvidia/...:free`) | NVIDIA | **262K** (262.144) | **262K** (262.144) | `minimal…xhigh`\* | ❌ |
65
+ | `north-mini-code` (`cohere/...:free`) | Cohere | **256K** (256.000) | **64K** (64.000) | `minimal…xhigh`\* | ❌ |
66
+ | `laguna-s-2.1:free` (`poolside/...:free`) | Poolside | **262K** (262.144) | **32K** (32.768) | `minimal…xhigh`\* | ❌ |
67
+ | `laguna-xs-2.1:free` (`poolside/...:free`) | Poolside | **262K** (262.144) | **32K** (32.768) | `minimal…xhigh`\* | ❌ |
68
+ | `lfm-2.5` (`liquid/lfm-2.5-2.6b:free`) | Liquid AI | **65K** (65.536) | **32K** (32.768) | `minimal…xhigh`\* | ❌ |
69
+ | `kilo-auto` (`kilo-auto/free`) | Kilo Gateway Auto | **256K** (256.000) | **10K** (10.000) | `minimal…xhigh`\* | ❌ |
70
+ | `openrouter` (`openrouter/free`) | OpenRouter Free | **200K** (200.000) | **65K** (65.536) | `minimal…xhigh`\* | ✅ |
71
+ | `content-safety` (`nvidia/...:free`) | NVIDIA | **128K** (128.000) | **8K** (8.192) | ❌ *(non-thinking)* | ✅ |
72
+ | `ling-3.0-flash-fin` (`inclusionai/ling-3.0-flash-fin:free`) | Inclusion AI | **262K** (262.144) | **32K** (32.768) | `minimal…xhigh`\* | ❌ |
73
+ | `ling-3.0-flash-sante` (`inclusionai/ling-3.0-flash-sante:free`) | Inclusion AI | **262K** (262.144) | **32K** (32.768) | `minimal…xhigh`\* | ❌ |
74
+ | `nex-n2.5-pro` (`nex-agi/nex-n2.5-pro:free`) | Nex AGI | **262K** (262.144) | **235K** (235.929) | `minimal…xhigh`\* | ✅ |
75
+ | `nex-n2.5-mini` (`nex-agi/nex-n2.5-mini:free`) | Nex AGI | **262K** (262.144) | **235K** (235.929) | `minimal…xhigh`\* | ✅ |
76
+ | `ling-3.0-flash-vl` (`inclusionai/ling-3.0-flash-vl:free`) | Inclusion AI | **262K** (262.144) | **32K** (32.768) | `minimal…xhigh`\* | ✅ |
77
+ | `inkling-small` (`thinkingmachines/inkling-small:free`) | Thinking Machines | **1M** (1.048.576) | **262K** (262.144) | `minimal…xhigh`\* | ✅ |
78
+
79
+ \* Levels are forwarded as-is through the OpenRouter-style nested `reasoning` parameter; effort mapping is decided by each model. MiMo collapses `minimal→low` and `xhigh→high` upstream, so its selector shows 5 labels but only 3 distinct effort values.
80
+
81
+ ---
82
+
83
+ ### How It Works: BYO Relays, Zero Rate Limits
84
+
85
+ ```
86
+ You → 127.0.0.1:28180 (dumb proxy, host-normalized) → x-relay-target → N egress IPs (your pool) → opencode.ai / api.kilo.ai
87
+ ↑ host already normalized thinking → proxy just forwards
88
+ ```
89
+
90
+ 1. **Per-Request Round-Robin**: 10 parallel subagents hit N different egress IPs (your pool size). No thundering herd.
91
+ 2. **Adaptive Health & Error Cooldown**: Relays hitting 429, 504, or socket disconnects enter temporary cooldown (30-90s) and automatically move behind healthy candidates. Healthy relays handle traffic with 0ms wasted delay.
92
+ 3. **Seamless 429 Roll**: `429 / 408 / 502 / 503 / 504 / 520-530` → instant roll to next relay, never 429 to agent.
93
+ 4. **Stream Truncation Resilience**: Stateful SSE terminal tracking prevents fatal unhandled stream closed errors when connections drop.
94
+ 5. **Direct Fallback Safety Net**: If all relays in the pool are exhausted, transparent direct fetch to upstream.
95
+ 6. **Zero Subagent Connect Errors**: 24h `DISK_CACHE_ONLY` model catalog avoids subagents hammering remote catalogs.
96
+
97
+ You bring the relays (free tiers). We bring the rolling.
98
+
99
+ ---
100
+
101
+ ### Interactive Commands Reference (`/freeflow`)
102
+
103
+ Manage your relay pool directly from the OMP / Pi terminal:
104
+
105
+ ```bash
106
+ /freeflow status # View active relay, pool status, and candidates
107
+ /freeflow list # List all relays with real-time health badges (✓ / ⚠️ [cooling])
108
+ /freeflow use <url|index|label> # Switch active relay
109
+ /freeflow url <url> # Set the active relay URL directly
110
+ /freeflow add <url> [label] # Add new relay to the pool
111
+ /freeflow label <index|url> <name># Assign a friendly label to a relay
112
+ /freeflow remove <index|url|label># Remove a relay from the pool
113
+ /freeflow test <index|url|label> # Probe a relay for reachability (HTTP 200 + latency)
114
+ /freeflow on | off | auto # Toggle relay mode (auto = enabled for freeflow)
115
+ /freeflow deploy <platform> # Guided relay deploy: vercel|cloudflare|deno — token in-memory, auto-adds (Vercel 1M/mo recommended)
116
+ /freeflow logs [lines] # Inspect recent proxy logs
117
+ /freeflow trace [req-id] # Tail logs filtered by request correlation ID
118
+ /freeflow refresh # Reload the model catalog from live upstreams
119
+ /freeflow update # Check for and install a package update
120
+ /freeflow debug on | off # Toggle full HTTP lifecycle debug logging
121
+ /freeflow kill # Stop the shared proxy daemon now (restarts on next use)
122
+ ```
123
+
124
+ ---
125
+
126
+ ### Quick Start in 30 Seconds
127
+
128
+ **On Oh My Pi (OMP):**
129
+ ```bash
130
+ omp plugin install pi-freeflow
131
+ # or local dev (repo checkout)
132
+ omp plugin link /path/to/pi-freeflow
133
+ ```
134
+
135
+ **On Pi:**
136
+ ```bash
137
+ pi install npm:pi-freeflow
138
+ ```
139
+
140
+ > Both commands fetch the **same npm package** from the registry — pi-freeflow
141
+ > is an extension loaded by the host, not a standalone CLI. It works on **OMP
142
+ > and Pi only** (they share the extension API).
143
+
144
+ #### 2. Pick a Model
145
+
146
+ **OMP — interactive:**
147
+ ```bash
148
+ omp
149
+ /model → freeflow → muse-spark-1.2-contributor-free (1M) → max
150
+ ```
151
+
152
+ **OMP — one-shot CLI:**
153
+ ```bash
154
+ omp -p --model freeflow/muse-spark-1.2-contributor-free "build me a SaaS"
155
+ omp -p --model freeflow/step-3.7-flash:high "solve this bug" # alias + thinking level
156
+ ```
157
+
158
+ **Pi — interactive:**
159
+ ```bash
160
+ pi
161
+ /model → freeflow → pick
162
+ ```
163
+
164
+ **Pi — one-shot CLI:**
165
+ ```bash
166
+ pi -p --model freeflow/step-3.7-flash:high "solve this bug"
167
+ ```
168
+
169
+ > Model IDs accept a full canonical ID, a short alias (see the tables above),
170
+ > and an optional `:effort` suffix (`:minimal` … `:xhigh`, `:max` where
171
+ > supported). The host resolves the rest — you only type `freeflow/<name>`.
172
+
173
+ #### 3. Manage Your Relay Pool (OMP & Pi both)
174
+
175
+ ```bash
176
+ /freeflow status # active relay, pool status, candidates
177
+ /freeflow list # relays with health badges
178
+ /freeflow add <url> [label]
179
+ /freeflow deploy # guided deploy: vercel|cloudflare|deno
180
+ /freeflow logs [n] # tail proxy logs
181
+ ```
182
+
183
+ These slash commands work **identically in OMP and Pi** — the extension
184
+ registers the same `/freeflow` command set in both hosts.
185
+ #### 4. Add Your Free Relays (Scale Infinitely)
186
+
187
+ Default ships direct. Add relays via `/freeflow add <url> [label]`.
188
+
189
+ **Zero setup?** Run `/freeflow deploy cloudflare` (or `deno`, `vercel`), paste your platform token once, and the relay is created and activated for you. Manual snippets below.
190
+
191
+ **Option A: Cloudflare Workers (100k req/day, no 25s timeout) — Auto Deploy**
192
+ ```bash
193
+ /freeflow deploy cloudflare # prompts token in-memory, auto-adds to pool
194
+ ```
195
+ *Manual fallback:* `dash.cloudflare.com` → Workers → Create → Deploy → Edit code → paste the canonical worker source (see "Canonical worker source" below) → Deploy → `/freeflow add https://your.workers.dev cf-worker-1`
196
+
197
+ **Option B: Vercel Edge Relay (1M req/mo) — Auto Deploy**
198
+ ```bash
199
+ /freeflow deploy vercel # prompts token in-memory, auto-adds to pool
200
+ # or shorthand: /freeflow deploy
201
+ ```
202
+ *Manual fallback:* Push 2 files (`api/relay.js` + `vercel.json`) to GitHub $\to$ Import on `vercel.com` $\to$ `/freeflow add https://your.vercel.app vercel-relay-1`
203
+
204
+ For `api/relay.js`, use the canonical worker source (see below); `vercel.json` stays:
205
+
206
+ ```json
207
+ { "rewrites": [{ "source": "/(.*)", "destination": "/api/relay" }] }
208
+ ```
209
+
210
+ **Option C: Deno Deploy (100k req/day) — Auto Deploy**
211
+ ```bash
212
+ /freeflow deploy deno # prompts token in-memory, auto-adds to pool
213
+ ```
214
+ *Manual fallback:* `dash.deno.com` → New Project → Playground → paste the canonical worker source (see below) → Deploy → `/freeflow add https://your-project.deno.dev deno-relay-1`
215
+
216
+ **Canonical worker source (all platforms)**
217
+
218
+ The relay worker template is generated per deployment by `/freeflow deploy` and lives in [`src/deploy.ts`](src/deploy.ts): one hardened core plus thin Vercel / Cloudflare / Deno wrappers. Deployed relays are public by default for seamless migration across proxy tools (such as 9router), while enforcing the target allowlist (`https://opencode.ai`, `https://api.kilo.ai`), SSRF/private-host guard, relay-path validation, and a header denylist.
219
+
220
+ ```js
221
+ // Minimal Cloudflare illustration. Prefer /freeflow deploy: the generated
222
+ // worker (src/deploy.ts) is the signed/hardened source for all three
223
+ // platforms. This example omits the SSRF guard, path validation, and auth.
224
+ const ALLOWED_TARGETS = ["https://opencode.ai", "https://api.kilo.ai"];
225
+ export default {
226
+ async fetch(req) {
227
+ const target = req.headers.get("x-relay-target");
228
+ const relayPath = req.headers.get("x-relay-path") || "/";
229
+ if (!target || !ALLOWED_TARGETS.includes(target.replace(/\/$/, ""))) {
230
+ return new Response(JSON.stringify({ error: "Forbidden target" }), { status: 403 });
231
+ }
232
+ const headers = new Headers(req.headers);
233
+ headers.delete("x-relay-target"); headers.delete("x-relay-path"); headers.delete("host");
234
+ return fetch(target.replace(/\/$/, "") + relayPath, { method: req.method, headers, body: req.method !== "GET" && req.method !== "HEAD" ? req.body : undefined });
235
+ },
236
+ };
237
+ ```
238
+
239
+ **Verify your pool:**
240
+ ```bash
241
+ /freeflow status # relay-A 1/N (ON) → candidates:N
242
+ /freeflow list # lists all relays with health status
243
+ /freeflow logs # tail -25
244
+ cat ~/.pi/agent/pi-freeflow.log | tail -n 20
245
+ ```
246
+
247
+ ---
248
+
249
+ ### Logs & Debugging
250
+
251
+ ```bash
252
+ /freeflow logs
253
+ cat ~/.pi/agent/pi-freeflow.log | tail -n 50
254
+
255
+ # debug toggle (full debug is on by default for complete error reports; `off` restores info)
256
+ /freeflow debug on
257
+ ```
258
+
259
+ Log rotation at 10MB. Clean, parseable, real-time HTTP lifecycle tracking.
260
+
261
+ ---
262
+
263
+ ### Design
264
+
265
+ This package stays thin. It ships three things: a model catalog, a relay proxy, and a log. There is no build step. Zero runtime dependencies — uses native Node.js global fetch. Thinking and prompt normalization stay with the host (`pi-ai`).
266
+
267
+ Current size: about 11.3k lines including tests. The full suite (sandboxed, mocked network) and typecheck pass before every release — see CHANGELOG.md.
268
+
269
+ ---
270
+
271
+ ### FAQ
272
+
273
+ **Do I need API keys?**
274
+ No. Kilo uses `Bearer kilo-free`, OpenCode free models are anonymous (no header needed).
275
+
276
+ **What if all relays are 429?**
277
+ Proxy tries direct. If that is also 429, Pi shows the rate limit. That number is the global upstream cap; without relays you would hit the same wall.
278
+
279
+ **Can I use without relays?**
280
+ Yes. `/freeflow off` → direct. Add relays later to scale.
281
+
282
+ **What happens when I update to a new version?**
283
+ The local proxy daemon is shared across sessions on port 28180. On upgrade, the new extension
284
+ detects a stale daemon (mismatched internal version) and replaces it automatically — no manual
285
+ kill, no restart of other sessions required. Replacement only happens when the running daemon is
286
+ idle: sessions with in-flight requests are never interrupted (busy or newer daemons are reused
287
+ with a log note instead). If a daemon cannot be replaced (e.g. port held by an unrelated process),
288
+ it falls back to reusing it with a warning. To disable replacement entirely, set the no-kill env
289
+ to `1` before starting a session.
290
+
291
+ **What happens when I close a session?**
292
+ Nothing visible to your other sessions. The proxy daemon is a separate background
293
+ process shared by every OMP/Pi session on the machine. Closing one session just
294
+ unregisters it; the daemon keeps serving the rest and retires itself automatically
295
+ once the last client disconnects and no client re-attaches within a short grace window.
296
+ To stop it manually, run `/freeflow kill` — the next freeflow use starts it again.
297
+
298
+ **Why did my session stop with "reasoning `encrypted_content` was not issued to this caller"?**
299
+ Reasoning models on the Responses API sign each thinking block for the upstream backend that produced it, and only that backend can read it back. When a later turn reaches a different backend, the replayed thinking blocks are rejected, and the host keeps re-sending the same history, so the session cannot continue on its own. pi-freeflow now handles this two ways: it keeps each conversation on the relay that issued its reasoning while that relay is healthy, and when the relay must change anyway (rate limit, relay removed or redeployed, direct-mode switch) it sends that turn's history without the signed thinking blocks, so the new backend accepts it immediately instead of rejecting the request. As a last resort it retries once without the blocks, then remembers which blocks were rejected and drops only those on later turns, keeping everything the current backend can read. Messages, tool calls and tool results are always preserved.
300
+
301
+ **Where's the normalizer?**
302
+ Deleted in 1.3.0. If zai/qwen/deepseek thinking broke before, it's fixed now because host handles it.
303
+
304
+ **Why is context free?**
305
+ We use OpenCode Zen & Kilo free tiers. You pay only with your own Cloudflare/Vercel free tiers for egress.
306
+ **Why is it installed via npm?**
307
+ The npm package is the **distribution channel** only — both hosts resolve it internally:
308
+ `omp plugin install pi-freeflow` and `pi install npm:pi-freeflow` install the same
309
+ package from the npm registry. pi-freeflow is an **extension, not a standalone CLI** —
310
+ the host (OMP or Pi) loads and runs it. A plain `npm install` just downloads the
311
+ files; it is not a supported way to run the extension.
312
+
313
+ **Which hosts can use it?**
314
+ Oh My Pi (OMP) and Pi only. They share the same extension API
315
+ (`extensions/index.ts` declares both `omp` and `pi` extension entries), so one
316
+ package serves both. Other AI agents (OpenCode, KiloCode, Cursor, ...) have their
317
+ own plugin systems and do not load this extension.
318
+
319
+ ---
320
+
321
+ ### Contributing
322
+
323
+ Contributions welcome — bug fixes, new relay platforms, model additions, docs improvements.
324
+
325
+ #### Prerequisites
326
+
327
+ - **Node.js ≥ 22.19.0** (uses `--experimental-strip-types`, no build step)
328
+ - **pnpm** (package manager)
329
+
330
+ #### Setup & Verify
331
+
332
+ ```bash
333
+ git clone https://github.com/trefeon/pi-freeflow
334
+ cd pi-freeflow
335
+ pnpm install
336
+
337
+ # run all three before opening a PR
338
+ pnpm test # full suite; sandboxed + network-mocked
339
+ pnpm typecheck # tsc --noEmit, must pass clean
340
+ pnpm smoke # verifies extensions/index.ts loads without crashing
341
+ ```
342
+
343
+ #### Project Structure
344
+
345
+ ```
346
+ src/
347
+ ├── index.ts # extension entry, lifecycle hooks
348
+ ├── models.ts # 26-model catalog definitions
349
+ ├── catalog.ts # model catalog cache (24h disk)
350
+ ├── proxy.ts # local proxy server (127.0.0.1:28180)
351
+ ├── relay.ts # relay selection & round-robin
352
+ ├── relay-state.ts # relay pool state, health tracking
353
+ ├── stream-pipe.ts # SSE stream piping & truncation resilience
354
+ ├── commands.ts # /freeflow CLI subcommands
355
+ ├── deploy.ts # guided relay deploy (vercel/cloudflare/deno)
356
+ ├── config.ts # constants, whitelists, paths, and runtime settings
357
+ ├── logger.ts # file logger with 10MB rotation
358
+ └── types.ts # shared type definitions
359
+ extensions/
360
+ └── index.ts # OMP/Pi extension manifest
361
+ test/
362
+ └── *.test.ts # mirrors src/, node:test runner
363
+ ```
364
+
365
+ #### Guidelines
366
+
367
+ - **Stay thin.** Zero runtime dependencies, no build step. If it belongs in the host (`pi-ai`), don't add it here.
368
+ - **Test what you touch.** Every `src/*.ts` has a matching `test/*.test.ts`. Add or update tests for your change.
369
+ - **Keep model IDs clean.** Slash-free, colon-free aliases for CLI compatibility. See existing patterns in `models.ts`.
370
+ - **One concern per PR.** Bug fix? One PR. New relay platform? Separate PR. Easier to review, faster to merge.
371
+
372
+ #### Reporting Issues
373
+
374
+ Found a bug or want a feature? [Open an issue](https://github.com/trefeon/pi-freeflow/issues) with:
375
+ - What happened vs what you expected
376
+ - Your relay setup (`/freeflow status` output helps)
377
+ - Relevant logs (`/freeflow logs` or `~/.pi/agent/pi-freeflow.log`)
378
+
379
+ ---
380
+
381
+ ### License
382
+
383
+ MIT © trefeon
384
+