pi-freeflow 1.4.3 → 1.4.5
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 +17 -25
- package/package.json +1 -1
- package/src/catalog.ts +38 -10
- package/src/index.ts +1 -1
- package/src/models.ts +12 -56
- package/src/proxy.ts +4 -14
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# pi-freeflow 🌊
|
|
2
2
|
|
|
3
|
-
> **
|
|
3
|
+
> **21 free models. Up to 1M context. Zero API keys. Infinite scale via your own relay pool.**
|
|
4
4
|
|
|
5
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
6
|
|
|
@@ -18,7 +18,7 @@ Join devs bypassing rate limits with their own relay pools. BYO, add as many as
|
|
|
18
18
|
|
|
19
19
|
| Feature | Description | Value | Cost |
|
|
20
20
|
| :--- | :--- | :--- | :--- |
|
|
21
|
-
| **
|
|
21
|
+
| **21 Curated Free Models** | 7 OpenCode Zen + 14 KiloCode Gateway models, up to 1M context & 512K output | Ceiling Unlocked | **$0** |
|
|
22
22
|
| **BYO Relay Pool** | Round-robin load balancing across your Cloudflare Workers & Vercel Edges | Zero Rate Limits | **$0** (your free tiers) |
|
|
23
23
|
| **Adaptive Health & Error Detection** | Auto-cooldown on 429 rate limits, 504 timeouts, and socket drops | 0ms Wasted Latency | **$0** |
|
|
24
24
|
| **Stream Truncation Resilience** | Stateful SSE terminal tracking (`response.failed` / `response.incomplete` injection) | Zero Host Crashes | **$0** |
|
|
@@ -32,21 +32,19 @@ Philosophy: **Thin by design.** We only ship model list + relay proxy + log. Hos
|
|
|
32
32
|
|
|
33
33
|
---
|
|
34
34
|
|
|
35
|
-
###
|
|
35
|
+
### 21 Curated Models, One Command
|
|
36
36
|
|
|
37
37
|
```bash
|
|
38
38
|
/model → freeflow → pick
|
|
39
39
|
```
|
|
40
40
|
|
|
41
|
-
#### OpenCode Zen (
|
|
41
|
+
#### OpenCode Zen (7 Models), Responses & Chat API
|
|
42
42
|
Optimized for deep reasoning, long-horizon coding & autonomous agentic workflows.
|
|
43
43
|
|
|
44
44
|
| Model ID | Creator / Lab | Context | Max Output | Thinking | Vision |
|
|
45
45
|
| :--- | :--- | :--- | :--- | :--- | :--- |
|
|
46
46
|
| `muse-spark-1.2-contributor-free` | Meta Superintelligence Labs | **1M** (1.048.576) | **131K** (131.072) | `minimal / low / medium / high / xhigh / max` | ✅ |
|
|
47
|
-
| `x-preview-f-free` | Ox Alpha | **1M** (1.048.576) | **131K** (131.072) | `low / high / max` | ✅ |
|
|
48
47
|
| `mimo-v2.5-free` | Xiaomi MiMo | **1M** (1.048.576) | **131K** (131.072) | `low / medium / high` | ✅ |
|
|
49
|
-
| `deepseek-v4-flash-free` | DeepSeek | **1M** (1.000.000) | **384K** (384.000) | `low / high / max` | ❌ |
|
|
50
48
|
| `laguna-s-2.1-free` | Poolside | **1M** (1.048.576) | **131K** (131.072) | `low / high / max` | ❌ |
|
|
51
49
|
| `nemotron-3.5-lightning-free` | NVIDIA | **1M** (1.000.000) | **262K** (262.144) | `low / high / max` | ❌ |
|
|
52
50
|
| `nemotron-3-ultra-free` | NVIDIA | **1M** (1.000.000) | **128K** (128.000) | `low / high / max` | ❌ |
|
|
@@ -107,7 +105,7 @@ Manage your relay pool directly from the OMP / Pi terminal:
|
|
|
107
105
|
/freeflow label <index|url> <name># Assign a friendly label to a relay
|
|
108
106
|
/freeflow remove <index|url|label># Remove a relay from the pool
|
|
109
107
|
/freeflow on | off | auto # Toggle relay mode (auto = enabled for freeflow)
|
|
110
|
-
/freeflow deploy
|
|
108
|
+
/freeflow deploy <platform> # Guided relay deploy: vercel|cloudflare|deno — token in-memory, auto-adds (Vercel 1M/mo recommended)
|
|
111
109
|
/freeflow logs [lines] # Inspect recent proxy logs
|
|
112
110
|
/freeflow debug on | off # Toggle full HTTP lifecycle debug logging
|
|
113
111
|
```
|
|
@@ -148,9 +146,11 @@ Default ships direct. Add relays via `/freeflow add <url> [label]`.
|
|
|
148
146
|
|
|
149
147
|
**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.
|
|
150
148
|
|
|
151
|
-
**Option A: Cloudflare Workers (100k req/day, no 25s timeout)**
|
|
152
|
-
|
|
153
|
-
|
|
149
|
+
**Option A: Cloudflare Workers (100k req/day, no 25s timeout) — Auto Deploy**
|
|
150
|
+
```bash
|
|
151
|
+
/freeflow deploy cloudflare # prompts token in-memory, auto-adds to pool
|
|
152
|
+
```
|
|
153
|
+
*Manual fallback:* `dash.cloudflare.com` → Workers → Create → Deploy → Edit code → paste snippet below → Deploy → `/freeflow add https://your.workers.dev cf-worker-1`
|
|
154
154
|
|
|
155
155
|
```js
|
|
156
156
|
// Only the 2 upstreams pi-freeflow talks to. Anything else = open proxy abuse.
|
|
@@ -170,20 +170,18 @@ export default {
|
|
|
170
170
|
},
|
|
171
171
|
};
|
|
172
172
|
```
|
|
173
|
-
3. Deploy and add it:
|
|
174
173
|
|
|
174
|
+
**Option B: Vercel Edge Relay (1M req/mo) — Auto Deploy**
|
|
175
175
|
```bash
|
|
176
|
-
|
|
176
|
+
/freeflow deploy vercel # prompts token in-memory, auto-adds to pool
|
|
177
|
+
# or shorthand: /freeflow deploy
|
|
177
178
|
```
|
|
178
179
|
|
|
179
|
-
**Option
|
|
180
|
+
**Option C: Deno Deploy (100k req/day) — Auto Deploy**
|
|
180
181
|
```bash
|
|
181
|
-
/freeflow deploy # prompts token in-memory, auto-adds to pool
|
|
182
|
+
/freeflow deploy deno # prompts token in-memory, auto-adds to pool
|
|
182
183
|
```
|
|
183
|
-
|
|
184
|
-
**Option C: Deno Deploy (100k req/day)**
|
|
185
|
-
1. Go to `dash.deno.com` → New Project → Playground
|
|
186
|
-
2. Paste this relay and click **Deploy**:
|
|
184
|
+
*Manual fallback:* `dash.deno.com` → New Project → Playground → paste snippet below → Deploy → `/freeflow add https://your-project.deno.dev deno-relay-1`
|
|
187
185
|
|
|
188
186
|
```ts
|
|
189
187
|
const ALLOWED_TARGETS = ["https://opencode.ai", "https://api.kilo.ai"];
|
|
@@ -201,12 +199,6 @@ Deno.serve(async (req) => {
|
|
|
201
199
|
});
|
|
202
200
|
```
|
|
203
201
|
|
|
204
|
-
3. Add it:
|
|
205
|
-
|
|
206
|
-
```bash
|
|
207
|
-
/freeflow add https://your-project.deno.dev deno-relay-1
|
|
208
|
-
```
|
|
209
|
-
|
|
210
202
|
**Verify your pool:**
|
|
211
203
|
```bash
|
|
212
204
|
/freeflow status # relay-A 1/N (ON) → candidates:N
|
|
@@ -285,7 +277,7 @@ pnpm smoke # verifies extensions/index.ts loads without crashing
|
|
|
285
277
|
```
|
|
286
278
|
src/
|
|
287
279
|
├── index.ts # extension entry, lifecycle hooks
|
|
288
|
-
├── models.ts #
|
|
280
|
+
├── models.ts # 21-model catalog definitions
|
|
289
281
|
├── catalog.ts # model catalog cache (24h disk)
|
|
290
282
|
├── proxy.ts # local proxy server (127.0.0.1:18080)
|
|
291
283
|
├── relay.ts # relay selection & round-robin
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pi-freeflow",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "1.4.
|
|
4
|
+
"version": "1.4.5",
|
|
5
5
|
"description": "Thin provider for OMP/Pi — model list + dumb relay proxy + log; host pi-ai owns thinking/normalization",
|
|
6
6
|
"main": "extensions/index.ts",
|
|
7
7
|
"types": "src/index.ts",
|
package/src/catalog.ts
CHANGED
|
@@ -31,9 +31,14 @@ import type {
|
|
|
31
31
|
Upstream,
|
|
32
32
|
} from "./types.ts";
|
|
33
33
|
|
|
34
|
+
/**
|
|
35
|
+
* Pruned model IDs that must never re-enter the catalog via disk cache or upstream merge.
|
|
36
|
+
*/
|
|
37
|
+
const DEAD_MODEL_IDS = new Set<string>(["deepseek-v4-flash-free", "x-preview-f-free"]);
|
|
38
|
+
|
|
34
39
|
/**
|
|
35
40
|
* In-memory cache of currently active/available free models.
|
|
36
|
-
* Initialized with all
|
|
41
|
+
* Initialized with all 21 verified models for 0ms instant availability.
|
|
37
42
|
*/
|
|
38
43
|
let aliveCatalog: RegisteredModel[] = ALL_MODELS.map((m) => ({
|
|
39
44
|
...m,
|
|
@@ -58,14 +63,17 @@ export function setAliveCatalog(catalog: RegisteredModel[]): void {
|
|
|
58
63
|
* Fresh entries win on id collision; unknown fresh ids are appended after the base.
|
|
59
64
|
* Guards the background refresh against a partial upstream cache removing
|
|
60
65
|
* verified static models from provider registration.
|
|
66
|
+
* Filters pruned dead IDs so they never re-enter via fresh upstream data.
|
|
61
67
|
*/
|
|
62
68
|
export function mergeCatalog(
|
|
63
69
|
base: RegisteredModel[],
|
|
64
70
|
fresh: RegisteredModel[],
|
|
65
71
|
): RegisteredModel[] {
|
|
72
|
+
const filteredFresh = fresh.filter((m) => !DEAD_MODEL_IDS.has(m.id));
|
|
66
73
|
const byId = new Map(base.map((m) => [m.id, m]));
|
|
67
|
-
for (const m of
|
|
68
|
-
|
|
74
|
+
for (const m of filteredFresh) byId.set(m.id, m);
|
|
75
|
+
// Ensure no dead IDs survive even if base was stale
|
|
76
|
+
return [...byId.values()].filter((m) => !DEAD_MODEL_IDS.has(m.id));
|
|
69
77
|
}
|
|
70
78
|
|
|
71
79
|
/**
|
|
@@ -122,7 +130,6 @@ export function enrichModelDef(raw: RawModelItem, source: Upstream): RegisteredM
|
|
|
122
130
|
idLower.includes("r1") ||
|
|
123
131
|
idLower.includes("o1") ||
|
|
124
132
|
idLower.includes("think") ||
|
|
125
|
-
idLower.includes("alpha") ||
|
|
126
133
|
idLower.includes("spark");
|
|
127
134
|
|
|
128
135
|
let contextWindow =
|
|
@@ -162,6 +169,7 @@ export function enrichModelDef(raw: RawModelItem, source: Upstream): RegisteredM
|
|
|
162
169
|
|
|
163
170
|
/**
|
|
164
171
|
* Read cached catalog data from disk if valid and unexpired.
|
|
172
|
+
* Filters out pruned dead IDs so stale disk entries never repopulate the catalog.
|
|
165
173
|
*/
|
|
166
174
|
export function readCatalogCache(): CatalogCacheData | null {
|
|
167
175
|
try {
|
|
@@ -170,6 +178,9 @@ export function readCatalogCache(): CatalogCacheData | null {
|
|
|
170
178
|
}
|
|
171
179
|
const raw = fs.readFileSync(CATALOG_CACHE_FILE, "utf8");
|
|
172
180
|
const data = JSON.parse(raw) as CatalogCacheData;
|
|
181
|
+
if (Array.isArray(data.models)) {
|
|
182
|
+
data.models = data.models.filter((m) => !DEAD_MODEL_IDS.has(m.id));
|
|
183
|
+
}
|
|
173
184
|
if (Date.now() - data.timestamp < CATALOG_CACHE_TTL_MS) {
|
|
174
185
|
return data;
|
|
175
186
|
}
|
|
@@ -203,20 +214,37 @@ export function writeCatalogCache(data: CatalogCacheData): void {
|
|
|
203
214
|
export async function refreshCatalog(force = false): Promise<RegisteredModel[]> {
|
|
204
215
|
// Thin provider: no live fetch — subagents must not hit upstream directly
|
|
205
216
|
// (proxy-only). Host Pi/OMP owns dynamic discovery via fetchDynamicModels (24h).
|
|
206
|
-
// We only serve disk cache if fresh, otherwise static
|
|
217
|
+
// We only serve disk cache if fresh, otherwise static 21-model aliveCatalog.
|
|
207
218
|
const disk = readCatalogCache();
|
|
208
219
|
if (disk && Array.isArray(disk.models) && disk.models.length > 0) {
|
|
209
220
|
const age = Date.now() - (disk.timestamp ?? 0);
|
|
210
221
|
if (!force && age < CATALOG_CACHE_TTL_MS) {
|
|
211
|
-
aliveCatalog = disk.models;
|
|
222
|
+
aliveCatalog = disk.models.filter((m) => !DEAD_MODEL_IDS.has(m.id));
|
|
212
223
|
return aliveCatalog;
|
|
213
224
|
}
|
|
214
|
-
// Stale cache still better than empty — return it without network
|
|
215
|
-
|
|
216
|
-
|
|
225
|
+
// Stale cache still better than empty — return it without network (filtered)
|
|
226
|
+
const filtered = disk.models.filter((m) => !DEAD_MODEL_IDS.has(m.id));
|
|
227
|
+
if (filtered.length >= 21) {
|
|
228
|
+
aliveCatalog = filtered;
|
|
217
229
|
return aliveCatalog;
|
|
218
230
|
}
|
|
219
231
|
}
|
|
220
|
-
// No valid cache —
|
|
232
|
+
// No valid fresh cache — try stale disk cache directly (readCatalogCache returns null when expired)
|
|
233
|
+
try {
|
|
234
|
+
if (fs.existsSync(CATALOG_CACHE_FILE)) {
|
|
235
|
+
const raw = fs.readFileSync(CATALOG_CACHE_FILE, "utf8");
|
|
236
|
+
const stale = JSON.parse(raw) as CatalogCacheData;
|
|
237
|
+
if (Array.isArray(stale.models) && stale.models.length > 0) {
|
|
238
|
+
const filtered = stale.models.filter((m) => !DEAD_MODEL_IDS.has(m.id));
|
|
239
|
+
if (filtered.length >= 21) {
|
|
240
|
+
aliveCatalog = filtered;
|
|
241
|
+
return aliveCatalog;
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
} catch (err) {
|
|
246
|
+
logDebug("Failed reading stale catalog cache", { error: String(err) });
|
|
247
|
+
}
|
|
248
|
+
// No valid cache — return in-memory static 21 (host will refresh if needed)
|
|
221
249
|
return aliveCatalog;
|
|
222
250
|
}
|
package/src/index.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* pi-freeflow — Modular, high-resiliency LLM extension for Pi & Oh My Pi (OMP)
|
|
3
3
|
*
|
|
4
|
-
* Provides access to
|
|
4
|
+
* Provides access to 21 free models (7 OpenCode Zen + 14 KiloCode Gateway) with:
|
|
5
5
|
* - Single-port daemon reuse on 18080 across concurrent subagents
|
|
6
6
|
* - Multi-cloud rolling egress relays (Vercel Edge, Cloudflare, Deno)
|
|
7
7
|
* - 0ms instant startup with verified static catalog and background live health checks
|
package/src/models.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Static model definitions and upstream routing catalogs for pi-freeflow
|
|
3
3
|
*
|
|
4
|
-
* Defines the
|
|
5
|
-
* -
|
|
4
|
+
* Defines the 21 verified free models:
|
|
5
|
+
* - 7 OpenCode Zen models (1 Responses API + 6 Chat Completions)
|
|
6
6
|
* - 14 KiloCode Keyless Gateway models (10 OpenRouter format + 4 Standard format)
|
|
7
7
|
*/
|
|
8
8
|
|
|
@@ -13,40 +13,6 @@ import type { ModelDef, Upstream } from "./types.ts";
|
|
|
13
13
|
* Endpoint: https://opencode.ai/zen/v1
|
|
14
14
|
*/
|
|
15
15
|
export const OPENCODE_MODELS: ModelDef[] = [
|
|
16
|
-
{
|
|
17
|
-
id: "deepseek-v4-flash-free",
|
|
18
|
-
name: "DeepSeek V4 Flash (1M)",
|
|
19
|
-
reasoning: true,
|
|
20
|
-
contextWindow: 1_000_000,
|
|
21
|
-
maxTokens: 384_000,
|
|
22
|
-
input: ["text"],
|
|
23
|
-
thinkingLevelMap: {
|
|
24
|
-
off: null,
|
|
25
|
-
minimal: "low",
|
|
26
|
-
low: "low",
|
|
27
|
-
medium: "high",
|
|
28
|
-
high: "high",
|
|
29
|
-
xhigh: "max",
|
|
30
|
-
max: "max",
|
|
31
|
-
},
|
|
32
|
-
},
|
|
33
|
-
{
|
|
34
|
-
id: "x-preview-f-free",
|
|
35
|
-
name: "Ox Alpha (1M)",
|
|
36
|
-
reasoning: true,
|
|
37
|
-
contextWindow: 1_048_576,
|
|
38
|
-
maxTokens: 131_072,
|
|
39
|
-
input: ["text", "image"],
|
|
40
|
-
thinkingLevelMap: {
|
|
41
|
-
off: null,
|
|
42
|
-
minimal: "low",
|
|
43
|
-
low: "low",
|
|
44
|
-
medium: "high",
|
|
45
|
-
high: "high",
|
|
46
|
-
xhigh: "max",
|
|
47
|
-
max: "max",
|
|
48
|
-
},
|
|
49
|
-
},
|
|
50
16
|
{
|
|
51
17
|
id: "muse-spark-1.2-contributor-free",
|
|
52
18
|
name: "Muse Spark 1.2 (1M)",
|
|
@@ -305,37 +271,27 @@ export const KILO_MODELS: ModelDef[] = [
|
|
|
305
271
|
|
|
306
272
|
/**
|
|
307
273
|
* Model ID Aliases — maps user-friendly / slash-free CLI IDs to canonical upstream model IDs.
|
|
274
|
+
* Single clean alias per model (no :free duplicates). Wrong cross-lab aliases removed:
|
|
275
|
+
* - Muse Spark 1.2 = Meta Superintelligence Labs (not Anthropic Claude) → removed claude-sonnet aliases
|
|
276
|
+
* - Laguna S 2.1 = Poolside (not MiniMax) → removed minimax-m2.1 alias
|
|
277
|
+
* - Hy3 = Tencent Hunyuan (not Alibaba Qwen) → removed qwen3-coder alias
|
|
308
278
|
*/
|
|
309
279
|
export const MODEL_ALIASES: Record<string, string> = {
|
|
310
|
-
// Kilo Gateway slash-free & colon-free
|
|
280
|
+
// Kilo Gateway — slash-free & colon-free clean aliases (one per model)
|
|
311
281
|
"dots-3-note-preview": "dots-studio/dots-3-note-preview:free",
|
|
312
|
-
"dots-3-note-preview:free": "dots-studio/dots-3-note-preview:free",
|
|
313
282
|
"step-3.7-flash": "stepfun/step-3.7-flash:free",
|
|
314
|
-
"step-3.7-flash:free": "stepfun/step-3.7-flash:free",
|
|
315
283
|
"nemotron-3-nano-omni": "nvidia/nemotron-3-nano-omni-30b-a3b-reasoning:free",
|
|
316
|
-
"nemotron-3-nano-omni:free": "nvidia/nemotron-3-nano-omni-30b-a3b-reasoning:free",
|
|
317
284
|
"nemotron-3-ultra-550b": "nvidia/nemotron-3-ultra-550b-a55b:free",
|
|
318
|
-
"nemotron-3-ultra-550b:free": "nvidia/nemotron-3-ultra-550b-a55b:free",
|
|
319
285
|
"nemotron-3-super": "nvidia/nemotron-3-super-120b-a12b:free",
|
|
320
|
-
"nemotron-3-super:free": "nvidia/nemotron-3-super-120b-a12b:free",
|
|
321
|
-
"hy3:free": "tencent/hy3:free",
|
|
322
286
|
"north-mini-code": "cohere/north-mini-code:free",
|
|
323
|
-
"north-mini-code:free": "cohere/north-mini-code:free",
|
|
324
|
-
"laguna-s-2.1:free": "poolside/laguna-s-2.1:free",
|
|
325
|
-
"laguna-xs-2.1:free": "poolside/laguna-xs-2.1:free",
|
|
326
287
|
"lfm-2.5": "liquid/lfm-2.5-2.6b:free",
|
|
327
|
-
"lfm-2.5:free": "liquid/lfm-2.5-2.6b:free",
|
|
328
288
|
"content-safety": "nvidia/nemotron-3.5-content-safety:free",
|
|
329
|
-
|
|
289
|
+
// provider-prefixed short aliases (slash-normalized)
|
|
290
|
+
"hy3:free": "tencent/hy3:free",
|
|
291
|
+
"laguna-s-2.1:free": "poolside/laguna-s-2.1:free",
|
|
292
|
+
"laguna-xs-2.1:free": "poolside/laguna-xs-2.1:free",
|
|
330
293
|
"kilo-auto": "kilo-auto/free",
|
|
331
294
|
"openrouter": "openrouter/free",
|
|
332
|
-
|
|
333
|
-
// OpenCode Zen aliases
|
|
334
|
-
"claude-sonnet-4.5-free": "muse-spark-1.2-contributor-free",
|
|
335
|
-
"claude-sonnet-4.5-contributor-free": "muse-spark-1.2-contributor-free",
|
|
336
|
-
"grok-code-fast-1-preview-f-free": "x-preview-f-free",
|
|
337
|
-
"minimax-m2.1-free": "laguna-s-2.1-free",
|
|
338
|
-
"qwen3-coder-480b-free": "hy3-free",
|
|
339
295
|
};
|
|
340
296
|
|
|
341
297
|
/**
|
|
@@ -357,7 +313,7 @@ export const KILO_MODEL_IDS = new Set<string>([
|
|
|
357
313
|
]);
|
|
358
314
|
|
|
359
315
|
/**
|
|
360
|
-
* Combined list of all
|
|
316
|
+
* Combined list of all 21 static free models (canonical)
|
|
361
317
|
*/
|
|
362
318
|
export const ALL_MODELS: ModelDef[] = [...OPENCODE_MODELS, ...KILO_MODELS];
|
|
363
319
|
|
package/src/proxy.ts
CHANGED
|
@@ -88,21 +88,11 @@ export function sanitizeHeaders(
|
|
|
88
88
|
}
|
|
89
89
|
|
|
90
90
|
/**
|
|
91
|
-
*
|
|
92
|
-
*
|
|
91
|
+
* Reasoning normalization is owned by host pi-ai; proxy passes through reasoning fields unchanged.
|
|
92
|
+
* Kept as no-op for compatibility — no per-model clamping.
|
|
93
93
|
*/
|
|
94
|
-
function sanitizeReasoningForModel(
|
|
95
|
-
|
|
96
|
-
if (model.includes("x-preview")) {
|
|
97
|
-
const effort = String(bodyObj.reasoning_effort || "").toLowerCase();
|
|
98
|
-
if (effort === "medium") {
|
|
99
|
-
bodyObj.reasoning_effort = "high";
|
|
100
|
-
} else if (effort === "minimal") {
|
|
101
|
-
bodyObj.reasoning_effort = "low";
|
|
102
|
-
} else if (!effort || effort === "off" || effort === "none") {
|
|
103
|
-
bodyObj.reasoning_effort = "low";
|
|
104
|
-
}
|
|
105
|
-
}
|
|
94
|
+
function sanitizeReasoningForModel(_bodyObj: Record<string, unknown>): void {
|
|
95
|
+
// no-op
|
|
106
96
|
}
|
|
107
97
|
/**
|
|
108
98
|
* Probe whether an existing pi-freeflow proxy daemon is running and responsive on a given port.
|