Skip to content

download: fix plugin wasm 404 coercion + api.github.com rate-limit lockout; back off failed installs#2

Open
dywongcloud wants to merge 1 commit into
AnEntrypoint:mainfrom
dywongcloud:fix/plugin-install-404-and-rate-limit
Open

download: fix plugin wasm 404 coercion + api.github.com rate-limit lockout; back off failed installs#2
dywongcloud wants to merge 1 commit into
AnEntrypoint:mainfrom
dywongcloud:fix/plugin-install-404-and-rate-limit

Conversation

@dywongcloud

Copy link
Copy Markdown

Summary

Three interlocking defects made bert/libsql/treesitter permanently uninstallable under agentplug-runner — the root cause of two live-hit failures: embed_text always failing (memorize-fire refusing NULL-embedding inserts, recall falling back to LIKE search with invalid query embedding) and codesearch stuck in fallback_kv with libsql_ok=false and zero chunks ever indexed.

  1. Every non-gm plugin's wasm URL was coerced to plugkit.wasm. ensure_plugin_installed's effective_basename decision (written for gm's plugkit-slim-vs-plugkit fallback) ran for every plugin: bert's sha sidecar fetch succeeded under its own name, then the wasm fetch requested agentplug-bert-bin/.../plugkit.wasm — a guaranteed 404 (live-verified: bert.wasm.sha256 = 200, same-release plugkit.wasm = 404). Non-gm plugins now keep their own basename; extracted to a pure effective_wasm_basename() with unit tests.

  2. "Latest" version resolution burned the unauthenticated api.github.com rate limit. Combined with (3), the 60-req/hour/IP budget was exhausted within minutes of boot, permanently locking out all plugin installs (live-witnessed: API rate limit exceeded on all three plugin-bin repos while the releases were fine). Version tags now come from the plain github.com/<repo>/releases/latest/download/<asset> redirect's first-hop Location header — not API-rate-limited, no auth needed.

  3. Failed installs were retried every ~200ms daemon tick — each a fresh network round trip plus a 5×/sec error log line. PluginModules now backs off 60s per failed plugin, skipping silently inside the window.

Why the wasm-side bert fallback (which saved the retired JS host) doesn't apply here: under agentplug the gm plugin ships as plugkit-slim.wasm, which deliberately carries no baked-in bert weights — correctness requires host_vec_embed's bert sibling to actually load, i.e. bert.wasm must install.

Test plan

  • cargo build --release — clean, zero warnings
  • cargo test -p agentplug-runner — 4/4 passing (basename coercion regression table, CDN-querystring slim detection, fat-fallback case, redirect-Location tag parsing)
  • Live-verified on the previously-broken machine: bert/libsql/treesitter all download+sha256-verify+install via the fixed path; against the rebuilt runner, a real memorize-fire dispatch returns ok:true, embedded:true, recall returns cosine-ranked vector hits, and codesearch returns mode:fusion with real symbol hits (fetchWithTimeout/ensureSessionMinted from ui/lib/api.ts) instead of fallback_kv-empty

🤖 Generated with Claude Code

…e-limit lockout; daemon: back off failed plugin installs

Three interlocking defects that together made bert/libsql/treesitter
permanently uninstallable under agentplug-runner -- which is what broke
embed_text (memorize-fire "embed_text failed ... refusing silent-NULL-
embedding insert", recall "invalid query embedding" LIKE-fallback; no bert
sibling for host_vec_embed, and plugkit-slim.wasm deliberately carries no
baked-in bert weights so the wasm-side fallback that saved the retired JS
host cannot engage) and codesearch (permanent libsql_ok=false fallback_kv
mode with zero chunks ever indexed; no libsql sibling):

1. ensure_plugin_installed's effective_basename decision -- written for
   gm's plugkit-slim-vs-plugkit fallback -- ran for EVERY plugin and
   coerced every non-slim download to "plugkit": bert's sha sidecar fetch
   succeeded under its own name, then the wasm fetch requested
   agentplug-bert-bin/.../plugkit.wasm, a guaranteed 404 (live-verified:
   bert.wasm.sha256 = 200, same-release plugkit.wasm = 404). Non-gm
   plugins now keep their own basename; only gm's fat-fallback case
   coerces (extracted to effective_wasm_basename() with unit tests).

2. "Latest" version resolution used unauthenticated api.github.com
   releases/latest calls (60 requests/hour/IP). Combined with defect 3
   this exhausted the budget within minutes of boot and then permanently
   locked out every plugin install on the machine -- live-witnessed as
   "API rate limit exceeded" on all three plugin-bin repos while the
   releases themselves were fine. Both fetch_latest_plugin_version and
   fetch_latest_runner_version now resolve the tag from the plain
   github.com releases/latest/download/<asset> redirect's first-hop
   Location header (resolve_latest_tag_via_redirect) -- not API
   rate-limited, no auth needed, and the redirect fires before any
   asset-existence check so it needs no slim/fat fallback of its own.

3. The daemon's compile-ahead pass retried a failing plugin install on
   every ~200ms main-loop tick -- each attempt a fresh network round trip
   (the API-quota burner above) plus a five-times-a-second error log
   line. PluginModules now records failed_at per plugin and backs off
   PLUGIN_INSTALL_RETRY_BACKOFF (60s) before re-attempting, skipping
   silently inside the window so the tick loop stops spamming both the
   remote and the log.

Verified live on the previously-broken machine: bert/libsql/treesitter
all download+sha-verify+install via the fixed path, and against the
rebuilt runner a real memorize-fire dispatch returns ok:true
embedded:true, recall returns genuine cosine-ranked vector hits, and
codesearch returns mode:fusion with real symbol hits (fetchWithTimeout /
ensureSessionMinted from ui/lib/api.ts) instead of fallback_kv-empty.
cargo test -p agentplug-runner: 4/4 passing.
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.

1 participant