Skip to content

Stop a preset that does not fit from taking the whole shell down - #64

Merged
AndrewCTF merged 3 commits into
masterfrom
claude/repo-setup-ui-access-hj3wtw
Jul 31, 2026
Merged

Stop a preset that does not fit from taking the whole shell down#64
AndrewCTF merged 3 commits into
masterfrom
claude/repo-setup-ui-access-hj3wtw

Conversation

@AndrewCTF

@AndrewCTF AndrewCTF commented Jul 31, 2026

Copy link
Copy Markdown
Owner

GET /api/ai/hardware nulls tier/repo_id/quant/est_size_gb for any preset the
box cannot run (_preset_dict(entry=None, ...) in app/localllm/hardware.py),
but the frontend typed those four fields as always-present and called
est_size_gb.toFixed() on them. On a machine with no GPU the speed preset is
always null, so the first-run wizard threw during render and the error
boundary replaced the ENTIRE console with "PANEL ERROR: shell". The globe,
the layer rail and every app were unreachable — on any keyless no-GPU box.

Type the four fields as nullable, which is what the backend actually
publishes, and render the missing ones as the house "no value reported" dash.
A preset with no repo/quant has nothing to download, so its card offers
"unavailable" rather than posting a null repo id.

Typecheck found the second consumer this would have crashed on: PresetsRow
passed the same nullable repo_id/quant straight into onDownload.

claude added 3 commits July 31, 2026 03:49
GET /api/ai/hardware nulls tier/repo_id/quant/est_size_gb for any preset the
box cannot run (`_preset_dict(entry=None, ...)` in app/localllm/hardware.py),
but the frontend typed those four fields as always-present and called
`est_size_gb.toFixed()` on them. On a machine with no GPU the speed preset is
always null, so the first-run wizard threw during render and the error
boundary replaced the ENTIRE console with "PANEL ERROR: shell". The globe,
the layer rail and every app were unreachable — on any keyless no-GPU box.

Type the four fields as nullable, which is what the backend actually
publishes, and render the missing ones as the house "no value reported" dash.
A preset with no repo/quant has nothing to download, so its card offers
"unavailable" rather than posting a null repo id.

Typecheck found the second consumer this would have crashed on: PresetsRow
passed the same nullable repo_id/quant straight into onDownload.
httpx only consults HTTPS_PROXY/NO_PROXY when `transport` is left unset
(`allow_env_proxies = trust_env and transport is None`), and get_client()
must pass a transport for the IPv4 local_address pin. That combination
silently disabled proxy support for every upstream call: behind an egress
proxy, any host reachable ONLY through that proxy died as a ReadTimeout.

Measured on a proxied box: celestrak.org timed out on every attempt while
curl through the same proxy answered 200 in 0.9 s, so /api/space/gp 500'd and
the satellite layer sat at zero. The directly-routable feeds (adsb.lol,
OpenSky, Carto, ShipXplorer) all worked, which is what made it look like a
CelesTrak-side throttle rather than our client.

Rebuild the per-pattern map httpx would have built and mount it. A NO_PROXY
entry maps to a direct transport, so the localhost sidecars (:8090/:8093)
keep bypassing the proxy. With nothing configured the map is empty and the
client behaves exactly as before, which is the unproxied default.
Several upstreams gate on the caller's IP rather than a key: airplanes.live
403s a datacenter address, adsb.lol rate-limits per source IP, and OpenSky's
anonymous credit budget is per IP. An operator with their own egress addresses
had no way to spread load across them.

UPSTREAM_PROXIES adds a rotating pool to the shared client, as a transport so
every existing get_client() call site is covered untouched. A proxy that errors
goes on a cooldown rather than being dropped (the usual cause is transient) and
the next request skips it. Empty config returns None and the client is wired
exactly as before, so the default path is unchanged.

Two deliberate defaults:

- Fails CLOSED when every proxy is cooling down. Configuring a proxy usually
  means "not from my own address", so a silent direct fallback would leak the
  thing the proxy was for. UPSTREAM_PROXY_FALLBACK_DIRECT opts in.
- Loopback always bypasses the pool. The :8090/:8093 sidecars are same-host; an
  external hop cannot reach them and would publish their traffic.

An explicit pool outranks HTTPS_PROXY. Found live, not by inspection: httpx
consults mounts before the default transport, so the env "https://" mount
answered all four test requests while the pool recorded zero successes — the
pool was dead code whenever the environment set a proxy. NO_PROXY exclusions
still apply, since those say "do not proxy this host" and bind the pool too.

There is no discovery and no bundled list, only what the operator configures.
Public free-proxy pools are largely consumer machines enrolled by malware whose
owners never agreed to carry traffic, and interception nodes that would read
every query the console makes; harvesting them would hand somebody else's
device the bill for our rate limits.

Credentials are redacted in stats and logs. Baseline 2124 -> 2141.
@AndrewCTF
AndrewCTF force-pushed the claude/repo-setup-ui-access-hj3wtw branch from 7c845cc to 9068962 Compare July 31, 2026 09:56
@AndrewCTF
AndrewCTF merged commit 1d4bdd1 into master Jul 31, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants