pi-freeflow 1.28.0 → 1.29.0

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/CHANGELOG.md CHANGED
@@ -1,5 +1,19 @@
1
1
  # Changelog
2
2
 
3
+ ## 1.29.0
4
+
5
+ ### Minor Changes
6
+
7
+ - e119a71: Sync upstream tracking to v1.18.34 and land compatibility improvements: Vercel relays are now treated as a last resort behind Cloudflare with clear quota guidance, new relays show when a deployment is disabled by quota, and streamed responses plus tool-using callers stay compatible through the local proxy.
8
+
9
+ ## 1.28.1
10
+
11
+ ### Patch Changes
12
+
13
+ - Retry relay reachability checks after deployment so edge routing propagation delays do not show a fresh relay as unreachable — the check retries with progress notices and only warns if the relay stays dark.
14
+
15
+ Fix upstream drift alerts to stop flagging commercial paid model families as free candidates, while known alpha and stealth free models keep their free status.
16
+
3
17
  ## 1.28.0
4
18
 
5
19
  ### Minor Changes
package/README.md CHANGED
@@ -82,17 +82,24 @@ stays in memory and is never written to disk.
82
82
 
83
83
  Manual fallback per platform:
84
84
 
85
- **Option A: Cloudflare Workers, auto deploy**
85
+ **Option A: Cloudflare Workers, auto deploy (recommended)**
86
86
  ```bash
87
87
  /freeflow deploy cloudflare # prompts token in-memory, auto-adds to pool
88
+ # or shorthand: /freeflow deploy (defaults to Cloudflare)
88
89
  ```
89
90
  Manual fallback: `dash.cloudflare.com` → Workers → Create → Deploy → Edit code → paste the canonical worker source (see below) → Deploy → `/freeflow add https://your.workers.dev cf-worker-1`
90
91
 
91
- **Option B: Vercel Edge Relay, auto deploy**
92
+ **Option B: Deno Deploy, auto deploy**
93
+ ```bash
94
+ /freeflow deploy deno # prompts token in-memory, auto-adds to pool
95
+ ```
96
+ 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`
97
+
98
+ **Option C: Vercel Edge Relay (last resort, paid plan only)**
92
99
  ```bash
93
100
  /freeflow deploy vercel # prompts token in-memory, auto-adds to pool
94
- # or shorthand: /freeflow deploy
95
101
  ```
102
+ Only use with a paid plan: the Hobby plan caps Fast Origin Transfer at 10 GB (~1.2 MB per streaming turn, about 8,000 turns), then every deployment in the project returns HTTP 402 until the quota resets.
96
103
  Manual fallback: push 2 files (`api/relay.js` + `vercel.json`) to GitHub, then Import on `vercel.com`, then `/freeflow add https://your.vercel.app vercel-relay-1`
97
104
 
98
105
  For `api/relay.js`, use the canonical worker source (see below); `vercel.json` stays:
@@ -101,12 +108,6 @@ For `api/relay.js`, use the canonical worker source (see below); `vercel.json` s
101
108
  { "rewrites": [{ "source": "/(.*)", "destination": "/api/relay" }] }
102
109
  ```
103
110
 
104
- **Option C: Deno Deploy, auto deploy**
105
- ```bash
106
- /freeflow deploy deno # prompts token in-memory, auto-adds to pool
107
- ```
108
- 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`
109
-
110
111
  **Canonical worker source (all platforms)**
111
112
 
112
113
  The relay worker template is generated per deployment by `/freeflow deploy`, with one shared core adapted for Vercel, Cloudflare, and Deno. Deployed relays accept requests from any pi-freeflow user by default, while only forwarding to an allowlist (`https://opencode.ai`, `https://api.kilo.ai`) with private-host and path checks.
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "pi-freeflow",
3
3
  "type": "module",
4
- "version": "1.28.0",
4
+ "version": "1.29.0",
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/commands.ts CHANGED
@@ -514,7 +514,7 @@ export function createCommandSpec(
514
514
  ): Omit<RegisteredCommand, "name"> {
515
515
  return {
516
516
  description:
517
- "Relay egress: auto | on | off | hide | show | widget hide/show | status | add <URL> [name] | list | use <URL|name|index> [name] | label <target> <name> | remove <target> | test [target|opencode] [--chat] | export [path] [--include-secrets] | import <path> [--merge|--replace] [--dry-run] | logs [level] [n] | debug on|off | refresh | update | deploy vercel | deploy cloudflare | deploy deno | install-startup | uninstall-startup | cline login [--key] [slot] | cline accounts | cline logout [slot]",
517
+ "Relay egress: auto | on | off | hide | show | widget hide/show | status | add <URL> [name] | list | use <URL|name|index> [name] | label <target> <name> | remove <target> | test [target|opencode] [--chat] | export [path] [--include-secrets] | import <path> [--merge|--replace] [--dry-run] | logs [level] [n] | debug on|off | refresh | update | deploy cloudflare | deploy deno | deploy vercel | install-startup | uninstall-startup | cline login [--key] [slot] | cline accounts | cline logout [slot]",
518
518
  getArgumentCompletions: (prefix: string) =>
519
519
  [
520
520
  "auto",
@@ -536,9 +536,9 @@ export function createCommandSpec(
536
536
  "test opencode",
537
537
  "url",
538
538
  "deploy",
539
- "deploy vercel",
540
539
  "deploy cloudflare",
541
540
  "deploy deno",
541
+ "deploy vercel",
542
542
  "install-startup",
543
543
  "uninstall-startup",
544
544
  "cline",
@@ -666,20 +666,20 @@ export function createCommandSpec(
666
666
  };
667
667
 
668
668
  const DEPLOY_OPTIONS: Record<string, DeployPlatform> = {
669
- "Vercel (1M req/mo — recommended)": "vercel",
670
- "Cloudflare (100k req/day)": "cloudflare",
669
+ "Cloudflare (100k req/day — recommended)": "cloudflare",
671
670
  "Deno Deploy (100k req/day)": "deno",
671
+ "Vercel (last resort — Hobby 10GB origin cap)": "vercel",
672
672
  };
673
673
 
674
674
  const parseDeployPlatform = (raw?: string): DeployPlatform | null => {
675
675
  const v = (raw || "").trim().toLowerCase();
676
- if (!v || v === "vercel") return "vercel";
677
- if (v === "cloudflare" || v === "cf") return "cloudflare";
676
+ if (!v || v === "cloudflare" || v === "cf") return "cloudflare";
678
677
  if (v === "deno") return "deno";
678
+ if (v === "vercel") return "vercel";
679
679
  return null;
680
680
  };
681
681
 
682
- const doDeploy = async (platform: DeployPlatform = "vercel") => {
682
+ const doDeploy = async (platform: DeployPlatform = "cloudflare") => {
683
683
  const defaultName = `relay-${Date.now().toString(36)}`;
684
684
  const label =
685
685
  platform === "cloudflare"
@@ -832,6 +832,10 @@ export function createCommandSpec(
832
832
  ctx.ui.notify("No saved relays (direct upstream mode)", "info");
833
833
  return;
834
834
  }
835
+ const isDeadParked = (url: string): boolean => {
836
+ const h = getRelayHealth(url);
837
+ return h != null && h.lastStatus === 402 && Date.now() < h.cooldownUntil;
838
+ };
835
839
  const lines = relayState.relays.map((r, idx) => {
836
840
  const star = r.url === relayState.url ? "★" : " ";
837
841
  const shortName = r.label ? `[${r.label}]` : `[${shortRelayLabel(r.url, relayState.relays)}]`;
@@ -839,11 +843,13 @@ export function createCommandSpec(
839
843
  const health = getRelayHealth(r.url);
840
844
  const isCooling = health && Date.now() < health.cooldownUntil;
841
845
  const remainingSec = isCooling ? Math.ceil((health.cooldownUntil - Date.now()) / 1000) : 0;
842
- const healthBadge = isCooling
843
- ? ` ⚠️ [cooling ${remainingSec}s: ${health.lastStatus ? `HTTP ${health.lastStatus}` : "error"}]`
844
- : health?.lastLatencyMs != null && Number.isFinite(health.lastLatencyMs)
845
- ? ` ✓ [${health.lastLatencyMs}ms]`
846
- : " ✓";
846
+ const healthBadge = isDeadParked(r.url)
847
+ ? ` ✖ [dead — HTTP 402 disabled deployment, parked ${remainingSec}s]`
848
+ : isCooling
849
+ ? ` ⚠️ [cooling ${remainingSec}s: ${health.lastStatus ? `HTTP ${health.lastStatus}` : "error"}]`
850
+ : health?.lastLatencyMs != null && Number.isFinite(health.lastLatencyMs)
851
+ ? ` ✓ [${health.lastLatencyMs}ms]`
852
+ : " ✓";
847
853
  const counterText = health && (health.successCount != null || health.failureCount != null)
848
854
  ? ` ${health.successCount ?? 0} ok / ${health.failureCount ?? 0} fail`
849
855
  : "";
@@ -1144,7 +1150,14 @@ export function createCommandSpec(
1144
1150
  })
1145
1151
  .join(" | ");
1146
1152
  const clineLine = formatClineStatusSnippet(loadPool());
1147
- ctx.ui.notify(`${modeLine} | ${poolLine}\n${stateFileLine}\nUpstream: ${upstreamLine}\n${clineLine}`, "info");
1153
+ const deadParked = relayState.relays.filter((r) => {
1154
+ const h = getRelayHealth(r.url);
1155
+ return h != null && h.lastStatus === 402 && Date.now() < h.cooldownUntil;
1156
+ });
1157
+ const deadLine = deadParked.length
1158
+ ? `\nDead relays (HTTP 402 disabled deployment, parked): ${deadParked.map((r) => r.url).join(", ")} — delete the Vercel project, run /freeflow remove <url>, then deploy Cloudflare`
1159
+ : "";
1160
+ ctx.ui.notify(`${modeLine} | ${poolLine}\n${stateFileLine}\nUpstream: ${upstreamLine}\n${clineLine}${deadLine}`, "info");
1148
1161
  } else if (sub === "kill" || sub === "stop" || sub === "shutdown") {
1149
1162
  const port = getClientPort() || PORT;
1150
1163
  try {
@@ -1815,7 +1828,7 @@ export function createCommandSpec(
1815
1828
  const pf = parseDeployPlatform(rest);
1816
1829
  if (!pf) {
1817
1830
  ctx.ui.notify(
1818
- "Unknown platform. Use: vercel | cloudflare | deno",
1831
+ "Unknown platform. Use: cloudflare | deno | vercel",
1819
1832
  "warning",
1820
1833
  );
1821
1834
  } else {
@@ -1840,9 +1853,9 @@ export function createCommandSpec(
1840
1853
  "Share relays (export file)…",
1841
1854
  "Load relays from file (import)…",
1842
1855
  "List saved relays",
1843
- "Deploy Vercel relay…",
1844
1856
  "Deploy Cloudflare relay…",
1845
1857
  "Deploy Deno relay…",
1858
+ "Deploy Vercel relay (last resort)…",
1846
1859
  "Mode: AUTO (auto-detect on model select)",
1847
1860
  "Mode: ON (always relay)",
1848
1861
  "Mode: OFF (always direct)",
@@ -1865,7 +1878,7 @@ export function createCommandSpec(
1865
1878
  await runImport(picked, "merge", false);
1866
1879
  } else if (choice === "List saved relays") {
1867
1880
  showList();
1868
- } else if (choice === "Deploy Vercel relay…") {
1881
+ } else if (choice === "Deploy Vercel relay (last resort)…") {
1869
1882
  await doDeploy("vercel");
1870
1883
  } else if (choice === "Deploy Cloudflare relay…") {
1871
1884
  await doDeploy("cloudflare");